Skip to main content

Integrating with an SNS

Advanced
Governance
Concept

Overview

When planning an SNS launch, one topic to consider is whether and how the SNS functionality should be integrated in the dapp. For example, one may want to embed a frontend for the SNS swap or for the SNS governance in the dapp's UI. Other dapps can also provide such a frontend or integrate with some of the SNS canisters. For example, DEXs might want to interact with the SNS ledger canisters or wallet dapps might want to provide an interface to interact with the different SNS governance canisters.

Ledger integration

The SNS ledger canister keeps track of the transactions between accounts in a chain, as well as the account balances at the last block of the chain. A ledger canister is always deployed as part of the SNS canisters. The ledger canister follows the ICRC-1 specification.

For instructions on how to install the ICRC-1 Ledger follow ICRC-1 Ledger Deployment. For instructions on how to interact with the ICRC-1 Ledger follow ICRC-1 Ledger Interaction.

Index integration

The index canister fetches transactions from the ledger canister and indexes them by account. It allows to query the transactions of an account in descending order from the ledger chain, and the list of accounts that belongs to a principal. An index canister is always deployed as part of an SNS project.

This canister is useful for applications that want to show the transactions of a specific account.

Regularly (at each heartbeat), the index canister will query the transactions from the ledger canister and then build the index of known transaction per account.

Initialization

This sections explains how to deploy an index canister in isolation. When the NNS creates a new SNS for a dapp, it will automatically be deployed with an SNS index canister.

The index canister initialization requires the principal of the ICRC-1 ledger canister that should be indexed:

type InitArgs = record {
ledger_id : principal;
};

Example with dfx:

dfx deploy icrc1-index --argument "(record {
ledger_id = principal \"rrkah-fqaaa-aaaaa-aaaaq-cai\"
}
)"

Usage

The provided methods are:

get_account_transactions : (GetAccountTransactionsArgs) -> (GetTransactionsResult);
  • This method returns the transactions for a given account. Transactions are returned in descending id order. Optionally, the user can specify a starting transaction id allowing to only query for transactions before this id. If no start is specified, the last transaction is used.
ledger_id : () -> (principal) query;
  • This method returns the principal of the ledger canister being indexed.
list_subaccounts : (ListSubaccountsArgs) -> (vec SubAccount) query;
  • This method lists all indexed subaccounts for a principal.

Candid reference file

Please check the Candid file of the index canister for the interface details.

Frontend integration

There are different reasons why you might want to interface with an SNS project. For example, you might want to integrate some of the SNS DAO functionality in the frontend of your dapp canister such that the dapp users can also vote on relevant SNS proposals (that govern and change the dapp) directly in the same application. However, you might also consider interfacing with SNSs if you work on a project that builds a wallet dapp or DEX, for example to provide an interface to the SNS swap, the SNS governance, or the SNS ledger.

sns-js library

For interfacing with an SNS project, you can use the sns-js library.

sns-js can be utilized with two distinct approaches. The first approach is exploratory, where you only need to provide the SNS root canister ID of your SNS project to initialize a wrapper that handles routing the calls to the appropriate canister. This means having a single entry point for all functions. The second approach, which is more common, involves instantiating the specific canisters you require.

Please refer to the following links to learn how to integrate with: