Skip to content

feat(tokens): add the CHYPE asset - #11

Draft
hubagaspar91 wants to merge 5 commits into
mainfrom
feat/tokens/chype-support
Draft

hubagaspar91 wants to merge 5 commits into
mainfrom
feat/tokens/chype-support

Conversation

@hubagaspar91

@hubagaspar91 hubagaspar91 commented Nov 6, 2026 •

Copy link
Copy Markdown
Collaborator

What

This PR adds CHYPE, HYPE bridged from HyperEVM to Canton, as a third asset. tokens::chype has the same API shape as tokens::beth.

  • tokens::chype holds the registrar and the bridge of each network, the account, mint and burn flows, and the credential filters.
  • The examples chype_credentials, chype_mint_flow and chype_redeem_flow copy the BETH examples.
  • dars/chype/chype-0.1.0.dar is the released chype 0.1.0 package. Its SHA-256 matches the release manifest.
  • The localnet suite runs a CHYPE phase on the sandbox image cbtc-6689a6a.

Why

The CHYPE bridge is live on devnet, testnet and mainnet. Integrators need the same library support that BETH has.

How

  • Same contract as BETH. The CHYPE bridge is the BETH bridge contract on HyperEVM. It takes HYPE through depositETH(bytes) and has the same deposit unit. The first commit moves the BETH mint builders into one crate-private module, so both assets share them. The public BETH paths do not change.
  • Three Daml names differ. The chype package uses lastProcessedBlock, destinationAddress and txId. The trait constants carry the first two; the crate never reads txId.
  • Destination check. CHYPE refuses a payout address that never gets a payout: the zero address, a HyperEVM system address or a CHYPE bridge proxy. The system-address rule copies the attestors' rule. create_withdraw_account checks the address, and submit_withdraw checks the account's address again before the burn.
Network Chain Bridge proxy Registrar
devnet HyperEVM testnet, 998 0xfBC38458ffb91D6Fd731151D46345E89ffc42358 chype-network::1220806e…2c52
testnet HyperEVM testnet, 998 0x1E5439257A314d11e6b0779297Ca92887Ed56087 chype-network::12204c05…1db0
mainnet HyperEVM, 999 0x2940FcBb3C32901Df405da0E96fd97D1E2a53f34 chype-network::1220cc3b…5956

Known limit

