Skip to main content

Multi-Chain Signing

1Claw signs and broadcasts transactions for six blockchains. Keys are envelope-encrypted under a KEK held in Cloud KMS (HSM on paid tiers) and unwrapped in the vault — or inside the Shroud TEE for agents with intents_require_tee — only to sign. Agents submit transaction intents; the server signs, optionally broadcasts, and returns the result. The private key is never returned to the agent. These are custody: server keys; see Custody for the threshold and passkey-owner models.

This page consolidates everything you need: key provisioning, supported chains, transaction signing, and guardrails. For the full Intents API reference (EVM-specific features like EIP-712, simulation, gasless transactions), see Intents API.


Supported chains​

ChainCurveAddress formatMainnet chainTestnet chain
Ethereumsecp256k10x (EIP-55)ethereum, base, optimism, arbitrum, polygonsepolia, base-sepolia
Bitcoinsecp256k1P2WPKH bech32 (bc1q…)bitcoinbitcoin-testnet, bitcoin-signet
SolanaEd25519Base58solanasolana-devnet, solana-testnet
XRPEd25519Base58Check (r…)xrpxrp-testnet
CardanoEd25519Bech32 enterprise (addr1…)cardanocardano-preprod, cardano-preview
Tronsecp256k1Base58Check (T…)trontron-shasta, tron-nile

Provisioning signing keys​

Signing keys are provisioned per-agent by a human. The HSM generates the keypair; the private key is stored in the org's __agent-keys vault.

const { data: key } = await client.signingKeys.create(agentId, {
chain: "ethereum",
});
console.log(key.public_key, key.address);

Repeat for each chain the agent needs (bitcoin, solana, xrp, cardano, tron).

Key lifecycle​

OperationEndpointSDK
ProvisionPOST /v1/agents/{id}/signing-keysclient.signingKeys.create(agentId, { chain })
ListGET /v1/agents/{id}/signing-keysclient.signingKeys.list(agentId)
Check balanceGET /v1/agents/{id}/signing-keys/{chain}/balanceclient.signingKeys.getBalance(agentId, chain)
RotatePOST /v1/agents/{id}/signing-keys/{chain}/rotateclient.signingKeys.rotate(agentId, chain)
DeactivateDELETE /v1/agents/{id}/signing-keys/{chain}client.signingKeys.deactivate(agentId, chain)
ExportPOST /v1/agents/{id}/signing-keys/{chain}/export— (requires X-Auth-Confirm password)
Import (BYOK)POST /v1/agents/{id}/signing-keys/{chain}/importclient.signingKeys.importKey(agentId, chain, { private_key, format })

Only human users can provision, rotate, export, and import keys — agents receive 403.

Import (BYOK)​

Bring your own key: import an existing private key for a chain instead of generating one server-side. Human-only, requires password re-authentication via the X-Auth-Confirm header. Audit-logged as signing_key.import.

FieldTypeRequiredDescription
private_keystring✅The raw private key
formatstring❌"hex" (default), "base64", or "wif" (Bitcoin only)
const { data: key } = await client.signingKeys.importKey(agentId, "ethereum", {
private_key: "0xabc123...",
format: "hex",
});
console.log(key.address);

The server derives the public key and address from the imported key, stores it in __agent-keys, and returns the same response shape as create.


Signing and broadcasting transactions​

Use POST /v1/agents/{id}/transactions to sign and broadcast, or POST /v1/agents/{id}/transactions/sign to sign without broadcasting.

The chain field determines which signing module is used. 1Claw automatically fetches chain data (UTXOs, fee rates, blockhashes, sequence numbers) before signing.

Value format​

value is always the human-readable major unit as a decimal string:

ChainExample valueMeaning
Bitcoin"0.001"0.001 BTC
Solana"0.5"0.5 SOL
XRP"10"10 XRP
Cardano"5"5 ADA
Tron"100"100 TRX

Chain-specific fields​

FieldChainPurpose
destination_tagXRPDestination tag for exchange deposits
fee_rate_sat_per_vbyteBitcoinOverride the auto-fetched fee rate
fee_limit_sunTronTRC-20 energy fee limit (default 100M sun; max 500M)
token_mintSolana, Tron, Cardano, EVMToken contract/mint for token transfers
token_decimalsSolana, TronToken decimals (default 6)
ttlCardanoTime-to-live in absolute slots (default: current + 7200)
xrpl_tx_jsonXRPFull XRPL transaction JSON for one of 1Claw's 31 supported types. Submit/sign still require top-level to and value (use "0" for non-Payment types).
memoSolanaOn-chain memo (Memo Program v2). On XRP the top-level field is not applied — put Memos inside xrpl_tx_json.

