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

Authentication

Info queries are public. Exchange actions require a signer, and TxFlow uses two signer roles with different permissions.

Owner and agent roles

RoleTypical signerUsed forCan withdraw externally
OwnerBrowser wallet or account private keyAuthorize agents, withdraw, transfer tokens, create vaultsYes
AgentDedicated backend or bot keyPlace, cancel, and modify orders; update leverage and marginNo

An agent may route balances between an owner and a vault through supported exchange actions, but it cannot perform owner-only withdrawals or external token transfers.

The recommended flow is:

  1. Generate a dedicated agent key in a secure backend environment.
  2. Ask the owner wallet to authorize the agent address once.
  3. Store the agent private key in a secret manager.
  4. Use that agent key for day-to-day trading.

Authorize an agent from a browser

Connect the wallet before passing its EIP-1193 provider to the SDK:

import {
  TxFlow,
  type AbstractEip1193Provider,
} from 'txflow-typescript-sdk'
 
const provider = (
  window as Window & {
    ethereum?: AbstractEip1193Provider
  }
).ethereum
 
if (!provider) {
  throw new Error('No EIP-1193 wallet provider found')
}
 
const accounts = await provider.request({
  method: 'eth_requestAccounts',
}) as string[]
 
const ownerAddress = accounts[0]
 
if (!ownerAddress) {
  throw new Error('No wallet account connected')
}
 
const sdk = new TxFlow('testnet')
 
const eligibility = await sdk.info.approveAgentEligibility({
  user: ownerAddress,
})
 
if (!eligibility.eligible) {
  throw new Error(
    eligibility.reason ?? 'This account cannot authorize an agent',
  )
}
 
sdk.exchange.setWallet(provider)
const result = await sdk.exchange.approveAgent({
  agentAddress: '0xYourAgentAddress',
  agentName: 'Trading bot',
})
 
if (result.status !== 'ok') {
  throw new Error(
    typeof result.response === 'string'
      ? result.response
      : 'Agent authorization failed',
  )
}

For browser owner actions, the connected wallet must be on the preset's signing chain:

TxFlow presetWallet signing chain
testnetArbitrum Sepolia (421614)
mainnetArbitrum One (42161)

The TxFlow business chain id is separate from the wallet signing chain. The SDK selects both values and forwards signatureChainId where required.

See approveAgent for the underlying action and revocation behavior.

Trade with the agent key

Configure the same SDK instance again, or create a separate instance in your backend:

const sdk = new TxFlow('testnet')
 
sdk.exchange.setPrivateKey(
  process.env.TXFLOW_AGENT_PRIVATE_KEY as `0x${string}`,
)
 
await sdk.exchange.placeLimitOrder({
  asset: 1,
  side: 'buy',
  px: '60000',
  sz: '0.001',
})

setPrivateKey can also execute owner actions from a trusted Node.js process when supplied an owner key. Keep owner and agent configuration separate in production so a trading process never receives withdrawal authority.

Supported wallet shapes

setWallet accepts:

WalletSupport
EIP-1193 provider, including window.ethereumSupported
ethers v6 SignerSupported
viem local accountSupported
ethers v5 signerNot supported
viem WalletClientNot currently supported directly

The SDK detects the wallet shape and adapts it to one signing interface. Invalid or unsupported wallets fail before a request is sent.

Authentication state

if (!sdk.exchange.isAuthenticated) {
  sdk.exchange.setPrivateKey(agentPrivateKey)
}

Calling an exchange method without a signer throws AuthenticationError. HTTP authentication errors are surfaced as TxFlowApiError; exchange business rejections are returned as { status: 'err', response: '...' }.

Signing model

The SDK chooses the signing path from the named action:

  • Trading actions use the agent-signed L1 flow.
  • Account actions such as approveAgent, withdraw3, and tokenSend use direct owner EIP-712 signing.

withdraw3 is USDC-only: the SDK fills tokenAddress from the network preset. See Withdraw.

You do not manually build hashes or envelopes. For the protocol-level format, see Signing.

Next steps