Skip to main content
This page walks through a complete first integration on testnet: construct the SDK, unlock the wallet session, derive a wallet, read its balances, and send a transaction.
Everything here runs on your backend. The API key and the end-user wallet password must never reach a browser or mobile client.

Before you start

  • Node.js 18 or newer.
  • An API key, issued from the Trustodian app for an account that has already completed onboarding. See Authentication.
  • The account holder’s wallet password, supplied per request.
  • Somewhere to persist device shares. The steps below sketch a database-backed IntegratorShareStore.
1

Install the package

2

Implement a share store

The SDK persists one device share per wallet through the store you provide. InMemoryShareStore is bundled for local experiments. Production needs durable storage, because losing a device share forces a password-based recovery on the next signing attempt.
share-store.ts
A device share is key material. Encrypt the column at rest, keep it out of logs and backups you would not treat as secrets, and never return it to a client.
3

Construct the SDK

apiKey, network, and shareStore are the three fields the constructor refuses to run without. Every other option is covered in the configuration table.
4

Resolve the userRef

userRef is the stable account identifier that ties session keys and shareStore rows together. Resolve it once and reuse it.
5

Unlock the session

The account already has a wallet password from onboarding, and your integration only unlocks it. The password is supplied by your end user on each request, never hardcoded and never stored.
The session stays unlocked for keyTtlMs (5 minutes by default). See Authentication for the full lifecycle.
6

Create a wallet

Omit mode. The account has a recovery phrase, so the wallet is derived from that seed: shareless, with a derivationPath and an index. A normal integration never passes mode.
7

Read the portfolio

chainId here is a ChainIdValue string ('1', '8453', 'sol_mainnet', 'BTC_T3', …). Add force: true to bypass the cached balance and re-read from the chain.
8

Send a transaction

For an ERC-20 transfer, set tokenAddress to the contract, decimals to the token’s decimals, symbol to its ticker, and drop isNativeToken. Signing needs an unlocked session; if the device share is missing on this host, pass walletPassword so the SDK can rotate it back in. See Transactions.
9

Lock the session

This wipes the session key immediately instead of waiting for keyTtlMs to expire. Call it as soon as the user’s request is done.

Putting it together

If you would rather not thread userRef through every call, wrap the block in sdk.runWithUserRef(userRef, async () => { … }). Concurrent requests stay isolated from one another.

Authentication

Headers, session lifecycle, password changes and hints

Recovery Phrase

Reveal, verification state, derivation paths

Key Management

Device shares, rotation, recovery on a new host

Transactions

Token transfers, fee estimation, and history

Preflight

Catch a failing transaction before you broadcast it

Errors

What each typed error means and how to recover
Last modified on August 31, 2026