npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ftptech/canton-agent-wallet

v0.1.15

Published

Self-custody Canton wallet + x402 autopay for AI agents. One CLI: create, pay, balance, withdraw, export, import. Backs the canton-x402-agent skill.

Readme

@ftptech/canton-agent-wallet

A self-custody Canton wallet + x402 autopay for AI agents. The agent holds its own Ed25519 key and pays for x402-gated resources on the Canton Network on its own — the hard parts of Canton (a party must be hosted on a validator, and its API is authed) are hidden behind a facilitator relay the agent talks to over plain HTTP. The relay can prepare and submit on the agent's behalf but never signs, so it has no custody.

Backs the canton-x402-agent skill.

Install

npm install @ftptech/canton-agent-wallet
# or run the CLI without installing:
npx @ftptech/canton-agent-wallet <command>

Bin: canton-agent-wallet.

CLI

canton-agent-wallet create --relay-url <url>        # generate + onboard a self-custody wallet (idempotent)
canton-agent-wallet address                         # print the party id (fund this)
canton-agent-wallet balance                         # print CC balance
canton-agent-wallet claim                           # accept incoming transfers (e.g. the initial funding)
canton-agent-wallet pay --relay-url <url> <url>      # fetch a URL, auto-paying any x402 402 challenge
canton-agent-wallet withdraw --to <party> [--amount <cc>]   # send CC back out (default: full balance)
canton-agent-wallet export                           # print the private key (backup; guard it)

create and pay require a relay (facilitator) URL — pass --relay-url <url> or set CANTON_AGENT_RELAY_URL. There is no default: a stale built-in default would silently send payments to a dead host, so the CLI fails fast when none is given. address, balance, claim, withdraw and export reuse the relay stored in the wallet at create time. The current FTP facilitator is http://46.225.91.251:4022 (plain HTTP by IP; a TLS domain is not yet live).

On Canton, incoming CC arrives as a pending transfer the agent must accept, so the first-run flow is: create --relay-url http://46.225.91.251:4022 → tell your human to send CC to the printed party id → claimbalance. Funding once is the only human step, exactly like funding an EVM agent.

Programmatic API

makePayingFetch() returns a fetch that transparently pays x402 challenges from the agent's wallet (lazily creating the wallet on first use):

import { makePayingFetch } from "@ftptech/canton-agent-wallet";

const fetch = await makePayingFetch({
  relayUrl: process.env.CANTON_AGENT_RELAY_URL,
  network: "canton:testnet",
});

const res = await fetch("https://paid.api/resource"); // 402 -> pay -> retry, transparently

On a 402 it resolves the transfer factory via the relay, builds the CIP-56 transfer, signs the prepared-transaction hash locally, has the relay submit it, then retries the request with the on-ledger proof.

Config (env)

  • CANTON_AGENT_RELAY_URL — facilitator relay base URL. Required for the commands that talk to a relay (create, pay); there is intentionally no built-in default (a stale default would silently send payments to a dead host). Supply it here or via --relay-url <url>. The current FTP facilitator is https://facilitator.ftptech.xyz.
  • CANTON_AGENT_NETWORKcanton:testnet (default) or canton:mainnet; also settable via --network <net>.
  • CANTON_AGENT_API_KEY — only if the relay requires one (sent as the X-Agent-Key header).
  • HTTPS_PROXY / HTTP_PROXY (or ALL_PROXY) — if set, the CLI routes all relay calls through that proxy. Node's fetch does NOT honor these on its own, so behind a corporate/regional proxy you must set one of them or every call fails with fetch failed. Credentials are supported (http://user:pass@host:port) and never logged.
  • CANTON_AGENT_HOME — override the wallet directory (default ~/.canton-agent; used by tests and power users).

Your wallet is YOURS (self-custody)

The wallet lives at ~/.canton-agent/wallet.json (mode 0600). This file IS your money — back it up. Losing it loses the funds. The agent reuses the same wallet forever and never silently creates a second one. The validator only hosts your party; it can never spend your CC — only your signature authorizes a transfer. canton-agent-wallet export prints the private key for backup or import.

How it works

Self-custody external party per CIP-0103: you generate and hold the Ed25519 key; the facilitator relay bridges onboarding and submission to the Canton participant using the validator's auth, so you need no Canton account.

  • Onboard: the relay runs generate-topology; the agent signs the returned multi-hash locally; the relay allocates the party.
  • Pay / withdraw: the relay prepares the transaction (and proxies the public Scan registry resolves the agent can't reach); the agent verifies the prepared transaction matches its intent and binds the hash to those exact bytes before signing; the relay only forwards the signed submission.

Every state-changing operation is authorized by the agent's signature.

Verify-before-sign and hash binding (fail-closed)

The relay is treated as untrusted. Before signing any transfer that moves funds, the agent structurally decodes the relay-prepared transaction and checks the sender / receiver / amount / instrument against its own intent (rejecting ambiguous encodings that a spec-conformant parser would read differently). It then binds the hash it signs to those validated bytes — because the Canton Ledger API is explicit that "clients MUST recompute the hash from the raw transaction if the preparing participant is not trusted". A compromised relay that returns honest bytes paired with the hash of a different (tampered) transaction is therefore rejected.

Binding requires one of:

  • recomputeHash (programmatic): pass hashBinding: { recomputeHash } to makePayingFetch / withdraw / transfer, where recomputeHash reproduces Canton's HASHING_SCHEME_VERSION_V2 for the prepared bytes. This is the real cryptographic binding.
  • CANTON_AGENT_TRUST_RELAY_HASH=1 (operator opt-in): accept the relay's hash WITHOUT recomputation. This re-opens the blind-signing risk and is only acceptable when a human reviews each transfer or the relay is fully trusted.

With neither configured, a value-moving transfer refuses to sign (fail-closed) rather than blind-sign a relay-chosen hash. Accepting incoming transfers (claim) needs no binding — no funds leave.

License

Apache-2.0.