Migration guide

Wallet SDK v1 is not backwards compatible with v0.

Quick links

We have removed the configure() and connect() pattern in favor of passing in a static configuration or a provider with ledger api capabilities.

Static configuration initialization where we supply an auth config and a ledgerClientUrl:

import { SDK, localNetStaticConfig } from '@canton-network/wallet-sdk'

export default async function () {
    const sdk = await SDK.create({
        auth: {
            method: 'self_signed',
            issuer: 'unsafe-auth',
            credentials: {
                clientId: 'ledger-api-user',
                clientSecret: 'unsafe',
                audience: 'https://canton.network.global',
                scope: '',
            },
        },
        ledgerClientUrl: 'http://localhost:2975',
        token: {
            validatorUrl: 'http://localhost:2000/api/validator',
            registries: ['http://localhost:2000/api/validator/v0/scan-proxy'],
            auth: global.TOKEN_PROVIDER_CONFIG_DEFAULT,
        },
        amulet: {
            validatorUrl: localNetStaticConfig.LOCALNET_APP_VALIDATOR_URL,
            scanApiUrl: localNetStaticConfig.LOCALNET_SCAN_API_URL,
            auth: TOKEN_PROVIDER_CONFIG_DEFAULT,
            registryUrl: localNetStaticConfig.LOCALNET_REGISTRY_API_URL,
        },
        asset: {
            registries: [localNetStaticConfig.LOCALNET_REGISTRY_API_URL],
            auth: TOKEN_PROVIDER_CONFIG_DEFAULT,
        },
    })

    const myParty = global.EXISTING_PARTY_1

    await sdk.token.utxos.list({ partyId: myParty })

    await sdk.amulet.traffic.status()

    sdk.asset.list

    // OR, you can defer loading config by calling .extend()

    const basicSDK = await SDK.create({
        auth: {
            method: 'self_signed',
            issuer: 'unsafe-auth',
            credentials: {
                clientId: 'ledger-api-user',
                clientSecret: 'unsafe',
                audience: 'https://canton.network.global',
                scope: '',
            },
        },
        ledgerClientUrl: 'http://localhost:2975',
    })

    // Extend with token namespace
    const tokenExtendedSDK = await basicSDK.extend({
        token: {
            validatorUrl: 'http://localhost:2000/api/validator',
            registries: ['http://localhost:2000/api/validator/v0/scan-proxy'],
            auth: global.TOKEN_PROVIDER_CONFIG_DEFAULT,
        },
    })

    // Now token namespace is available
    await tokenExtendedSDK.token.utxos.list({ partyId: myParty })

    // Can extend further with more namespaces
    const fullyExtendedSDK = await tokenExtendedSDK.extend({
        amulet: {
            validatorUrl: localNetStaticConfig.LOCALNET_APP_VALIDATOR_URL,
            scanApiUrl: localNetStaticConfig.LOCALNET_SCAN_API_URL,
            auth: global.TOKEN_PROVIDER_CONFIG_DEFAULT,
            registryUrl: localNetStaticConfig.LOCALNET_REGISTRY_API_URL,
        },
    })

    // Now both token and amulet are available
    await fullyExtendedSDK.token.utxos.list({ partyId: myParty })
    await fullyExtendedSDK.amulet.traffic.status()
}

Provider intialization: The provider is an abstraction that ultimately interacts with the Ledger (JSON LAPI). This can be implemented for either a dApp consumer, direct ledger user, or alternative transport channels such as Wallet Connect.

// Notice that `auth` and `ledgerClientUrl` are no longer needed
// when supplying sdk with custom provider
const sdk = await SDK.create(config, provider)

Namespace changes

We have removed the controllers and replaced them with namespaces to appropriately segregate the service layer in terms of business context. When the sdk is initialized, it has access to the users, keys, ledger, and party namespaces. The amulet, token, asset, and events namespace can initialized with a separate config via .extend() method.

Removed functionality

The following methods have been removed:

