Skip to main content

Assemble

The Solana /sor/assemble endpoint converts a fresh quote into transaction data for signing and submission on Solana.

A quote is valid for 60 seconds. If it is not assembled within that time, request a new quote and assemble the new pathId.

Use the transaction data from this endpoint exactly as provided. Modifying transaction data can cause failed swaps or loss of funds, and Odos does not provide support for transactions that use modified transaction data.


Request Body Parameters

ParameterDescriptionRequired
userAddrSolana wallet address that requested the quote. Must match the quote request.Yes
pathIdPath ID returned from /sor/quote/v3.Yes
simulateRequest assemble-time simulation metadata. Solana simulation results are currently informational and are not authoritative execution guarantees. Defaults to false.No

Example: Assemble a Transaction

const assembleUrl = 'https://solana-beta-api.odos.xyz/sor/assemble';

const assembleRequestBody = {
userAddr: 'MWd2HaFHzC7fPy4YKMbuJfUqrrn7HsouhPXrBwp8tff',
pathId: quote.pathId,
simulate: true
};

const response = await fetch(assembleUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(assembleRequestBody)
});

const assembled = await response.json();
console.log(assembled.transaction.data);

Response Body

ParameterDescription
transactionSolana transaction data and metadata to sign and submit.
computeUnitsCompute unit limit for the assembled transaction.
simulationInformational simulation metadata returned when requested. isSuccess: false is not currently an authoritative transaction failure signal.
traceIdRequest trace ID, useful for support.

Transaction Object

Treat the fields returned by assembly as API output, not as values to recalculate. Use the transaction data exactly as provided.

ParameterDescription
dataBase64-encoded Solana transaction data returned by assembly. Decode and sign this value exactly as provided.
computeUnitsLimitCompute unit limit for the transaction.
feePayerSolana wallet address paying transaction fees.
recentBlockhashRecent blockhash included in the transaction message.
priorityFeeMicroLamportsPriority fee in micro-lamports.

Your application is responsible for decoding the base64 transaction data, collecting a user signature, submitting the transaction, and confirming it onchain.


Example Response

{
"transaction": {
"data": "BASE64_ENCODED_TRANSACTION_DATA",
"computeUnitsLimit": 500000,
"feePayer": "MWd2HaFHzC7fPy4YKMbuJfUqrrn7HsouhPXrBwp8tff",
"recentBlockhash": "HiBsi5e8wPJPb1WCyEGxkJgfBfsQnQM9CRhjKHMeSpw4",
"priorityFeeMicroLamports": 0
},
"computeUnits": 500000,
"simulation": {
"isSuccess": false,
"gasEstimate": 0,
"amountsOut": []
},
"traceId": "13b8c84d-4d21-4d2b-8579-71b1f8c0c0c7"
}

Signing and Submission

Once you have the assembled transaction:

  1. Decode transaction.data from base64.
  2. Create a signed transaction with the wallet or keypair that matches userAddr.
  3. Submit the signed transaction to the Solana network.
import { Connection, Keypair, VersionedTransaction } from '@solana/web3.js';

const txBytes = Buffer.from(assembled.transaction.data, 'base64');
const tx = VersionedTransaction.deserialize(txBytes);

const keypair = Keypair.fromSecretKey(/* your secret key bytes */);
tx.sign([keypair]);

const connection = new Connection('https://api.mainnet-beta.solana.com');
const signature = await connection.sendTransaction(tx);
await connection.confirmTransaction(signature);