The BitSafe API does not serve the /chype/* routes yet. Until it does, get_account_contract_rules and redeem::submit_withdraw fail for CHYPE. CI skips the CHYPE live API checks on all three networks for that reason.

How tested

  • cargo fmt, cargo clippy --all-targets --all-features -D warnings and cargo test pass: 144 library tests, the public-surface tests and the doc tests.
  • Two compile_fail doc tests prove that a BETH account cannot build a CHYPE deposit call, and the reverse.
  • The localnet suite passes against cbtc-6689a6a, with the CBTC, BETH and CHYPE phases.
  • The live API tests pass for CBTC and BETH. The CHYPE devnet check fails, because the API has no CHYPE routes.
  • The devnet test round of the CHYPE examples is still open. The factory reports below record it.

Size

The diff is larger than 400 lines. Most of it is the CHYPE tests and the three examples, which copy the BETH ones line for line.

🤖 Generated with Claude Code

hubagaspar91 and others added 2 commits November 6, 2026 11:10
The CHYPE bridge is the same contract as the BETH bridge, so both
assets build the same depositETH call. DepositCall, DepositTarget and
their builders now live in one crate-private module. tokens::beth::mint
re-exports them, so every public BETH path stays the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CHYPE is HYPE bridged from HyperEVM to Canton. tokens::chype has the
BETH API shape: the registrar and bridge of each network, the account,
mint and burn flows, the credential filters, three examples and the
chype 0.1.0 DAR.

A CHYPE withdraw destination must not be a HyperEVM system address.
The attestors never pay HYPE to one, and a burn cannot be undone.

The localnet image moves to cbtc-6689a6a, which holds the CHYPE
packages. CI skips the CHYPE live API checks, because the BitSafe API
does not serve the CHYPE routes yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hubagaspar91

hubagaspar91 commented Nov 6, 2026 •

Copy link
Copy Markdown
Collaborator Author

Factory report 1: requirements and implementation spec

Phases: requirements, implementation-spec. The product spec was skipped: the task is "CHYPE, same pattern as BETH", so the product is already defined.

Size: medium. The change adds one asset module that copies an existing pattern. It touches no public BETH or CBTC path.

Facts collected

Fact devnet testnet mainnet
EVM chain HyperEVM testnet, 998 HyperEVM testnet, 998 HyperEVM, 999
Bridge proxy 0xfBC38458ffb91D6Fd731151D46345E89ffc42358 0x1E5439257A314d11e6b0779297Ca92887Ed56087 0x2940FcBb3C32901Df405da0E96fd97D1E2a53f34
Deploy block 66_360_856 67_938_405 49_937_745
Registrar chype-network::1220806e…2c52 chype-network::12204c05…1db0 chype-network::1220cc3b…5956
  • The bridge contract is the BETH contract: depositETH(bytes), the 4-field Deposit event, and a deposit unit of 1e8 wei. The deploy receipts on the public HyperEVM RPCs confirm the proxies and blocks.
  • The chype 0.1.0 Daml package matches beth 0.2.0 except for three names: lastProcessedBlock, destinationAddress and txId. The claim is hasCHYPERole.
  • The attestors refuse payouts to HyperEVM system addresses for CHYPE.
  • The BitSafe API serves no /chype/* route on any network yet.

Decisions

  1. One module, tokens::chype, with the same functions as tokens::beth: Chype, ChypeNetworkConfig, config, registrar, bridge, instrument, client_config, mint, redeem and the credential filters.
  2. Shared EVM mint code. DepositCall, DepositTarget and their builders move from tokens::beth::mint to one crate-private generic module. Both assets re-export them. The BETH public paths do not change. The crate's own rule says that a family exists when two assets share it, and BETH and CHYPE now share the EVM bridge.
  3. Destination check. CHYPE refuses what BETH refuses (a bad checksum, the zero address). It also refuses the HyperEVM system addresses, with the attestors' rule. A burn to such an address would never get a payout.
  4. Localnet suite. The sandbox image moves to cbtc-6689a6a, which holds the CHYPE DARs. The suite runs a CHYPE phase after the BETH phase.
  5. Live API test. chype_devnet, chype_testnet and chype_mainnet follow the BETH tests. CI skips all three networks until the BitSafe API serves CHYPE.
  6. DARs. dars/chype/chype-0.1.0.dar is the released chype 0.1.0 package. Its SHA-256 matches the release manifest.

Considered and rejected

  • Copy the BETH mint module into CHYPE. It duplicates about 150 lines of logic and its tests.
  • One shared EvmNetworkConfig for both assets. It renames the public BethNetworkConfig, which breaks callers.
  • Skip the system-address check. The bridge refuses only address(0) and itself. A user could burn CHYPE that the attestors never pay out.

Agents

Agent Model Effort Task
Orchestrator Claude Opus 5.5 high Sizing, Daml diff, API and image checks, spec
general-purpose research agent Claude Opus 5.5 (inherited) high EVM bridge facts and registrar parties

@hubagaspar91

Copy link
Copy Markdown
Collaborator Author

Factory report 2: implementation

Phase: implementation. The orchestrator wrote the code itself. The change copies an existing pattern, so no implementer agent ran.

What was done

  • The first commit, e8b4663, moves DepositCall, DepositTarget and their builders into flows/canton_bridge_v1/evm_mint.rs. tokens::beth::mint re-exports them, so every public BETH path stays the same.
  • The second commit, 872c424, adds tokens::chype. It also adds the CHYPE examples, the DAR, the localnet phase and the live API tests, and updates the docs.
  • The live API helper check_unless_skipped now serves BETH and CHYPE. CI sets CHYPE_LIVE_API_SKIP to all three networks.

Verification

Gate Result
cargo fmt -- --check pass
cargo clippy --all-targets --all-features -- -D warnings pass
cargo test 132 library tests, 10 integration tests and 3 doc tests pass
compile_fail doc test: a BETH account in chype::mint::deposit_call does not compile, as intended
cargo build --examples 33 examples build
Localnet suite on cbtc-6689a6a pass in 22 s, with the CBTC, BETH and CHYPE phases
Live API, CBTC and BETH on all networks pass
Live API, CHYPE devnet without the skip fails: the BitSafe API answers 303 for /chype/*

Considered and rejected

  • Copy the BETH examples' amounts unchanged. The CHYPE examples use 0.25 HYPE by default, which is the mainnet bridge minimum.
  • Reuse DESTINATION_ETH_ADDRESS for CHYPE. A HyperEVM payout address is a different address. A shared variable could send a burn to the wrong chain's address. The CHYPE example reads DESTINATION_HYPE_ADDRESS.
  • Keep the localnet image at cbtc-4ee9822. That image has no CHYPE DARs, so the suite could not test CHYPE.

Agents

Agent Model Effort Task
Orchestrator Claude Opus 5.5 high Code, tests, docs, gates, commits

hubagaspar91 and others added 2 commits November 6, 2026 11:15
The suite tested CHYPE deposits on devnet only and BETH's acceptance
of one HyperEVM system address. These tests pin each network's bridge
from the requirement literals, the documented deposit check order, the
largest token system address, every system address BETH must accept,
the CHYPE Daml field names, and that a CHYPE account does not compile
in the BETH deposit call.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Another client can create a CHYPE withdraw account that pays a HyperEVM
system address. The burn now checks the account's address again, so it
refuses a burn that never gets a payout. The check also refuses the
CHYPE bridge proxies, because the bridge reverts a payout to itself.

The docs now state the CHYPE limits, the missing API routes and the
units. .env.example leaves the amounts unset, so each example uses its
own default and a CHYPE run does not burn less than the bridge minimum.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hubagaspar91

Copy link
Copy Markdown
Collaborator Author

Factory report 3: review and fix

Phases: review, fix. Self-review ran once with Gate A, two Claude personas and a Codex lens. One fix round followed. The Codex lens then found nothing material. A second employee still has to do the peer review.

Gate A: test audit

  • Verdict: pass. CI was green on c3a141c.
  • Tests added: commit c3a141c adds 13 tests and one compile_fail doc test.
    • The tests cover every network's bridge through deposit_call, the order of the deposit checks and the largest token system address.
    • They also prove that BETH still accepts all HyperEVM system addresses.
    • The doc test proves that a CHYPE account does not compile in beth::mint::deposit_call.

Findings and dispositions

# Lens Severity Finding Disposition
1 Security major submit_withdraw did not check the destination of an account that another client created. Fixed in 64fb991: a new trait hook, check_payout_destination, runs before the burn.
2 Security minor A CHYPE bridge proxy was accepted as a destination. The bridge reverts a payout to itself. Fixed in 64fb991 for CHYPE. Issue #12 tracks the same check for BETH.
3 Security, PM major .env.example set amounts below the mainnet CHYPE minimum of 0.25 HYPE. Fixed: the file leaves both amounts unset, so each example uses its own default.
4 PM major The CHYPE mint and burn cannot finish while the BitSafe API has no /chype routes. Nothing tracked the gap. Issue #13 tracks it. The pilot decides at the human gate.
5 PM minor The docs understated the API limit and left out the bridge limits and units. Fixed in README.md, examples/README.md and CHANGELOG.md.
6 PM minor Stale texts: "either asset", ASSET (cbtc or beth) in 19 examples, and "BTC or ETH" in the burn docs. Fixed.
7 PM minor AGENTS.md now needs a CHYPE docs space. Open for the pilot.
8 PM minor The DAR comes from the devnet release. Mainnet may run another package id. Open for the pilot.
9 Security nit The PR text named a private repository. Fixed in the PR body and in report 1.
10 PM nit Wording and line length. Fixed.
11 Codex none No material findings on 64fb991. Nothing to do.

Verification on 64fb991

  • cargo fmt, cargo clippy -D warnings and cargo test pass on the head. They ran 144 library tests and the doc tests.
  • The localnet suite passes on my machine.
  • The first CI localnet run failed before any test: the image registry answered toomanyrequests: Rate exceeded. The failed job runs again.

Considered and rejected

  • Use the full validate_destination in the burn path. It also enforces the EIP-55 checksum, so a valid older account with odd letter case could not burn. The new hook checks only what makes a payout impossible.
  • Add the burn-path check for BETH in this PR. It changes BETH behaviour, so issue fix(beth): check the payout address before a burn #12 tracks it.
  • Change the API client so that a missing route fails with a clear status. The client is shared by all assets. The docs name the parse error instead.

Agents

Agent Model Effort Task
Gate A test auditor Claude Opus 5.5 high Test audit, 13 tests, CI watch
Security persona Claude Opus 5.5 high Security lens, independent fact checks
Product-manager persona Claude Opus 5.5 high Spec and docs lens
Codex lens Codex GPT-6.1-Sol high Second-vendor review of 64fb991
Orchestrator Claude Opus 5.5 high Fix round, issues, reports

@hubagaspar91
hubagaspar91 marked this pull request as draft November 6, 2026 10:37
@hubagaspar91

Copy link
Copy Markdown
Collaborator Author

The pilot decided to hold this PR until the BitSafe API serves the /chype routes. Issue #13 tracks the full devnet round that follows. The PR is a draft until then.

@hubagaspar91

Copy link
Copy Markdown
Collaborator Author

Factory report 4: human gate and devnet round

Phase: human-gate. The pilot made three decisions:

Registrar ids on the clusters

The orchestrator read the config maps of each cluster, read-only, with no secrets. Every id matches the crate.

Network Config map Registrar
devnet attestor/attestor-env chype-network::1220806e…2c52
testnet attestor/attestor-env chype-network::12204c05…1db0
mainnet pqs/pqs-chype-config chype-network::1220cc3b…5956

Devnet round on 64fb991

Step Result
check_dars, ASSET=chype PASS: 22 of 22 packages, chype 0.1.0 among them
chype_credentials Ran. The party has no CHYPE credential and no CHYPE offer yet.
check_balance, ASSET=chype Ran: 0 CHYPE, 0 holdings
list_incoming_offers, ASSET=chype Ran: no offers
chype_mint_flow, chype_redeem_flow Not run: the BitSafe API has no /chype routes

CI is green on 64fb991. The first localnet run failed on a registry rate limit, and the rerun passed.

Considered and rejected

  • Add the CHYPE routes to the BitSafe API in this flow. The pilot chose to hold the PR instead.
  • Read the party ids from cluster secrets. The config maps hold the ids, so the check read no secrets.

Agents

Agent Model Effort Task
Orchestrator Claude Opus 5.5 high Cluster check, devnet round, report

@hubagaspar91

Copy link
Copy Markdown
Collaborator Author

Factory report 5: devnet credential check

Phase: human-gate. The pilot offered the test party a CHYPE Minter credential in DecMan on devnet.

Step Result
Read-only check of the party's credentials The party holds int-test-1-chype-minter, issued by the CHYPE devnet registrar, with the claim hasCHYPERole = Minter.
chype::minter_credential_cids(Network::Devnet, …) Finds the credential. It ignores the party's CBTC and BETH credentials.
Open credential offers None. The offer was accepted before the check.

The orchestrator used a small read-only program for the check, because chype_credentials accepts the first offer it finds. The mint and burn rounds wait for the BitSafe API, as issue #13 records. This PR stays a draft until then.

Agent Model Effort Task
Orchestrator Claude Opus 5.5 high Read-only credential check, report

The devnet BitSafe API now serves the CHYPE routes, and the
read-only live check passes there. The testnet and mainnet APIs
still redirect the CHYPE routes, so CI skips those networks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant