SDK Integration
Directly integrate the @navalabs/sdk package into your TypeScript/Node agent.
Install
npm install @navalabs/sdk
The base package has zero heavy dependencies and only needs fetch (Node 18+).
Subpath Exports
The SDK is split into three entry points so you only pull in what you need:
| Import | What you get | Extra deps |
|---|---|---|
@navalabs/sdk | NavaClient + types | None |
@navalabs/sdk/ai | Vercel AI SDK tools | ai, zod |
@navalabs/sdk/mcp | MCP server + NavaBackend interface | @modelcontextprotocol/sdk, zod |
Install optional peer dependencies only for the entry points you use:
# For Vercel AI integration
npm install ai zod
# For MCP server
npm install @modelcontextprotocol/sdk zod
NavaClient
Configuration
const nava = new NavaClient({
apiKey: 'nava_live_...', // Required - your Nava API key
walletAddress: '0x...', // Required - your wallet address
baseUrl: '...', // Optional - defaults to https://internal.navalabs.dev/api
chainId: 11155111, // Optional - defaults to 11155111 (Sepolia)
});
Methods
requestVerification(params)
Submit a transaction for arbiter review.
const result = await nava.requestVerification({
userPrompt: 'Swap 1 ETH for USDC on Uniswap',
tx: {
to: '0x...', // Target contract address
value: '0', // Value in Wei
data: '0x...', // Encoded calldata
},
protocol: 'uniswap_v3', // Optional - skips arbiter protocol detection
decodedTx: { // Optional - skips arbiter TX normalization
functionName: 'swapExactTokensForTokens',
tokenIn: { address: '0x...', symbol: 'WETH', decimals: 18 },
tokenOut: { address: '0x...', symbol: 'USDC', decimals: 6 },
amountIn: '1000000000000000000',
amountOut: '3200000000',
},
contextLogs: { ... }, // Optional - additional context for the arbiter
agentSignature: '...', // Optional - agent signature
});
// result.requestHash → '0xabc...' (use this to poll status)
// result.id → transaction UUID
// result.status → 'PENDING' (initial status)
// Throws NavaFetchError on HTTP errors
checkVerificationStatus(requestHash)
Poll for the arbiter’s decision.
const status = await nava.checkVerificationStatus('0xabc...');
// status.status → 'APPROVED' | 'REJECTED' | 'UNDECIDED' | 'PENDING' | 'NONE'
// status.decision → 'APPROVED' | 'REJECTED' | 'UNDECIDED' (when an Orion decision exists)
// status.canExecute → true only when status is APPROVED
// status.confidence → arbiter confidence score (0-1)
// status.analysis → arbiter reasoning
// status.message → human-readable summary
// status.executionTrace → per-node arbiter pipeline results (on rejection)
// status.failedNodes → IDs of nodes that failed (on rejection)
// status.primaryFailure → main node responsible for rejection
Status meanings:
- APPROVED: Transaction approved and executed (or will execute automatically)
- REJECTED: Transaction rejected; read
analysisandexecutionTracefor the arbiter’s feedback - UNDECIDED: Arbiter completed checks but could not make an approve/reject decision; treat as terminal
- PENDING: Still under review; poll again in 2-3 seconds
- NONE: No transaction found for this hash
requestAndAwaitVerification(params, options?)
Submit a transaction and block until the arbiter reaches a terminal status.
const status = await nava.requestAndAwaitVerification(
{
userPrompt: 'Swap 1 ETH for USDC',
tx: { to: '0x...', value: '0', data: '0x...' },
protocol: 'uniswap_v3',
},
{ intervalMs: 2000, maxAttempts: 30 },
);
Throws NavaTimeoutError if maxAttempts is exceeded without a terminal status.
waitForVerification(requestHash, options?)
Poll an already-submitted request until it leaves PENDING.
const status = await nava.waitForVerification('0xabc...', {
intervalMs: 2000, // Polling interval (default: 2000ms)
maxAttempts: 30, // Max polls before timeout (default: 30)
onPoll: (attempt, result) => console.log(`Poll${attempt}:${result.status}`),
});
getWalletAddress()
Returns the wallet address configured for this client instance.