Skip to main content
Canton Network uses Ed25519 keypairs for external party identities — wallets that participate in the ledger without running a Canton node. Because Para-managed Solana wallets are native Ed25519 keys, they work directly with Canton’s external party API. This walkthrough shows how to connect through ParaModal, prove key ownership to Canton, and receive a partyId on the ledger — entirely from a React app.

How it works

1

Connect with Para

User authenticates through ParaModal and gets an embedded Solana wallet.
2

Register the public key with Canton

Server sends the Solana public key to Canton’s generateExternalParty, which returns a multiHash challenge.
3

Sign the challenge with Para

Client signs the multiHash with useSignMessage.
4

Allocate the party

Server submits the signature to Canton’s allocateExternalParty, which returns a partyId.

Prerequisites

  • A Para API key from the Para Developer Portal
  • Access to a Canton ledger and validator — either a hosted deployment or a local Splice LocalNet stack via docker-compose
  • Node.js 18+ with Next.js (for the server-side Canton SDK calls)
  • Basic familiarity with React and TypeScript

Installation

The Canton SDK (@canton-network/wallet-sdk) must run on the server. Using server-only ensures it never bundles into the browser.

Project structure

The Canton SDK holds credentials for your validator. Keep it in Next.js API routes so those credentials never reach the client.

Setup

1. Configure the Para Provider

Set up ParaProvider with embedded-wallet signups enabled. Para automatically provisions a Solana (Ed25519) wallet for each user, which is what Canton needs.
No externalWalletConfig is set — Canton external parties are backed by Para’s own MPC-managed Solana key, not a user-supplied wallet like Phantom or MetaMask.

2. Initialize the Canton SDK (server-only)

Create src/lib/canton.ts. This mirrors Canton’s own localNetAuthDefault pattern and is memoized so the SDK connects once per server process.
For production Canton deployments, replace localNetAuthDefault with your validator’s authentication method (typically OAuth/JWT). Update VALIDATOR_AUDIENCE to match your validator’s expected audience.

3. Create the API routes

/api/canton/generate — decodes the Solana address and calls Canton to prepare the external party challenge.
/api/canton/allocate — submits the Para-produced Ed25519 signature to finalize the party.

4. Build the onboarding hook

useCantonOnboarding does three things on the client:
  1. Makes sure the user’s Para Solana wallet is the active one (embedded accounts default to EVM).
  2. Fetches the Canton challenge, signs it with useSignMessage, and submits the signature.
useSignMessage goes straight to Para’s MPC signMessage endpoint, so there’s no Solana RPC client to configure.

5. Wire up the UI

Environment variables

These defaults target the app-user node of a Splice LocalNet docker-compose stack. For a hosted Canton deployment, update the URLs, swap localNetAuthDefault for the appropriate auth factory, and set VALIDATOR_AUDIENCE to whatever your validator expects.

Complete example

A fully working Next.js app with this flow, including styled UI and error handling, is available in the Para Examples Hub:

Canton External Party Example

Next.js + ParaModal + Canton Network — generate, sign, and allocate an external party on the Canton ledger

Solana Transfers

Intermediate · 25 min · Send SOL with Web3.js, Signers v2, and Anchor

Ethereum Transfers

Intermediate · 20 min · Send ETH with Ethers and Viem

EIP-712 Typed Data Signing

Intermediate · 20 min · Structured data signing