New Xendra Keys — shard your phrase, recover with any two. Read the note →

Developers

Wallet SDK

One connector for seven chains. Request accounts, build transactions and get them signed, without writing a separate integration for every network.

Package @xendra/sdkVersion 2.4.0Licence Apache-2.0Size 18 kB gzip

01Install

npm install @xendra/sdk
# or
pnpm add @xendra/sdk

The SDK ships ESM and CJS builds, has no runtime dependencies beyond a small base58 helper, and works in the browser, in a service worker and in React Native.

02Connect and request accounts

import { Xendra } from '@xendra/sdk'

const wallet = new Xendra({
  appName: 'Meridian',
  appIcon: 'https://meridian.example/icon.png',
  chains: ['eip155:1', 'eip155:8453', 'solana:mainnet', 'tron:mainnet'],
})

const session = await wallet.connect()
console.log(session.accounts)
// [{ chain: 'eip155:1', address: '0x8f2…c41' },
//  { chain: 'solana:mainnet', address: '7Gq…9Zt' }]

Chains use CAIP-2 identifiers. Ask only for what you need: a request for four chains where one would do is the fastest way to lose a user at the permission sheet.

03Request a signature

const hash = await wallet.sendTransaction({
  chain: 'eip155:8453',
  to: '0x1f9…0ab',
  value: '0',
  data: encodedSwapCall,
  preview: {
    summary: 'Swap 400 USDC for at least 0.118 ETH',
    worstCase: '0.118 ETH',
    expires: 1789459200,
  },
})

The preview block is optional and never trusted on its own. The wallet decodes and simulates the payload independently, then compares the result with your claim. If they disagree, the user sees both, with yours marked unverified.

Design note

Write a preview summary anyway. Honest apps get a green screen and a faster confirmation; the comparison is what makes that signal worth anything.

04Events and session lifecycle

wallet.on('accountsChanged', accounts => render(accounts))
wallet.on('chainChanged',   chain    => refetch(chain))
wallet.on('disconnect',     reason   => teardown(reason))

await wallet.disconnect()

Sessions last 30 days by default and are scoped to your origin. A session cannot be revived from another domain, and a popup that changes origin mid-request is refused outright.

05Errors

CodeMeaningWhat to do
4001User rejectedReturn to your idle state quietly
4100Not authorised for this chainRequest the chain in connect()
4200Method unsupported on this chainCheck the capability matrix
4900Wallet lockedPrompt the user to unlock, then retry
5001Simulation mismatchYour preview disagreed with reality; fix the preview

06Rate limits and good manners

  • Batch balance reads. One call for twenty assets, not twenty calls.
  • Never poll for accounts; subscribe to the event.
  • Ask for a signature in response to a click, never on page load.
  • Public endpoints allow 30 requests per minute per origin. Ask for a key if you need more.

Questions and integration reviews: developers@xendra.xyz.

Start holding your own keys.

iOS, Android, desktop and a browser extension — the same vault on all of them. Free, and it stays free.