Finding and Reading Data

Reading from ledger

Parties and synchronizers are considered a core component on the Ledger API and they are therefore a common filter on requests. To facilitate the party and synchronizer fields to be changed easily, the ledger controller in the Wallet SDK allows you to change the fields but requires them for certain operations. This is to ensure that you always have the correct context when reading data from the ledger.

import {
    WalletSDKImpl,
    localNetAuthDefault,
    localNetLedgerDefault,
} from '@canton-network/wallet-sdk'

const sdk = new WalletSDKImpl().configure({
    logger: console,
    authFactory: localNetAuthDefault,
    ledgerFactory: localNetLedgerDefault,
})
await sdk.connect()

sdk.userLedger?.setPartyId('my-wallet-1')
sdk.userLedger?.setSynchronizerId('synchronizer-1')

Reading Available Parties

Reading all available parties to you can easily be done using the wallet SDK as shown in the example below, and the result is paginated. It’s worth noting that the call to read all available parties doesn’t use the the party and synchronizer fields therefore changing them has no effect on the result.

import {
    WalletSDKImpl,
    localNetAuthDefault,
    localNetLedgerDefault,
} from '@canton-network/wallet-sdk'

const sdk = new WalletSDKImpl().configure({
    logger: console,
    authFactory: localNetAuthDefault,
    ledgerFactory: localNetLedgerDefault,
})

await sdk.connect()

const wallets = await sdk.userLedger?.listWallets()

Reading Ledger End

A lot of different requests will take a ledger offset to ensure the requested time correlates with ledger time. A Validator does not have a block height since there is no total state replication. There are two values that correlate:

  • ledger time - this is the time the ledger chooses when computing a transaction prior to commit.

  • record time - this is the time assigned by the sequencer when registering the confirmation request.

Ledger time should be used for all operations in your local environment (that does not affect partners). When doing reconciliation for transactions with partners or other members of a synchronizer it is better to use record time.

Ledger end can easily be derived from with the wallet SDK:

import {
    WalletSDKImpl,
    localNetAuthDefault,
    localNetLedgerDefault,
} from '@canton-network/wallet-sdk'

const sdk = new WalletSDKImpl().configure({
    logger: console,
    authFactory: localNetAuthDefault,
    ledgerFactory: localNetLedgerDefault,
})
await sdk.connect()

const ledgerEnd = await sdk.userLedger?.ledgerEnd()

Reading Active Contracts

Using the above ledger time we can figure out what the current state of all active contracts are. Contracts can be in two states - active and archived - which correlates to the UTXO mode of unspent and spent. Active contracts are contracts that are unspent and thereby can be used in new transactions or to exercise choices.

import {
    WalletSDKImpl,
    localNetAuthDefault,
    localNetLedgerDefault,
} from '@canton-network/wallet-sdk'

const sdk = new WalletSDKImpl().configure({
    logger: console,
    authFactory: localNetAuthDefault,
    ledgerFactory: localNetLedgerDefault,
})
await sdk.connect()

const offset = 100 // you can use the sdk.userLedger.ledgerEnd() to get the latest offset

const allActiveContracts = await sdk.userLedger?.activeContracts({ offset })

const myTemplateId = 'your-template-id-here'

const allActiveContractOfMyTemplate = await sdk.userLedger?.activeContracts({
    offset,
    templateIds: [myTemplateId], //this is optional for if you want to filter by template id
})

Visualizing a Transaction