Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.canton.network/llms.txt

Use this file to discover all available pages before exploring further.

There are two ways to interact with the dApp API:
  1. dApp SDK - A high-level SDK that wraps the Provider API with convenient methods and event handlers. This is the recommended approach for most applications.
  2. Provider API - The low-level interface that follows the EIP-1193 pattern. Use this when you need direct control over the API or are integrating with existing provider-based infrastructure.
The examples below show both approaches side by side.

Setup

dApp SDK: Import the dApp SDK:
import * as sdk from '@canton-network/dapp-sdk'
Call init() once early (e.g. on app mount). This registers adapters and attempts to restore a previously connected session without opening the wallet picker.
await sdk.init()
If you want to add or replace wallets (e.g. WalletConnect), see Adapter registration & wallet discovery (picker). Provider API: Import and create a provider instance:
const provider = window.canton

Request-Response Methods

Connecting to a Wallet

Establish a connection to the Wallet. This initiates the authentication flow if the user is not already authenticated. dApp SDK:
await sdk.init() // optional if already called
const result = await sdk.connect()
console.log(result.isConnected) // true if connected
Provider API:
const result = await provider.request<ConnectResult>({
    method: 'connect',
})
console.log(result.isConnected) // true if connected

Disconnecting from a Wallet

Close the session between the client and the Wallet. dApp SDK:
await sdk.disconnect()
Provider API:
await provider.request({ method: 'disconnect' })

Checking the Connection Status

Check the connection status of the Wallet. The status returns an object containing network connection- and session-related information. dApp SDK:
sdk.status()
    .then((result) => {
        setStatus(
            `${result.connection.isConnected ? 'connected' : 'disconnected'}`
        )
    })
    .catch(() => setStatus('disconnected'))
Provider API:
provider
    .request<StatusEvent>({ method: 'status' })
    .then((result) => {
        setStatus(
            `${result.connection.isConnected ? 'connected' : 'disconnected'}`
        )
    })
    .catch(() => setStatus('disconnected'))

Checking if Connected (without login)

Check if the user is connected without triggering the login flow. dApp SDK:
const result = await sdk.isConnected()
console.log(result.isConnected)
Provider API:
const result = await provider.request<ConnectResult>({
    method: 'isConnected',
})
console.log(result.isConnected)

Getting the Active Network

Retrieve details about the network the user is connected to. dApp SDK:
const network = await sdk.getActiveNetwork()
console.log(network.networkId) // e.g., 'canton:da-mainnet'
Provider API:
const network = await provider.request<Network>({
    method: 'getActiveNetwork',
})
console.log(network.networkId)

Listing Accounts

List all accounts (parties) the user has access to in the Wallet. dApp SDK:
const accounts = await sdk.listAccounts()
console.log(accounts)
Provider API:
const accounts = await provider.request<Account[]>({
    method: 'listAccounts',
})
console.log(accounts)

Getting the Primary Account

Get the account currently set as primary by the user. dApp SDK:
const account = await sdk.getPrimaryAccount()
console.log(account.partyId)
Provider API:
const account = await provider.request<Account>({
    method: 'getPrimaryAccount',
})
console.log(account.partyId)

Signing a Message

Sign an arbitrary string message using the primary account’s private key. dApp SDK:
const signature = await sdk.signMessage('Hello, Canton!')
console.log(signature)
Provider API:
const signature = await provider.request<string>({
    method: 'signMessage',
    params: { message: 'Hello, Canton!' },
})
console.log(signature)

Executing a Transaction

Prepare, sign, and execute a Daml transaction. This method handles the full lifecycle: preparing the commands, requesting user approval/signature, and submitting to the ledger. dApp SDK:
const createPingCommand = (party: string) => ({
    commands: [
        {
            CreateCommand: {
                templateId: '#AdminWorkflows:Canton.Internal.Ping:Ping',
                createArguments: {
                    id: `my-test-${new Date().getTime()}`,
                    initiator: party,
                    responder: party,
                },
            },
        },
    ],
})

// Get the primary party the user selected in the Wallet
const primaryParty = (await sdk.listAccounts()).find((w) => w.primary)?.partyId

