feat: support custom ERC-20 and native chain coin via customToken#5
Merged
Merged
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ 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.
markwu35
approved these changes
Apr 29, 2026
Merged
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Adds two features to
evm.chargewhile keeping the existingtoken: 'USDC'zero-config path untouched:customToken: { address, decimals, symbol?, name?, version?, credentialTypes? }to settle in any ERC-20 by address. Default credential types:['permit2', 'hash'](opt-in forauthorizationsince EIP-3009 isn't guaranteed on arbitrary tokens).customToken.addresstoNATIVE_TOKEN_ADDRESS(zero address) to settle in the chain's native coin (ETH / MATIC / AVAX / …). Restricted to thehashcredential and to direct EOA sends (tx.input === '0x'). Documented as a non-normative extension todraft-evm-charge-00.tokenandcustomTokenare 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 inclient/hash.ts.Test plan
npm run lintnpm run typechecknpm test— all 88 tests pass (79 + 9 skipped integration), including 7 newcustomTokencases:token+customTokenboth set → throws['hash']['permit2', 'hash']name/versionoverridesnpm run build— clean disthashpermit2Note
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
hashcredentials. Changes are scoped and covered by new unit tests but still affect core payment flow.Overview
Extends
evm.chargeto accept a newcustomTokenconfiguration (mutually exclusive with curatedtoken) so servers can settle payments in arbitrary ERC-20s by address, with per-token/default credential-type gating and optional EIP-712name/versionoverrides.Adds first-class native chain coin support via
NATIVE_TOKEN_ADDRESS(zero address): the clienthashflow now sends a value transfer instead ofERC20.transfer, and the serverhashverifier validatestx.to/tx.value/tx.input === '0x'rather than ERC-20Transferlogs. 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.