Examples​

// Bitcoin: send 0.001 BTC
const btc = await client.agents.submitTransaction(agentId, {
chain: "bitcoin-signet",
to: "tb1q...",
value: "0.001",
});

// Solana: send 0.25 SOL
const sol = await client.agents.submitTransaction(agentId, {
chain: "solana-devnet",
to: "9xQ...",
value: "0.25",
});

// XRP: send 10 XRP with a destination tag
const xrp = await client.agents.submitTransaction(agentId, {
chain: "xrp-testnet",
to: "rPT1...",
value: "10",
destination_tag: 12345,
});

// Cardano: send 2 ADA
const ada = await client.agents.submitTransaction(agentId, {
chain: "cardano-preprod",
to: "addr_test1...",
value: "2",
});

// Tron: send 100 TRX
const trx = await client.agents.submitTransaction(agentId, {
chain: "tron-shasta",
to: "T...",
value: "100",
});

Token transfers​

For SPL, TRC-20, ERC-20, and Cardano native assets, add token_mint:

// Solana SPL token (USDC)
const spl = await client.agents.submitTransaction(agentId, {
chain: "solana-devnet",
to: "9xQ...",
value: "5",
token_mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
token_decimals: 6,
});

// Tron TRC-20 (USDT)
const trc20 = await client.agents.submitTransaction(agentId, {
chain: "tron",
to: "TR7NH...",
value: "5",
token_mint: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
token_decimals: 6,
});

Solana SPL transfers auto-create the recipient's Associated Token Account if it doesn't exist.


XRPL advanced transactions​

For any of 1Claw's 31 supported XRPL types beyond simple Payment, use xrpl_tx_json. This is a 1Claw subset — types the ledger accepts but 1Claw does not (DID, oracles, Batch, …) are rejected. Submit/sign still require top-level to and value (use "0" when the JSON is not a Payment).

// TrustSet — allow up to 1000 USD from an issuer
const trustSet = await client.agents.submitTransaction(agentId, {
chain: "xrp-testnet",
to: "rIssuer...",
value: "0",
xrpl_tx_json: {
TransactionType: "TrustSet",
LimitAmount: {
currency: "USD",
issuer: "rIssuer...",
value: "1000",
},
},
});

1Claw auto-fills Account, Sequence, Fee ("12" drops), LastLedgerSequence (current ledger + 20), SigningPubKey, Flags (tfFullyCanonicalSig), and SourceTag 482684816 (caller-supplied value wins). SetRegularKey, SignerListSet, AccountSet, and AccountDelete are blocked unless explicitly listed in xrpl_allowed_tx_types. See XRP transaction type allowlist.


Transaction guardrails​

Per-agent controls enforced before signing. Configure via the dashboard, SDK, or CLI.

GuardrailPurpose
tx_allowed_chainsRestrict to specific chains
tx_to_allowlistPermitted destination addresses
tx_max_valueMax value per transaction (native major units). Deprecated alias: tx_max_value_eth.
tx_daily_limitRolling 24h cumulative spend per chain family. Deprecated alias: tx_daily_limit_eth.
xrpl_allowed_tx_typesAllowed XRPL TransactionTypes. Empty = all supported except four dangerous types.
tx_token_allowlistAllowed token contracts/mints
tx_max_per_dayMax transactions per UTC day
per_chain_guardrailsChain-specific overrides (JSON)
await client.agents.update(agentId, {
intents_api_enabled: true,
tx_allowed_chains: ["ethereum", "solana"],
tx_to_allowlist: ["0x...", "9xQ..."],
tx_max_value: "1.0",
tx_daily_limit: "10.0",
});

Violations return 403 with a descriptive error before any signing occurs.


UTXO locking (Bitcoin & Cardano)​

Concurrent transactions are serialized via UTXO locks to prevent double-spends. Locks auto-expire after 5 minutes and are released on successful broadcast or error.


Testnet faucets​

ChainFaucet
Bitcoin Signetfaucet.coinbin.org
Solana Devnetfaucet.solana.com or solana airdrop
XRP Testnetxrpl.org/resources/dev-tools/xrp-faucets (default 10 XRP)
Cardano Preprodfaucet.preprod.world.dev.cardano.org
Tron Shastashasta.tronex.io

Further reading​

  • Intents API — full reference including EVM features, EIP-712, simulation, and the unified sign endpoint
  • Payment Cards — order prepaid cards using the agent's Ethereum signing key via x402
  • Securing Agent Access — scoped permissions, vault binding, and token TTL