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

Crosschain

1auth provides complete chain abstraction through intents. Users can execute transactions on any chain using funds from any other chain - no bridging, no chain switching, no gas token management.

How it works

  1. User has funds on Chain A (e.g., USDC on Ethereum)
  2. User wants to execute a transaction on Chain B (e.g., mint NFT on Base)
  3. 1auth's orchestrator handles the bridging and execution automatically
  4. User signs once with their passkey - done

The user's balance is aggregated and abstracted across all chains. They see one unified balance, not separate balances per chain.

Using wagmi

Wagmi provides hooks to integrate crosschain transactions into your React app.

Install the SDK

npm install @rhinestone/1auth

Create config.ts

Create a wagmi config file with the 1auth connector. For crosschain transactions, add all the chains you want to support:

config.ts
import { createConfig, http } from 'wagmi'
import { base, mainnet, optimism, arbitrum } from 'wagmi/chains'
import { OneAuthClient } from '@rhinestone/1auth'
import { oneAuth } from '@rhinestone/1auth/wagmi'
 
// Create the 1auth client
const client = new OneAuthClient({ 
  providerUrl: 'https://passkey.1auth.box', 
}) 
 
// Create the wagmi config with 1auth connector
export const config = createConfig({
  chains: [mainnet, base, optimism, arbitrum], 
  connectors: [oneAuth({ client })], 
  transports: {
    [mainnet.id]: http(),
    [base.id]: http(),
    [optimism.id]: http(),
    [arbitrum.id]: http(),
  },
})

Build your calls

The calls array defines what contract interactions to execute. Each call has a to address, optional data (calldata), and optional value (ETH amount). Multiple calls execute atomically - all succeed or all fail together.

import { encodeFunctionData, parseUnits } from 'viem'
 
// Example: Approve + Swap in a single atomic batch
const calls = [
  {
    to: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC contract
    data: encodeFunctionData({
      abi: erc20Abi,
      functionName: 'approve',
      args: [DEX_ADDRESS, parseUnits('100', 6)],
    }),
  },
  {
    to: DEX_ADDRESS, // DEX contract
    data: encodeFunctionData({
      abi: dexAbi,
      functionName: 'swap',
      args: [USDC, WETH, parseUnits('100', 6)],
    }),
  },
]

Send to any chain

Use useSendCalls with your calls array. The key crosschain parameters are:

  • chainId - specifies which chain the calls execute on (required)
  • tokenRequests - specifies what tokens the user needs for the transaction (optional)
sendCalls({
  calls,
  chainId: 8453, // Execute on Base 
  tokenRequests: [{ 
    token: USDC_ADDRESS, 
    amount: parseUnits('100', 6), 
  }], 
})

The tokenRequests parameter enables the output-first model: instead of specifying which tokens to spend, you specify what tokens you need. The orchestrator automatically finds the cheapest route to deliver those tokens from the user's assets across all chains.

The orchestrator finds the cheapest route to fund the transaction, regardless of where the user's assets currently are. See Token Requests for more details on the output-first model.

Done

You're now sending crosschain transactions with 1auth! Users sign once with their passkey and the orchestrator handles everything else.

Using the SDK directly

If you prefer not to use wagmi, you can use the SDK's sendIntent method:

import { OneAuthClient } from '@rhinestone/1auth'
import { parseEther } from 'viem'
 
const client = new OneAuthClient({
  providerUrl: 'https://passkey.1auth.box',
})
 
const result = await client.sendIntent({
  username: 'alice',
  targetChain: 8453, // Base 
  calls: [
    {
      to: '0x...', // Contract on Base
      data: '0x...', // Calldata
      value: parseEther('0.1'),
    },
  ],
  closeOn: 'completed',
})
 
if (result.success) {
  console.log('TX Hash:', result.transactionHash)
}

Next steps