Skip to content

Add API v1: standardized, wallet-shaped URL format (#26) - #29

Open
dawsbot wants to merge 1 commit into
masterfrom
api-v1
Open

Add API v1: standardized, wallet-shaped URL format (#26)#29
dawsbot wants to merge 1 commit into
masterfrom
api-v1

Conversation

@dawsbot

@dawsbot dawsbot commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Implements the API v1 proposed by @ItsNickBarry in #26. Built additively so v0 keeps working for existing links and the Hardhat plugin. No v0 page or encoding source was modified.

What v1 is

The whole transaction lives in the URL, wallet-shaped:

Param Notes
chainId hex (0x1) or decimal (1)
to recipient (no EOA/contract distinction)
value wei, optional, defaults to 0
data a pre-encoded hex string, or omitted and supplied via fnSignature + fnArgs
fnSignature full signature, e.g. transfer(address,uint256) (named params supported)
fnArgs JSON-encoded argument array

The ABI is inferred from fnSignature, so the Etherscan ABI lookup is not needed on the v1 encode path.

Approach (per request)

  1. v0 regression tests firsttype-casting + real example-URL decoding, locking v0 behavior before any v1 work.
  2. v1 logic via TDD — pure, fully unit-tested module in packages/txn-dot-xyz/utils/v1 (parseChainId, parseTxValue, encodeCalldata, parseTransaction, parseRouterQuery, buildV1Url). 21 tests, incl. large-uint precision, named params, bytes32[] merkle proofs.
  3. v1 pages — new pages/v1/encode.tsx + pages/v1/decode.tsx. v0 pages untouched.
  4. Homepage now links to /v1/encode and ships v1 example URLs, so users no longer generate v0.

tsconfig target bumped es5 → es2020 (BigInt literals / viem / tsgo). Build config only.

Verification

npm test (34 tests), tsgo --noEmit, and next build all pass. All routes serve 200 locally. Connect a wallet on these to confirm end-to-end (they switch chains + send):

v1 (new):

  • Transfer DAI: /v1/decode?chainId=1&to=0x6b175474e89094c44da98b954eedeac495271d0f&fnSignature=transfer(address,uint256)&fnArgs=["0xc0DEAF6bD3F0c6574a6a625EF2F22f62A5150EAB","100"]
  • Approve DAI: /v1/decode?chainId=1&to=0x6b175474e89094c44da98b954eedeac495271d0f&fnSignature=approve(address,uint256)&fnArgs=["0xc0DEAF6bD3F0c6574a6a625EF2F22f62A5150EAB","100"]
  • Claim Airdrop (nested bytes32[] proof): see the homepage "Claim Airdrop" card.
  • Native transfer (no data): /v1/decode?chainId=1&to=0xc0DEAF6bD3F0c6574a6a625EF2F22f62A5150EAB&value=1000000000000000000

v0 (still works, unchanged):

  • Transfer DAI: /v0/decode?chainID=1&contractAddress=0x6b175474e89094c44da98b954eedeac495271d0f&fn=transfer&fnParams=0=0xc0DEAF6bD3F0c6574a6a625EF2F22f62A5150EAB,1=100

Open question for @ItsNickBarry

I encoded fnArgs as a JSON array (preserves string precision for large uints and supports nesting). Happy to switch to repeated fnArgs= params or another shape if you prefer for the plugin.

Closes #26

🤖 Generated with Claude Code

Implements the API v1 proposed in #26 by @ItsNickBarry, additively and
without touching any v0 code so existing links and the Hardhat plugin keep
working.

v1 describes the whole transaction in the URL, wallet-shaped:
  chainId, to, value, and data as either a pre-encoded hex string or
  fnSignature + fnArgs. The ABI is inferred from the signature
  (transfer(address,uint256)), so no Etherscan ABI lookup is needed.

- packages/txn-dot-xyz/utils/v1: pure, fully unit-tested parse/encode
  (parseChainId, parseTxValue, encodeCalldata, parseTransaction,
  parseRouterQuery, buildV1Url). 21 tests.
- pages/v1/decode.tsx + pages/v1/encode.tsx (v0 pages untouched).
- Homepage now links to /v1/encode and ships v1 example URLs.
- Added v0 regression tests (type-casting + example-URL decoding) first,
  to lock v0 behavior before adding v1.
- Bumped tsconfig target es5 -> es2020 (BigInt literals, viem, tsgo).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
txnxyz Ready Ready Preview, Comment Jun 16, 2026 6:44pm

@ItsNickBarry

Copy link
Copy Markdown
Contributor

I will review soon. Tag me again if I don't get to it this weekend.

chainId,
to,
value,
data: encodeCalldata(query.fnSignature, fnArgs),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should error if a data param is included. Or, should validate that the hex-encoded fnSignature and fnArgs exactly match the data param.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I originally suggested that fnSignature and fnArgs be encoded in an object and passed as the data param because it would be impossible to send both the object and a hex string. But keeping the params separate makes the URL a bit cleaner.

const value = parseTxValue(query.value);

if (query.fnSignature) {
const fnArgs = query.fnArgs ?? [];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should validate that fnArgs is an array.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If it's a string with a length equal to the number of expected fn args, each char could be parsed as if it were an array element. For most data types this would fail later, but I think this example would silently pass: fnSignature of fn(uint256 a,uint256 b,uint256 c) and fnArgs of '123'.

@ItsNickBarry

Copy link
Copy Markdown
Contributor

By the way, here's an update the Hardhat plugin that makes use of this new API: solidstate-network/hardhat-txn-dot-xyz#5

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.

API V1 suggestions

2 participants