curl --request POST \
--url https://trails-api.sequence.app/rpc/Trails/WaitIntentReceipt \
--header 'Content-Type: application/json' \
--header 'X-Access-Key: <api-key>' \
--data '
{
"intentId": "<string>",
"lastReceiptStates": [
"UNKNOWN"
]
}
'{
"intentReceipt": {
"id": 123,
"projectId": 123,
"intentId": "<string>",
"status": "QUOTED",
"ownerAddress": "<string>",
"originChainId": 123,
"destinationChainId": 123,
"depositTransactionId": 123,
"depositTransaction": {
"id": 123,
"intentId": "<string>",
"chainId": 123,
"type": "UNKNOWN",
"context": "NONE",
"fromAddress": "<string>",
"toAddress": "<string>",
"tokenAddress": "<string>",
"tokenAmount": 123,
"status": "UNKNOWN",
"calldata": "<string>",
"metaTxnId": "<string>",
"metaTxnFeeQuote": "<string>",
"precondition": {
"type": "<string>",
"chainId": 123,
"ownerAddress": "<string>",
"tokenAddress": "<string>",
"minAmount": 123
},
"depositIntentEntry": {
"intentSignature": "<string>",
"feeAmount": "<string>",
"feeToken": "<string>",
"feeCollector": "<string>",
"userNonce": 123,
"deadline": 123,
"permitSignature": "<string>",
"permitDeadline": 123,
"permitAmount": 123
},
"txnHash": "<string>",
"txnMinedAt": "<string>",
"statusReason": "<string>",
"updatedAt": "<string>",
"createdAt": "<string>"
},
"originTransactionId": 123,
"originTransaction": {
"id": 123,
"intentId": "<string>",
"chainId": 123,
"type": "UNKNOWN",
"context": "NONE",
"fromAddress": "<string>",
"toAddress": "<string>",
"tokenAddress": "<string>",
"tokenAmount": 123,
"status": "UNKNOWN",
"calldata": "<string>",
"metaTxnId": "<string>",
"metaTxnFeeQuote": "<string>",
"precondition": {
"type": "<string>",
"chainId": 123,
"ownerAddress": "<string>",
"tokenAddress": "<string>",
"minAmount": 123
},
"depositIntentEntry": {
"intentSignature": "<string>",
"feeAmount": "<string>",
"feeToken": "<string>",
"feeCollector": "<string>",
"userNonce": 123,
"deadline": 123,
"permitSignature": "<string>",
"permitDeadline": 123,
"permitAmount": 123
},
"txnHash": "<string>",
"txnMinedAt": "<string>",
"statusReason": "<string>",
"updatedAt": "<string>",
"createdAt": "<string>"
},
"destinationTransactionId": 123,
"destinationTransaction": {
"id": 123,
"intentId": "<string>",
"chainId": 123,
"type": "UNKNOWN",
"context": "NONE",
"fromAddress": "<string>",
"toAddress": "<string>",
"tokenAddress": "<string>",
"tokenAmount": 123,
"status": "UNKNOWN",
"calldata": "<string>",
"metaTxnId": "<string>",
"metaTxnFeeQuote": "<string>",
"precondition": {
"type": "<string>",
"chainId": 123,
"ownerAddress": "<string>",
"tokenAddress": "<string>",
"minAmount": 123
},
"depositIntentEntry": {
"intentSignature": "<string>",
"feeAmount": "<string>",
"feeToken": "<string>",
"feeCollector": "<string>",
"userNonce": 123,
"deadline": 123,
"permitSignature": "<string>",
"permitDeadline": 123,
"permitAmount": 123
},
"txnHash": "<string>",
"txnMinedAt": "<string>",
"statusReason": "<string>",
"updatedAt": "<string>",
"createdAt": "<string>"
},
"updatedAt": "<string>",
"createdAt": "<string>"
},
"receiptStates": [
"UNKNOWN"
],
"done": true
}Wait for an intent receipt to be ready
curl --request POST \
--url https://trails-api.sequence.app/rpc/Trails/WaitIntentReceipt \
--header 'Content-Type: application/json' \
--header 'X-Access-Key: <api-key>' \
--data '
{
"intentId": "<string>",
"lastReceiptStates": [
"UNKNOWN"
]
}
'{
"intentReceipt": {
"id": 123,
"projectId": 123,
"intentId": "<string>",
"status": "QUOTED",
"ownerAddress": "<string>",
"originChainId": 123,
"destinationChainId": 123,
"depositTransactionId": 123,
"depositTransaction": {
"id": 123,
"intentId": "<string>",
"chainId": 123,
"type": "UNKNOWN",
"context": "NONE",
"fromAddress": "<string>",
"toAddress": "<string>",
"tokenAddress": "<string>",
"tokenAmount": 123,
"status": "UNKNOWN",
"calldata": "<string>",
"metaTxnId": "<string>",
"metaTxnFeeQuote": "<string>",
"precondition": {
"type": "<string>",
"chainId": 123,
"ownerAddress": "<string>",
"tokenAddress": "<string>",
"minAmount": 123
},
"depositIntentEntry": {
"intentSignature": "<string>",
"feeAmount": "<string>",
"feeToken": "<string>",
"feeCollector": "<string>",
"userNonce": 123,
"deadline": 123,
"permitSignature": "<string>",
"permitDeadline": 123,
"permitAmount": 123
},
"txnHash": "<string>",
"txnMinedAt": "<string>",
"statusReason": "<string>",
"updatedAt": "<string>",
"createdAt": "<string>"
},
"originTransactionId": 123,
"originTransaction": {
"id": 123,
"intentId": "<string>",
"chainId": 123,
"type": "UNKNOWN",
"context": "NONE",
"fromAddress": "<string>",
"toAddress": "<string>",
"tokenAddress": "<string>",
"tokenAmount": 123,
"status": "UNKNOWN",
"calldata": "<string>",
"metaTxnId": "<string>",
"metaTxnFeeQuote": "<string>",
"precondition": {
"type": "<string>",
"chainId": 123,
"ownerAddress": "<string>",
"tokenAddress": "<string>",
"minAmount": 123
},
"depositIntentEntry": {
"intentSignature": "<string>",
"feeAmount": "<string>",
"feeToken": "<string>",
"feeCollector": "<string>",
"userNonce": 123,
"deadline": 123,
"permitSignature": "<string>",
"permitDeadline": 123,
"permitAmount": 123
},
"txnHash": "<string>",
"txnMinedAt": "<string>",
"statusReason": "<string>",
"updatedAt": "<string>",
"createdAt": "<string>"
},
"destinationTransactionId": 123,
"destinationTransaction": {
"id": 123,
"intentId": "<string>",
"chainId": 123,
"type": "UNKNOWN",
"context": "NONE",
"fromAddress": "<string>",
"toAddress": "<string>",
"tokenAddress": "<string>",
"tokenAmount": 123,
"status": "UNKNOWN",
"calldata": "<string>",
"metaTxnId": "<string>",
"metaTxnFeeQuote": "<string>",
"precondition": {
"type": "<string>",
"chainId": 123,
"ownerAddress": "<string>",
"tokenAddress": "<string>",
"minAmount": 123
},
"depositIntentEntry": {
"intentSignature": "<string>",
"feeAmount": "<string>",
"feeToken": "<string>",
"feeCollector": "<string>",
"userNonce": 123,
"deadline": 123,
"permitSignature": "<string>",
"permitDeadline": 123,
"permitAmount": 123
},
"txnHash": "<string>",
"txnMinedAt": "<string>",
"statusReason": "<string>",
"updatedAt": "<string>",
"createdAt": "<string>"
},
"updatedAt": "<string>",
"createdAt": "<string>"
},
"receiptStates": [
"UNKNOWN"
],
"done": true
}WaitIntentReceipt endpoint provides a streaming or long-polling mechanism to wait for an intent to complete. Unlike GetIntentReceipt, which requires manual polling, this endpoint holds the connection until the intent reaches a terminal state or times out.
true: Intent is complete (SUCCEEDED or FAILED)false: Intent is still processing (may require another call)SUCCEEDED or FAILED), return immediately with done: trueasync function waitForCompletion(intentId: string) {
const response = await fetch('https://trails-api.sequence.app/rpc/Trails/WaitIntentReceipt', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': 'YOUR_ACCESS_KEY'
},
body: JSON.stringify({ intentId })
});
const { intentReceipt, done } = await response.json();
if (done) {
if (intentReceipt.status === 'SUCCEEDED') {
console.log('Transaction succeeded!');
return intentReceipt;
} else {
throw new Error(`Transaction failed: ${intentReceipt.originTransaction.statusReason}`);
}
} else {
// Not done yet, call again
return waitForCompletion(intentId);
}
}
// Usage
try {
const receipt = await waitForCompletion('intent_123abc');
console.log('Completed:', receipt);
} catch (error) {
console.error('Failed:', error);
}
// Requires manual polling loop
async function pollReceipt(intentId: string) {
while (true) {
const { intentReceipt } = await getIntentReceipt(intentId);
if (intentReceipt.status === 'SUCCEEDED' || intentReceipt.status === 'FAILED') {
return intentReceipt;
}
await new Promise(resolve => setTimeout(resolve, 2000)); // 2s delay
}
}
// Automatic waiting, no manual delay needed
async function waitReceipt(intentId: string) {
const { intentReceipt, done } = await waitIntentReceipt(intentId);
if (!done) {
return waitReceipt(intentId); // Recursively wait if needed
}
return intentReceipt;
}
WaitIntentReceipt is more efficient as it reduces the number of API calls and provides near-instant updates.async function waitWithProgress(intentId: string, onProgress?: (status: string) => void) {
let lastStatus = '';
const wait = async (): Promise<IntentReceipt> => {
const { intentReceipt, done } = await fetch(
'https://trails-api.sequence.app/rpc/Trails/WaitIntentReceipt',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': 'YOUR_ACCESS_KEY'
},
body: JSON.stringify({ intentId })
}
).then(r => r.json());
// Report progress if status changed
if (intentReceipt.status !== lastStatus) {
lastStatus = intentReceipt.status;
onProgress?.(intentReceipt.status);
}
if (done) {
return intentReceipt;
}
return wait(); // Continue waiting
};
return wait();
}
// Usage with progress callback
const receipt = await waitWithProgress('intent_123abc', (status) => {
console.log('Status update:', status);
// Update UI, show loading state, etc.
});
async function waitWithTimeout(intentId: string, timeoutMs = 300000) {
const timeoutPromise = new Promise<never>((_, reject) => {
setTimeout(() => reject(new Error('Timeout waiting for intent')), timeoutMs);
});
const waitPromise = (async () => {
let done = false;
let receipt;
while (!done) {
const response = await fetch(
'https://trails-api.sequence.app/rpc/Trails/WaitIntentReceipt',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': 'YOUR_ACCESS_KEY'
},
body: JSON.stringify({ intentId })
}
);
const data = await response.json();
receipt = data.intentReceipt;
done = data.done;
}
return receipt;
})();
return Promise.race([waitPromise, timeoutPromise]);
}
try {
const receipt = await waitWithTimeout('intent_123abc', 60000); // 1 minute timeout
console.log('Completed:', receipt);
} catch (error) {
console.error('Timed out or failed:', error);
}
API Key for authenticating requests, get an access key at https://trails.build and request early access
Successful response
Show child attributes
Represented as uint8 on the server side
QUOTED, COMMITTED, EXECUTING, FAILED, SUCCEEDED Show child attributes
Represented as uint8 on the server side
UNKNOWN, DEPOSIT, ORIGIN, DESTINATION, ROUTE Represented as uint8 on the server side
NONE, CCTPV2_MESSAGE Represented as uint8 on the server side
UNKNOWN, ON_HOLD, PENDING, RELAYING, SENT, ERRORED, MINING, SUCCEEDED, FAILED, ABORTED Show child attributes
Show child attributes
Show child attributes
Represented as uint8 on the server side
UNKNOWN, DEPOSIT, ORIGIN, DESTINATION, ROUTE Represented as uint8 on the server side
NONE, CCTPV2_MESSAGE Represented as uint8 on the server side
UNKNOWN, ON_HOLD, PENDING, RELAYING, SENT, ERRORED, MINING, SUCCEEDED, FAILED, ABORTED Show child attributes
Show child attributes
Show child attributes
Represented as uint8 on the server side
UNKNOWN, DEPOSIT, ORIGIN, DESTINATION, ROUTE Represented as uint8 on the server side
NONE, CCTPV2_MESSAGE Represented as uint8 on the server side
UNKNOWN, ON_HOLD, PENDING, RELAYING, SENT, ERRORED, MINING, SUCCEEDED, FAILED, ABORTED Show child attributes
Show child attributes
[]TransactionStatus
Represented as uint8 on the server side
UNKNOWN, ON_HOLD, PENDING, RELAYING, SENT, ERRORED, MINING, SUCCEEDED, FAILED, ABORTED Was this page helpful?