Copy <?php
/**
* Copy-and-run manual sell flow (PHP):
* 1) Fill the config below
* 2) php src/test/sellManualFlow.guide.php
*/
$API_KEY = "your_api_key"; // change it later, (CONTACT :https://t.me/wantingtrx)
$TRONSAVE_API_URL = "https://api-dev.tronsave.io"; // change it later
$INPUT_RESOURCE_TYPE = "ENERGY"; // change it later: ENERGY | BANDWIDTH
$PAGE = 0; // change it later
$PAGE_SIZE = 10; // change it later
$PAYMENT_ADDRESS = ""; // optional, change it later
$IS_ALLOW_SELL_FOR_LOCKED_DELEGATOR = false; // change it later
$SIGNED_TX_JSON = '{"txID":"your_signed_tx_id","raw_data_hex":"your_raw_data_hex"}'; // change it later
function assertConfig(
string $apiKey,
string $resourceType,
string $signedTxJson
): void {
if ($apiKey === "" || $apiKey === "your_api_key") {
throw new RuntimeException("API_KEY is required");
}
if (!in_array($resourceType, ["ENERGY", "BANDWIDTH"], true)) {
throw new RuntimeException("INPUT_RESOURCE_TYPE must be ENERGY or BANDWIDTH");
}
if (str_contains($signedTxJson, "your_signed_tx_id")) {
throw new RuntimeException("Please update SIGNED_TX_JSON");
}
}
function requestJson(string $url, string $apiKey, string $method = "GET", ?array $body = null): array
{
$headers = [
"apikey: {$apiKey}",
"content-type: application/json",
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if ($body !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body, JSON_UNESCAPED_SLASHES));
}
$raw = curl_exec($ch);
$httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($raw === false) {
$error = curl_error($ch);
curl_close($ch);
throw new RuntimeException("cURL error: {$error}");
}
curl_close($ch);
$data = json_decode($raw, true);
if (!is_array($data)) {
throw new RuntimeException("Invalid JSON response: {$raw}");
}
if ($httpCode >= 400 || !empty($data["error"])) {
$message = $data["message"] ?? "Unknown error";
throw new RuntimeException("Request failed ({$httpCode}): {$message}");
}
return $data;
}
function getOrdersActiveGlobal(string $baseUrl, string $apiKey, int $page, int $pageSize): array
{
$query = http_build_query(["page" => $page, "pageSize" => $pageSize]);
$url = "{$baseUrl}/v2/orders/active-global?{$query}";
$result = requestJson($url, $apiKey, "GET");
return $result["data"]["data"] ?? [];
}
function pickHighestPriceOrder(array $orders, string $resourceType): array
{
$candidates = array_values(array_filter($orders, function ($order) use ($resourceType) {
return ($order["status"] ?? "") === "Active"
&& (int)($order["remainAmount"] ?? 0) > 0
&& ($order["resourceType"] ?? "") === $resourceType;
}));
if (count($candidates) === 0) {
throw new RuntimeException("No active order found");
}
usort($candidates, function ($a, $b) {
$priceDiff = (float)($b["price"] ?? 0) <=> (float)($a["price"] ?? 0);
if ($priceDiff !== 0) return $priceDiff;
return (int)($b["remainAmount"] ?? 0) <=> (int)($a["remainAmount"] ?? 0);
});
return $candidates[0];
}
function sellManual(
string $baseUrl,
string $apiKey,
string $orderId,
array $signedTx,
string $paymentAddress,
bool $allowLockedDelegator
): array {
$url = "{$baseUrl}/v2/orders/sell-manual";
$payload = [
"orderId" => $orderId,
"signedTx" => $signedTx,
"paymentAddress" => $paymentAddress !== "" ? $paymentAddress : null,
"isAllowSellForLockedDelegator" => $allowLockedDelegator,
];
return requestJson($url, $apiKey, "POST", $payload);
}
try {
assertConfig($API_KEY, $INPUT_RESOURCE_TYPE, $SIGNED_TX_JSON);
$signedTx = json_decode($SIGNED_TX_JSON, true);
if (!is_array($signedTx)) {
throw new RuntimeException("SIGNED_TX_JSON must be valid JSON object");
}
echo "Step 1: Get active orders\n";
$orders = getOrdersActiveGlobal($TRONSAVE_API_URL, $API_KEY, $PAGE, $PAGE_SIZE);
$targetOrder = pickHighestPriceOrder($orders, $INPUT_RESOURCE_TYPE);
echo "Step 2: Picked highest-price active order\n";
print_r([
"orderId" => $targetOrder["id"] ?? null,
"receiver" => $targetOrder["receiver"] ?? null,
"remainAmount" => $targetOrder["remainAmount"] ?? null,
"price" => $targetOrder["price"] ?? null,
"resourceType" => $targetOrder["resourceType"] ?? null,
"durationSec" => $targetOrder["durationSec"] ?? null,
"inputResourceType" => $INPUT_RESOURCE_TYPE,
]);
echo "Step 3: Use pre-signed delegate tx from SIGNED_TX_JSON\n";
print_r(["signedTxId" => $signedTx["txID"] ?? "N/A"]);
echo "Step 4: Sell manual\n";
$result = sellManual(
$TRONSAVE_API_URL,
$API_KEY,
(string)$targetOrder["id"],
$signedTx,
$PAYMENT_ADDRESS,
$IS_ALLOW_SELL_FOR_LOCKED_DELEGATOR
);
echo "Done:\n";
print_r($result);
} catch (Throwable $e) {
fwrite(STDERR, "Failed: " . $e->getMessage() . PHP_EOL);
exit(1);
}