Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Swap

A swap intent requests an output token and amount on the target chain. For a plain swap, send no calldata:

calls: []

Do not add a dummy token transfer, { data: '0x' }, or a self-transfer to make the intent look like a transaction. Placeholder calldata changes the review UI and can cause the quoter to reject the route as unsupported destination calldata.

Install the SDK

npm install @rhinestone/1auth viem

Create client

client.ts
import { OneAuthClient } from '@rhinestone/1auth'
 
export const client = new OneAuthClient({
  providerUrl: 'https://passkey.1auth.app',
  clientId: 'my-app',
})

Send a swap intent

import { parseUnits } from 'viem'
 
const usdcOnBase = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
 
const result = await client.sendIntent({
  accountAddress: '0x...',
  targetChain: 8453,
  calls: [],
  tokenRequests: [{
    token: usdcOnBase,
    amount: parseUnits('0.1', 6),
  }],
  sourceAssets: ['0x0000000000000000000000000000000000000000'],
})
 
if (result.success) {
  console.log('Swap intent:', result.intentId)
}

Done

The orchestrator routes the input asset into the requested output token.

Cross-chain swap

Use the same shape for cross-chain routes. Constrain the source chain when your source asset address only exists on one chain:

import { parseUnits } from 'viem'
 
const BASE_SEPOLIA = 84532
const ARB_SEPOLIA = 421614
const mUSDOnBaseSepolia = '0x2f6fdE5E2AeAB6335d8f978B4d8B2a9c1129AcFb'
const usdcOnArbitrumSepolia = '0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d'
 
await client.sendIntent({
  accountAddress,
  targetChain: ARB_SEPOLIA,
  calls: [],
  tokenRequests: [{
    token: usdcOnArbitrumSepolia,
    amount: parseUnits('0.1', 6),
  }],
  sourceAssets: [mUSDOnBaseSepolia],
  sourceChainId: BASE_SEPOLIA,
})

The route delivers the requested USDC on the target chain.

Token requests vs calls

Use this distinction when deciding what to send:

Intent shapeUse it forWhat to send
Plain swapUser receives an output tokensendIntent({ calls: [], tokenRequests })
ERC20 paymentUser sends tokens to a recipientReal ERC20.transfer(...) calldata plus matching tokenRequests
Contract action requiring tokensContract consumes tokens during executionReal app calldata plus matching tokenRequests

tokenRequests specify the target-chain output; calls specify the contract action that consumes it. Plain swaps need only tokenRequests; payments and contract actions need both.

Funding target-chain execution

When the delivered token must be consumed by a contract call, include the real call and the token request together:

import { encodeFunctionData, parseUnits } from 'viem'
 
const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
const amount = parseUnits('100', 6)
 
const transferData = encodeFunctionData({
  abi: erc20Abi,
  functionName: 'transfer',
  args: [recipientAddress, amount],
})
 
await client.sendIntent({
  accountAddress,
  targetChain: 8453,
  calls: [{
    to: USDC_BASE,
    data: transferData,
    label: 'Send USDC',
    sublabel: '100 USDC',
  }],
  tokenRequests: [{
    token: USDC_BASE,
    amount,
  }],
})

Constraining source assets

Omit sourceAssets to use available balances, or pass it with optional sourceChainId to constrain the input side:

const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
 
await client.sendIntent({
  accountAddress,
  targetChain: 8453,
  calls: [],
  tokenRequests: [{
    token: USDC_BASE,
    amount: parseUnits('100', 6),
  }],
  sourceAssets: [
    '0x0000000000000000000000000000000000000000', // ETH
    '0x4200000000000000000000000000000000000006', // WETH
  ],
})

Use token addresses for both output requests and source-asset constraints.

Tracking status

sendIntent returns an intent id. Pass waitForHash: true when you need the transaction hash before the promise resolves:

const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
 
const result = await client.sendIntent({
  accountAddress,
  targetChain: 8453,
  calls: [],
  tokenRequests: [{
    token: USDC_BASE,
    amount: parseUnits('0.1', 6),
  }],
  waitForHash: true,
  closeOn: 'completed',
})
 
if (result.success) {
  console.log(result.intentId)
  console.log(result.transactionHash)
}

Poll later with getIntentStatus(result.intentId).

Next steps