// Request user's signature and execute the transaction
await sdk.prepareExecute(createPingCommand(primaryParty!))
Provider API:
const createPingCommand = (party: string) => ({
    commands: [
        {
            CreateCommand: {
                templateId: '#AdminWorkflows:Canton.Internal.Ping:Ping',
                createArguments: {
                    id: `my-test-${new Date().getTime()}`,
                    initiator: party,
                    responder: party,
                },
            },
        },
    ],
})

// Get the primary party the user selected in the Wallet
const accounts = await provider.request<Account[]>({ method: 'listAccounts' })
const primaryParty = accounts.find((w) => w.primary)?.partyId

// Request user's signature and execute the transaction
await provider.request({
    method: 'prepareExecute',
    params: createPingCommand(primaryParty!),
})

Calling the Ledger API

Proxy requests to the Canton JSON Ledger API. The request is authenticated using the user’s session. dApp SDK:
const response = await sdk.ledgerApi({
    requestMethod: 'GET',
    resource: '/v2/version',
})
console.log(JSON.parse(response.response))
Provider API:
const response = await provider.request<LedgerApiResponse>({
    method: 'ledgerApi',
    params: {
        requestMethod: 'GET',
        resource: '/v2/version',
    },
})
console.log(JSON.parse(response.response))

Events

The dApp API emits events to notify your application of state changes. Subscribe to these events to keep your UI in sync with the Wallet state.

Listening for Connection Status Changes

Receive notifications when the connection status or session state changes. dApp SDK:
sdk.onStatusChanged((status) => {
    console.log('Status changed:', status)
    console.log('Connected:', status.connection.isConnected)
})
Provider API:
provider.on('statusChanged', (status: StatusEvent) => {
    console.log('Status changed:', status)
    console.log('Connected:', status.connection.isConnected)
})

Listening for Account Changes

Receive notifications when accounts are added, removed, or when the primary account changes. dApp SDK:
sdk.onAccountsChanged((accounts) => {
    console.log('Accounts changed:', accounts)
    const primary = accounts.find((a) => a.primary)
    console.log('Primary account:', primary?.partyId)
})
Provider API:
provider.on('accountsChanged', (accounts: Account[]) => {
    console.log('Accounts changed:', accounts)
    const primary = accounts.find((a) => a.primary)
    console.log('Primary account:', primary?.partyId)
})

Listening for Transaction Changes

Receive notifications about the lifecycle of transactions initiated via prepareExecute. The event payload includes the transaction status (pending, signed, executed, failed) and relevant details. dApp SDK:
sdk.onTxChanged((tx) => {
    console.log('Transaction status:', tx.status)
    if (tx.status === 'executed') {
        console.log('Update ID:', tx.payload.updateId)
    }
})
Provider API:
provider.on('txChanged', (tx: TxChangedEvent) => {
    console.log('Transaction status:', tx.status)
    if (tx.status === 'executed') {
        console.log('Update ID:', tx.payload.updateId)
    }
})

Removing Event Listeners

When your component unmounts or you no longer need to listen for events, remove the listeners to prevent memory leaks. dApp SDK:
const handleStatus = (status) => console.log(status)

// Subscribe
sdk.onStatusChanged(handleStatus)

// Unsubscribe (when cleaning up)
sdk.offStatusChanged(handleStatus)
Provider API:
const handleStatus = (status: StatusEvent) => console.log(status)

// Subscribe
provider.on('statusChanged', handleStatus)

// Unsubscribe (when cleaning up)
provider.removeListener('statusChanged', handleStatus)

Adapter / Provider information

Get the current provider

sdk.getConnectedProvider() returns the raw CIP-103 provider for the currently active discovery session, or null if you are not connected. Use this when you need direct access to provider.request(...), to subscribe to provider-level events, or to instantiate the Wallet SDK (upcoming feature).
const provider = sdk.getConnectedProvider()
if (!provider) {
    // Not connected yet
    return
}

const status = await provider.request({ method: 'status' })
console.log(status.connection.isConnected)

Adapter registration & wallet discovery (picker)

See Adapter registration & wallet discovery (picker) for multiple ways to register adapters and what appears in the wallet picker.