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
| Parameter | Description | Required |
|---|---|---|
userAddr | Solana wallet address that requested the quote. Must match the quote request. | Yes |
pathId | Path ID returned from /sor/quote/v3. | Yes |
simulate | Request assemble-time simulation metadata. Solana simulation results are currently informational and are not authoritative execution guarantees. Defaults to false. | No |
Example: Assemble a Transaction
- JavaScript
- Python
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);
import requests
assemble_url = "https://solana-beta-api.odos.xyz/sor/assemble"
assemble_request_body = {
"userAddr": "MWd2HaFHzC7fPy4YKMbuJfUqrrn7HsouhPXrBwp8tff",
"pathId": quote["pathId"],
"simulate": True,
}
response = requests.post(assemble_url, json=assemble_request_body)
assembled = response.json()
print(assembled["transaction"]["data"])
Response Body
| Parameter | Description |
|---|---|
transaction | Solana transaction data and metadata to sign and submit. |
computeUnits | Compute unit limit for the assembled transaction. |
simulation | Informational simulation metadata returned when requested. isSuccess: false is not currently an authoritative transaction failure signal. |
traceId | Request 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.
| Parameter | Description |
|---|---|
data | Base64-encoded Solana transaction data returned by assembly. Decode and sign this value exactly as provided. |
computeUnitsLimit | Compute unit limit for the transaction. |
feePayer | Solana wallet address paying transaction fees. |
recentBlockhash | Recent blockhash included in the transaction message. |
priorityFeeMicroLamports | Priority 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:
- Decode
transaction.datafrom base64. - Create a signed transaction with the wallet or keypair that matches
userAddr. - 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);