Instructions should be serialized one by one, final calldata is a concatenation of separately serialized instructions.
For the info about the rewards, substitutions, and expenses check the previous section.
Solana's TransactionInstructions could be serialized into calldata format using @debridge-finance/debridge-external-call npm package:
import*as wasm from"@debridge-finance/debridge-external-call";import { PublicKey, TransactionInstruction } from"@solana/web3.js";/** * Substitutes amount at offset with `walletBalance(accounts[account_index]) - subtraction` */typeAmountSubstitution= {/** * big or little endian */ is_big_endian:boolean;/** * At what offset substitution should be done */ offset:number;/** * index of account in TransactionInstruction.keys to get balance for */ account_index:number;/** * Amount to deduct from wallet balance */ subtraction:number;};/** * Since we don't know submissionAuth at the moment of calldata preparation we can prepare substitution to replace * account at `index` with actual ATA(submissionAuth, tokenMint) during execution */typeWalletSubstitution= {/** * Token mint to calculate ATA for */ token_mint:string;/** * Account at this index will be replaced with ATA(submissionAuth, tokenMint) during execution */ index:number;};/** * Structure required by wasm module */interfaceIExtIx { keys: { pubkey:string; isSigner:boolean; isWritable:boolean; }[]; data:Buffer; programId:string;}functionixToIExtIx(ix:TransactionInstruction):IExtIx {return { keys:ix.keys.map((meta) => ({ pubkey:meta.pubkey.toBase58(), isSigner:meta.isSigner, isWritable:meta.isWritable, })), programId:ix.programId.toBase58(), data:ix.data, };}functionserialize( instruction:TransactionInstruction, substitutions?: { amountSubstitutions?:AmountSubstitution[]; walletSubstitutions?:WalletSubstitution[]; }, expense?:bigint, reward?:bigint, isInMandatoryBlock:boolean=false,) {constixWrapper=newwasm.ExternalInstructionWrapper( reward, expense, isInMandatoryBlock,substitutions?.amountSubstitutions ?? [],substitutions?.walletSubstitutions ?? [],ixToIExtIx(instruction), );returnixWrapper.serialize();}constix1:TransactionInstruction;constix2:TransactionInstruction;constserializedIx1=serialize(ix1,undefined,1000n);constserializedIx2=serialize(ix2,undefined,2000n);constcalldata=Buffer.concat([serializedIx1, serializedIx2 /** rest serialized instructions if any */]);