Skip to content

feat(pay): attribute every CLI-brokered payment with Tenjin's builder code - #187

Open
A1igator wants to merge 1 commit into
mainfrom
A1igator/cli-builder-code-attribution
Open

feat(pay): attribute every CLI-brokered payment with Tenjin's builder code#187
A1igator wants to merge 1 commit into
mainfrom
A1igator/cli-builder-code-attribution

Conversation

@A1igator

@A1igator A1igator commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Scope

  • src/lib/x402-pay.ts: buildExactPayment registers the SDK's BuilderCodeClientExtension with Tenjin's registered code bc_kc0altv3 before it signs, so every payment the CLI brokers carries the code in the ERC-8021 s (client service) field. buy and pay both sign through this one function, so first-party and Bazaar-lane payments are covered by the same line.
  • Standard-only, no custom surface: the SDK fires the hook exclusively for sellers whose 402 advertises the builder-code extension, so a seller who never declared it gets an extension-free payload, and payload.extensions is never hand-set. The single-accept binding keeps extensions through its spread, which is the one way this can silently stop working; a test asserts the code survives end to end.
  • Risk: the code is a public client identity in settlement calldata (it names the CLI, never the user), and it changes no payment term. src/lib/x402-pay.test.ts pins that the authorized from/to/value and the accepted requirement are identical with and without the extension.

Why one code, not a CLI-specific second one

Base registers one builder code per account, and ERC-8021 Schema 2 separates the roles structurally: the seller-advertised code lands in a, the client's in s, the facilitator's in w. So server-side and CLI-side volume stay fully distinguishable on-chain with a single value. A payment to a foreign seller carries bc_kc0altv3 in s alone; a first-party buy carries it in both a and s. Tests cover both shapes. No owner action is required: the code is already registered and live on the three web 402s.

Testing

  • pnpm lint, pnpm typecheck, pnpm format:check: clean. pnpm run check (build + full suite): 2190 passed, 10 skipped.
  • New: 4 unit tests in src/lib/x402-pay.test.ts (s present alongside a foreign seller's distinct a; both roles filled when Tenjin is also the seller; no extension at all for a non-advertising seller; authorized terms identical either way), 3 in src/commands/pay.test.ts (tenjin lane advertised and not-advertised, plus a Bazaar-lane pay whose registry-evidence verdict is unchanged), 1 in src/commands/buy.test.ts (the paid retry's envelope carries the code and still authorizes the advertised price and payee).
  • The existing 26 pay and 19 buy tests are untouched and green.

Definition of Done

  • Attribution rides the standard extension; nothing non-spec is added to the payment flow.
  • A seller that does not advertise builder-code receives no extension.
  • Changeset added (.changeset/cli-builder-code.md).

Refs the plan at tenjin/docs/plans/2026-08-18-cli-vip-discover-builder-code.md (PR A) and #151.

Stack: #151 → this PR → #189 (discover pins, based on this branch). This layer shares no file with #158.

@A1igator A1igator added the priority: medium Medium priority label Aug 18, 2026

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@A1igator
A1igator force-pushed the A1igator/cli-builder-code-attribution branch from 6491386 to b1cbb5c Compare August 18, 2026 20:30

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@A1igator

Copy link
Copy Markdown
Contributor Author

Amended per the operator decision on the service-code question: the CLI now claims the existing registered code bc_kc0altv3 rather than a new CLI-specific one. Base registers one code per account, and Schema 2 keeps the roles apart structurally (a seller, s client, w facilitator), so CLI volume stays distinguishable from web volume with one value. The register-a-new-code owner action is gone. Tests are unchanged apart from the value, plus one new case pinning that a foreign seller's own a stays distinct from our s. Force-pushed as b1cbb5c.

@A1igator
A1igator changed the base branch from A1igator/x402-pay-discover to main August 18, 2026 20:32
@A1igator
A1igator changed the base branch from main to A1igator/x402-pay-discover August 18, 2026 20:33
Base automatically changed from A1igator/x402-pay-discover to main August 19, 2026 14:26
… code

buildExactPayment registers the SDK's BuilderCodeClientExtension before it
signs, so the payload carries Tenjin's registered code `bc_kc0altv3` in the
ERC-8021 `s` (client service) field. buy and pay share that path, and the SDK
fires the hook only for sellers whose 402 advertises the standard builder-code
extension.
@A1igator
A1igator force-pushed the A1igator/cli-builder-code-attribution branch from b1cbb5c to c41880d Compare August 19, 2026 14:30

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@A1igator

Copy link
Copy Markdown
Contributor Author

Rebased onto main after #151 squash-merged (014932a). git rebase --onto origin/main <my fork point> dropped every pre-squash #151 commit and replayed only this layer's commit, no conflicts: b1cbb5cc41880d, force-pushed with lease. The PR is MERGEABLE again and its diff is the same six files as before. Gates re-run on the rebased tree: lint, typecheck, and format:check clean, pnpm run check 2251 passed / 10 skipped. CI fires on this PR for the first time now that it targets main; expect it green, since it runs the same lint/typecheck/build/test/audit set that just passed locally against this exact tree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: medium Medium priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant