Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions examples/ping/tests/blockdaemon.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@ test('dApp: execute externally signed tx with Blockdaemon', async ({

await dappPage.getByRole('button', { name: 'Accounts' }).click()
expect(
await dappPage.getByText(`${blockdaemonPartyHint}::`).count()
).toBeGreaterThanOrEqual(2)
await dappPage
.getByText(`${blockdaemonPartyHint}::`)
.filter({ visible: true })
.count()
).toBe(1)

// Guard against another wallet being selected as primary.
await wg.setPrimaryWallet(blockdaemonPartyId)
Expand Down
2 changes: 1 addition & 1 deletion examples/portfolio/src/contexts/ConnectionProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export const ConnectionProvider: React.FC<{ children: React.ReactNode }> = ({

// Second effect: request accounts only when connected
useEffect(() => {
const provider = window.canton
const provider = sdk.getConnectedProvider()
if (!provider || !connectionStatus?.connection?.isConnected) return
provider
.request({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import { v4 } from 'uuid'
import { PartyId } from '@canton-network/core-types'
import * as sdk from '@canton-network/dapp-sdk'
import {
type Holding,
type TransferInstructionView,
Expand Down Expand Up @@ -107,7 +108,7 @@ export const createTransfer = async ({
disclosedContracts,
}

const provider = window.canton
const provider = sdk.getConnectedProvider()
// TODO: check success
await provider?.request({
method: 'prepareExecuteAndWait',
Expand Down Expand Up @@ -149,7 +150,7 @@ export const exerciseTransfer = async ({
disclosedContracts,
}

const provider = window.canton
const provider = sdk.getConnectedProvider()
// TODO: check success
await provider?.request({
method: 'prepareExecuteAndWait',
Expand Down Expand Up @@ -214,7 +215,7 @@ export const createAllocation = async ({
disclosedContracts,
}

const provider = window.canton
const provider = sdk.getConnectedProvider()
// TODO: check success
await provider?.request({
method: 'prepareExecuteAndWait',
Expand Down Expand Up @@ -267,7 +268,7 @@ export const withdrawAllocation = async ({
disclosedContracts,
}

const provider = window.canton
const provider = sdk.getConnectedProvider()
// TODO: check success
await provider?.request({
method: 'prepareExecuteAndWait',
Expand Down Expand Up @@ -339,7 +340,7 @@ export const tap = async ({
disclosedContracts,
}

const provider = window.canton
const provider = sdk.getConnectedProvider()
// TODO: check success
await provider?.request({
method: 'prepareExecuteAndWait',
Expand Down
10 changes: 6 additions & 4 deletions examples/portfolio/src/services/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { TokenStandardClient } from '@canton-network/core-token-standard'
import { ScanProxyClient } from '@canton-network/core-splice-client'
import { TransactionHistoryService } from './transaction-history-service'
import type { LedgerProvider } from '@canton-network/core-provider-ledger'
import * as sdk from '@canton-network/dapp-sdk'
import {
AuthTokenProvider,
type AccessTokenProvider,
Expand All @@ -17,11 +18,12 @@ import {
// This module allows us to resolve (i.e. get an instance of) the different
// dependency services used throughout the project.

const resolveLedgerProvider = () => {
if (window.canton) {
return window.canton as unknown as LedgerProvider
export const resolveLedgerProvider = () => {
const provider = sdk.getConnectedProvider()
if (provider) {
return provider as unknown as LedgerProvider
} else {
throw new Error('window.canton is not available')
throw new Error('Dapp Provider is not available')
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from '@canton-network/core-tx-parser'
import { type Transaction } from '@canton-network/core-tx-parser'
import { LedgerProvider, type Ops } from '@canton-network/core-provider-ledger'
import { resolveLedgerProvider } from './resolve'

type FiltersByParty = Types['Map_Filters']

Expand Down Expand Up @@ -204,7 +205,7 @@ export class TransactionHistoryService {

const newUnprocessed: JsTransaction[] = []
for (const jsTransaction of unapplied) {
const provider = window.canton as unknown as LedgerProvider
const provider = resolveLedgerProvider()
const parser = new TransactionParser(
provider,
jsTransaction,
Expand Down
2 changes: 1 addition & 1 deletion examples/portfolio/tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const tap = async (
await page.goto(`${BASE_URL}/settings`)

// Wait for the DevNet Tap section to be visible
await expect(page.getByText('DevNet Tap')).toBeVisible({ timeout: 10000 })
await expect(page.getByText('DevNet Tap')).toBeVisible({ timeout: 20000 })

const tapForm = page.locator('form').filter({
has: page.getByRole('button', { name: 'TAP' }),
Expand Down
37 changes: 9 additions & 28 deletions sdk/dapp-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

## Features

- **Wallet Discovery** — Remote gateways, `window.*` namespace scanning, EIP-6963-style `canton:announceProvider` events, and pluggable adapters
- **Wallet Discovery** — Remote gateways, EIP-6963-style `canton:announceProvider` events, and pluggable adapters
- **Wallet Picker UI** — Built-in, framework-agnostic Web Component that lets users choose a wallet, enter custom gateway URLs, and manage recently used connections
- **Wallet Connectivity** — Connect, disconnect, and monitor connection status
- **Account Management** — List accounts and respond to account changes
Expand Down Expand Up @@ -74,22 +74,22 @@ The SDK is built around three layers:
┌──────────────────────────────────────────────┐
│ DappClient │
│ Thin wrapper: typed RPC helpers, events, │
window.canton injection, session persist │
│ session persist
├──────────────────────────────────────────────┤
│ DiscoveryClient │
│ Adapter registry, session restore, │
│ wallet picker integration │
├──────────────────────────────────────────────┤
│ ProviderAdapter implementations │
│ ExtensionAdapter, InjectedAdapter
│ (browser / postMessage, window.* inject)
│ ExtensionAdapter (announce protocol)
│ (browser / postMessage)
│ RemoteAdapter (HTTP/SSE gateway) │
└──────────────────────────────────────────────┘
```

## Wallet providers

Wallet and extension authors: see **[Wallet providers (discovery)](https://github.com/canton-network/wallet/blob/main/docs/dapp-building/dapp-sdk/provider.md)** in the dApp Building docs for how to appear in the picker (`RemoteAdapter`, `window.*` scan, `canton:announceProvider`, and `additionalAdapters`).
Wallet and extension authors: see **[Wallet providers (discovery)](https://github.com/canton-network/wallet/blob/main/docs/dapp-building/dapp-sdk/provider.md)** in the dApp Building docs for how to appear in the picker (`RemoteAdapter`, `canton:announceProvider`, and `additionalAdapters`).

## Usage

Expand Down Expand Up @@ -163,23 +163,6 @@ const client = new DappClient(provider)
const result = await client.connect()
```

### Provider API

The SDK also exposes a CIP-103 provider on `window.canton` (injected by default when a `DappClient` is created):

```typescript
const provider = window.canton

const result = await provider.request({ method: 'connect' })
const accounts = await provider.request({ method: 'listAccounts' })

provider.on('statusChanged', (event) => {
console.log('Status:', event.connection.isConnected)
})

provider.removeListener('statusChanged', listener)
```

## API Reference

### DappClient
Expand All @@ -203,7 +186,6 @@ provider.removeListener('statusChanged', listener)

| Option | Type | Default | Description |
| -------------- | -------------- | ---------- | ------------------------------------------------------------------------- |
| `injectGlobal` | `boolean` | `true` | Inject the provider into `window.canton` |
| `providerType` | `ProviderType` | `'remote'` | Affects `open()` routing (`'browser'` uses postMessage, others use popup) |

### DiscoveryClient
Expand All @@ -221,11 +203,10 @@ provider.removeListener('statusChanged', listener)

### Built-in Adapters

| Adapter | Provider Type | Transport | Description |
| ------------------ | ------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ExtensionAdapter` | `'browser'` | `postMessage` | Browser extensions (announced wallets or dApp-registered; optional explicit slot). |
| `InjectedAdapter` | `'browser'` | in-page `window` | Created when namespace scan finds a provider on `window` ([Wallet providers guide](https://github.com/canton-network/wallet/blob/main/docs/dapp-building/dapp-sdk/provider.md)). |
| `RemoteAdapter` | `'remote'` | HTTP/SSE | CIP-103 Wallet Gateways over the network. |
| Adapter | Provider Type | Transport | Description |
| ------------------ | ------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ExtensionAdapter` | `'browser'` | `postMessage` | Browser extensions discovered via `canton:announceProvider` ([Wallet providers guide](https://github.com/canton-network/wallet/blob/main/docs/dapp-building/dapp-sdk/provider.md)). |
| `RemoteAdapter` | `'remote'` | HTTP/SSE | CIP-103 Wallet Gateways over the network. |

## Documentation

Expand Down
1 change: 0 additions & 1 deletion sdk/dapp-sdk/src/adapter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export * from './types'
export * from './errors'
export * from './events'
export { ExtensionAdapter } from './extension-adapter'
export { InjectedAdapter } from './injected-adapter'
export { RemoteAdapter } from './remote-adapter'
export type { RemoteAdapterConfig } from './remote-adapter'
export { WalletConnectAdapter } from './walletconnect-adapter'
Expand Down
77 changes: 0 additions & 77 deletions sdk/dapp-sdk/src/adapter/injected-adapter.ts

This file was deleted.

9 changes: 1 addition & 8 deletions sdk/dapp-sdk/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import type {
Provider,
EventListener,
} from '@canton-network/core-splice-provider'
import { injectProvider } from '@canton-network/core-provider-dapp'
import { WalletEvent, type SpliceMessage } from '@canton-network/core-types'
import type {
AccountsChangedEvent,
Expand All @@ -27,8 +26,6 @@ import { popup } from '@canton-network/core-wallet-ui-components'
import { clearAllLocalState } from './util'

export interface DappClientOptions {
/** Inject provider into `window.canton`. Defaults to true. */
injectGlobal?: boolean | undefined
/** Provider type hint — affects `open()` routing. Defaults to `'remote'`. */
providerType?: ProviderType | undefined
/** Optional routing key for extension open messages. */
Expand All @@ -40,7 +37,7 @@ export interface DappClientOptions {
* `Provider<DappRpcTypes>`.
*
* It exposes typed RPC helpers, event subscription shortcuts,
* `window.canton` injection, and session-persistence listeners.
* and session-persistence listeners.
*
* How to obtain a provider is **not** this class's concern.
* Use `DiscoveryClient` + the wallet picker, or construct any
Expand All @@ -56,10 +53,6 @@ export class DappClient {
) {
this.provider = provider
this.options = options

if (options.injectGlobal !== false) {
injectProvider(provider)
}
}

// ── Provider access ───────────────────────────────────
Expand Down
2 changes: 1 addition & 1 deletion sdk/dapp-sdk/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

// Import global Window augmentation for the DappProvider injection
// Import global Window augmentation for `window.canton`
import '@canton-network/core-provider-dapp'

// ── Asset exports (icons for wallet adapters) ──
Expand Down
Loading