CIP-0103 — dApp API
CIP-0103 is the Canton standard a website uses to talk to a wallet. The machine-readable spec is the sync OpenRPC document in the Splice wallet kernel. This page is the Ekiden reading of that spec: what we implement, and the one method we refuse. Specification: CIP-0103.Browser discovery: Canton docs — browser extension. Attach discovery, connect, and submit beside this page.
Discovery
The Canton SDK does not look forwindow.ekidenWallet or window.canton. It dispatches canton:requestProvider and collects canton:announceProvider for a few hundred milliseconds.
Ekiden announces:
The SDK’s provider id is
browser:ext:ekiden-wallet.
A dApp that does not want auto-discovery can register the extension itself:
window.ekidenWallet on the page is only a marker (isEkiden, id, name, version). Call the SDK, not that object.
Wire protocol
Requests and responses arewindow.postMessage frames.
Request:
response.error with { code, message, data? }.
Events are the same request frame without id:
target is set and is not ekidenWallet are ignored.
Methods
prepareExecute params are a JSON Ledger API prepare body: commands (required), plus optional commandId, actAs, synchronizerId, disclosedContracts. A nested params.params object is flattened.
Events
txChanged.status is pending (approval opened), executed (payload.updateId, payload.completionOffset), or failed (user rejected, or submit failed). Ekiden does not emit a separate signed event; signing and submit are one approval.
Errors
CIP-0103 uses the EIP-1193 / EIP-1474 codes. On theSPLICE_WALLET_* path Ekiden returns:
The named Ekiden SDK methods (
ekidenWallet.connect, …) still reject with Error.message and no code. ekidenWallet.request uses the codes above.
Gaps
ledgerApi
CIP-0103 says a wallet should proxy the participant JSON Ledger API, authenticated as the connected party, and return the JSON body unchanged.
Ekiden does not do that. The extension does not hold a participant token it can safely hand to a website, and it does not forward arbitrary HTTP to a validator. An open proxy would let any connected origin read or write anything that token allows.
Use these instead:
request("ledgerApi", …) fails with 4200 and data.reason explaining the same limit.
Async API
The remote CIP-0103 variant (userUrl, connected event) is for server-side wallets. Ekiden is in-page and synchronous. There is no userUrl.
signed transaction event
The spec allows txChanged with status: "signed" before submit. Ekiden signs inside prepareExecute and only emits pending, then executed or failed.
Ekiden SDK and CIP-0103 together
@ekidenfi/dapp-sdk is a thin client.
- Named methods use Ekiden’s own
postMessagetypes (CONNECT,GET_ACTIVE_ACCOUNT,EXECUTE, …).prepareExecuteresolves{ tx: { status, commandId, payload } }. ekidenWallet.request(method, params)andekidenWallet.on(event, listener)use the CIP-0103 frames above.request("prepareExecute", body)resolvesnull.
sdk.connect() from @canton-network/dapp-sdk when the app should list every CIP-0103 wallet.