Skip to main content

Interact with the ICP ledger

Overview

Interact with ICP ledger from the command line

dfx provides a convenience command to interact with the ICP ledger canister and related functionality. You can find the documentation here or just enter the following command into your console:

dfx ledger --help

It's worth checking out the --help flag of the subcommands as well.

Currently, dfx exposes only a subset of the ICP ledger functionality, namely balance and transfer. Both commands provide a flag to specify a ledger canister id (--ledger-canister-id). This simplifies interacting with a local ledger deployment or other tokens that provide the same interface.

Balance

Get the ICP balance of a specific account:

dfx ledger --network ic balance <account-id>

The <account-id> is encoded as a hex string. You can print the account id of the current dfx identity by running:

dfx ledger account-id

In many cases you want to check the main account balance of a specific principal. You can combine the balance command with the account-id command, while specifying an --of-principal argument to yield this helpful command:

dfx ledger --network ic balance $(dfx ledger account-id --of-principal <principal-id>)

Transfer

The transfer function can be used to transfer ICP from your account to another.

dfx ledger --network ic transfer --amount <amount> --memo <memo> <receiver-account-id>

Interact with ICP ledger from your web application

In order to simplify working with ICP ledger from JavaScript applications, you can use the nns-js library.

Interact with ICP from a canister

The ICP transfer example provides a good starting point for interacting with ICP ledger from a canister. The example showcases the usage of balance and transfer in Motoko and Rust.

Receiving ICP

If you want a canister to receive payment in ICP you need to make sure that the canister knows about the payment, because a transfer only involves the sender and the ledger canister.

There are currently two main patterns to achieve this. Furthermore, there is a chartered working group on Ledger & Tokenization which is focused on defining a standard ledger/token interface as well payment flows.

Direct notification by sender

In this pattern the sender notifies the receiver about the payment. However, the receiver needs to verify the payment by using the query_blocks interface of the ledger. The following diagram shows a simplified illustration of this pattern:

Notification by ICP ledger (currently disabled)

In this pattern the ledger itself notifies the receiver. Thereby, the receiver can trust the notification immediately. However, this flow is currently disabled because the call to the receiver is not yet implemented as a one-way call.

icrc-ledger-types Rust crate

To interact with ICRC-1 and ICRC-2 compatible canisters, the Rust crate icrc-ledger-types can be used.

The crate can be installed with the command:

cargo add icrc-ledger-types

Or, it can be added to the Cargo.toml file:

icrc-ledger-types = "0.1.1"

The documentation for this crate can be found here.