PartyLayer

Canton wallets / Console Wallet

Console wallet integration

ConsoleAdapter is the reference integration in this repository and the one with the widest surface. It is the only adapter here whose registry entry declares an announce transport, so an installed wallet is discovered through the CIP-0103 announcement rather than by probing a window property. It reaches all three networks, and it is the only one in this set that serves desktop and mobile from a single entry.

What the registry declares

TransportBrowser extension, with mobile deep link
Adapter package@partylayer/adapter-console
SDK version>=0.2.5
Networksdevnet, testnet, mainnet
CIP-0103Native, since 2025-11-01

The CIP-0103 marker is recorded with its evidence: https://www.npmjs.com/package/@console-wallet/dapp-sdk. That link is the source; this page does not restate what it says.

Install

npm install @partylayer/react @partylayer/adapter-console

Construct the adapter

import { ConsoleAdapter } from '@partylayer/adapter-console';

// No configuration required. The default target is 'combined': the adapter
// tries the extension first and falls back to the QR and deep-link flow.
const console = new ConsoleAdapter();

// Pin a single path when you do not want the fallback:
//   new ConsoleAdapter({ target: 'local' })   extension only
//   new ConsoleAdapter({ target: 'remote' })  QR and deep link only

Register it

Pass the adapter to PartyLayerKit. Everything else, the button and the modal, is the same for every wallet.

import { PartyLayerKit, ConnectButton } from '@partylayer/react';

export default function App() {
  return (
    <PartyLayerKit network="devnet" adapters={[console]}>
      <ConnectButton />
    </PartyLayerKit>
  );
}

Connection flow

With the default 'combined' target the adapter resolves its transport at connect time rather than up front, so until connect succeeds there is no transport to report. That is why diagnostics show no transport for a combined-mode adapter that has not connected yet. In 'local' mode it calls checkExtensionAvailability() first and refuses to start a flow that cannot finish.

What the transport means for you

Because one adapter covers both the extension and the QR path, a single picker entry serves a desktop user with the extension installed and a phone user without it. The cost is that you cannot tell in advance which path a given user will take, so any copy you write around the connect button has to make sense for both. If you need to know, pin the target and register two entries rather than reading the transport before connect.

What this adapter supports

CapabilityCallThrough this adapter
Sign messageuseSignMessage()Yes
Sign transactionuseSignTransaction()Yes
Submit transactionuseSubmitTransaction()Yes
Report transaction statussubmit resultYes
Switch networkclient.switchNetwork()Not available
Multi-partymulti-party flowsNot available

Not available, and why

switchNetwork
The registry entry declares switchNetwork: false, and ConsoleAdapter exposes no switchNetwork path. Configure the network on PartyLayerKit instead.
multi-party flows
The registry entry declares multiParty: false. Nothing in ConsoleAdapter implements a multi-party path.

Things that will catch you out

signMessage sends base64, not raw textConsoleAdapter base64-encodes the message's UTF-8 bytes before sending. The registry entry records this as adapter config signMessageBase64: true. If you compare a signature against one produced by signing raw bytes elsewhere, they will not match.
transfer requires an explicit deadlineConsoleAdapter refuses a transfer intent with no executeBefore, throwing CapabilityNotSupportedError rather than choosing a deadline for you. Always set intent.executeBefore as an ISO 8601 timestamp.
connect throws rather than inventing a party idEarlier versions returned a generated party id of the form party-<timestamp> when the wallet returned none. That value never came from the wallet, and a session carrying it failed later, far from the cause. ConsoleAdapter.connect now throws instead. This was our defect, not the wallet's.

Troubleshooting

Every symptom below is a real rejection path in @partylayer/adapter-console, quoted from the adapter rather than reconstructed.

SymptomCauseWhat to do
WalletNotInstalledError: "Console Wallet extension not detected. Install from https://consolewallet.io"The adapter is running in 'local' target, or resolved to the local path, and checkExtensionAvailability() reported a status other than installed.Leave target at the default 'combined' so the QR and deep-link path stays available, or gate the wallet behind an install call to action when you deliberately pin 'local'.
"Console Wallet returned no party id from getPrimaryAccount, so there is no account to connect."The connect handshake completed but getPrimaryAccount came back without a partyId, so there is no account to build a session from.Treat it as a failed connect and let the user retry. Do not synthesise an id: this is the exact case where the adapter used to fabricate one and fail later instead.
CapabilityNotSupportedError mentioning "ledgerApi"The connected extension build does not expose the CIP-0103 ledgerApi method, so the adapter has nothing to proxy the request to.Feature-detect before offering ledger reads in your UI, and handle the rejection rather than assuming ledgerApi is always present.
Connect rejects with the wallet's own reason textThe connect result came back with isConnected false; the adapter surfaces the reason the wallet gave rather than replacing it.Show that reason to the user. It is the wallet's message, not ours, and it is usually more specific than anything generic we could substitute.

Related

Other wallets

5N Loop · Cantor8 · Bron · Nightly · WalletConnect