sendTransaction moves value out of a personal, single-signature wallet. Multisig transfers go
through the order lifecycle instead. See Orders.
A wallet on a hardware root sends with
prepareHardwareSend (or prepareHardwareTrustLine for XRP
trust lines). sendTransaction throws HardwareSignerRequiredError for it. See
Hardware Wallets.Prerequisites
If the account runs in strict authentication, pass
walletPassword on every signing call. Without it the SDK throws
StrictAuthPasswordRequiredError.runWithUserRef scopes the signing user for the whole callback, keeping concurrent requests
isolated. The alternative is passing userRef on each input.
SendTransactionInput
RPC endpoints
Sends and fee quotes talk to a chain node. Defaults ship per network, andSDKConfig.rpcOverrides
replaces them:
rpcOverrides at your own nodes before you go live.
Cardano ships no default RPC and does not need one: Cardano sends and fee quotes source their
UTXOs from the Trustodian API rather than from a node.
Address validation
Validate before you send. These helpers check the address’s embedded checksum rather than matching a shape regex, so a single mistyped character is rejected instead of paid to an address nobody controls.Two rejections are intentional: XRP X-addresses, since the destination tag is carried separately
(see below), and Cardano Byron addresses (
Ae2..., DdzFF...). Cardano addresses are also checked
against the network, so a well-formed testnet address is rejected on mainnet.Memos and destination tags
memo entirely.
An empty memo is always valid.
Spend authorization
Before a key is rebuilt, every send hands the unsigned transaction to Trustodian and gets back a single-use handle, which travels with the share request. This exists because the share request would otherwise carry a recipient and an amount that the client computed, and those are what the Address Book whitelist and the organization spending limit are enforced against. A caller could simply understate them. By reading the payee and amount out of the transaction that is actually about to be signed, the server enforces its policies against the real spend rather than a claim about it. The SDK does all of this insidesendTransaction; there is no method for you to call and nothing to
configure. What you may see is its effect: a send can be refused by an organization policy at this
step, before any signature exists. Nothing is reserved, so an abandoned send costs no allowance.
Per-chain behaviour
What each chain needs from you, and what it will refuse.EVM
EVM
chainIdselects both the RPC endpoint and the network; it defaults to1.- Token sends need
tokenAddressanddecimals; native sends leavetokenAddressempty and setisNativeToken: true. - A chain id with no configured RPC throws
No RPC endpoint configured for EVM chain ID ….
Solana
Solana
- The RPC URL must be
https://. - A native send will not leave the recipient below rent-exemption, and refuses rather than creating an unusable account.
- Sending a token to a recipient who has no account for it creates that account in the same transaction, and the sender pays rent for it. Budget for that.
- Both SPL and Token-2022 tokens are supported; the right one is detected from the mint.
Tron
Tron
- Native sends keep about 0.3 TRX back for bandwidth, and refuse when the amount would eat into it: “Insufficient TRX for transaction. Please leave ~0.1 TRX for bandwidth costs.”
- TRC-20 sends require both
tokenAddressanddecimals. - Sending to an account that is not yet activated costs roughly 1 TRX extra.
Bitcoin
Bitcoin
- The recipient is checked against the active network before anything else.
- Inputs are selected automatically and the fee comes from the current network rate.
- Change below the dust limit is dropped into the fee rather than creating a dust output.
- Chain type is
BTCon mainnet andBTC_T3on testnet.
Cardano
Cardano
- For a token transfer,
tokenAddresscarries the policy id andsymbolthe asset name; both are required. amountis the token amount. Every output must also carry a minimum of ADA, which the SDK derives. You do not choose it.- A token send needs pure-ADA UTXOs to pay from. If all the ADA is locked in UTXOs that also hold tokens, the send is refused and the tokens must be moved first.
XRP
XRP
- Sending to yourself is refused up front.
- For an issued asset,
tokenAddressmust be"currency.issuer", for example"USD.rIssuer...". A trust line for that pair must already exist; see XRP trust lines. - A numeric
memobecomes the destination tag; a non-numeric one is dropped. - Every account locks 1 XRP as a base reserve plus 0.2 XRP per owned object, and that part of the balance cannot be spent.
Minimum balances and native currencies
These are the per-chain floors and native units the SDK works with, reproduced so you can apply the same thresholds yourself.Fee estimation
payload.from is the wallet the quote is priced against. For a token transfer add tokenAddress and
decimals. When chainId is omitted it defaults to the SDK’s network: '1' / '11155111' on EVM,
sol_mainnet / sol_devnet, and so on.
Pass the result back as feeHint on sendTransaction to reuse the quote instead of re-pricing it.
Always use the
TransactionEstimatingType members rather than string literals, because an
unrecognised value is priced as a plain transfer instead of throwing. The other operation types, the full
EstimatedFee shape, and who pays what on each chain are covered in
Multisig Fees.New device or missing device share
If the device share for a wallet is absent or stale, passwalletPassword and the SDK performs a
recovery rotation as part of the send. Without it, the failed send throws an error you can test
with isDeviceShareRecoveryError(error), then retry after recovering explicitly.
ensureWalletReadyForCrypto or ensureWalletDeviceShare. See
Keeping a device share current for the
recovery pattern and what makes a share stale.
XRP trust lines
An XRP wallet can only hold an issued asset once a trust line to that currency/issuer pair is open. Opening one consumes 0.2 XRP of the account’s available balance as a reserve object.address and issuer are validated before any network call. Opening the line needs roughly
0.2 XRP of available balance for the new reserve object.
Inspecting reserve and existing lines
Errors worth handling
A reconstructed key that fails to derive the wallet’s address does not surface as a thrown
KeyMismatchError instance; catch it with isDeviceShareRecoveryError(error) instead. See
Keeping a device share current.
Use isTrustodianError(error) to narrow before reading these fields. For the full error taxonomy,
HTTP status mapping and retry guidance, see Errors.
Next
Preflight
Simulate the send before a signature is collected
Orders
Multisig transfers through the order lifecycle
Wallets
Creating, listing, and reading wallets
Address Book
Whitelisting payees before they can be paid