Skip to content

feat: support custom ERC-20 and native chain coin via customToken#5

Merged
AlejandroFabianCampos merged 3 commits into
mainfrom
feat/custom-token-and-native
Apr 29, 2026
Merged

feat: support custom ERC-20 and native chain coin via customToken#5
AlejandroFabianCampos merged 3 commits into
mainfrom
feat/custom-token-and-native

Conversation

@AlejandroFabianCampos
Copy link
Copy Markdown
Collaborator

@AlejandroFabianCampos AlejandroFabianCampos commented Apr 29, 2026

Summary

Adds two features to evm.charge while keeping the existing token: 'USDC' zero-config path untouched:

  • Custom ERC-20 — pass customToken: { address, decimals, symbol?, name?, version?, credentialTypes? } to settle in any ERC-20 by address. Default credential types: ['permit2', 'hash'] (opt-in for authorization since EIP-3009 isn't guaranteed on arbitrary tokens).
  • Native chain coin — set customToken.address to NATIVE_TOKEN_ADDRESS (zero address) to settle in the chain's native coin (ETH / MATIC / AVAX / …). Restricted to the hash credential and to direct EOA sends (tx.input === '0x'). Documented as a non-normative extension to draft-evm-charge-00.

token and customToken are mutually exclusive — passing both throws at construction time.

The verifiers were already token-agnostic, so the change is small: one new field, one zero-address branch in verifiers/hash.ts, one zero-address branch in client/hash.ts.

Test plan

  • npm run lint
  • npm run typecheck
  • npm test — all 88 tests pass (79 + 9 skipped integration), including 7 new customToken cases:
    • token + customToken both set → throws
    • native + non-hash credential types → throws at construction
    • native customToken defaults to ['hash']
    • custom ERC-20 customToken defaults to ['permit2', 'hash']
    • authorization rejected by default on a custom ERC-20
    • opt-in authorization on a custom ERC-20 with name/version overrides
  • npm run build — clean dist
  • Live smoke on Base Sepolia: native ETH transfer via hash
  • Live smoke on Base Sepolia: custom ERC-20 via permit2

Note

Medium Risk
Touches payment settlement and on-chain verification paths, adding a new native-transfer branch and new validation rules; mistakes could cause false accepts/rejects for hash credentials. Changes are scoped and covered by new unit tests but still affect core payment flow.

Overview
Extends evm.charge to accept a new customToken configuration (mutually exclusive with curated token) so servers can settle payments in arbitrary ERC-20s by address, with per-token/default credential-type gating and optional EIP-712 name/version overrides.

Adds first-class native chain coin support via NATIVE_TOKEN_ADDRESS (zero address): the client hash flow now sends a value transfer instead of ERC20.transfer, and the server hash verifier validates tx.to/tx.value/tx.input === '0x' rather than ERC-20 Transfer logs. Public exports, types, tests, and README are updated accordingly.

Reviewed by Cursor Bugbot for commit 4f39d1b. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2b3c94e. Configure here.

Comment thread src/server/Charge.ts
Comment thread src/server/Charge.ts
@AlejandroFabianCampos AlejandroFabianCampos merged commit afe2f66 into main Apr 29, 2026
2 checks passed
@AlejandroFabianCampos AlejandroFabianCampos mentioned this pull request Apr 30, 2026
2 tasks
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.

2 participants