This example demonstrates how a backend automation submits Canton ledger transactions through the Wallet Gateway without a human clicking through the approval UI.
It is intentionally written in Python to show that service account automation is language agnostic: any HTTP client that can send JSON-RPC requests and an Authorization: ApiKey … header can integrate with the Gateway. The Wallet Gateway APIs are not tied to TypeScript or JavaScript.
- Calls the dApp API
listAccountsto verify API key authentication. - Calls
getPrimaryAccountto read the primary wallet party ID. - Builds a simple Ping create command.
- Calls
prepareExecutewith that command so the Gateway runs prepare → sign → execute straight through.
When the network is configured with serviceAccountAuth and the wallet uses participant signing, the transaction should complete during the prepareExecute call. For external signers (Fireblocks, Blockdaemon, Dfns), the transaction may stay pending until the custody provider approves and the Gateway signing worker finishes the flow.
Before running this script, complete the one-time setup described in Service account automations:
- Wallet Gateway running locally (default
http://localhost:3030) or pointing at your deployment. - Network configuration with
serviceAccountAuth(client_credentials) on the target network. - Logged-in user with a primary wallet on that network.
- API key created in the User UI or via User API
generateApiKey.
Edit main.py and set:
| Variable | Description |
|---|---|
API_KEY |
API key from generateApiKey (shown only once at creation) |
SUBMITTER |
Party ID to act as in the Ping command (must belong to the API key owner) |
This project uses uv for dependency management:
cd examples/service-account
uv run main.pyAutomation requests use API key auth, not a user OAuth bearer token:
Authorization: ApiKey <your-api-key>The Gateway validates the key, associates the request with the key owner's wallets and network, and obtains a ledger access token using the network's serviceAccountAuth configuration.
Only the dApp API (/api/v0/dapp) accepts API key authentication. Create and revoke keys through the User API (/api/v0/user) while logged in with a normal user session.
On success you should see:
- Account listing from
listAccounts - The resolved primary party ID
- A
prepareExecuteresponse containing auserUrl(returned for API compatibility; automations typically ignore it and monitortxChangedevents instead) - The
transactionIdextracted from that URL
- Store API keys in environment variables or a secrets manager — do not commit them.
- Subscribe to dApp API Server-Sent Events (
txChanged) for reliable completion notification, especially with external signing providers. - See the full operations guide: Automations.