Documentation
Server
Wallet API Server
Wallet API Server

properties

allAccounts$

Represents all available wallet accounts

Account is a slightly modified subject of the Account type used by the Ledger Live platform

details of the Account type
export type Account = {
  /**
   * The unique identifier of this account used internally by Ledger Live software
   */
  id: string;
  /**
   * The account’s name set by the user.
   */
  name: string;
  /**
   * The "next" public address where a user should receive funds. In the context of Bitcoin, the address is "renewed" each time funds are received in order to allow some privacy. In other blockchains, the address might never change
   */
  address: string;
  /**
   * The associated cryptocurrency id of the Account
   */
  currency: string;
  /**
   * The total amount of assets that this account holds
   */
  balance: BigNumber;
  /**
   * The amount of the balance that can be spent. Most of the time it will be equal to the balance, but this can vary in some blockchains
   */
  spendableBalance: BigNumber;
  /**
   * Tracks the current blockchain block height
   */
  blockHeight: number | undefined;
  /**
   * The date of the last time a synchronization was performed. In other words, tracks how up-to-date the Account data is
   */
  lastSyncDate: Date;
}; 
Created vianame
settersetAccounts

allCurrencies$

All available currencies that supported by the wallet.

details of the Currency type
type Currency = {
    type: "CryptoCurrency";
    name: string;
    id: string;
    color: string;
    ticker: string;
    decimals: number;
    family: "bitcoin" | "ethereum" | "algorand" | "crypto_org" | "ripple" | "cosmos" | "celo" | ... 10 more ... | "solana";
}
 
Created vianame
settersetCurrencies

permissions

Permissions are a set of two lists:

  1. The first restricting the currencies that can be used,
  2. The second restricting the requestHandlers method that can be used, this list also restricts the calls that the sendMessage method can make
Created vianame
settersetPermissions

permissions.currencyIds$

  • a list of currencies ids an application can interact with
example
permissions.currencyIds$ = ["ethereum", "bitcoin"];
  • ℹ️ it is possible to allow all currencies available in allCurrencies by setting this value to ["**"]
example with glob
permissions.currencies$ = ["**"],

permissions.methodIds$

  • a list of methods a live app can call, corresponds to a requestHandler's name
  • this list is also checked against when SERVER -> APP communication is done (in sendMessage)
example
permissions.methodIds$ = [
  "account.request",
  "currency.list",
  "account.list",
  "transaction.signAndBroadcast",
  "transaction.sign",
  "message.sign",
  "account.receive",
  "wallet.capabilities",
  "storage.set",
  "storage.get",
  "wallet.userId",
  "wallet.info",
  "bitcoin.getXPub",
  "exchange.start",
  "exchange.complete",
];

walletContext

walletContext.currencies$

The allowed currencies:

allCurrencies filtered against the currencies listed in permissions.currencyIds

Created vianamenote
observableset in constructor, updates anytime allAccounts or allowedCurrencies changes, more info on how it does this using rxjs here

walletContext.accounts$

The allowed accounts:

allAccounts filtered against the allowedCurrencies computed above

Created vianamenote
observableset in constructor, updates anytime allAccounts or walletContext.allowedCurrencies changes, more info on how it does this using rxjs here

walletContext.config

An object of this form

ServerConfig = {
  userId: string; // used in internal handler wallet.userID
  tracking: boolean;
  appId: string; // used in internal handler storage.ts, to store data in this fashion: object[app.id]
  wallet: { // used in internal handler wallet.info
    name: string;
    version: string;
  };
};
Created vianame
constructorconfig
settersetConfig

transport

A transport protocol used to communicate with an application

Show diagram

diagram

type Transport = {
  // A function to handle messages coming from the application
  onMessage: MessageHandler
 
  // A function to send messages to the application
  send(message: string): void;
};
 
Created vianame
constructortransport

requestHandlers

Show diagram

diagram

More on RpcRequest here.

A handler is a function of type RPCHandler

packages/server/src/types.ts
 type RPCHandler<TResult, TParam = unknown> = (
  request: RpcRequest<string, TParam>,
  context: WalletContext,
  handlers: Partial<WalletHandlers>,
) => Promisable<TResult>;
 

requestHandlers is an object of this type, mapping method ids (handlers name) to their RPCHandlers:

{
 'handlerName': RPCHandler,
 'handlerName2': RPCHandler,
 'handlerName3': RPCHandler,
 ...
}

A default set of handlers will always be present, those are the internalHandlers.

ℹ️

You can find a comprehensive list of those internalHandlers here.

Additionally, you can pass customHandlers to the constructor.

To put it simply: requestHandlers = internalHandlers + customHandlers

Created vianame
constructorcustomHandlers
settersetCustomHandlers

walletHandlers

Show diagram

diagram

wallets using the wallet-api-server must implements this spec: https://github.com/LedgerHQ/wallet-api/blob/main/spec/rpc/README.md (opens in a new tab)

those functions will allow requestHandlers to interact with the wallet most requestHandlers use one or more walletHandlers internally, to request / send data to the wallet on top of that, request handlers will use permissions set above to filter out what's show / operated on (allowed accounts, allowed currencies)

Created vianamenote
settersetHandler
settersetHandlerssets in bulk, overriding all existing wallet handlers

methods

handleMessage

A function to handle messages coming from the application

Used in conjonction with the transport property.

the server.transport.onMessage value is set to this function.

Parse json to either a rpcRequest or rpcResponse object

Will then call handleRpcRequest

handleRpcRequest

calls .onrequest, then creates an RpcResponse with the result and sends that response back to the application (using this.transport.send)

onRequest

call the appropriate requestHandler for that request

  1. check if method exists by looking up requestHandlers
  2. check if permissions allows for it to be called
  3. calls it, with the following parameters :

sendMessage

  1. checks if it can send a message to the server by checking permissions.
  2. then calls notify

constructor

packages/server/src/WalletAPIServer.ts
class WalletAPIServer{
  constructor(
    transport: Transport,
    config: ServerConfig,
    logger = defaultLogger,
    customHandlers: CustomHandlers = {},
  ) {...}
}
 
Parameterrequired?note
transportsets the transport
configsets the walletContext.config value
logger(optional) sets the logger
customHandlers(optional) sets customHandlers
ℹ️

It is how a WalletAPIServer is created in the example here