Problem
The Snap's crypto output is cross-validated against Go test vectors, and unit tests verify each RPC method in isolation. But nobody has proven the full flow works end-to-end: Snap produces a signature → middleware accepts it → Canton executes the submission. If there is any format mismatch (DER encoding, hash pre-image, fingerprint derivation), we won't know until we wire everything together.
This issue covers integration testing against a local Docker stack (canton-middleware's docker-compose.e2e.yaml) for fast, repeatable iteration.
Part of: #3 (Non-custodial signing epic)
Depends on: #4 (CI)
What to change
Create a scripted integration test (Node.js) that:
- Starts the middleware Docker stack — or assumes it's already running via
make test-e2e-api / presets.DoMain
- Serves the Snap locally —
npm run serve (Snap available at local:http://localhost:8080)
- Invokes Snap RPC methods programmatically — using
@metamask/snaps-jest or a lightweight Snap executor
- Executes the full non-custodial flow:
Step 1: canton_getPublicKey → compressedPubKey, fingerprint
Step 2: POST /register/prepare-topology
Body: { signature: <EVM sig>, message: "register", canton_public_key: <Snap pubkey> }
Response: { topology_hash, registration_token }
Step 3: canton_signTopology → derSignature of topology_hash
Step 4: POST /register
Body: { signature: <EVM sig>, message: "register", key_mode: "external",
canton_public_key: <Snap pubkey>, registration_token, topology_signature: <Snap sig> }
Response: { party, fingerprint, key_mode: "external" }
Step 5: Mint DEMO tokens to the new party (via Canton shim or bootstrap script)
Step 6: POST /api/v2/transfer/prepare
Headers: X-Signature: <EVM timed sig>, X-Message: "transfer:<timestamp>"
Body: { to: <recipient_address>, amount: "10", token: "DEMO" }
Response: { transfer_id, transaction_hash }
Step 7: canton_signHash → derSignature of transaction_hash
Step 8: POST /api/v2/transfer/execute
Headers: X-Signature: <EVM timed sig>, X-Message: "transfer:<timestamp>"
Body: { transfer_id, signature: <Snap DER sig>, signed_by: <Snap fingerprint> }
Response: { status: "completed" }
Step 9: Verify recipient balance updated via balanceOf
Key validation points:
- Step 4: Middleware accepts Snap's topology signature and completes external registration
- Step 8: Canton's
ExecuteSubmission accepts the Snap-produced DER signature — this is the critical test
- Fingerprint from Snap matches what middleware stored during registration
Test location: test/integration/local.test.ts or scripts/test-e2e-local.ts
Acceptance Criteria
Problem
The Snap's crypto output is cross-validated against Go test vectors, and unit tests verify each RPC method in isolation. But nobody has proven the full flow works end-to-end: Snap produces a signature → middleware accepts it → Canton executes the submission. If there is any format mismatch (DER encoding, hash pre-image, fingerprint derivation), we won't know until we wire everything together.
This issue covers integration testing against a local Docker stack (canton-middleware's
docker-compose.e2e.yaml) for fast, repeatable iteration.Part of: #3 (Non-custodial signing epic)
Depends on: #4 (CI)
What to change
Create a scripted integration test (Node.js) that:
make test-e2e-api/presets.DoMainnpm run serve(Snap available atlocal:http://localhost:8080)@metamask/snaps-jestor a lightweight Snap executorKey validation points:
ExecuteSubmissionaccepts the Snap-produced DER signature — this is the critical testTest location:
test/integration/local.test.tsorscripts/test-e2e-local.tsAcceptance Criteria
ExecuteSubmission