@sigilry/dapp
@sigilry/dapp is the core package for CIP-103-compliant dApp ↔ wallet extension communication on Canton Network. It provides the CIP-103 provider interface (SpliceProvider), JSON-RPC client and server, transport abstractions, and Zod schemas generated from the CIP-103 OpenRPC spec.
Install
Section titled “Install”yarn add @sigilry/dappProvider usage (dApp)
Section titled “Provider usage (dApp)”The wallet extension injects a CIP-103 provider at window.canton. The object shape (request, on, removeListener) is the EIP-1193 pattern that CIP-103 adopts; method names, params, results, and error codes are fixed by the CIP-103 spec.
async function connect() { const status = await window.canton.request({ method: "status" }); if (!status.connection.isConnected) { await window.canton.request({ method: "connect" }); }
const accounts = await window.canton.request({ method: "listAccounts" }); console.log(accounts); return accounts;}
const accounts = await window.canton.request({ method: "listAccounts" });console.log(accounts);Typed client usage (custom transport)
Section titled “Typed client usage (custom transport)”import { createCantonClient, WindowTransport } from "@sigilry/dapp";
async function getStatus() { const transport = new WindowTransport(window, { timeout: 30000 }); const client = createCantonClient(transport); return await client.status();}
getStatus().then(console.log);Extension server usage
Section titled “Extension server usage”import { createCantonServer, createStubHandlers, isSpliceMessageEvent, jsonRpcResponse, WalletEvent,} from "@sigilry/dapp";
const server = createCantonServer({ ...createStubHandlers(), status: async () => ({ provider: { id: "send-extension", providerType: "browser" }, connection: { isConnected: true, isNetworkConnected: true }, }), connect: async () => ({ isConnected: true, isNetworkConnected: true, }), disconnect: async () => null, getActiveNetwork: async () => ({ networkId: "canton:localnet" }), listAccounts: async () => [], getPrimaryAccount: async () => ({ primary: true, partyId: "alice::1220abc123", status: "allocated", hint: "alice", publicKey: "ed25519:abc123", namespace: "1220abc123", networkId: "canton:localnet", signingProviderId: "passkey", }), prepareExecute: async () => null, prepareExecuteAndWait: async () => ({ tx: { status: "executed", commandId: "cmd-123", payload: { updateId: "update-1", completionOffset: 1 }, }, }), signMessage: async () => ({ signature: "base64-signature" }), ledgerApi: async () => ({ events: [] }),});
window.addEventListener("message", async (event) => { if (!isSpliceMessageEvent(event)) return; if (event.data.type !== WalletEvent.SPLICE_WALLET_REQUEST) return;
const response = await server.handleRequest(event.data.request.method, event.data.request.params);
window.postMessage( { type: WalletEvent.SPLICE_WALLET_RESPONSE, response: jsonRpcResponse(event.data.request.id, response), }, "*", );});Key exports
Section titled “Key exports”CANTON_DAPP_API_VERSIONSpliceProviderBase,SpliceProviderWindowTransportcreateCantonClient,createCantonServer,createStubHandlersWalletEvent,isSpliceMessage,isSpliceMessageEventjsonRpcRequest,jsonRpcResponseRpcErrorCode,rpcError,RpcClientError
Generated schemas
Section titled “Generated schemas”Zod schemas are generated from OpenRPC specifications and exposed under @sigilry/dapp/schemas:
import { StatusEventSchema, JsPrepareSubmissionRequestSchema, type StatusEvent,} from "@sigilry/dapp/schemas";
const status = StatusEventSchema.parse(data);Regenerate schemas after spec updates:
yarn workspace @sigilry/dapp codegen