diff --git a/docs-main/docs.json b/docs-main/docs.json index 01caf85ec..0d356de91 100644 --- a/docs-main/docs.json +++ b/docs-main/docs.json @@ -522,17 +522,36 @@ { "group": "Wallet Gateway", "pages": [ - "integrations/wallet-gateway/download", - "integrations/wallet-gateway/configuration", + "integrations/wallet-gateway/overview", + "integrations/wallet-gateway/quickstart", { - "group": "Wallet Gateway Integration Guide", + "group": "Set up & operate", "pages": [ - "integrations/wallet-gateway/usage", - "integrations/wallet-gateway/signing-providers", - "integrations/wallet-gateway/apis", - "integrations/wallet-gateway/troubleshooting" + "integrations/wallet-gateway/operate/configure", + "integrations/wallet-gateway/operate/networks-and-identity", + "integrations/wallet-gateway/operate/signing-providers", + "integrations/wallet-gateway/operate/deploy", + "integrations/wallet-gateway/operate/security", + "integrations/wallet-gateway/operate/troubleshooting" ] - } + }, + { + "group": "Use the Wallet Gateway", + "pages": [ + "integrations/wallet-gateway/use/party-management", + "integrations/wallet-gateway/use/approve-and-sign", + "integrations/wallet-gateway/use/automate-with-user-api" + ] + }, + { + "group": "Reference", + "pages": [ + "integrations/wallet-gateway/reference/user-api", + "integrations/wallet-gateway/reference/dapp-api", + "integrations/wallet-gateway/reference/configuration-reference" + ] + }, + "integrations/release-notes/wallet-gateway" ] }, { diff --git a/docs-main/integrations/release-notes/wallet-gateway.mdx b/docs-main/integrations/release-notes/wallet-gateway.mdx index f36c0f3f1..17cb6d81c 100644 --- a/docs-main/integrations/release-notes/wallet-gateway.mdx +++ b/docs-main/integrations/release-notes/wallet-gateway.mdx @@ -1,5 +1,5 @@ --- -title: "Wallet Gateway" +title: "Release Notes" description: "Release notes for the Canton Network Wallet Gateway" --- diff --git a/docs-main/integrations/wallet-gateway/apis.mdx b/docs-main/integrations/wallet-gateway/apis.mdx deleted file mode 100644 index 64521620b..000000000 --- a/docs-main/integrations/wallet-gateway/apis.mdx +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: "APIs" -description: "Wallet Gateway dApp API and User API reference" ---- - -{/* COPIED_START source="wallet-gateway:docs/dapp-building/wallet-gateway/apis/index.md@82ec39c9" hash="dbda9001" */} - -The Wallet Gateway exposes two JSON-RPC 2.0 APIs: one for dApps interactions and one for user interactions. Both APIs use the same base URL but different paths. - -## API Endpoints - -- **dApp API**: `/api/v0/dapp` - Used by decentralized applications to interact with wallets and submit transactions -- **User API**: `/api/v0/user` - Used by users to manage wallets, networks, and signing providers - -Both APIs follow the JSON-RPC 2.0 specification and use JWT-based authentication for secure access. - -## dApp API Reference - -The dApp API enables decentralized applications to connect to wallets, query ledger state, prepare transactions, and submit commands. This API is designed for programmatic access from web or mobile applications. - -**Authentication:** - -The dApp API requires a valid JWT token in the `Authorization` header: - -```text -Authorization: Bearer -``` - -**Full API Specification:** - -The complete OpenRPC specification is available at [openrpc-dapp-api.json](https://github.com/canton-network/wallet-gateway/blob/main/api-specs/openrpc-dapp-api.json). - -## User API Reference - -The User API enables users to manage their wallets, configure networks, manage identity providers, create parties, and interact with their wallet through the web UI. - -**Methods:** - -| Category | Method | Description | -| ------------------ | ---------------------- | ------------------------------------------------------------------- | -| Sessions | `addSession()` | Create a new session (unauthenticated, used for initial connection) | -| | `removeSession()` | End the current session | -| | `listSessions()` | List sessions for the current user | -| Networks | `listNetworks()` | List all configured networks | -| | `addNetwork()` | Add a new network configuration | -| | `removeNetwork()` | Remove a network configuration | -| Identity Providers | `listIdps()` | List all identity providers | -| | `addIdp()` | Add a new identity provider | -| | `removeIdp()` | Remove an identity provider | -| Wallets | `createWallet()` | Create a new wallet (party) on a network | -| | `listWallets()` | List all wallets for the current user | -| | `setPrimaryWallet()` | Set the primary wallet | -| | `removeWallet()` | Remove a wallet | -| | `syncWallets()` | Sync wallets with the ledger | -| | `isWalletSyncNeeded()` | Check if wallet sync is needed | -| Transactions | `sign()` | Sign a transaction | -| | `execute()` | Execute a signed transaction | -| | `getTransaction()` | Get a transaction by ID | -| | `listTransactions()` | List transactions | - -**Authentication:** - -Most User API methods require authentication via JWT token. However, the following methods are available without authentication: - -- `addSession()` -- `listNetworks()` -- `listIdps()` - -**Full API Specification:** - -The complete OpenRPC specification is available at [openrpc-user-api.json](https://github.com/canton-network/wallet-gateway/blob/main/api-specs/openrpc-user-api.json). - -## Server-Sent Events (SSE) Support - -The dApp API supports Server-Sent Events (SSE) for real-time notifications. Connect to the `/events` path relative to the dApp API base URL (e.g. `/api/v0/dapp/events`). Authenticate by passing the JWT token as the `token` query parameter (the `Authorization: Bearer` header is also supported): - -```javascript -const eventsUrl = new URL('events', dappApiUrl + '/') -eventsUrl.searchParams.set('token', jwtToken) -const eventSource = new EventSource(eventsUrl.toString()) - -eventSource.addEventListener('accountsChanged', (e) => { - /* ... */ -}) -eventSource.addEventListener('statusChanged', (e) => { - /* ... */ -}) -eventSource.addEventListener('connected', (e) => { - /* ... */ -}) -eventSource.addEventListener('txChanged', (e) => { - /* ... */ -}) -``` - -SSE connections receive real-time updates about: - -- Transaction status changes (`txChanged`) -- Account changes (`accountsChanged`) -- Session/connection state (`connected`, `statusChanged`) - -## Rate Limiting - -API requests are rate-limited to prevent abuse. The default limits can be configured in the server configuration. Rate limit headers are included in responses: - -- `X-RateLimit-Limit` - Maximum number of requests per window -- `X-RateLimit-Remaining` - Remaining requests in current window -- `X-RateLimit-Reset` - Time when the rate limit resets - -## CORS Configuration - -Cross-Origin Resource Sharing (CORS) is configured via the `allowedOrigins` setting in the server configuration. By default, all origins are allowed (`['*']`), but for production deployments, you should restrict this to known dApp origins. - -Example Configuration: - -```json -{ - "server": { - "allowedOrigins": [ - "https://my-dapp.example.com", - "https://another-dapp.example.com" - ] - } -} -``` - -Alternatively, you can allow all origins by setting `allowedOrigins` to `"*"`. - -```json -{ - "server": { - "allowedOrigins": ["*"] - } -} -``` - -{/* COPIED_END */} diff --git a/docs-main/integrations/wallet-gateway/configuration.mdx b/docs-main/integrations/wallet-gateway/configuration.mdx deleted file mode 100644 index fc513ddc4..000000000 --- a/docs-main/integrations/wallet-gateway/configuration.mdx +++ /dev/null @@ -1,604 +0,0 @@ ---- -title: "Configuration" -description: "Configure a remote Wallet Gateway" ---- - -{/* COPIED_START source="wallet-gateway:docs/dapp-building/wallet-gateway/configuration/index.md@82ec39c9" hash="82d4f3ee" */} - -This section covers the different ways the Wallet Gateway can be configured to support a variety of use cases and deployment scenarios. - -## Overview - -The Wallet Gateway configuration is a JSON file that defines: - -- **Kernel Settings**: Identity and client type information -- **Server Settings**: Network binding, ports, API paths, and admin user -- **Store Configuration**: Database connection and persistence settings -- **Bootstrap Configuration**: Initial identity providers and network definitions seeded on first run -- **Signing Store**: Optional database for key storage (when using internal signing) - -## Default Configuration Example - -Here is a minimalistic configuration example that can be used against a Splice localnet using SQLite storage and a mock OAuth setup. The mock OAuth configuration showcases how an IDP configuration would look. - -```json -{ - "kernel": { - "id": "remote-da", - "clientType": "remote" - }, - "server": { - "port": 3030, - "dappPath": "/api/v0/dapp", - "userPath": "/api/v0/user", - "allowedOrigins": ["http://localhost:8080", "http://localhost:8081"], - "admin": "operator" - }, - "store": { - "connection": { - "type": "sqlite", - "database": "store.sqlite" - } - }, - "signingStore": { - "connection": { - "type": "sqlite", - "database": "signingStore.sqlite" - } - }, - "bootstrap": { - "idps": [ - { - "id": "idp-mock-oauth", - "type": "oauth", - "issuer": "http://127.0.0.1:8889", - "configUrl": "http://127.0.0.1:8889/.well-known/openid-configuration" - } - ], - "networks": [ - { - "id": "canton:localnet", - "name": "LocalNet", - "description": "LocalNet configuration", - "identityProviderId": "idp-self-signed", - "auth": { - "method": "self_signed", - "issuer": "self-signed", - "audience": "https://canton.network.global", - "scope": "openid daml_ledger_api offline_access", - "clientId": "ledger-api-user", - "clientSecret": "unsafe" - }, - "adminAuth": { - "method": "self_signed", - "issuer": "self-signed", - "scope": "openid daml_ledger_api offline_access", - "audience": "https://canton.network.global", - "clientId": "ledger-api-user", - "clientSecret": "unsafe" - }, - "ledgerApi": { - "baseUrl": "http://localhost:2975" - } - } - ] - } -} -``` - -You can easily create a similar configuration file by running: - -```bash -wallet-gateway --config-example > config.json -``` - -To view the complete possible JSON Schema of the configuration file, see [Schema.md](https://github.com/canton-network/wallet-gateway/blob/82ec39c9/docs/dapp-building/wallet-gateway/configuration/schema.md). - -## Configuration Structure - -The configuration file has the following main sections: - -- **kernel**: Basic information about the Wallet Gateway identity -- **server**: Network binding, ports, API endpoint configuration, and admin user designation -- **store**: Database connection and persistence settings -- **bootstrap**: Initial identity providers and network definitions seeded when the database is first created -- **signingStore**: (optional) Secondary database for key storage when using internal signing - -## Configuring Kernel Settings - -The **kernel** section contains information that is served to dApps and used to uniquely identify the Gateway instance. - -**kernel:** - -- _id_ (required): A unique identifier for this Gateway instance. This should be a stable, unique string (e.g., `"my-gateway-prod"` or `"remote-da"`). -- _publicUrl_ (optional): The base URL used for redirecting clients. If not provided, it will be automatically derived from the server host and port settings. This is particularly important when running behind a reverse proxy or load balancer. -- _clientType_ (required): The type of client. For a remote Wallet Gateway, this should always be set to `'remote'`. - -**Example:** - -```json -{ - "kernel": { - "id": "my-production-gateway", - "clientType": "remote", - "publicUrl": "https://wallet.example.com" - } -} -``` - -## Configuring Server Settings - -The **server** section configures network binding, ports, and API paths. - -**server:** - -- _port_ (optional, default: `3030`): The port on which the Node.js server will bind. This port is also used for generating popup URLs in the discovery flow. -- _dAppPath_ (optional, default: `'/api/v0/dapp'`): The API path for dApp JSON-RPC requests. This is where dApps connect to interact with wallets. -- _userPath_ (optional, default: `'/api/v0/user'`): The API path for user JSON-RPC requests. This is used by the web UI and user-facing applications. -- _allowedOrigins_ (optional, default: `['*']`): CORS allowed origins. For production, specify exact origins instead of `'*'` for better security. Example: `["https://my-dapp.com", "https://another-dapp.com"]`. -- _requestSizeLimit_ (optional, default: `'1mb'`): Maximum request body size the server will accept. Use standard size notation (e.g., `'1mb'`, `'10mb'`, `'50kb'`). -- _requestRateLimit_ (optional, default: `10000`): Maximum number of requests per minute from a single IP address (this excludes health endpoints). -- _admin_ (optional): The user ID (JWT `sub` claim) of the admin user. When set, the matching user is granted admin privileges, allowing them to manage networks and identity providers through the User API and web UI. Other users can only view these settings. If omitted, no user has admin privileges and network/IDP management is restricted to the bootstrap configuration. - -**Example:** - -```json -{ - "server": { - "port": 3030, - "dAppPath": "/api/v0/dapp", - "userPath": "/api/v0/user", - "allowedOrigins": ["https://my-dapp.example.com"], - "requestSizeLimit": "10mb", - "requestRateLimit": 10000, - "admin": "operator" - } -} -``` - -**store:** - -- _connection:_ Configures the database connection. See [Configuring Store](#configuring-store) for details. - -**bootstrap:** - -- _idps:_ Configures the initial identity providers (IDPs) seeded when the database is first created. See [Configuring Identity Providers](#configuring-identity-providers) for details. -- _networks:_ Configures the initial networks seeded when the database is first created. See [Configuring Networks](#configuring-networks) for details. - -## Configuring Store - -The store connection determines where the Wallet Gateway persists its data, including sessions, wallet configurations, networks, identity providers, and transactions. - -**Available Storage Options:** - -Three storage backends are available: **memory**, **sqlite**, and **postgres**. - -**Recommendations:** - -- **Production/Test Environments**: Use **postgres** for reliability, scalability, and backup capabilities -- **Local Development**: Use **sqlite** for simplicity and persistence across restarts -- **Quick Testing**: Use **memory** for temporary setups (all data is lost on restart) - -> [!IMPORTANT] -> If using Docker or Kubernetes with the memory store, all data will be lost when the container/pod is recreated. SQLite will persist only if the database file is stored on a persistent volume. - -**PostgreSQL Configuration:** - -For production deployments, PostgreSQL is recommended due to its robustness, concurrent access support, and backup/restore capabilities. - -**postgres:** - -- _type_ (required): Must be `'postgres'` -- _host_ (required): The hostname or IP address of the PostgreSQL server -- _port_ (optional, default: `5432`): The port on which PostgreSQL is listening -- _user_ (required): The database user to connect with -- _password_ (required): The password for the database user -- _database_ (required): The name of the database to use (must exist) - -**Example:** - -```json -{ - "store": { - "connection": { - "type": "postgres", - "host": "db.example.com", - "port": 5432, - "user": "wallet_gateway", - "password": "secure-password", - "database": "wallet_gateway_db" - } - } -} -``` - -**SQLite Configuration:** - -SQLite is suitable for single-instance deployments and local development. It stores all data in a single file. - -**sqlite:** - -- _type_ (required): Must be `'sqlite'` -- _database_ (required): Path to the SQLite database file (e.g., `'store.sqlite'` or `'/var/lib/wallet-gateway/store.sqlite'`) - -**Example:** - -```json -{ - "store": { - "connection": { - "type": "sqlite", - "database": "store.sqlite" - } - } -} -``` - -**Memory Store Configuration:** - -The memory store keeps all data in RAM. Useful for testing but not suitable for any production use. - -**memory:** - -- _type_ (required): Must be `'memory'` - -**Example:** - -```json -{ - "store": { - "connection": { - "type": "memory" - } - } -} -``` - -### Database Recovery and Backups - -For production and sensitive environments, regular database backups are **strongly recommended**. - -**What's Stored in the Database:** - -The store database contains: - -- User sessions and authentication state -- Networks and identity providers (seeded from bootstrap configuration on first run, manageable by admin at runtime) -- Wallet configurations and party mappings -- In-flight transactions (pending signing or signed but not yet submitted) - -**What Happens Without Backups:** - -If the database is lost and cannot be restored: - -- All user sessions will be invalidated (users must log in again) -- Networks and IDPs will be re-seeded from the bootstrap configuration, but any runtime modifications made by the admin will be lost -- In-flight transactions will be lost (may require manual intervention) -- Wallet configurations referencing lost networks may need to be reconfigured - -**Backup Recommendations:** - -- **PostgreSQL**: Use `pg_dump` or automated backup solutions (e.g., pgBackRest, WAL-E) -- **SQLite**: Copy the database file regularly, ensuring no writes occur during the copy -- Set up automated daily backups with retention policies -- Test restore procedures regularly - -> [!IMPORTANT] -> If the wallet gateway is used as signing provider then clients private keys will be lost! It is therefor highly recommended -> to not use wallet gateway as signing provider in any important system. - -## Configuring Identity Providers - -Identity Providers (IDPs) are used for generating JWT tokens that authenticate against Canton validator networks. Each network must reference an IDP that provides or generates the required authentication tokens. - -IDPs are defined in the `bootstrap` section of the configuration and are seeded into the database when it is first created. After initial setup, IDPs can be managed at runtime through the User API or web UI by the admin user (see `server.admin`). - -**Supported IDP Types:** - -The Wallet Gateway supports two types of identity providers: **self_signed** and **oauth**. - -> [!IMPORTANT] -> For production environments, it is **highly recommended** to use an **oauth** IDP provider. Self-signed tokens should only be used for development and testing. - -**Self-Signed IDP:** - -Self-signed IDPs generate JWT tokens locally using a secret key. This is convenient for development but less secure for production. - -**self_signed:** - -- _id_ (required): Unique identifier that must match the `identityProviderId` referenced in network configurations -- _type_ (required): Must be `'self_signed'` -- _issuer_ (required): The issuer value that will be set in the JWT token's `iss` claim. This must match the issuer expected by the validator node - -**Example:** - -```json -{ - "bootstrap": { - "idps": [ - { - "id": "idp-self-signed", - "type": "self_signed", - "issuer": "self-signed" - } - ] - } -} -``` - -**OAuth IDP:** - -OAuth IDPs integrate with external OAuth 2.0 / OpenID Connect providers to obtain authentication tokens. This is the recommended approach for production. - -**oauth:** - -- _id_ (required): Unique identifier that must match the `identityProviderId` referenced in network configurations -- _type_ (required): Must be `'oauth'` -- _issuer_ (required): The issuer value that will be set in the JWT token's `iss` claim. This should match the issuer from your OAuth provider's configuration -- _configUrl_ (required): The OpenID Connect discovery endpoint URL. Typically follows the pattern: `${OAuthServerURL}/.well-known/openid-configuration` - -**Example:** - -```json -{ - "bootstrap": { - "idps": [ - { - "id": "idp-production", - "type": "oauth", - "issuer": "https://auth.example.com", - "configUrl": "https://auth.example.com/.well-known/openid-configuration" - } - ] - } -} -``` - -## Configuring Networks - -Networks represent different Canton validator nodes that clients can connect to through the Wallet Gateway. -Networks defined in the `bootstrap` section are seeded into the database when it is first created and serve as the default networks available to all users. After initial setup, networks can be managed at runtime through the User API or web UI by the admin user (see `server.admin`). - -**Network Configuration:** - -Networks is an array, so you can define multiple networks in a single configuration: - -**networks** (array): - -- _id_ (required): Unique identifier for the network. Should follow CAIP-2 format (e.g., `"canton:localnet"` or `"canton:production"`) -- _name_ (required): User-friendly name displayed in the UI (e.g., `"Local Network"` or `"Production Network"`) -- _description_ (optional): A description of the network shown to users -- _synchronizerId_ (required): The synchronizer ID used on the validator. If your validator has multiple synchronizers, create separate network configurations for each -- _identityProviderId_ (required): Must match the `id` of an IDP defined in the `idps` section -- _ledgerApi_ (required): Configuration object for the Ledger API: - - _baseUrl_ (required): The base URL of the Canton validator's Ledger API (e.g., `"http://localhost:2975"` or `"https://ledger.example.com"`) -- _auth_ (required): Authentication configuration for normal ledger operations. This is the method users go through in the UI — use `authorization_code` for interactive flows or `self_signed` for development -- _adminAuth_ (optional): Authentication configuration for admin operations. Only needed for operations requiring elevated privileges. This is used by the backend only — use `client_credentials` for machine-to-machine authentication - -**Authentication Methods:** - -The Wallet Gateway supports three authentication methods for network access: **authorization_code**, **client_credentials**, and **self_signed**. - -**Recommendations:** - -- **Production**: Use **client_credentials** for machine-to-machine authentication -- **Interactive/User-facing**: Use **authorization_code** for user-initiated flows -- **Development/Testing**: Use **self_signed** for local development - -**Authorization Code:** - -Used for interactive authentication flows where users grant authorization through their browser. - -**authorization_code:** - -- _method_ (required): Must be `'authorization_code'` -- _audience_ (required): The audience claim (`aud`) in the JWT token. Must match the audience expected by the validator -- _scope_ (required): Space-separated list of OAuth scopes. Typically includes `'openid daml_ledger_api offline_access'` -- _clientId_ (required): The OAuth client ID registered with the identity provider - -**Example:** - -```json -{ - "auth": { - "method": "authorization_code", - "audience": "https://canton.network.global", - "scope": "openid daml_ledger_api offline_access", - "clientId": "my-client-id" - } -} -``` - -**Client Credentials:** - -Used for machine-to-machine authentication. Recommended for production server deployments. - -**client_credentials:** - -- _method_ (required): Must be `'client_credentials'` -- _audience_ (required): The audience claim (`aud`) in the JWT token. Must match the audience expected by the validator -- _scope_ (required): Space-separated list of OAuth scopes. Typically includes `'openid daml_ledger_api offline_access'` -- _clientId_ (required): The OAuth client ID registered with the identity provider -- _clientSecret_ (required): The OAuth client secret for authenticating with the IDP - -**Example:** - -```json -{ - "auth": { - "method": "client_credentials", - "audience": "https://canton.network.global", - "scope": "openid daml_ledger_api offline_access", - "clientId": "my-service-client", - "clientSecret": "my-secure-secret" - } -} -``` - -**Self-Signed:** - -Used for development and testing. The Gateway generates and signs JWT tokens locally. - -**self_signed:** - -- _method_ (required): Must be `'self_signed'` -- _issuer_ (required): The issuer claim (`iss`) in the JWT token. Must match the issuer expected by the validator -- _audience_ (required): The audience claim (`aud`) in the JWT token. Must match the audience expected by the validator -- _scope_ (required): Space-separated list of scopes. Typically includes `'openid daml_ledger_api offline_access'` -- _clientId_ (required): The client identifier used in the token -- _clientSecret_ (required): The secret used to sign the JWT token. Must match the secret expected by the validator - -**Example:** - -```json -{ - "auth": { - "method": "self_signed", - "issuer": "self-signed", - "audience": "https://canton.network.global", - "scope": "openid daml_ledger_api offline_access", - "clientId": "ledger-api-user", - "clientSecret": "unsafe-secret-for-development" - } -} -``` - -**Complete Network Configuration Example:** - -```json -{ - "bootstrap": { - "networks": [ - { - "id": "canton:localnet", - "name": "Local Network", - "description": "Local development network", - "synchronizerId": "local", - "identityProviderId": "idp-self-signed", - "auth": { - "method": "self_signed", - "issuer": "self-signed", - "audience": "https://canton.network.global", - "scope": "openid daml_ledger_api offline_access", - "clientId": "ledger-api-user", - "clientSecret": "unsafe" - }, - "ledgerApi": { - "baseUrl": "http://localhost:2975" - } - } - ] - } -} -``` - -## Configuring Signing Store - -The signing store is an optional secondary database used for storing private keys when the Wallet Gateway is configured to act as a signing provider (using the `wallet-kernel` signing provider). - -> [!IMPORTANT] -> If you use the Wallet Gateway as a signing provider, private keys will be stored in the signing store database. This is **not recommended** for production environments with valuable assets. Use external signing providers (Dfns, Fireblocks, Blockdaemon, or Participant-based) for production. - -**Configuration:** - -The signing store uses the same connection configuration options as the main store. See [Configuring Store](#configuring-store) for available options (memory, sqlite, postgres). - -**When is Signing Store Required?** - -The signing store is only needed if: - -- You're using the `wallet-kernel` signing provider (internal signing) -- You want to store keys managed by the Wallet Gateway itself - -If you're using external signing providers (Dfns, Fireblocks, Blockdaemon, Participant), you can omit the `signingStore` configuration entirely. - -**Example:** - -```json -{ - "signingStore": { - "connection": { - "type": "sqlite", - "database": "signingStore.sqlite" - } - } -} -``` - -**Security Considerations:** - -- Store the signing store database file in a secure location with restricted access -- Use strong filesystem permissions (e.g., `chmod 600` for SQLite files) -- For PostgreSQL, use separate credentials with minimal privileges -- Consider encrypting the database at rest -- Regularly backup the signing store if it contains production keys -- Never commit signing store files to version control - -## Configuring for Different Environments - -**Environment-Specific Configuration Files** - -It is recommended to maintain separate configuration files for each environment (development, staging, production). This allows you to: - -- Isolate settings per environment -- Apply different security levels and policies -- Prevent accidental use of production credentials in development -- Simplify environment-specific deployments - -**Best Practices:** - -1. **Use separate files**: Create `config.dev.json`, `config.staging.json`, `config.prod.json` - -2. **Sensitive data**: Never commit sensitive values (passwords, secrets, API keys) directly in configuration files, especially if stored in version control - -3. **Environment variables**: Use environment variables to override sensitive configuration values: - - ```json - { - "bootstrap": { - "networks": [ - { - "auth": { - "clientSecretEnv": "OAUTH_CLIENT_SECRET" - } - } - ] - } - } - ``` - - Then set the environment variable when running: - - ```bash - export OAUTH_CLIENT_SECRET="my-secret" - wallet-gateway -c ./config.json - ``` - -4. **Access control**: Be aware that: - - Network and IDP configurations (excluding secrets) are visible to users with ledger access - - If configuration files are stored in shared repositories, anyone with read access can see non-secret configuration - - Use environment variables or secret management systems (e.g., HashiCorp Vault, AWS Secrets Manager) for sensitive values - -5. **Admin authentication**: The `adminAuth` configuration contains sensitive credentials and should be: - - Stored securely (not in version control) - - Rotated regularly - - Restricted to production environments where truly needed - -**Example Environment Setup:** - -**Development (config.dev.json):** - -- SQLite or memory store -- Self-signed authentication -- Localhost network endpoints -- Permissive CORS settings - -**Production (config.prod.json):** - -- PostgreSQL store -- OAuth authentication -- Production network endpoints -- Restricted CORS settings -- Secrets via environment variables - -{/* COPIED_END */} diff --git a/docs-main/integrations/wallet-gateway/download.mdx b/docs-main/integrations/wallet-gateway/download.mdx deleted file mode 100644 index 2db7d0d0c..000000000 --- a/docs-main/integrations/wallet-gateway/download.mdx +++ /dev/null @@ -1,160 +0,0 @@ ---- -title: "Download" -description: "Install and start the Wallet Gateway" ---- - -{/* COPIED_START source="wallet-gateway:docs/dapp-building/wallet-gateway/getting-started/index.md@82ec39c9" hash="e71f253b" */} - -This guide will help you get the Wallet Gateway up and running quickly. - -## Installation - -Choose your preferred installation method: - -**Global Installation (npm):** - -Install the Wallet Gateway globally using npm: - -```bash -npm install -g @canton-network/wallet-gateway-remote -``` - -After installation, you can run it from anywhere: - -```bash -wallet-gateway -c ./config.json -``` - -**Run with npx (No Installation):** - -Run the Wallet Gateway directly through npx without installing (tested with Node.js v24): - -```bash -npx @canton-network/wallet-gateway-remote -c ./config.json -``` - -This downloads and runs the latest version each time, useful for testing or one-off runs. - -## Quick Start - -1. **Create a Configuration File** - - First, generate an example configuration file: - - **Global Installation:** - - ```bash - wallet-gateway --config-example > config.json - ``` - - **npx:** - - ```bash - npx @canton-network/wallet-gateway-remote --config-example > config.json - ``` - -2. **Edit the Configuration** - - Open `config.json` and customize it for your environment. At minimum, you'll need to configure: - - **Store connection**: Database configuration (in-memory, SQLite, or PostgreSQL) - - **Networks**: At least one Canton network with its Ledger API endpoint - - **Identity Providers**: Authentication configuration for your networks - - See [Configuration](/integrations/wallet-gateway/configuration) for detailed configuration options. - -3. **Start the Gateway** - - **Global Installation:** - - ```bash - wallet-gateway -c ./config.json - ``` - - Or with a custom port: - - ```bash - wallet-gateway -c ./config.json -p 8080 - ``` - - **npx:** - - ```bash - npx @canton-network/wallet-gateway-remote -c ./config.json - ``` - - Or with a custom port: - - ```bash - npx @canton-network/wallet-gateway-remote -c ./config.json -p 8080 - ``` - -4. **Verify it's Running** - - Once started, the Wallet Gateway exposes three endpoints: - - **Web UI**: `http://localhost:3030` (or your configured port) - - **dApp JSON-RPC API**: `http://localhost:3030/api/v0/dapp` - - **User JSON-RPC API**: `http://localhost:3030/api/v0/user` - - Open the web UI in your browser to confirm it's running. - -## Command Line Options - -The Wallet Gateway supports the following command-line options: - -```text --c, --config Set config path (default: ./config.json) ---config-schema Output the config schema (JSON Schema) and exit ---config-example Output an example config and exit --p, --port [port] Set port (overrides config file) --f, --log-format Set log format: json or pretty (default: pretty) -``` - -Example: - -**Global Installation:** - -```bash -# Generate config schema -wallet-gateway --config-schema - -# Run with JSON logging -wallet-gateway -c ./config.json -f json -``` - -**npx:** - -```bash -# Generate config schema -npx @canton-network/wallet-gateway-remote --config-schema - -# Run with JSON logging -npx @canton-network/wallet-gateway-remote -c ./config.json -f json -``` - -## Configuration Schema - -To see the full JSON Schema for the configuration file, run: - -**Global Installation:** - -```bash -wallet-gateway --config-schema -``` - -**npx:** - -```bash -npx @canton-network/wallet-gateway-remote --config-schema -``` - -This outputs a complete JSON Schema that can be used for validation and IDE autocomplete support. - -## Next Steps - -- Read [Configuration](/integrations/wallet-gateway/configuration) to understand all configuration options -- Explore the [APIs](/integrations/wallet-gateway/apis) to understand how to interact with the Gateway -- Learn about [Signing Providers](/integrations/wallet-gateway/signing-providers) to configure transaction signing -- Check out the [Deployment](https://github.com/canton-network/wallet-gateway/blob/82ec39c9/docs/dapp-building/wallet-gateway/deployment/index.md) guide to host the Gateway with Docker or Helm -- Check [Troubleshooting](/integrations/wallet-gateway/troubleshooting) if you encounter any issues - -{/* COPIED_END */} diff --git a/docs-main/integrations/wallet-gateway/operate/configure.mdx b/docs-main/integrations/wallet-gateway/operate/configure.mdx new file mode 100644 index 000000000..59c9dc63f --- /dev/null +++ b/docs-main/integrations/wallet-gateway/operate/configure.mdx @@ -0,0 +1,189 @@ +--- +title: "Configure the Wallet Gateway" +description: "Understand the Wallet Gateway configuration file: kernel, server, and store settings." +--- + +The Wallet Gateway reads a single JSON configuration file that defines who the Wallet Gateway is, +how it serves requests, where it persists data, and which networks and identity providers it +starts with. This guide covers the file's structure and the kernel, server, and store +sections. For networks and authentication, see +[Networks & identity providers](/integrations/wallet-gateway/operate/networks-and-identity). +For an exhaustive field reference, see the +[Configuration reference](/integrations/wallet-gateway/reference/configuration-reference). + +## Generate a starting point + +Write an example configuration you can edit: + +```bash +wallet-gateway --config-example > config.json +``` + +To see the full JSON Schema (useful for validation and IDE autocompletion): + +```bash +wallet-gateway --config-schema +``` + +## File structure + +The configuration file has five top-level sections: + +| Section | Required | Purpose | +| --- | --- | --- | +| `kernel` | yes | Identity of this Wallet Gateway instance, served to dApps. | +| `server` | yes | Network binding, ports, API paths, and the admin user. | +| `store` | yes | Database connection for sessions, wallets, networks, IDPs, and transactions. | +| `bootstrap` | yes | Networks and identity providers seeded on first run. | +| `signingStore` | no | Secondary database for keys when using internal signing. | + +A minimal configuration for a local setup looks like this: + +```json +{ + "kernel": { + "id": "remote-da", + "clientType": "remote" + }, + "server": { + "port": 3030, + "dappPath": "/api/v0/dapp", + "userPath": "/api/v0/user", + "allowedOrigins": ["http://localhost:8080"], + "admin": "operator" + }, + "store": { + "connection": { + "type": "sqlite", + "database": "store.sqlite" + } + }, + "bootstrap": { + "idps": [], + "networks": [] + } +} +``` + +Fill in `bootstrap.idps` and `bootstrap.networks` following +[Networks & identity providers](/integrations/wallet-gateway/operate/networks-and-identity). + +## Kernel + +The `kernel` section identifies this Wallet Gateway instance to dApps. + +- `id` (required): a stable, unique identifier, for example `"my-gateway-prod"`. +- `clientType` (required): `"remote"` for a remote Wallet Gateway. +- `publicUrl` (optional): the base URL used to redirect clients. If omitted, it is derived + from the server host and port. Set this when running behind a reverse proxy or load + balancer. + +```json +{ + "kernel": { + "id": "my-production-gateway", + "clientType": "remote", + "publicUrl": "https://wallet.example.com" + } +} +``` + +## Server + +The `server` section configures binding, ports, and API paths. + +- `port` (optional, default `3030`): the port the server binds to. Also used to generate + popup URLs in the discovery flow. +- `dappPath` (optional, default `/api/v0/dapp`): the path where dApps connect. +- `userPath` (optional, default `/api/v0/user`): the path used by the User UI and User API. +- `allowedOrigins` (optional, default `["*"]`): CORS allowed origins. In production, list + exact origins instead of `"*"`. +- `requestSizeLimit` (optional, default `"1mb"`): maximum request body size. +- `requestRateLimit` (optional, default `10000`): maximum requests per minute per IP + (health endpoints excluded). +- `admin` (optional): the user ID (JWT `sub` claim) granted admin privileges, which allow + managing networks and identity providers at runtime. If omitted, network and IDP + management is restricted to the bootstrap configuration. + +```json +{ + "server": { + "port": 3030, + "dappPath": "/api/v0/dapp", + "userPath": "/api/v0/user", + "allowedOrigins": ["https://my-dapp.example.com"], + "requestSizeLimit": "10mb", + "requestRateLimit": 10000, + "admin": "operator" + } +} +``` + +## Store + +The `store` connection determines where the Wallet Gateway persists sessions, wallet +configurations, networks, identity providers, and in-flight transactions. Three backends are +available: + +| Backend | Use for | Persistence | +| --- | --- | --- | +| `memory` | Quick testing | Lost on restart. | +| `sqlite` | Local development | Persists to a file. | +| `postgres` | Production and test | Reliable, scalable, backup-friendly. | + +```json +{ + "store": { + "connection": { + "type": "postgres", + "host": "db.example.com", + "port": 5432, + "user": "wallet_gateway", + "password": "secure-password", + "database": "wallet_gateway_db" + } + } +} +``` + + +With the `memory` store in Docker or Kubernetes, all data is lost when the container or pod is +recreated. `sqlite` persists only if the database file is on a persistent volume. Use +`postgres` for production. See the +[Configuration reference](/integrations/wallet-gateway/reference/configuration-reference) +for backup guidance. + + +## Signing store + +The optional `signingStore` is a secondary database used only when the Wallet Gateway signs +transactions itself (the internal signing provider). It uses the same connection options as +`store`. Omit it entirely when using a participant node or an external custody provider. + +```json +{ + "signingStore": { + "connection": { + "type": "sqlite", + "database": "signingStore.sqlite" + } + } +} +``` + + +The internal signing provider stores private keys in the signing store database. Do not use it +in production systems with valuable assets. See +[Signing providers](/integrations/wallet-gateway/operate/signing-providers). + + +## Next steps + + + + Connect to a validator and configure authentication. + + + Every field, all auth methods, and per-environment guidance. + + diff --git a/docs-main/integrations/wallet-gateway/operate/deploy.mdx b/docs-main/integrations/wallet-gateway/operate/deploy.mdx new file mode 100644 index 000000000..49c66b60b --- /dev/null +++ b/docs-main/integrations/wallet-gateway/operate/deploy.mdx @@ -0,0 +1,56 @@ +--- +title: "Deploy" +description: "Run the Wallet Gateway in a container with Docker or Helm." +--- + +For anything beyond local development, run the Wallet Gateway as a container. This guide +covers what to get right when deploying, and points to the deployment manifests. The Wallet Gateway +is a Node.js server that reads a single configuration file and exposes its User UI, User API, +and dApp API on one port. + +## Before you deploy + +Make production choices in your configuration file before packaging it. See +[Configure the Wallet Gateway](/integrations/wallet-gateway/operate/configure) and the +[Configuration reference](/integrations/wallet-gateway/reference/configuration-reference). + +- **Use a persistent store.** Prefer `postgres`. The `memory` store loses all data when a + container or pod is recreated, and `sqlite` persists only if its file is on a persistent + volume. +- **Set `kernel.publicUrl`.** Behind a reverse proxy or load balancer, set it to the external + URL so client redirects work. +- **Restrict CORS.** Set `server.allowedOrigins` to your known dApp origins instead of `"*"`. +- **Keep secrets out of the image.** Supply `clientSecret`, `adminAuth`, and provider API keys + through environment variables or a secret manager, not the baked-in config file. See + [Secrets and environments](/integrations/wallet-gateway/reference/configuration-reference#secrets-and-environments). + +## Docker + +Provide the configuration file and any required secrets to the container, and expose the +Wallet Gateway's port. Mount the config (and, for `sqlite`, a persistent volume for the database +file), then start the Wallet Gateway pointing at the mounted config. + + +If you use the internal signing provider, its `signingStore` holds private keys. Put it on +durable, access-controlled storage, or use a participant node or external custody provider +instead. See [Signing providers](/integrations/wallet-gateway/operate/signing-providers). + + +## Helm + +For Kubernetes, deploy with Helm and back the Wallet Gateway with a managed PostgreSQL instance. +Supply the configuration through a ConfigMap and secrets through a Kubernetes Secret so +sensitive values never live in the chart. + +## Deployment manifests + +The Wallet Gateway repository maintains the reference Docker and Helm manifests and the +step-by-step deployment guide: + +- [Deployment guide](https://github.com/canton-network/wallet-gateway/blob/82ec39c9/docs/dapp-building/wallet-gateway/deployment/index.md) + +## After deploying + +- Confirm the three endpoints respond (User UI, `/api/v0/dapp`, `/api/v0/user`). +- Review the [Security checklist](/integrations/wallet-gateway/operate/security). +- If something fails to start, see [Troubleshooting](/integrations/wallet-gateway/operate/troubleshooting). diff --git a/docs-main/integrations/wallet-gateway/operate/networks-and-identity.mdx b/docs-main/integrations/wallet-gateway/operate/networks-and-identity.mdx new file mode 100644 index 000000000..0296b27bf --- /dev/null +++ b/docs-main/integrations/wallet-gateway/operate/networks-and-identity.mdx @@ -0,0 +1,194 @@ +--- +title: "Networks & identity providers" +description: "Connect the Wallet Gateway to a Canton validator and configure how users authenticate." +--- + +A Wallet Gateway connects users to one or more **networks**. Each network points at a Canton +validator's Ledger API and references an **identity provider** (IDP) that issues the JWT used +to authenticate against that validator. This guide covers both, plus the authentication +methods a network can use. + +Networks and IDPs are seeded from the `bootstrap` section on first run. After that, the admin +user (see `server.admin` in [Configure the Wallet Gateway](/integrations/wallet-gateway/operate/configure)) +can manage them at runtime through the User API or User UI. + +## Identity providers + +Every network references an IDP by `id`. The Wallet Gateway supports two IDP types. + + +Use an **OAuth** IDP for production. Self-signed tokens are for development and testing only. + + +### OAuth / OpenID Connect + +Integrates with an external OAuth 2.0 / OpenID Connect provider to obtain tokens. + +- `id` (required): must match the `identityProviderId` referenced by networks. +- `type` (required): `"oauth"`. +- `issuer` (required): the `iss` claim value, matching your provider's configuration. +- `configUrl` (required): the OpenID Connect discovery endpoint, typically + `${OAuthServerURL}/.well-known/openid-configuration`. + +```json +{ + "bootstrap": { + "idps": [ + { + "id": "idp-production", + "type": "oauth", + "issuer": "https://auth.example.com", + "configUrl": "https://auth.example.com/.well-known/openid-configuration" + } + ] + } +} +``` + +### Self-signed + +Generates JWTs locally using a secret. Convenient for development, not for production. + +- `id` (required): must match the `identityProviderId` referenced by networks. +- `type` (required): `"self_signed"`. +- `issuer` (required): the `iss` claim value, matching what the validator expects. + +```json +{ + "bootstrap": { + "idps": [ + { + "id": "idp-self-signed", + "type": "self_signed", + "issuer": "self-signed" + } + ] + } +} +``` +### Identity Provider Management in the Wallet Gateway +This guide is only for parties with administrator access. +1. Select the hamburger icon on the top right and click **Identity Provider**. +2. Review the list of available identity providers. +3. To **add**: click on **+ New** to add a new identify provider. +4. To **edit**: click on an identity provider card to make changes or delete it permanently. + + +## Networks + +A network represents a Canton validator that users can reach through the Wallet Gateway. `networks` +is an array, so you can configure several in one Wallet Gateway. + +- `id` (required): unique identifier in [CAIP-2](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md) + form, for example `"canton:localnet"`. +- `name` (required): a user-friendly name shown in the UI. +- `description` (optional): a description shown to users. +- `synchronizerId` (required): the synchronizer ID used on the validator. For multiple + synchronizers, configure a separate network per synchronizer. +- `identityProviderId` (required): must match the `id` of a configured IDP. +- `ledgerApi.baseUrl` (required): the base URL of the validator's Ledger API. +- `auth` (required): authentication for normal ledger operations. This is the method users go + through in the UI. +- `adminAuth` (optional): authentication for admin operations, used by the backend only. + +```json +{ + "bootstrap": { + "networks": [ + { + "id": "canton:localnet", + "name": "Local Network", + "description": "Local development network", + "synchronizerId": "local", + "identityProviderId": "idp-self-signed", + "auth": { + "method": "self_signed", + "issuer": "self-signed", + "audience": "https://canton.network.global", + "scope": "openid daml_ledger_api offline_access", + "clientId": "ledger-api-user", + "clientSecret": "unsafe" + }, + "ledgerApi": { + "baseUrl": "http://localhost:2975" + } + } + ] + } +} +``` + +## Authentication methods + +A network's `auth` (and optional `adminAuth`) uses one of three methods. + +| Method | Use for | Notes | +| --- | --- | --- | +| `authorization_code` | Interactive, user-facing flows | Users grant authorization in their browser. | +| `client_credentials` | Machine-to-machine (production) | Recommended for `adminAuth` and server deployments. | +| `self_signed` | Development and testing | The Wallet Gateway signs tokens locally. | + +### authorization_code + +```json +{ + "auth": { + "method": "authorization_code", + "audience": "https://canton.network.global", + "scope": "openid daml_ledger_api offline_access", + "clientId": "my-client-id" + } +} +``` + +### client_credentials + +```json +{ + "auth": { + "method": "client_credentials", + "audience": "https://canton.network.global", + "scope": "openid daml_ledger_api offline_access", + "clientId": "my-service-client", + "clientSecret": "my-secure-secret" + } +} +``` + +### self_signed + +```json +{ + "auth": { + "method": "self_signed", + "issuer": "self-signed", + "audience": "https://canton.network.global", + "scope": "openid daml_ledger_api offline_access", + "clientId": "ledger-api-user", + "clientSecret": "unsafe-secret-for-development" + } +} +``` + + +`clientSecret` and `adminAuth` credentials are sensitive. Keep them out of version control and +supply them through environment variables or a secret manager. See the +[Configuration reference](/integrations/wallet-gateway/reference/configuration-reference#secrets-and-environments). + + +### Network Management in the Wallet Gateway +This guide is only for parties with administrator access. +1. Select the hamburger icon on the top right and choose **Network**. +2. Review the list of available networks. +3. To **add**: click on **+ New** to add a new network. +4. To **edit**: click on a network card to make changes or delete it permanently. +5. The connected network can be reviewed at the top of the pop-up showing a green dot: [network name] or in the network list with a green `Connected` tag. + +## Runtime management + +Once the Wallet Gateway is running, the admin user can add, edit, and remove networks and IDPs +without restarting, using the User API (`addNetwork`, `removeNetwork`, `addIdp`, `removeIdp`, +`listNetworks`, `listIdps`) or the **Settings** page in the User UI. Runtime changes are +stored in the database, so back it up to avoid losing them. See the +[User API](/integrations/wallet-gateway/reference/user-api) and +[Manage wallets](/integrations/wallet-gateway/use/manage-wallets). diff --git a/docs-main/integrations/wallet-gateway/operate/security.mdx b/docs-main/integrations/wallet-gateway/operate/security.mdx new file mode 100644 index 000000000..43a9c0211 --- /dev/null +++ b/docs-main/integrations/wallet-gateway/operate/security.mdx @@ -0,0 +1,49 @@ +--- +title: "Security checklist" +description: "Harden a Wallet Gateway deployment before exposing it to users and dApps." +--- + +Work through this checklist before running a Wallet Gateway in production. Each item links to +the relevant configuration. + +## Authentication and identity + +- **Use OAuth / OpenID Connect IDPs.** Reserve self-signed tokens for development. See + [Networks & identity providers](/integrations/wallet-gateway/operate/networks-and-identity#identity-providers). +- **Use `client_credentials` for `adminAuth`.** Store admin credentials securely and rotate + them regularly. +- **Set `server.admin` deliberately.** Only the configured admin can manage networks and IDPs + at runtime. Leave it unset to lock management to the bootstrap configuration. + +## Signing and key custody + +- **Do not use internal signing for valuable assets.** Use a participant node or an external + custody provider (Fireblocks, Blockdaemon, DFNS). See + [Signing providers](/integrations/wallet-gateway/operate/signing-providers). +- **If you must run a signing store,** restrict filesystem permissions, consider encryption at + rest, back it up, and keep it out of version control. See + [Signing store security](/integrations/wallet-gateway/reference/configuration-reference#signing-store-security). + +## Network exposure + +- **Restrict CORS.** Set `server.allowedOrigins` to known dApp origins instead of `"*"`. See + [Configure the Wallet Gateway](/integrations/wallet-gateway/operate/configure#server). +- **Set `kernel.publicUrl`** to the external URL when running behind a proxy or load balancer. +- **Tune rate and size limits.** Review `server.requestRateLimit` and `server.requestSizeLimit` + for your traffic. +- **Terminate TLS** in front of the Wallet Gateway and use valid certificates. + +## Data and secrets + +- **Use PostgreSQL** and take regular, tested backups. See + [Backups and recovery](/integrations/wallet-gateway/reference/configuration-reference#backups-and-recovery). +- **Keep secrets out of config files.** Supply `clientSecret`, `adminAuth`, and provider API + keys through environment variables or a secret manager. See + [Secrets and environments](/integrations/wallet-gateway/reference/configuration-reference#secrets-and-environments). +- **Separate configuration per environment** to avoid using production credentials elsewhere. + +## Operations + +- **Use structured logging** (`-f json`) for aggregation. +- **Monitor the three endpoints** (User UI, `/api/v0/dapp`, `/api/v0/user`). +- **Rehearse restores** so a lost database does not become a lost deployment. diff --git a/docs-main/integrations/wallet-gateway/operate/signing-providers.mdx b/docs-main/integrations/wallet-gateway/operate/signing-providers.mdx new file mode 100644 index 000000000..11bfc61ab --- /dev/null +++ b/docs-main/integrations/wallet-gateway/operate/signing-providers.mdx @@ -0,0 +1,109 @@ +--- +title: "Signing Providers" +description: "How the Wallet Gateway delegates transaction signing, and how to configure each provider." +--- + +The Wallet Gateway does not have to hold private keys. Signing is delegated to a **signing +provider** chosen per wallet, so you decide where each wallet's keys live and who performs the +cryptographic signing. Different wallets in the same Wallet Gateway can use different providers, +and you select the provider per party when you create a wallet. + +When a wallet submits a transaction, the Wallet Gateway hands the prepared transaction to that +wallet's signing provider, which signs it with the party's key and returns it for the Wallet +Gateway to submit. + +## Available providers + +| Provider | Key custody | Best for | +| --- | --- | --- | +| [Internal](#internal) | Wallet Gateway signing store database | Local development and testing only. | +| [Participant](#participant) | Canton participant node | Enterprise deployments with a dedicated participant. | +| [Fireblocks](#fireblocks) | Fireblocks (HSM-backed) | Compliance-sensitive, high-security production. | +| [Blockdaemon](#blockdaemon) | Blockdaemon infrastructure | Managed, cloud-native deployments. | +| [DFNS](#dfns) | DFNS (MPC) | Programmable custody with policy controls. | + + +The internal provider stores private keys in the Wallet Gateway's signing store database. Do not +use it for wallets holding valuable assets. Prefer a participant node or an external custody +provider in production. + + +## Internal + +Stores private keys directly in the Wallet Gateway's signing store database and signs +transactions itself. Suitable for development and testing only. + +It is available whenever a `signingStore` is configured; no other setup is required. See +[Configure the Wallet Gateway](/integrations/wallet-gateway/operate/configure#signing-store). + +```json +{ + "signingStore": { + "connection": { + "type": "sqlite", + "database": "signingStore.sqlite" + } + } +} +``` + + +Private keys are stored in the signing store database. If it is compromised, all keys are at +risk; if it is lost, they are unrecoverable. Protect the database file with strict filesystem +permissions and never commit it to version control. + + +## Participant + +Uses a Canton participant node to sign. The participant holds the key material and performs all +cryptographic operations, so keys never live in the Wallet Gateway. + +It is always available and needs no additional configuration; select it when creating a party. +When a transaction is submitted, the Wallet Gateway forwards the command to the participant +node, which signs it using the party's key from the participant's keystore. + +## Fireblocks + +Enterprise-grade, HSM-backed key management and signing from Fireblocks. Keys stay in +Fireblocks' secure infrastructure. + +1. Complete steps 1-3 from the [Fireblocks signing documentation](https://github.com/canton-network/wallet-gateway/tree/main/core/signing-fireblocks). +2. Supply `FIREBLOCKS_API_KEY` with your Fireblocks API key (from the `API User (ID)` column in + the Fireblocks API users table). + +The provider reads its configuration from environment variables and key files; no additional +Wallet Gateway configuration is needed beyond placing the required files. + +## Blockdaemon + +Managed signing from Blockdaemon's infrastructure. Set the following environment variables: + +| Variable | Description | +| --- | --- | +| `BLOCKDAEMON_API_URL` | The base URL for the Blockdaemon API. | +| `BLOCKDAEMON_API_KEY` | Your Blockdaemon API key. | + +## DFNS + +Programmable, MPC-based key management and signing from DFNS. Keys are managed in DFNS' secure +infrastructure. + +Set up a service account with appropriate permissions and download its credentials, then set +the following environment variables: + +| Variable | Description | +| --- | --- | +| `DFNS_ORG_ID` | Your DFNS organization ID. | +| `DFNS_BASE_URL` | The DFNS API URL (defaults to `https://api.dfns.io`). | +| `DFNS_CRED_ID` | Your service account credential ID. | +| `DFNS_PRIVATE_KEY` | Your service account private key (PEM format). | +| `DFNS_AUTH_TOKEN` | Your service account authentication token. | + +DFNS creates and activates Canton wallets directly through its validator integration: it +provisions a Canton-formatted key, registers the party on the network, and returns the wallet +ready for use. When signing, DFNS broadcasts the transaction to Canton in a single step and +returns the update ID. + + +Only `Canton` and `CantonTestnet` network wallets are supported. + diff --git a/docs-main/integrations/wallet-gateway/operate/troubleshooting.mdx b/docs-main/integrations/wallet-gateway/operate/troubleshooting.mdx new file mode 100644 index 000000000..75c538786 --- /dev/null +++ b/docs-main/integrations/wallet-gateway/operate/troubleshooting.mdx @@ -0,0 +1,136 @@ +--- +title: "Troubleshooting" +description: "Common Wallet Gateway problems and how to resolve them." +--- + +Common issues you may hit when running the Wallet Gateway, with fixes. + +## Database connection errors + +The Wallet Gateway fails to start with database connection errors. + +- **PostgreSQL**: verify the database exists (`psql -U postgres -l`), check credentials in your + config, ensure PostgreSQL is running (`pg_isready`), and check network and firewall rules. +- **SQLite**: ensure the directory for the database file exists, check read/write permissions, + and verify disk space. +- **Memory**: no configuration is needed, but remember data is lost on restart. + +## Authentication failures + +API calls return `401 Unauthorized`. + +- **Invalid or expired token**: use a valid JWT, check its expiration, and regenerate it if + needed. +- **Missing Authorization header**: include `Authorization: Bearer ` in the correct + format. +- **Session not found**: create a session with `addSession()` first, ensure it has not expired, + and confirm you are using the correct user context. + +## Network connection issues + +The Wallet Gateway cannot connect to a configured network or Ledger API. + +- **Network unreachable**: verify the Ledger API URL, test connectivity with + `curl /v2/version`, and check firewall rules and routing. +- **Invalid network configuration**: confirm `synchronizerId` matches the validator, the + `identityProviderId` matches an IDP, and the credentials are correct. +- **SSL/TLS issues**: verify certificates for HTTPS endpoints. In development you may need HTTP + or to configure certificate trust. + +## Port already in use + +`EADDRINUSE: address already in use :::3030`. + +- Find and stop the process using the port: + + ```bash + lsof -ti:3030 | xargs kill -9 + # Or inspect it first + lsof -i :3030 + ``` + +- Use a different port: + + ```bash + wallet-gateway -c ./config.json -p 8080 + ``` + +- Check whether another Wallet Gateway instance is running: + + ```bash + ps aux | grep wallet-gateway + ``` + +## Configuration validation errors + +The Wallet Gateway fails to start with configuration errors. + +- Validate your config against the schema: + + ```bash + wallet-gateway --config-schema > schema.json + # Then run it through a JSON Schema validator + ``` + +- Check for common mistakes: missing required fields, invalid JSON, type mismatches (strings + vs numbers), and incorrect IDP references in networks. +- Start from the example config: + + ```bash + wallet-gateway --config-example > my-config.json + ``` + +## Signing provider issues + +Transactions fail with signing errors. Verify the provider's environment variables and +permissions: + +- **Fireblocks**: `FIREBLOCKS_SECRET` and `FIREBLOCKS_API_KEY` set, keys valid with proper + permissions, and the Fireblocks API reachable. +- **Participant**: the participant node is running and reachable, the party exists on it, and + the participant logs show no signing errors. +- **Blockdaemon**: `BLOCKDAEMON_API_URL` and `BLOCKDAEMON_API_KEY` set, API reachable, and the + key has signing permissions. +- **DFNS**: `DFNS_ORG_ID`, `DFNS_BASE_URL`, `DFNS_CRED_ID`, `DFNS_PRIVATE_KEY`, and + `DFNS_AUTH_TOKEN` set, credentials correct, and the service account has wallet-creation and + signing permissions. + +See [Signing providers](/integrations/wallet-gateway/operate/signing-providers) for each +provider's setup. + +## Debugging + +- **Enable pretty logs** for readable, detailed output: + + ```bash + wallet-gateway -c ./config.json -f pretty + ``` + +- **Use structured logs** for aggregation: + + ```bash + wallet-gateway -c ./config.json -f json + ``` + +- **Check logs** in console output, system logs, or container logs depending on how you run + the Wallet Gateway. + +- **Verify endpoints** respond: + + ```bash + # Web UI + curl http://localhost:3030 + + # dApp API status (requires authentication) + curl -X POST http://localhost:3030/api/v0/dapp \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer " \ + -d '{"jsonrpc":"2.0","id":1,"method":"status","params":[]}' + ``` + +## Getting help + +If problems persist: check the logs for detailed errors, validate your configuration against +the schema, review the [User API](/integrations/wallet-gateway/reference/user-api) and +[dApp API](/integrations/wallet-gateway/reference/dapp-api) specifications, and check the +project's GitHub issues for similar reports. diff --git a/docs-main/integrations/wallet-gateway/overview.mdx b/docs-main/integrations/wallet-gateway/overview.mdx new file mode 100644 index 000000000..ca037d34d --- /dev/null +++ b/docs-main/integrations/wallet-gateway/overview.mdx @@ -0,0 +1,135 @@ +--- +title: "Overview" +description: "Connect your own validator and signing provider to any dApp on Canton Network." +--- + +The Wallet Gateway is a self-hosted component that connects your Canton validator to dApps on +Canton Network. You run it in your own environment, next to a validator you already operate, +so you can connect to any [CIP-0103](https://github.com/canton-foundation/cips/blob/main/cip-0103/cip-0103.md) +dApp using **your** validator and **your** signing or custody provider, without moving signing +away from infrastructure you already trust. + +Run the Wallet Gateway to: + +- **Connect to dApps**: expose the CIP-0103 dApp API so any compatible dApp can connect, + list accounts, and request transactions. +- **Use your own validator**: talk to your Canton validator's Ledger API on behalf of + authenticated users. +- **Keep signing where you want it**: sign with a participant node, an external custody + provider (Fireblocks, Blockdaemon, DFNS), or an internal store for development. +- **Manage wallets**: create and manage parties across one or more networks, through a web + UI or programmatically. +- **Authenticate users**: log users in through OAuth / OpenID Connect or self-signed tokens, + and issue sessions for API access. + + +The Wallet Gateway is for teams that operate their own infrastructure: validator operators, +builders, and organizations that want to connect a validator and signing provider they control +to dApps. If you are building a dApp frontend instead, use the [dApp SDK](/sdks-tools/sdks/dapp-sdk/overview). + + +## How it fits together + +```mermaid +flowchart TB + D["dApp
(dApp SDK)"] + U["User"] + subgraph WG["Wallet Gateway (self-hosted)"] + direction TB + DA["dApp API"] + UA["User API"] + UI["User UI"] + end + V["Your Canton validator"] + S["Signing provider
(participant, Fireblocks, …)"] + D -->|dApp API| DA + U -->|browser| UI + U -->|programmatic| UA + WG <-->|Ledger API| V + WG <-->|signing| S +``` + +## Core concepts + +**Networks.** A network points the Wallet Gateway at one Canton validator's Ledger API, identified +in [CAIP-2](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md) form (for +example `canton:localnet`). You can configure several networks in one Wallet Gateway, and each +wallet belongs to exactly one network. + +**Identity providers.** Every network references an identity provider (IDP) that issues the +JWT used to authenticate against the validator. The Wallet Gateway supports **OAuth / OpenID Connect** +providers (recommended for production) and **self-signed** tokens (development only). + +**Sessions.** Users authenticate through an IDP, and the Wallet Gateway issues a session (a JWT) +that the User and dApp APIs use to authorize later calls. Sessions are created on login and +ended on logout. + +**Wallets and parties.** A wallet is a Canton party the Wallet Gateway manages for a user. Each +wallet is tied to a network and a signing provider, and a user can mark one wallet as +primary. dApps see these wallets as the accounts a user can transact with. + +**Signing providers.** Signing is delegated to a signing provider chosen per wallet, so +different wallets in the same Wallet Gateway can sign through different providers. Keys stay with the +provider you choose: a participant node, an external custody service, or an internal store for +testing. See [Signing providers](/integrations/wallet-gateway/operate/signing-providers). + +## Transaction lifecycle + +Once a dApp is connected, transactions flow through the Wallet Gateway so that approval and +signing stay under your control. A dApp asks the Wallet Gateway to run a transaction, the +Wallet Gateway prepares it against your validator, the user reviews and approves it in the +User UI, your signing provider signs it, and the Wallet Gateway submits it to the ledger and +returns the result. Preparation and submission happen on your validator's Ledger API, approval +happens in your User UI, and signing happens in the provider you chose, so private keys never +pass through the dApp. + +```mermaid +sequenceDiagram + participant D as dApp + participant UI as User UI + participant WG as Wallet Gateway + participant S as Signing provider + participant L as Ledger API + + D->>WG: prepareExecute + WG->>L: prepare + L-->>WG: prepared transaction + + alt UI approval + WG->>UI: queue for user approval + Note over UI: User clicks Approve + UI->>WG: user approves + end + + alt Signing driver + WG->>S: sign + S-->>WG: signed transaction + end + + WG->>L: execute + L-->>WG: completion + WG-->>D: result +``` + +## Quickstart + +Ready to run it? The [Quickstart](/integrations/wallet-gateway/quickstart) walks through +installing the Wallet Gateway, generating a configuration file, starting it against a network, and +verifying the three endpoints. + +## Where to go next + + + + Install, configure, run, and verify a Wallet Gateway. + + + Understand the configuration file, store, and server settings. + + + Choose where transaction signing and key custody happen. + + + Drive the Wallet Gateway from scripts with the User API. + + diff --git a/docs-main/integrations/wallet-gateway/quickstart.mdx b/docs-main/integrations/wallet-gateway/quickstart.mdx new file mode 100644 index 000000000..b9305903f --- /dev/null +++ b/docs-main/integrations/wallet-gateway/quickstart.mdx @@ -0,0 +1,105 @@ +--- +title: "Quickstart" +description: "Install the Wallet Gateway, configure it, run it against a network, and verify it is up." +--- + +This is the shortest path to a running Wallet Gateway: install it, generate a configuration +file, start it against a Canton network, and confirm its three endpoints respond. It targets +a local setup you can adapt to your own validator. + + +You need Node.js (tested with v24) and access to a Canton network's Ledger API. For a fully +local target, run a [Splice LocalNet](/sdks-tools/development-tools/localnet). + + + + +Install globally with npm: + +```bash +npm install -g @canton-network/wallet-gateway-remote +``` + +Or run it without installing, using `npx`: + +```bash +npx @canton-network/wallet-gateway-remote -c ./config.json +``` + +`npx` downloads and runs the latest version each time, which is useful for one-off runs. + + + +Write an example configuration you can edit: + +```bash +wallet-gateway --config-example > config.json +``` + +The example targets a Splice LocalNet with SQLite storage and a mock OAuth identity provider. + + + +Open `config.json` and set, at minimum: + +- **Store**: where the Wallet Gateway persists data (`memory`, `sqlite`, or `postgres`). +- **Networks**: at least one Canton network with its Ledger API `baseUrl`. +- **Identity providers**: how users authenticate against those networks. + +See [Configure the Wallet Gateway](/integrations/wallet-gateway/operate/configure) for every option, and +[Networks & identity providers](/integrations/wallet-gateway/operate/networks-and-identity) to +wire up authentication. + + + +```bash +wallet-gateway -c ./config.json +``` + +Override the port with `-p` if needed: + +```bash +wallet-gateway -c ./config.json -p 8080 +``` + + + +The Wallet Gateway exposes three endpoints (default port `3030`): + +- **User UI**: `http://localhost:3030` +- **dApp API**: `http://localhost:3030/api/v0/dapp` +- **User API**: `http://localhost:3030/api/v0/user` + +Open the User UI in your browser to confirm the Wallet Gateway is up. + + + +## Command-line options + +| Option | Description | +| --- | --- | +| `-c, --config ` | Set the config path (default: `./config.json`). | +| `--config-schema` | Output the config JSON Schema and exit. | +| `--config-example` | Output an example config and exit. | +| `-p, --port [port]` | Set the port (overrides the config file). | +| `-f, --log-format ` | Set the log format: `json` or `pretty` (default: `pretty`). | + +The `--config-schema` output is a complete JSON Schema you can use for validation and IDE +autocompletion. + +## Next steps + + + + All configuration options for kernel, server, and store. + + + Connect to a validator and set up authentication. + + + Create and manage wallets through the User UI or User API. + + + Run the Wallet Gateway with Docker or Helm. + + diff --git a/docs-main/integrations/wallet-gateway/reference/configuration-reference.mdx b/docs-main/integrations/wallet-gateway/reference/configuration-reference.mdx new file mode 100644 index 000000000..8c7b1074b --- /dev/null +++ b/docs-main/integrations/wallet-gateway/reference/configuration-reference.mdx @@ -0,0 +1,164 @@ +--- +title: "Configuration reference" +description: "Full reference for the Wallet Gateway store backends, backups, signing store, and secrets." +--- + +This reference complements the task-oriented guides with the details you need for production: +the store backends in full, backup and recovery, signing store security, and how to handle +secrets across environments. For the config file's overall shape, see +[Configure the Wallet Gateway](/integrations/wallet-gateway/operate/configure). For networks and +authentication, see [Networks & identity providers](/integrations/wallet-gateway/operate/networks-and-identity). + +## Store backends + +The `store.connection` object selects one of three backends. + +### PostgreSQL + +Recommended for production for its robustness, concurrent access, and backup support. + +| Field | Required | Description | +| --- | --- | --- | +| `type` | yes | Must be `"postgres"`. | +| `host` | yes | Hostname or IP of the PostgreSQL server. | +| `port` | no (default `5432`) | Port PostgreSQL listens on. | +| `user` | yes | Database user to connect with. | +| `password` | yes | Password for the database user. | +| `database` | yes | Name of the database to use (must exist). | + +```json +{ + "store": { + "connection": { + "type": "postgres", + "host": "db.example.com", + "port": 5432, + "user": "wallet_gateway", + "password": "secure-password", + "database": "wallet_gateway_db" + } + } +} +``` + +### SQLite + +Suitable for single-instance deployments and local development. Stores all data in one file. + +| Field | Required | Description | +| --- | --- | --- | +| `type` | yes | Must be `"sqlite"`. | +| `database` | yes | Path to the SQLite database file. | + +```json +{ + "store": { + "connection": { + "type": "sqlite", + "database": "store.sqlite" + } + } +} +``` + +### Memory + +Keeps all data in RAM. Useful for testing, not for production. + +| Field | Required | Description | +| --- | --- | --- | +| `type` | yes | Must be `"memory"`. | + +```json +{ + "store": { + "connection": { + "type": "memory" + } + } +} +``` + +## Backups and recovery + +The store database holds user sessions, networks and IDPs (seeded from bootstrap, then +modifiable at runtime), wallet configurations and party mappings, and in-flight transactions. + +If the database is lost and cannot be restored: + +- All sessions are invalidated (users must log in again). +- Networks and IDPs are re-seeded from bootstrap, but runtime changes are lost. +- In-flight transactions are lost and may need manual intervention. +- Wallets referencing lost networks may need reconfiguration. + +Recommendations: + +- **PostgreSQL**: use `pg_dump` or an automated solution (pgBackRest, WAL-E). +- **SQLite**: copy the database file regularly, with no writes during the copy. +- Schedule automated daily backups with a retention policy, and test restores. + + +If the Wallet Gateway is used as the signing provider, the signing store holds private keys. If it is +lost, those keys are unrecoverable. Do not use internal signing for any important system. See +[Signing providers](/integrations/wallet-gateway/operate/signing-providers). + + +## Signing store security + +The optional `signingStore` uses the same connection options as `store` and is only needed for +the internal signing provider. When it holds keys: + +- Store the file in a secure location with restricted access. +- Use strict filesystem permissions (for example `chmod 600` for SQLite files). +- For PostgreSQL, use separate credentials with minimal privileges. +- Consider encrypting the database at rest. +- Back it up regularly if it holds production keys. +- Never commit signing store files to version control. + +## Secrets and environments + +Maintain separate configuration files per environment (for example `config.dev.json`, +`config.staging.json`, `config.prod.json`) to isolate settings and credentials. + +Never commit secrets. Override sensitive values with environment variables using the `Env` +suffix on the field, for example `clientSecretEnv`: + +```json +{ + "bootstrap": { + "networks": [ + { + "auth": { + "clientSecretEnv": "OAUTH_CLIENT_SECRET" + } + } + ] + } +} +``` + +Then set the variable when running: + +```bash +export OAUTH_CLIENT_SECRET="my-secret" +wallet-gateway -c ./config.json +``` + +Additional guidance: + +- Network and IDP configurations (excluding secrets) are visible to users with ledger access. +- Anyone with read access to a shared config repository can see non-secret configuration. +- Use environment variables or a secret manager (HashiCorp Vault, AWS Secrets Manager) for + sensitive values. +- `adminAuth` credentials are sensitive: store them securely, rotate them regularly, and use + them only where truly needed. + +### Suggested environment profiles + +| Setting | Development | Production | +| --- | --- | --- | +| Store | SQLite or memory | PostgreSQL | +| Authentication | Self-signed | OAuth | +| Network endpoints | Localhost | Production endpoints | +| CORS | Permissive | Restricted to known origins | +| Secrets | Inline (non-sensitive) | Environment variables or secret manager | diff --git a/docs-main/integrations/wallet-gateway/reference/dapp-api.mdx b/docs-main/integrations/wallet-gateway/reference/dapp-api.mdx new file mode 100644 index 000000000..33af7e8e3 --- /dev/null +++ b/docs-main/integrations/wallet-gateway/reference/dapp-api.mdx @@ -0,0 +1,58 @@ +--- +title: "dApp API" +description: "The Wallet Gateway's CIP-0103 dApp API, and where it is documented." +--- + +The dApp API is the [CIP-0103](https://github.com/canton-foundation/cips/blob/main/cip-0103/cip-0103.md) +JSON-RPC 2.0 API that dApps call to connect to a wallet, list accounts, and prepare and +execute transactions. The Wallet Gateway exposes it, but you almost never call it directly. + +- **Base path**: `/api/v0/dapp` (configurable via `server.dappPath`) +- **Protocol**: JSON-RPC 2.0, per CIP-0103 +- **Authentication**: JWT bearer token (obtained through a session) + + +Build dApps with the [dApp SDK](/sdks-tools/sdks/dapp-sdk/overview), which implements the +dApp API and adds a high-level interface, session handling, wallet discovery, and multi-transport +support. Use the raw API only for lower-level infrastructure. The SDK documentation is the +reference for methods, events, and error handling. + + +## Full specification + +The complete OpenRPC specification is available at +[openrpc-dapp-api.json](https://github.com/canton-network/wallet-gateway/blob/main/api-specs/openrpc-dapp-api.json). + +## Real-time events (SSE) + +The dApp API supports Server-Sent Events for real-time notifications. Connect to the `/events` +path relative to the dApp API base URL (for example `/api/v0/dapp/events`), authenticating with +the JWT as the `token` query parameter (the `Authorization: Bearer` header is also supported): + +```javascript +const eventsUrl = new URL('events', dappApiUrl + '/') +eventsUrl.searchParams.set('token', jwtToken) +const eventSource = new EventSource(eventsUrl.toString()) + +eventSource.addEventListener('accountsChanged', (e) => { + /* ... */ +}) +eventSource.addEventListener('statusChanged', (e) => { + /* ... */ +}) +eventSource.addEventListener('connected', (e) => { + /* ... */ +}) +eventSource.addEventListener('txChanged', (e) => { + /* ... */ +}) +``` + +SSE connections deliver real-time updates about transaction status (`txChanged`), account +changes (`accountsChanged`), and session state (`connected`, `statusChanged`). + +## See also + +- [dApp SDK overview](/sdks-tools/sdks/dapp-sdk/overview) +- [dApp SDK events reference](/sdks-tools/sdks/dapp-sdk/reference/events) +- [User API](/integrations/wallet-gateway/reference/user-api) diff --git a/docs-main/integrations/wallet-gateway/reference/user-api.mdx b/docs-main/integrations/wallet-gateway/reference/user-api.mdx new file mode 100644 index 000000000..772bad8fc --- /dev/null +++ b/docs-main/integrations/wallet-gateway/reference/user-api.mdx @@ -0,0 +1,71 @@ +--- +title: "User API" +description: "The Wallet Gateway User API for managing sessions, networks, identity providers, wallets, and transactions." +--- + +The User API is a JSON-RPC 2.0 API for managing a user's wallets, networks, identity +providers, sessions, and transactions. The User UI is built on it, and you can call it +directly from scripts, a backend, or a custom UI. + +- **Base path**: `/api/v0/user` (configurable via `server.userPath`) +- **Protocol**: JSON-RPC 2.0 +- **Authentication**: JWT bearer token, except where noted below + +## Methods + +| Category | Method | Description | +| --- | --- | --- | +| Sessions | `addSession()` | Create a new session (unauthenticated, used for the initial connection). | +| | `removeSession()` | End the current session. | +| | `listSessions()` | List sessions for the current user. | +| Networks | `listNetworks()` | List all configured networks. | +| | `addNetwork()` | Add a new network configuration. | +| | `removeNetwork()` | Remove a network configuration. | +| Identity providers | `listIdps()` | List all identity providers. | +| | `addIdp()` | Add a new identity provider. | +| | `removeIdp()` | Remove an identity provider. | +| Wallets | `createWallet()` | Create a new wallet (party) on a network. | +| | `listWallets()` | List all wallets for the current user. | +| | `setPrimaryWallet()` | Set the primary wallet. | +| | `removeWallet()` | Remove a wallet. | +| | `syncWallets()` | Sync wallets with the ledger. | +| | `isWalletSyncNeeded()` | Check whether a wallet sync is needed. | +| Transactions | `sign()` | Sign a transaction. | +| | `execute()` | Execute a signed transaction. | +| | `getTransaction()` | Get a transaction by ID. | +| | `listTransactions()` | List transactions. | + +## Authentication + +Most methods require a JWT in the `Authorization` header: + +```text +Authorization: Bearer +``` + +The following methods are available without authentication, so a client can bootstrap a +connection: + +- `addSession()` +- `listNetworks()` +- `listIdps()` + +## Full specification + +The complete OpenRPC specification is available at +[openrpc-user-api.json](https://github.com/canton-network/wallet-gateway/blob/main/api-specs/openrpc-user-api.json). + +## Rate limiting + +Requests are rate-limited to prevent abuse. Configure the limits in the +[server settings](/integrations/wallet-gateway/operate/configure#server). Responses include: + +- `X-RateLimit-Limit`: maximum requests per window. +- `X-RateLimit-Remaining`: remaining requests in the current window. +- `X-RateLimit-Reset`: when the limit resets. + +## CORS + +Cross-origin access is controlled by `server.allowedOrigins`. It defaults to `["*"]`; in +production, restrict it to known origins. See +[Configure the Wallet Gateway](/integrations/wallet-gateway/operate/configure#server). diff --git a/docs-main/integrations/wallet-gateway/signing-providers.mdx b/docs-main/integrations/wallet-gateway/signing-providers.mdx deleted file mode 100644 index 09cf22117..000000000 --- a/docs-main/integrations/wallet-gateway/signing-providers.mdx +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: "Signing Providers" -description: "Wallet Gateway signing provider integrations" ---- - -{/* COPIED_START source="wallet-gateway:docs/dapp-building/wallet-gateway/signing-providers/index.md@82ec39c9" hash="ce58d241" */} - -The Wallet Gateway supports multiple signing providers that handle cryptographic key management and transaction signing. Each provider has different use cases and security characteristics. - -## Available Providers - -## Wallet Gateway (Internal) - -The Wallet Gateway provider stores private keys directly in the signing store database. This is suitable for development and testing but **not recommended for production** use cases where security is critical. - -**Configuration:** - -This provider is automatically available when a `signingStore` is configured in the Gateway configuration. No additional setup is required. - -**Use Cases:** - -- Local development -- Testing environments -- Proof-of-concept applications - -**Security Considerations:** - -> [!IMPORTANT] -> Private keys are stored in the database. If the database is compromised, all keys are at risk. Use only in non-production environments. - -## Participant-Based Signing - -The Participant signing provider uses Canton's participant node for signing transactions. The participant maintains the key material and handles all cryptographic operations. - -**Configuration:** - -This provider is always available and requires no additional configuration. You simply select it when creating a party. - -**Use Cases:** - -- Enterprise deployments where the participant node manages keys -- Scenarios where key management is handled by the infrastructure -- Production environments with dedicated participant nodes - -**How it Works:** - -When a transaction is submitted, the Gateway forwards the command to the participant node, which signs it using the party's key stored in the participant's keystore. - -## Fireblocks - -Fireblocks is a third-party crypto custody service provider that offers enterprise-grade key management and signing services. - -**Setup:** - -1. Complete steps 1-3 from the [Fireblocks signing documentation](https://github.com/canton-network/wallet-gateway/tree/main/core/signing-fireblocks) - -2. Supply an environment variable named `FIREBLOCKS_API_KEY` containing your Fireblocks API key (from the `API User (ID)` column in the Fireblocks API users table). - -**Configuration:** - -The Fireblocks provider reads configuration from environment variables and key files. No additional Gateway configuration is needed beyond placing the required files. - -**Use Cases:** - -- Enterprise deployments requiring HSM-backed key storage -- Compliance-sensitive applications -- High-security production environments - -## Blockdaemon - -Blockdaemon provides signing services as part of their infrastructure offerings. - -**Configuration:** - -Set the following environment variables: - -- `BLOCKDAEMON_API_URL` - The base URL for the Blockdaemon API -- `BLOCKDAEMON_API_KEY` - Your Blockdaemon API key - -**Use Cases:** - -- Managed infrastructure deployments -- Cloud-native applications -- Environments leveraging Blockdaemon's services - -## Dfns - -Dfns is a crypto custody platform that provides programmable key management and signing infrastructure. - -**Configuration:** - -Set the following environment variables: - -- `DFNS_ORG_ID` - Your Dfns organization ID -- `DFNS_BASE_URL` - The Dfns API URL (defaults to `https://api.dfns.io`) -- `DFNS_CRED_ID` - Your service account credential ID -- `DFNS_PRIVATE_KEY` - Your service account private key (PEM format) -- `DFNS_AUTH_TOKEN` - Your service account authentication token - -**Prerequisites:** - -1. Set up a service account with appropriate permissions in Dfns -2. Generate and download the service account credentials - -**Use Cases:** - -- Enterprise deployments requiring MPC-based key management -- Programmable custody with policy controls -- Multi-party approval workflows -- High-security production environments - -**How it Works:** - -Dfns creates and activates Canton wallets directly through its validator integration. When the Gateway requests a wallet, Dfns provisions a Canton-formatted key, registers the party on the network, and returns the wallet ready for use. When signing a prepared transaction, Dfns broadcasts it to Canton in a single step and returns the resulting update ID. Only `Canton` and `CantonTestnet` network wallets are supported. - -## Selecting a Provider - -When creating a new party through the User API or web UI, you can select which signing provider to use. The choice depends on your security requirements, infrastructure setup, and compliance needs. - -**Recommendations:** - -- **Development/Testing**: Use Wallet Gateway (internal) or Participant-based signing -- **Production (Enterprise)**: Use Fireblocks, Dfns, or Participant-based signing -- **Production (Managed)**: Use Blockdaemon, Dfns, or Participant-based signing - -The signing provider is selected per-party, so you can have different parties using different providers within the same Gateway instance. - -## Key Management - -Each provider handles key management differently: - -- **Wallet Gateway**: Keys are stored in the signing store database -- **Participant**: Keys are managed by the Canton participant node -- **Fireblocks**: Keys are stored in Fireblocks' secure infrastructure (HSM-backed) -- **Blockdaemon**: Keys are managed by Blockdaemon's infrastructure -- **Dfns**: Keys are managed by Dfns' secure infrastructure - -When migrating between providers, keys cannot be directly transferred. You'll need to: - -1. Create a new party with the new provider -2. Transfer any assets/contracts to the new party -3. Update your dApp to use the new party - -{/* COPIED_END */} diff --git a/docs-main/integrations/wallet-gateway/troubleshooting.mdx b/docs-main/integrations/wallet-gateway/troubleshooting.mdx deleted file mode 100644 index 311b396d9..000000000 --- a/docs-main/integrations/wallet-gateway/troubleshooting.mdx +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: "Troubleshooting" -description: "Common Wallet Gateway issues and fixes" ---- - -{/* COPIED_START source="wallet-gateway:docs/dapp-building/wallet-gateway/troubleshooting/index.md@82ec39c9" hash="f67950b4" */} - -This section covers common issues and their solutions when working with the Wallet Gateway. - -## Common Issues - -## Database Connection Errors - -**Problem:** The Gateway fails to start with database connection errors. - -**Solutions:** - -1. **PostgreSQL:** - - Verify the database exists: `psql -U postgres -l` - - Check connection credentials in your config file - - Ensure PostgreSQL is running: `pg_isready` - - Verify network connectivity and firewall rules - -2. **SQLite:** - - Ensure the directory exists for the database file - - Check file permissions (read/write access required) - - Verify disk space is available - -3. **Memory Store:** - - No configuration needed, but remember: data is lost on restart - -## Authentication Failures - -**Problem:** API calls return 401 Unauthorized errors. - -**Solutions:** - -1. **Invalid or Expired Token:** - - Ensure you're using a valid JWT token - - Check token expiration time - - Regenerate the token if necessary - -2. **Missing Authorization Header:** - - Include the Authorization header: `Authorization: Bearer ` - - Verify the header format is correct - -3. **Session Not Found:** - - Create a session using `addSession()` method first - - Ensure the session hasn't expired - - Check that you're using the correct user context - -## Network Connection Issues - -**Problem:** Cannot connect to configured networks or ledger API. - -**Solutions:** - -1. **Network Unreachable:** - - Verify the ledger API URL is correct in your network configuration - - Test connectivity: `curl /v2/version` - - Check firewall rules and network routing - -2. **Invalid Network Configuration:** - - Verify the `synchronizerId` matches the validator configuration - - Ensure the identity provider ID matches between network and IDP configs - - Check that authentication credentials are correct - -3. **SSL/TLS Issues:** - - For HTTPS endpoints, verify certificates are valid - - In development, you may need to use HTTP or configure certificate trust - -## Port Already in Use - -**Problem:** Error: `EADDRINUSE: address already in use :::3030` - -**Solutions:** - -1. Find and stop the process using the port: - - ```bash - # macOS/Linux - lsof -ti:3030 | xargs kill -9 - - # Or find the process - lsof -i :3030 - ``` - -2. Use a different port: - - ```bash - wallet-gateway -c ./config.json -p 8080 - ``` - -3. Check if another Gateway instance is running: - - ```bash - ps aux | grep wallet-gateway - ``` - -## Configuration Validation Errors - -**Problem:** Gateway fails to start with configuration errors. - -**Solutions:** - -1. **Validate your config against the schema:** - - ```bash - wallet-gateway --config-schema > schema.json - # Use a JSON schema validator tool - ``` - -2. **Check for common mistakes:** - - Missing required fields - - Invalid JSON syntax - - Type mismatches (strings vs numbers) - - Missing or incorrect IDP references in network configs - -3. **Use the example config as a template:** - - ```bash - wallet-gateway --config-example > my-config.json - # Edit my-config.json - ``` - -## Signing Provider Issues - -**Problem:** Transactions fail with signing errors. - -**Solutions:** - -1. **Fireblocks:** - - Verify environment variables are set correctly: `FIREBLOCKS_SECRET` and `FIREBLOCKS_API_KEY` - - Ensure API keys are valid and have proper permissions - - Verify Fireblocks API is accessible from your network - -2. **Participant:** - - Ensure the participant node is running and accessible - - Verify the party exists on the participant - - Check participant logs for signing errors - -3. **Blockdaemon:** - - Verify environment variables are set: `BLOCKDAEMON_API_URL` and `BLOCKDAEMON_API_KEY` - - Test API connectivity - - Ensure API key has signing permissions - -4. **Dfns:** - - Verify environment variables are set: `DFNS_ORG_ID`, `DFNS_BASE_URL`, `DFNS_CRED_ID`, `DFNS_PRIVATE_KEY`, and `DFNS_AUTH_TOKEN` - - Ensure the service account credentials are correct - - Confirm the service account has wallet creation and signing permissions - -## Debugging - -## Enable Debug Logging - -Set log level to debug for more detailed information: - -```bash -wallet-gateway -c ./config.json -f pretty -# Logs will show debug-level information -``` - -For structured logging (useful for log aggregation): - -```bash -wallet-gateway -c ./config.json -f json -``` - -## Check Logs - -Review the Gateway logs for error messages and stack traces. Common log locations: - -- Console output (when running directly) -- System logs (when running as a service) -- Container logs (when running in Docker/Kubernetes) - -## Verify API Endpoints - -Test that the Gateway is responding: - -```bash -# Health check (web UI) -curl http://localhost:3030 - -# dApp API status (requires authentication) -curl -X POST http://localhost:3030/api/v0/dapp \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer " \ - -d '{"jsonrpc":"2.0","id":1,"method":"status","params":[]}' -``` - -## Getting Help - -If you continue to experience issues: - -1. Check the logs for detailed error messages -2. Verify your configuration against the schema -3. Review the API specifications for correct usage -4. Check GitHub issues for similar problems -5. Review the configuration documentation for your specific setup - -## Log Levels - -The Gateway uses structured logging with the following levels: - -- **ERROR**: Critical errors that prevent operation -- **WARN**: Warning conditions that may cause issues -- **INFO**: Informational messages about normal operation -- **DEBUG**: Detailed diagnostic information - -Adjust log verbosity based on your needs. In production, INFO level is typically sufficient, while DEBUG is useful for troubleshooting. - -{/* COPIED_END */} diff --git a/docs-main/integrations/wallet-gateway/usage.mdx b/docs-main/integrations/wallet-gateway/usage.mdx deleted file mode 100644 index d5fc6a743..000000000 --- a/docs-main/integrations/wallet-gateway/usage.mdx +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: "Usage" -description: "Operating and using the Wallet Gateway" ---- - -{/* COPIED_START source="wallet-gateway:docs/dapp-building/wallet-gateway/usage/index.md@82ec39c9" hash="51f3cf2d" */} - -You can use the Wallet Gateway in two ways: - -- mainly through the **User UI** (Web UI) for end users -- or through the **User API** (for automation, custom UIs, or integration with your own systems). - -The **dApp API** is used by your dApp via the dApp SDK when users connect their wallet. See the [dApp SDK](/integrations/dapp-sdk/usage) for more details. - -This section describes typical workflows, the User UI, session handling, and when to use which interface. - -## User UI - -The Wallet Gateway serves a **Web UI** at the Gateway root URL (e.g. `http://localhost:3030`). Users manage wallets, approve transactions, and adjust settings there. - -**Main pages:** - -- **Login** (`/login`): Choose a network and identity provider (IDP), then sign in (OAuth redirect or self-signed). Unauthenticated users are redirected here when they need to log in. - -- **Wallets** (`/wallets`): List wallets, create new wallets (choose network, signing provider, party id), set the primary wallet, and remove wallets. This is the default landing page after login. - -- **Transactions** (`/transactions`): List transactions. View status and details for prepared, signed, and executed transactions. - -- **Approve** (`/approve`): Shown when a dApp requests a transaction (e.g. via `prepareExecute`). The user reviews the transaction and signs or rejects it. The dApp is notified of the result. - -- **Settings** (`/settings`): Manage networks and identity providers (add, edit, remove), view sessions, and see Gateway version info. - -- **Callback** (`/callback`): Used internally for OAuth redirects after login. Users are redirected back to the intended page (e.g. `/wallets`) or to the dApp. - -Users **log out** via the layout logout control. Logout calls `removeSession`, clears local auth state, and redirects to `/login` (or closes the window if the UI was opened in a popup for approval). - -## When to use which interface - -- **User UI**: Best for end users. They log in, create and manage wallets, view transactions, and approve dApp requests. No code required. - -- **User API**: Use when you need to: - - Drive wallet setup or management from scripts or your own backend. - - Build a custom wallet UI (e.g. embedded in your app) instead of the default User UI. - - Automate session, network, IDP, or wallet operations. - -- **dApp API** (via dApp SDK): Use from your **dApp** frontend. The SDK calls the dApp API to connect, list accounts, and prepare/execute transactions. Users approve via the Web UI or browser extension. See [dApp SDK usage](/integrations/dapp-sdk/usage) and [APIs](/integrations/wallet-gateway/apis) for details. - -## Typical flows - -**1. User sets up a wallet** - -- User opens the User UI and goes to **Login**. -- Selects network and IDP, completes login (e.g. OAuth). -- Lands on **Wallets**, creates a wallet (network, signing provider, party id), optionally sets it as primary. -- Can add networks or IDPs under **Settings** if needed. - -**2. dApp connects and sends a transaction** - -- Your dApp uses the dApp SDK: `connect()` → user is redirected to Gateway to log in if needed → `listAccounts()` → `prepareExecute(commands)`. -- User is sent to **Approve** to sign (or reject) the transaction. -- Once signed and executed, the dApp receives the result and can react to `onTxChanged`. - -**3. User checks activity and manages wallets** - -- User opens **Transactions** to list and inspect transactions. -- User opens **Wallets** to add wallets, change primary, or remove wallets. -- User opens **Settings** to manage networks, IDPs, or sessions. - -**4. Automated wallet setup (User API)** - -- Your script or backend calls `addSession()`, then your auth flow provides a JWT. -- Calls `listNetworks()` / `listIdps()`, then `createWallet()` with desired network and signing provider. -- Uses `listWallets()`, `sign()`, `execute()`, etc. as needed for your use case. - -## Next steps - -- Configure the Gateway: [Configuration](https://github.com/canton-network/wallet-gateway/blob/82ec39c9/docs/dapp-building/wallet-gateway/configuration/index.md) -- Explore User API and dApp API: [APIs](/integrations/wallet-gateway/apis) -- Set up signing: [Signing Providers](/integrations/wallet-gateway/signing-providers) -- Run and operate the Gateway: [Getting Started](https://github.com/canton-network/wallet-gateway/blob/82ec39c9/docs/dapp-building/wallet-gateway/getting-started/index.md), [Troubleshooting](/integrations/wallet-gateway/troubleshooting) - -{/* COPIED_END */} diff --git a/docs-main/integrations/wallet-gateway/use/approve-and-sign.mdx b/docs-main/integrations/wallet-gateway/use/approve-and-sign.mdx new file mode 100644 index 000000000..70a992782 --- /dev/null +++ b/docs-main/integrations/wallet-gateway/use/approve-and-sign.mdx @@ -0,0 +1,113 @@ +--- +title: "Approve & Sign Transactions" +description: "Review, approve, and track the transactions dApps ask the Wallet Gateway to run." +--- + +When a dApp wants to act on your behalf, it does not sign anything itself. It asks the Wallet +Gateway to run a transaction, and the Wallet Gateway routes it to you for approval and to your +signing provider for signing. This keeps approval and key custody under your control: private +keys never reach the dApp. This guide covers what you see on the **Approve** page, how to +approve or reject, and how to track a transaction afterwards. + +## How a Transaction Reaches You + +A dApp submits a transaction through the [dApp SDK](/sdks-tools/sdks/dapp-sdk/overview), which +calls the Wallet Gateway's dApp API. The Wallet Gateway prepares it against your validator, +queues it for your approval, has your signing provider sign it, and submits it to the ledger. + +```mermaid +sequenceDiagram + participant D as dApp + participant WG as Wallet Gateway + participant UI as User UI (Approve) + participant S as Signing provider + participant L as Ledger API + + D->>WG: prepareExecute + WG->>L: prepare + L-->>WG: prepared transaction + WG->>UI: queue for approval + Note over UI: You review and Approve + UI->>WG: approved + WG->>S: sign + S-->>WG: signed transaction + WG->>L: execute + L-->>WG: completion + WG-->>D: result +``` + +The dApp learns the outcome through the `txChanged` event, so once you approve and the +transaction executes, the dApp updates on its own. + +## Review a transaction + +When a dApp requests a transaction, the Wallet Gateway takes you to the **Approve** page of the particular transaction (it may +open in a popup window if the dApp triggered it). There you can see: + +- The **wallet** (party) the transaction will act as. +- The **network** it will be submitted to. +- The **transaction details** the dApp prepared, so you can confirm it matches what you expect. + +transaction detail + +## Approve or Reject + +- **Approve** — the Wallet Gateway hands the prepared transaction to the wallet's + [signing provider](/integrations/wallet-gateway/operate/signing-providers), which signs it, + and then submits it to the ledger. The dApp is notified of the result. +- **Reject** — the Wallet Gateway discards the request and notifies the dApp that you declined. + Nothing is signed or submitted. + +If the **Approve** page opened as a popup, it closes and returns you to the dApp after you +decide. + +If you accidentally closed the pop-up and lost the transaction approval page, reopen the User UI and navigate to **Activities** to review the transactions. + +approve or reject a transaction + + +Only approve transactions you understand and expect. Approving signs with your wallet's key +through its signing provider and submits to the ledger — it cannot be undone. If anything looks +wrong, reject it. + + +## Where Signing Happens + +Signing is delegated per wallet to the signing provider you chose when you created it — a +participant node, an external custody provider (Fireblocks, Blockdaemon, DFNS), or the internal +store for development. Your keys stay with that provider; approving in the UI authorizes the +provider to sign, but the key never passes through the dApp or the browser. See +[Signing providers](/integrations/wallet-gateway/operate/signing-providers). + +## Track a Transaction + +Open the **Transactions** page to follow a transaction through its lifecycle and inspect its +details. Each transaction moves through these states: + +| Status | Meaning | +| --- | --- | +| **Pending** | Prepared and waiting for your approval. | +| **Signed** | Approved and signed by the signing provider, being submitted. | +| **Executed** | Submitted to the ledger and completed successfully. | +| **Failed** | Rejected, or failed during signing or submission. | + +Use this page to confirm a transaction executed, or to see why one failed. If executions fail +to start or never complete, see +[Troubleshooting](/integrations/wallet-gateway/operate/troubleshooting). + +## Next Steps + + + + Log in and create, organize, and remove wallets in the User UI. + + + Sign and execute transactions programmatically. + + + Choose where signing and key custody happen. + + + See how dApps request transactions through the dApp API. + + diff --git a/docs-main/integrations/wallet-gateway/use/automate-with-user-api.mdx b/docs-main/integrations/wallet-gateway/use/automate-with-user-api.mdx new file mode 100644 index 000000000..01aa13d7b --- /dev/null +++ b/docs-main/integrations/wallet-gateway/use/automate-with-user-api.mdx @@ -0,0 +1,162 @@ +--- +title: "Automate with the User API" +description: "Drive wallet setup, signing, and transactions from a script or backend using the User API." +--- + +The User API is the JSON-RPC 2.0 API behind the User UI. Anything a person can do in the UI — +manage sessions, networks, identity providers, wallets, and transactions — you can do +programmatically with the same API. Use it to script wallet setup, build a custom wallet UI +embedded in your app, or automate operations from a backend. + +This guide walks through a typical automation flow. For the full method list, authentication +rules, and the OpenRPC specification, see the +[User API reference](/integrations/wallet-gateway/reference/user-api). + + +The User API drives **your own** wallets and setup. It is different from the +[dApp API](/integrations/wallet-gateway/reference/dapp-api), which dApps call through the dApp +SDK to connect to a user's wallet. + + +## Before you start + +You need: + +- A running Wallet Gateway you can reach (for example `http://localhost:3030`). See the + [Quickstart](/integrations/wallet-gateway/quickstart). +- At least one configured network and identity provider. See + [Networks & identity providers](/integrations/wallet-gateway/operate/networks-and-identity). +- A way to obtain a JWT from that identity provider for the user you are automating. + +All calls are JSON-RPC 2.0 `POST` requests to the User API base path +(`/api/v0/user` by default, configurable via `server.userPath`): + +```bash +curl -X POST http://localhost:3030/api/v0/user \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer ' \ + -d '{ "jsonrpc": "2.0", "id": 1, "method": "", "params": { } }' +``` + +Most methods require the `Authorization` header. Three methods are available without it so a +client can bootstrap a connection: `addSession()`, `listNetworks()`, and `listIdps()`. + + +Parameter shapes vary per method. Use the +[OpenRPC specification](https://github.com/canton-network/wallet-gateway/blob/main/api-specs/openrpc-user-api.json) +as the source of truth for exact request and response fields. + + +## Create a session + +Start the connection with `addSession()` (no authentication required), then complete your +identity provider's auth flow to obtain a JWT. Pass that JWT in the `Authorization` header on +every later call. + +```bash +curl -X POST http://localhost:3030/api/v0/user \ + -H 'Content-Type: application/json' \ + -d '{ "jsonrpc": "2.0", "id": 1, "method": "addSession", "params": { } }' +``` + +The Wallet Gateway issues a session tied to the authenticated user. List active sessions with +`listSessions()` and end the current one with `removeSession()`. + +## Discover networks and identity providers + +List what the Wallet Gateway offers before creating wallets. Both calls work without authentication. + +```bash +# List configured networks +curl -X POST http://localhost:3030/api/v0/user \ + -H 'Content-Type: application/json' \ + -d '{ "jsonrpc": "2.0", "id": 2, "method": "listNetworks", "params": { } }' + +# List identity providers +curl -X POST http://localhost:3030/api/v0/user \ + -H 'Content-Type: application/json' \ + -d '{ "jsonrpc": "2.0", "id": 3, "method": "listIdps", "params": { } }' +``` + +Admins can also manage these at runtime with `addNetwork()`, `removeNetwork()`, `addIdp()`, and +`removeIdp()`. Admin privileges are granted to the user configured as `server.admin`; see +[Configure the Wallet Gateway](/integrations/wallet-gateway/operate/configure#server). + +## Create and manage wallets + +Create a wallet by choosing a network and a signing provider, then manage the set with the +wallet methods. + +```bash +# Create a wallet (party) on a network +curl -X POST http://localhost:3030/api/v0/user \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer ' \ + -d '{ "jsonrpc": "2.0", "id": 4, "method": "createWallet", "params": { } }' +``` + +| Method | Description | +| --- | --- | +| `createWallet()` | Create a new wallet (party) on a network. | +| `listWallets()` | List all wallets for the current user. | +| `setPrimaryWallet()` | Set the primary wallet dApps default to. | +| `removeWallet()` | Remove a wallet from the Wallet Gateway. | +| `syncWallets()` | Sync wallets with the ledger. | +| `isWalletSyncNeeded()` | Check whether a wallet sync is needed. | + +## Sign and execute a transaction + +Once a wallet exists, sign and submit transactions with `sign()` and `execute()`, then read +status with the transaction methods. + +```bash +# Sign a prepared transaction +curl -X POST http://localhost:3030/api/v0/user \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer ' \ + -d '{ "jsonrpc": "2.0", "id": 5, "method": "sign", "params": { } }' + +# Execute a signed transaction +curl -X POST http://localhost:3030/api/v0/user \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer ' \ + -d '{ "jsonrpc": "2.0", "id": 6, "method": "execute", "params": { } }' +``` + +Read transactions with `getTransaction()` and `listTransactions()`. Signing is delegated to the +wallet's [signing provider](/integrations/wallet-gateway/operate/signing-providers), so the key +never leaves that provider. + +## Follow transactions in real time + +The dApp API exposes Server-Sent Events for real-time updates (`txChanged`, `accountsChanged`, +`connected`, `statusChanged`). If you are building a custom UI, subscribe to them instead of +polling. See [Real-time events](/integrations/wallet-gateway/reference/dapp-api#real-time-events-sse). + +## End the session + +When you are done, end the session: + +```bash +curl -X POST http://localhost:3030/api/v0/user \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer ' \ + -d '{ "jsonrpc": "2.0", "id": 7, "method": "removeSession", "params": { } }' +``` + +## Next steps + + + + Every method, authentication rules, rate limits, and the OpenRPC spec. + + + The same operations in the User UI. + + + How approval and signing work end to end. + + + Where each wallet's keys live and who signs. + + diff --git a/docs-main/integrations/wallet-gateway/use/images/addWallet.png b/docs-main/integrations/wallet-gateway/use/images/addWallet.png new file mode 100644 index 000000000..df587836b Binary files /dev/null and b/docs-main/integrations/wallet-gateway/use/images/addWallet.png differ diff --git a/docs-main/integrations/wallet-gateway/use/images/approveDetail.png b/docs-main/integrations/wallet-gateway/use/images/approveDetail.png new file mode 100644 index 000000000..5491b830a Binary files /dev/null and b/docs-main/integrations/wallet-gateway/use/images/approveDetail.png differ diff --git a/docs-main/integrations/wallet-gateway/use/images/detail.png b/docs-main/integrations/wallet-gateway/use/images/detail.png new file mode 100644 index 000000000..8a881427a Binary files /dev/null and b/docs-main/integrations/wallet-gateway/use/images/detail.png differ diff --git a/docs-main/integrations/wallet-gateway/use/images/discovery-comp.png b/docs-main/integrations/wallet-gateway/use/images/discovery-comp.png new file mode 100644 index 000000000..ef25a2198 Binary files /dev/null and b/docs-main/integrations/wallet-gateway/use/images/discovery-comp.png differ diff --git a/docs-main/integrations/wallet-gateway/use/images/parties.png b/docs-main/integrations/wallet-gateway/use/images/parties.png new file mode 100644 index 000000000..54214e623 Binary files /dev/null and b/docs-main/integrations/wallet-gateway/use/images/parties.png differ diff --git a/docs-main/integrations/wallet-gateway/use/images/selectNetwork.png b/docs-main/integrations/wallet-gateway/use/images/selectNetwork.png new file mode 100644 index 000000000..fc6ff738c Binary files /dev/null and b/docs-main/integrations/wallet-gateway/use/images/selectNetwork.png differ diff --git a/docs-main/integrations/wallet-gateway/use/party-management.mdx b/docs-main/integrations/wallet-gateway/use/party-management.mdx new file mode 100644 index 000000000..eb22c2f3e --- /dev/null +++ b/docs-main/integrations/wallet-gateway/use/party-management.mdx @@ -0,0 +1,138 @@ +--- +title: "Party Management" +description: "Log in and create, organize, and remove parties through the Wallet Gateway's User UI." +--- + +End users work with the Wallet Gateway through its **User UI**: a web app the Wallet Gateway +serves at its root URL. From it they log in, create and manage parties, review transactions, and approve +requests from dApps. This guide covers logging in and managing parties in the UI. To drive the +same operations from a script or backend, see +[Automate with the User API](/integrations/wallet-gateway/use/automate-with-user-api). + + +The **dApp API** is separate. dApps call it through the [dApp SDK](/sdks-tools/sdks/dapp-sdk/overview) +when a user connects a wallet; users never call it directly. See +[dApp API](/integrations/wallet-gateway/reference/dapp-api). + + +## The User UI + +The Wallet Gateway serves a web UI at its root URL (for example `http://localhost:3030`). Its +main pages are: + +| Page | Path | What it does | +| --- | --- | --- | +| **Login** | `/login` | Choose a network and identity provider, then sign in (OAuth redirect or self-signed). | +| **Parties** | `/parties` | List, create, and remove parties, and set the primary party. Default landing page. | +| **Activities** | `/activities` | List of activities and view their status and details. | +| **Approve** | `/approve` | Review and sign or reject a transaction a dApp requested. | +| **Settings** | `/settings` | Manage `/networks` and `/identity-providers`, view sessions, and see version info. | +| **Callback** | `/callback` | Internal OAuth redirect target after login. | + +## Log in + +1. Open the User UI and go to **Login** or **Connect**. +2. Select from the list of available CIP-0103-compliant providers or gateways. Or enter a custom remote gateway URL. +3. By selecting the **Wallet Gateway** option, a network of choice will be prompted. This network is associated with the connected validator or node, which needs to be configured within the validator or node settings. +wallet gateway network selection + + +4. Click **Connect** to authorize to view your parties. + - **OAuth / OpenID Connect**: you are redirected to your provider and back. + - **Self-signed**: a token is generated locally (development only). +5. On success you land on **Parties**. Unauthenticated users are redirected to **Login** +automatically whenever a page needs a session. + + +The networks and IDPs you can choose from are configured by the operator. To add more, an +admin manages them under **Settings** or in the configuration file. See +[Networks & identity providers](/integrations/wallet-gateway/operate/networks-and-identity). + + +## Create a Party + +A wallet is a Canton **party** the Wallet Gateway manages for you on one network, signed by one +signing provider. + +1. Navigate to the **Parties** list +2. Choose **+ New** +3. Provide the **Party ID** (or hint) for the wallet. +4. Select the **network** the wallet belongs to. +5. Select the **signing provider** that will hold the key and sign transactions for this + wallet. See [Signing providers](/integrations/wallet-gateway/operate/signing-providers). +add a new party + + +6. Optionally mark it as your **primary** wallet. +7. Choose **Create party** + +Each wallet is tied to exactly one network and one signing provider, so you can keep different +parties on different networks or custody providers side by side in the same Wallet Gateway. + + +By the Parties header, you may click the refresh icon to reload your party list. If there is a party that was created outside of the Wallet Gateway, it may still appear but unable to access; showing a disabled status. + + +## Set Primary Party + +You can mark one wallet as **primary**. dApps that request your primary account receive this +wallet by default, so set it to the party you transact with most. Change it at any time on the +**parties** page. + +1. Locate the desired party card (newer party cards located at the bottom of the list) +2. Select **Set as primary** +3. Verify with a green `Primary` tag + +navigating between parties + + +Changing your primary wallet changes which party dApps default to. Connected dApps are notified +through the `accountsChanged` event and should re-read the primary account rather than caching +it. See [dApp API](/integrations/wallet-gateway/reference/dapp-api). + + +## View Activities + +The **Activities** page lists transactions the Wallet Gateway has prepared, signed, or executed for +your parties, with their status and details. Reviewing and approving transactions that dApps +request happens on the **Approve** page — see +[Approve & sign transactions](/integrations/wallet-gateway/use/approve-and-sign). + +## Changing Wallet Providers +1. Select the hamburger icon on the top right and **Logout**. +2. Click **Login** or **Connect** in the dApp UI to trigger the pop-up. +3. Select a new provider to log into and follow its instructions. + + +## Sessions and Logout + +When you log in, the Wallet Gateway issues a **session** (a JWT) that authorizes your later +calls to the User and dApp APIs. Sessions are created on login and stored in the Wallet +Gateway's database. + +Log out from the layout control. Logout ends the session (`removeSession`), clears local auth +state, and returns you to **Login** — or closes the window if the UI was opened as an approval +popup. + + +Sessions live in the Wallet Gateway's database. If the operator restores the database from a backup or +loses it, active sessions may be invalidated and users must log in again. See +[Networks & identity providers](/integrations/wallet-gateway/operate/networks-and-identity). + + +## Next Steps + + + + Review, approve, and track transactions dApps request. + + + Drive wallet setup and transactions from scripts or a backend. + + + Understand the networks and login options an operator configures. + + + See where each wallet's keys live and who signs. + +