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 via | name |
---|---|
setter | setAccounts |
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 via | name |
---|---|
setter | setCurrencies |
permissions
Permissions are a set of two lists:
- The first restricting the currencies that can be used,
- The second restricting the requestHandlers method that can be used, this list also restricts the calls that the sendMessage method can make
Created via | name |
---|---|
setter | setPermissions |
permissions.currencyIds$
- a list of currencies ids an application can interact with
permissions.currencyIds$ = ["ethereum", "bitcoin"];
- ℹ️ it is possible to allow all currencies available in allCurrencies by setting this value to
["**"]
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)
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 via | name | note |
---|---|---|
observable | set 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 via | name | note |
---|---|---|
observable | set 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 via | name |
---|---|
constructor | config |
setter | setConfig |
transport
A transport protocol used to communicate with an application
Show 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 via | name |
---|---|
constructor | transport |
requestHandlers
Show diagram
More on RpcRequest here.
A handler is a function of type RPCHandler
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 via | name |
---|---|
constructor | customHandlers |
setter | setCustomHandlers |
walletHandlers
Show 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 via | name | note |
---|---|---|
setter | setHandler | |
setter | setHandlers | sets 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
- check if method exists by looking up requestHandlers
- check if permissions allows for it to be called
- calls it, with the following parameters :
- request (RpcRequest)
- walletContext
- walletHandlers
sendMessage
- checks if it can send a message to the server by checking permissions.
- then calls notify
constructor
class WalletAPIServer{
constructor(
transport: Transport,
config: ServerConfig,
logger = defaultLogger,
customHandlers: CustomHandlers = {},
) {...}
}
Parameter | required? | note |
---|---|---|
transport | ✅ | sets the transport |
config | ✅ | sets the walletContext.config value |
logger | ❌ | (optional) sets the logger |
customHandlers | ❌ | (optional) sets customHandlers |
It is how a WalletAPIServer is created in the example here