@canton-network/core-splice-provider

中文文档
1.17.0发布于 2026/11/06Apache-2.0TypeScriptESM + CJS近 30 天下载 34.5万

A JavaScript Splice Provider API (EIP-1193 compliant).

原始使用文档
文档目录13 节
  1. Install
  2. Goals
  3. Provider interface
  4. AbstractProvider
  5. Typing model
  6. OpenRPC (dApp API)
  7. OpenAPI (Ledger API)
  8. Implementations
  9. Minimal custom provider
  10. Events
  11. Errors
  12. Exports
  13. Related packages

@canton-network/core-splice-provider

Shared Provider abstraction for talking to a Canton ledger — either directly (JSON Ledger API) or through a wallet / dApp API.

Consumers never call the ledger or a specific transport themselves. They use one interface:

import {
    AbstractProvider,
    Provider,
} from '@canton-network/core-splice-provider'

The shape follows EIP-1193 (request + events) without Ethereum method semantics. Concrete APIs are defined elsewhere — for example CIP-103 for dApps and the Canton JSON Ledger API for direct access.

Published on npm under Apache-2.0.

Install

npm install @canton-network/core-splice-provider

Goals

  • One interface for direct ledger access and wallet-mediated access
  • Transport agnostic — HTTP, postMessage, SSE, in-process, or anything else
  • Auth agnostic — implementations choose how credentials are obtained
  • Request + events — request for RPC-style calls; on / removeListener / emit for streams
  • Typed methods — params and results inferred from the method name
  • Small surface — easy to reimplement in other languages; transport-specific providers can be published separately

What this package does not define: which LAPI or dApp methods exist, how authentication works, or wallet / UI behaviour. Those belong to specs, codegen, and concrete providers.

flowchart TB
    subgraph consumers [Consumers]
        DappSDK["dApp SDK"]
        WalletSDK["Wallet SDK"]
        Custom["Custom app / tooling"]
    end

    Provider["Provider / AbstractProvider<br/><i>request · on · emit · removeListener</i>"]

    subgraph impls [Implementations]
        LedgerP["LedgerProvider"]
        SyncP["DappSyncProvider"]
        AsyncP["DappAsyncProvider"]
    end

    subgraph transports [Transports]
        HTTP["HTTP"]
        PM["postMessage"]
        SSE["HTTPS + SSE"]
    end

    subgraph backends [Backends]
        LAPI["JSON Ledger API"]
        LocalW["Extension / desktop wallet"]
        RemoteW["Remote wallet gateway"]
    end

    DappSDK --> Provider
    WalletSDK --> Provider
    Custom --> Provider

    Provider --> LedgerP
    Provider --> SyncP
    Provider --> AsyncP

    LedgerP --> HTTP --> LAPI
    SyncP --> PM --> LocalW
    AsyncP --> SSE --> RemoteW

Provider interface

import type { RequestArgs, UnknownRpcTypes } from '@canton-network/core-types'

export type EventListener<T> = (...args: T[]) => void

export interface Provider<T extends UnknownRpcTypes> {
    request<M extends keyof T>(args: RequestArgs<T, M>): Promise<T[M]['result']>

    on<E>(event: string, listener: EventListener<E>): Provider<T>
    emit<E>(event: string, ...args: E[]): boolean
    removeListener<E>(
        event: string,
        listenerToRemove: EventListener<E>
    ): Provider<T>
}

The interface does not assume which methods are supported, how authentication works, or whether calls go through a wallet — only a typed request and an event bus.

AbstractProvider

Implements the event map (on / emit / removeListener) and leaves request abstract:

export abstract class AbstractProvider<
    T extends UnknownRpcTypes,
> implements Provider<T> {
    abstract request<M extends keyof T>(
        args: RequestArgs<T, M>
    ): Promise<T[M]['result']>

    // on / emit / removeListener provided
}

Subclasses wire request to their transport (HTTP JSON LAPI, window postMessage, HTTPS + SSE, and so on).

Typing model

Every call is keyed by a method name M. Params come from C[M]['params'] and the result from C[M]['result']. Helpers live in @canton-network/core-types:

type UnknownRpcTypes = {
    [method: string]: {
        params: unknown
        result: unknown
    }
}

type RequestArgs<
    T extends UnknownRpcTypes,
    M extends keyof T,
> = T[M]['params'] extends never
    ? { method: M }
    : { method: M; params: T[M]['params'] }

Specs usually come from OpenRPC (JSON-RPC style) or OpenAPI (Ledger API). Codegen produces TypeScript models; providers map them into this params / result shape.

OpenRPC (dApp API)

Map each method to params and result. Use params: never when a method takes no arguments:

type DappClient = {
    prepareExecute: {
        params: PrepareExecuteParams
        result: PrepareExecuteResult
    }
    status: {
        params: never
        result: StatusResult
    }
}

class DappProvider implements Provider<DappClient> {
    async request<M extends keyof DappClient>(
        args: RequestArgs<DappClient, M>
    ): Promise<DappClient[M]['result']> {
        // dispatch via transport…
    }
}

