Tron
What the profile facilitator verifies and settles for x402/exact/tron/lcp-trc20-memo.
On Tron, H rides in the payer's own signed transaction: raw_data.data holds the 77 ASCII bytes lcp:sha256:
followed by H, beside exactly one TRC-20 transfer(payTo, amount). The payer pays every fee: energy, bandwidth and the
network's memo fee.
| Requirement | Value |
|---|---|
scheme | exact |
network | tron:<chain id in decimal>, such as tron:728126428 for mainnet |
amount | The token's atomic units |
asset | The TRC-20 contract, in base58check |
payTo | The payee, in base58check |
maxTimeoutSeconds | At most 86 340 |
extra.assetTransferMethod | lcp-trc20-memo |
payload.transaction | The serialized, signed Transaction, in lowercase hex |
The facilitator needs a FullNode (it calls /wallet/triggerconstantcontract, /wallet/broadcasthex and
/wallet/gettransactioninfobyid) and a Solidity node (/walletsolidity/gettransactioninfobyid and
/walletsolidity/getnowblock). A java-tron node serves both, on HTTP ports 8090 and 8091 by default.
What /verify checks
In order; the first failure is the answer.
- The network is configured, and the requirements are ones the profile admits (its rule 1), else
invalid_networkorinvalid_payment_requirements. payload.transactionis a serialized TronTransactionin hex that decodes to exactly oneTriggerSmartContractwhosedatais an LCPsha256string, elseinvalid_payload.assetandpayToare Tron addresses, elseinvalid_payment_requirements.- The contract called is
asset, and the call data is exactlytransfer(payTo, amount), elseinvalid_payload. - The transaction carries exactly one signature, else
unsupported_permission. That signature recovers to the transaction's owner, elseinvalid_payload. A multi-signature owner permission is not served. expirationis in the future and no later than now plusmaxTimeoutSeconds, elseinvalid_payload.- The FullNode's
/wallet/triggerconstantcontractsimulates the transfer without failure, elseinvalid_transaction. A node that does not answer givesunexpected_verify_error.
The answer is {isValid: true, payer}, with payer the owner in base58check.
What /settle does
- Repeats every check of
/verify. - Reads the stored answer for the transaction id. A final one is returned as it is, so a repeated
/settlegets the first answer. - Claims the transaction id with one conditional insert, so concurrent settles of one payment broadcast once.
- Broadcasts the signed bytes with
/wallet/broadcasthex. ADUP_TRANSACTION_ERRORcounts as broadcast. - Reads the receipt with
gettransactioninfobyidevery second.SUCCESSat the FullNode is success. Any other result is a failure only once the Solidity node, which serves solidified blocks alone, shows it. A transaction whose expiration has passed and that no node shows once the solidified head is two slots past it can never be included, and is answeredinvalid_transaction_state. - Stores the answer and returns it.
Success is {success: true, transaction, network, payer}, where transaction is the transaction id in hex.
Where H is on chain
H is in raw_data.data, inside the bytes whose SHA-256 is the transaction id the payer signed. It is read by
transaction id from a Solidity node. No index searches memos.
Last updated on