sdk.connect() No longer needed, SDK is connected on creation sdk.connectAdmin() No longer needed, admin operations are available in the ledger namespace and rights are extracted from the token. sdk.connectTopology() No longer needed, the grpc endpoints have been removed and replaced with ledger api endpoints. sdk.setPartyId() Pass partyId explicitly to each operation

In v0, the controllers and sdk were stateful. In v1, party information should be passed explicitly to each function. This enables acting as multiple parties and allows for thread safety in concurrent use.

Migration reference table

Migration reference table

v0 controller + method

v1 namespace + method

createKeyPair()

sdk.keys.generate()

sdk.userLedger.signAndAllocateExternalParty(privateKey, partyHint)

sdk.party.external.create(publicKey, {partyHint}).sign(privateKey).execute()

sdk.userLedger.listWallets()

sdk.party.list()

sdk.userLedger.prepareSignExecuteAndWaitFor

sdk.ledger.prepare({partyId, commands, disclosedContracts}).sign(privateKey).execute(partyId)

sdk.userLedger.activeContracts

sdk.ledger.acs.read

sdk.adminLedger.uploadDar

sdk.ledger.dar.upload

sdk.userLedger.isPackageUploaded

sdk.ledger.dar.check

sdk.adminLedger.createUser

sdk.user.create

sdk.userLedger.grantRights

sdk.user.rights.grant

sdk.tokenStandard.createTransfer

sdk.token.transfer.create

sdk.tokenStandard.exerciseTransferInstructionChoice

sdk.token.transfer.accept / sdk.token.transfer.reject / sdk.token.transfer.withdraw

sdk.tokenStandard.fetchPendingTransferInstructionView

sdk.token.transfer.pending

sdk.tokenStandard.listHoldingTransactions({partyId})

sdk.token.holdings

sdk.tokenStandard.listHoldingUtxos()

sdk.token.utxos.list({partyId})

sdk.tokenStandard.mergeHoldingUtxos

sdk.token.utxos.merge

sdk.tokenStandard.fetchPendingAllocationRequestView

sdk.token.allocation.pending(partyId, ALLOCATION_REQUEST_INTERFACE_ID)

sdk.tokenStandard.fetchPendingAllocationInstructionView

sdk.token.allocation.pending(partyId, ALLOCATION_INSTRUCTION_INTERFACE_ID)

sdk.tokenStandard.fetchPendingAllocationView

sdk.token.allocation.pending(partyId)

sdk.tokenStandard.getAllocationExecuteTransferChoiceContext(cId)

sdk.token.allocation.context.execute

sdk.tokenStandard.getAllocationWithdrawChoiceContext(cId)

sdk.token.allocation.context.withdraw

sdk.tokenStandard.getAllocationCancelChoiceContext(cId)

sdk.token.allocation.context.cancel

sdk.tokenStandard.getMemberTrafficStatus

sdk.amulet.traffic.status

sdk.tokenStandard.buyMemberTraffic

sdk.amulet.traffic.buy

sdk.userLedger.createTransferPreapprovalCommand

sdk.amulet.preapproval.command.create

sdk.tokenStandard.getTransferPreApprovalByParty

sdk.amulet.preapproval.fetchStatus

sdk.tokenStandard.createRenewTransferPreapproval

sdk.amulet.preapproval.renew

sdk.tokenStandard.createCancelTransferPreapproval

sdk.amulet.preapproval.command.cancel

sdk.tokenStandard.createTap

sdk.amulet.tap

sdk.tokenStandard.lookupFeaturedApps

sdk.amulet.featuredApp.rights

sdk.tokenStandard.selfGrantFeatureAppRights

sdk.amulet.featuredApp.grant

sdk.tokenStandard.getInstrumentById

sdk.asset.find

sdk.tokenStandard.listInstruments

sdk.asset.list

sdk.userLedger.subscribeToUpdates

sdk.events.updates

sdk.userLedger.subscribeToCompletions

sdk.events.completions