await provider.request({ method: 'status' })
await provider.request({
    method: 'prepareExecute',
    params: {/* PrepareExecuteParams */},
})

OpenAPI (Ledger API)

Ledger access is exposed as one RPC-style method, ledgerApi, whose params encode the HTTP operation (resource, requestMethod, optional body / path / query).

For per-operation type safety, each Ledger API operation is a distinct member of a union. TypeScript narrows params and results from resource + requestMethod (you can also pass an explicit operation type argument):

type LedgerClient =
    | {
          ledgerApi: {
              params: {
                  resource: '/v2/parties'
                  requestMethod: 'get'
                  query: { /* … */ }
              }
              result: ListKnownPartiesResponse
          }
      }
    | {
          ledgerApi: {
              params: {
                  resource: '/v2/parties'
                  requestMethod: 'post'
                  body: AllocatePartyRequest
              }
              result: AllocatePartyResponse
          }
      }
    | /* … */

Stock OpenAPI codegen does not emit this shape; a dedicated generator produces the provider-oriented operation types used by @canton-network/core-provider-ledger.

Implementations

PackageClassAccess modelTypical transport
@canton-network/core-provider-ledgerLedgerProviderDirect JSON LAPIHTTP
@canton-network/core-provider-dappDappSyncProviderCIP-103 Sync (extension / desktop)postMessage / window bridge
@canton-network/core-provider-dappDappAsyncProviderCIP-103 Async (remote / custody)HTTPS + SSE

Higher-level SDKs (@canton-network/dapp-sdk, @canton-network/wallet-sdk) sit on these providers so app code keeps the same interface for local and remote wallets.

Minimal custom provider

import { AbstractProvider } from '@canton-network/core-splice-provider'
import { RequestArgs } from '@canton-network/core-types'

type MyRpc = {
    ping: { params: { message: string }; result: string }
}

class MyProvider extends AbstractProvider<MyRpc> {
    async request<M extends keyof MyRpc>(
        args: RequestArgs<MyRpc, M>
    ): Promise<MyRpc[M]['result']> {
        if (args.method === 'ping') {
            return `pong:${args.params.message}` as MyRpc[M]['result']
        }
        throw new Error('Unsupported method')
    }
}

const provider = new MyProvider()
provider.on('ready', () => console.log('ready'))
await provider.request({ method: 'ping', params: { message: 'hi' } })

Events

AbstractProvider maintains an in-memory listener map:

  • on(event, listener) — register
  • removeListener(event, listener) — unregister
  • emit(event, …args) — notify; returns false if nobody is listening

Event names and payloads come from the concrete API (for example CIP-103 statusChanged, accountsChanged, txChanged, plus Async-only connected and messageSignature). This package only provides the subscription machinery.

Errors

Implementations should expose a consistent error shape (code + message) regardless of transport, normalizing underlying JSON Ledger API / JSON-RPC failures where needed. dApp providers typically follow EIP-1193 / EIP-1474-style codes; see the dApp SDK errors reference.

Exports

ExportDescription
Provider<T>Typed provider interface
AbstractProvider<T>Base class with events; implement request
EventListener<T>Listener callback type

RPC map helpers (UnknownRpcTypes, RequestArgs) are in @canton-network/core-types.

PackageRole
@canton-network/core-typesShared RPC typing helpers
@canton-network/core-provider-ledgerDirect ledger provider
@canton-network/core-provider-dappSync / Async dApp providers
@canton-network/core-rpc-transportTransports used by RPC clients
@canton-network/dapp-sdkHigh-level dApp SDK
@canton-network/wallet-sdkWallet SDK

版本与发布记录

@canton-network/core-splice-provider 共发布 78 个版本,首次发布于 2025/08/29;过去 12 个月发布了 64 个版本。

版本发布日期距今
1.17.0latest2026/11/063 天前
1.16.02026/10/2910 天前
1.12.1-backport.3bugfix2026/10/2613 天前
1.15.02026/10/2317 天前
1.14.02026/10/1227 天前
1.12.1-backport.12026/10/031 个月前

关于 @canton-network/core-splice-provider 的常见问题

@canton-network/core-splice-provider 是什么?

A JavaScript Splice Provider API (EIP-1193 compliant).

如何安装 @canton-network/core-splice-provider?

在项目目录运行 npm install @canton-network/core-splice-provider,或使用 pnpm add / yarn add / bun add。

@canton-network/core-splice-provider 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@canton-network/core-splice-provider 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@canton-network/core-splice-provider 可以商用吗?

@canton-network/core-splice-provider 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@canton-network/core-splice-provider 的下载量有多少?

根据 npm 官方下载统计,@canton-network/core-splice-provider 在 2026/10/09 – 2026/11/07 这 30 天内被下载 344,901 次,日均约 11,497 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@canton-network/core-splice-provider 还在维护吗?

最新版本 1.17.0 发布于 2026/11/06(3 天前);至今共发布 78 个版本,其中过去 12 个月发布了 64 个;首次发布于 2025/08/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。