Overview
Transactions in Agentic Wallet follow a complete lifecycle from creation through confirmation. All transactions are created via intents - high-level instructions that the platform translates into protocol-specific on-chain operations.
Transaction Lifecycle
Every transaction moves through these states:
pending
Transaction created and queued for processing
simulating
Transaction simulated on-chain to estimate costs and catch errors
policy_eval
Policy engine evaluates rules (spending limits, allowlists, etc.)
approval_gate
Transaction paused for manual approval (if required by policy)
signing
Wallet engine signs the transaction
submitting
Transaction submitted to Solana network
confirmed | failed
Final state after on-chain confirmation or failure
Creating Transactions
Basic Transfer (SOL)
npm run cli -- tx create \
--wallet-id < walletI d > \
--type transfer_sol \
--protocol system-program \
--intent '{"destination":"<pubkey>","lamports":1000000}'
curl -X POST http://localhost:3000/api/v1/transactions \
-H "Content-Type: application/json" \
-H "x-api-key: dev-api-key" \
-d '{
"walletId": "<walletId>",
"type": "transfer_sol",
"protocol": "system-program",
"intent": {
"destination": "<destination-pubkey>",
"lamports": 1000000
}
}'
const tx = await client . transaction . create ({
walletId: walletId ,
type: 'transfer_sol' ,
protocol: 'system-program' ,
intent: {
destination: destinationPubkey ,
lamports: 1_000_000
}
});
console . log ( `Transaction ID: ${ tx . id } ` );
console . log ( `Status: ${ tx . status } ` );
SPL Token Transfer
{
"walletId" : "<walletId>" ,
"type" : "transfer_spl" ,
"protocol" : "spl-token" ,
"intent" : {
"destination" : "<destination-pubkey>" ,
"mint" : "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" ,
"amount" : "1000000"
}
}
Token Swap
{
"walletId" : "<walletId>" ,
"type" : "swap" ,
"protocol" : "jupiter" ,
"intent" : {
"inputMint" : "So11111111111111111111111111111111111111112" ,
"outputMint" : "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" ,
"amount" : "1000000" ,
"slippageBps" : 50
}
}
Intent Structure
All transactions require these fields:
Field Type Required Description walletIdUUID Yes Wallet performing the transaction typestring Yes Transaction type (see supported types below) protocolstring Yes Protocol adapter to use intentobject Yes Protocol-specific intent payload agentIdUUID No Agent executing this transaction gaslessboolean No Use gasless transaction (if supported) idempotencyKeystring No Prevent duplicate executions
Supported Transaction Types
transfer_sol - Transfer native SOL
transfer_spl - Transfer SPL tokens
x402_pay - HTTP 402 payment flow
swap - Token swaps (Jupiter, Orca, Raydium)
stake - Stake SOL (Marinade)
unstake - Unstake SOL
lend_supply - Supply assets to lending (Solend)
lend_borrow - Borrow assets from lending
create_mint - Create new SPL token mint
mint_token - Mint tokens to address
create_escrow - Create new escrow
accept_escrow - Accept escrow as counterparty
release_escrow - Release funds to recipient
refund_escrow - Refund to creator
dispute_escrow - Initiate dispute
resolve_dispute - Resolve dispute
create_milestone_escrow - Multi-milestone escrow
release_milestone - Release specific milestone
Query Operations (Read-only)
query_balance - Check wallet balance
query_positions - Get DeFi positions
flash_loan_bundle - Flash loan operations
cpi_call - Cross-program invocation
custom_instruction_bundle - Custom instruction set
treasury_allocate - Treasury allocation
treasury_rebalance - Treasury rebalancing
paper_trade - Paper trading (simulation)
Polling for Confirmation
Transactions are processed asynchronously. Poll the transaction status:
npm run cli -- tx get < txI d >
Response Structure:
{
"status" : "success" ,
"data" : {
"id" : "tx-uuid" ,
"walletId" : "wallet-uuid" ,
"type" : "transfer_sol" ,
"protocol" : "system-program" ,
"status" : "confirmed" ,
"signature" : "5j7s..." ,
"intent" : { ... },
"createdAt" : "2026-03-08T12:00:00.000Z" ,
"confirmedAt" : "2026-03-08T12:00:05.000Z"
}
}
Idempotency Keys
Prevent duplicate transaction execution with idempotency keys:
const tx = await client . transaction . create ({
walletId: walletId ,
type: 'transfer_sol' ,
protocol: 'system-program' ,
idempotencyKey: 'payment-invoice-12345' ,
intent: {
destination: destinationPubkey ,
lamports: 1_000_000
}
});
If you submit the same idempotencyKey again, the API returns the original transaction instead of creating a duplicate.
Approval Gate Workflow
If a policy requires approval, the transaction pauses at approval_gate:
Transaction Paused
Transaction reaches approval_gate status and waits for operator action.
Review Transaction
Retrieve pending approvals: npm run cli -- tx pending --wallet-id < walletI d >
Approve or Reject
npm run cli -- tx approve < txI d >
# Or via API:
curl -X POST -H "x-api-key: dev-api-key" \
http://localhost:3000/api/v1/transactions/ < txI d > /approve
Transaction Continues
After approval, transaction proceeds to signing → submitting → confirmed.
Transaction Proofs
Every transaction generates cryptographic proof artifacts:
npm run cli -- tx proof < txI d >
Response:
{
"intentHash" : "sha256-hash-of-intent" ,
"policyHash" : "sha256-hash-of-policy-eval" ,
"simulationHash" : "sha256-hash-of-simulation" ,
"proofHash" : "combined-proof-hash" ,
"signature" : "on-chain-signature" ,
"timestamp" : "2026-03-08T12:00:00.000Z"
}
Replay Data
Get full execution replay for auditing:
npm run cli -- tx replay < txI d >
Returns complete transaction history including all state transitions and policy decisions.
Gasless Transactions
Enable gasless execution for supported protocols:
const tx = await client . transaction . create ({
walletId: walletId ,
type: 'swap' ,
protocol: 'jupiter' ,
gasless: true , // Route through Kora RPC
intent: { ... }
});
Gasless execution requires KORA_RPC_URL configured and protocol must have gaslessEligible: true in risk config.
Real Examples from Source
From scripts/devnet-smoke.ts
import 'dotenv/config' ;
import { Connection , Keypair , PublicKey , SystemProgram , Transaction } from '@solana/web3.js' ;
const apiBase = 'http://localhost:3000' ;
const apiKey = 'dev-api-key' ;
// Create wallet
const createRes = await fetch ( ` ${ apiBase } /api/v1/wallets` , {
method: 'POST' ,
headers: { 'content-type' : 'application/json' , 'x-api-key' : apiKey },
body: JSON . stringify ({ label: 'smoke-wallet' })
});
const wallet = await createRes . json ();
// Execute transfer
const transferRes = await fetch ( ` ${ apiBase } /api/v1/transactions` , {
method: 'POST' ,
headers: { 'content-type' : 'application/json' , 'x-api-key' : apiKey },
body: JSON . stringify ({
walletId: wallet . data . id ,
type: 'transfer_sol' ,
protocol: 'system-program' ,
gasless: false ,
intent: {
destination: destinationPubkey ,
lamports: 1_000_000
}
})
});
const tx = await transferRes . json ();
console . log ( `Transaction status: ${ tx . data . status } ` );
Next Steps
Setting Policies Add spending limits and security rules to your transactions
Protocol Interactions Execute DeFi operations across Jupiter, Marinade, Solend, and more