From 96df915c3a0fb98899fdbf78619f1e8e89f4e712 Mon Sep 17 00:00:00 2001 From: Noak Date: Mon, 29 Jun 2026 01:38:56 -0400 Subject: [PATCH 1/4] docs(mypaytag): add code contract closure todos --- agent-context/todo.md | 62 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/agent-context/todo.md b/agent-context/todo.md index 2b23c9f..dced236 100644 --- a/agent-context/todo.md +++ b/agent-context/todo.md @@ -638,3 +638,65 @@ Acceptance notes: - `pnpm validate` passes. - Public boundary scan passes and finds no private backend, Cubid internal, wallet graph, service-role, private storage, or deployment internals. - Staged smoke checklist references the corrected SDK contracts for Cubid SDK, MyPayTag backend, one test PayingDapp, one test PayToDapp, and SmarTrust swap/bridge NEAR 1Click. + +## Sprint 8: Code-Verified Backend Compatibility Closure + +### GPTS-S8-T1 Add Backend Compatibility Fixtures For Public Paytag Boundaries + +Status: Todo +Feature branch: codex/mypaytag-mvp-code-gap-todos-20260629 +Session log: TBD +Depends on: mypaytag:GPTR-S8-T1, smartrust-wallet:STW-S28-T1 + +Add fixtures and conformance tests that prove the SDK's canonical +`identifierType: "paytag"` resolve, route registration, provider callback, +notification, and intent payloads are the payloads the backend accepts and +returns. + +Acceptance notes: + +- Tests fail if SDK fixtures or generated types reintroduce public + `identifierType: "verified_stamp"`. +- Fixtures include SmarTrust PayingDapp resolve and SmarTrust PayToDapp route + registration examples. +- Backend response examples validate through SDK schemas without compatibility + casts. +- The staged smoke checklist names this as the contract gate before hosted + staging smoke. + +### GPTS-S8-T2 Add Public NEAR 1Click Endpoint Client Helpers + +Status: Todo +Feature branch: codex/mypaytag-mvp-code-gap-todos-20260629 +Session log: TBD +Depends on: mypaytag:GPTR-S8-T2, mypaytag-sdk:GPTS-S7-T1, mypaytag-sdk:GPTS-S7-T2 + +Add SDK helpers for calling the backend NEAR 1Click MVP quote and selected-quote +payable-instruction endpoints once those endpoints are exposed. + +Acceptance notes: + +- Helpers build and validate quote requests, quote options, selected-quote + requests, and payable instructions using the existing NEAR schemas. +- Helpers do not expose LI.FI, Squid, 0x, Across, LayerZero/Stargate, broad + fanout, or generic external adapter support as MVP dependencies. +- Tests cover success and safe failure parsing for quote unavailable, quote + expired, route revoked, authorization required, and invalid response. + +### GPTS-S8-T3 Guard Phase 2 Solver Helpers Against MVP Import Drift + +Status: Todo +Feature branch: codex/mypaytag-mvp-code-gap-todos-20260629 +Session log: TBD +Depends on: mypaytag-sdk:GPTS-S8-T2 + +Add a package-level guardrail proving MVP examples and helpers do not require +the Phase 2 `requestExecutionQuotes` fanout helper. + +Acceptance notes: + +- MVP examples import resolve, provider callback, hosted action, route CRUD, + and NEAR 1Click helpers only. +- Phase 2 solver helper tests remain labeled as non-MVP. +- Validation fails if Phase 2 solver ids appear in MVP happy-path fixtures as + active execution requirements. From 8e2666e0f297a1222eb26c5e92285b22656b6ea9 Mon Sep 17 00:00:00 2001 From: Noak Date: Mon, 29 Jun 2026 01:56:07 -0400 Subject: [PATCH 2/4] test(mypaytag): guard public paytag payload contract --- agent-context/todo.md | 4 ++-- packages/sdk/src/sdk.test.ts | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/agent-context/todo.md b/agent-context/todo.md index dced236..71f11a9 100644 --- a/agent-context/todo.md +++ b/agent-context/todo.md @@ -643,9 +643,9 @@ Acceptance notes: ### GPTS-S8-T1 Add Backend Compatibility Fixtures For Public Paytag Boundaries -Status: Todo +Status: Complete Feature branch: codex/mypaytag-mvp-code-gap-todos-20260629 -Session log: TBD +Session log: agent-context/session-log/main.md#2026-06-29-gpts-s8-t1 Depends on: mypaytag:GPTR-S8-T1, smartrust-wallet:STW-S28-T1 Add fixtures and conformance tests that prove the SDK's canonical diff --git a/packages/sdk/src/sdk.test.ts b/packages/sdk/src/sdk.test.ts index 38375be..0f84e5a 100644 --- a/packages/sdk/src/sdk.test.ts +++ b/packages/sdk/src/sdk.test.ts @@ -9,6 +9,8 @@ import { validResolvedResponse, validResolveRequest, validRouteSelectionResponse, + validProviderCallbackRequest, + validRouteRegistrationRequest, } from "@mypaytag/protocol"; import { @@ -36,6 +38,14 @@ describe("@mypaytag/sdk", () => { expect(buildResolveRequest(validResolveRequest)).toEqual(validResolveRequest); }); + it("keeps public MVP payloads on the paytag identifier contract", () => { + expect(validResolveRequest.recipient.identifierType).toBe("paytag"); + expect(validResolvedResponse.intent.recipient.identifierType).toBe("paytag"); + expect(validNotificationEvent.recipient.identifierType).toBe("paytag"); + expect(validRouteRegistrationRequest.recipient.identifierType).toBe("paytag"); + expect(validProviderCallbackRequest.recipient.identifierType).toBe("paytag"); + }); + it("builds generic payor-app resolve request inputs", () => { const supportedPath = buildSupportedPath({ chain: " base ", From 94d9f736ffcb2bf47fc75e8a2f29f980c82a5aee Mon Sep 17 00:00:00 2001 From: Noak Date: Mon, 29 Jun 2026 01:57:44 -0400 Subject: [PATCH 3/4] feat(mypaytag): add near oneclick endpoint helpers --- agent-context/todo.md | 4 +- packages/sdk/src/index.ts | 102 +++++++++++++++++++++++++++++++++++ packages/sdk/src/sdk.test.ts | 60 +++++++++++++++++++++ 3 files changed, 164 insertions(+), 2 deletions(-) diff --git a/agent-context/todo.md b/agent-context/todo.md index 71f11a9..9ea25bc 100644 --- a/agent-context/todo.md +++ b/agent-context/todo.md @@ -666,9 +666,9 @@ Acceptance notes: ### GPTS-S8-T2 Add Public NEAR 1Click Endpoint Client Helpers -Status: Todo +Status: Complete Feature branch: codex/mypaytag-mvp-code-gap-todos-20260629 -Session log: TBD +Session log: agent-context/session-log/main.md#2026-06-29-gpts-s8-t2 Depends on: mypaytag:GPTR-S8-T2, mypaytag-sdk:GPTS-S7-T1, mypaytag-sdk:GPTS-S7-T2 Add SDK helpers for calling the backend NEAR 1Click MVP quote and selected-quote diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 7478b23..acdb714 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -22,6 +22,37 @@ export type SupportedPath = ResolveRequest["supportedPaths"][number]; export type ResolveAmount = ResolveRequest["amount"]; export type PayorAmountExactness = "exact_send" | "exact_receive"; +export interface NearOneClickReceiveRequirement { + destinationAsset: string; + recipient: string; + amount: string; + expiresAt: string; + resolverReference: string; +} + +export interface NearOneClickQuoteEndpointRequest { + schema?: "mypaytag.near_1click.quote_request.v1"; + receiveRequirement: NearOneClickReceiveRequirement; + selectedRouteReference?: string; + sourceAsset: string; + sourceAmount: string; + payorReference: string; +} + +export interface NearOneClickQuoteEndpointResponse { + status: "quoted"; + adapter: "near_intents_1click"; + resolverReference: string; + selectedRouteReference: string; + quotes: NearOneClickMvpQuoteOption[]; +} + +export interface MyPayTagEndpointCallOptions { + endpoint: string; + fetch?: typeof fetch; + headers?: Record; +} + export interface PayorAppReferenceInput { payorAppId: string; reference: string; @@ -176,6 +207,21 @@ export function parseNearOneClickPayableInstruction( return validateNearOneClickPayableInstruction(payload); } +export async function requestNearOneClickQuoteOptions( + options: MyPayTagEndpointCallOptions & { request: NearOneClickQuoteEndpointRequest }, +): Promise { + assertNearOneClickQuoteRequest(options.request); + const payload = await postJson(options.endpoint, options.request, options); + return parseNearOneClickQuoteEndpointResponse(payload); +} + +export async function selectNearOneClickQuote( + options: MyPayTagEndpointCallOptions & { request: NearOneClickMvpQuoteSelectionRequest }, +): Promise { + const request = buildNearOneClickQuoteSelectionRequest(options.request); + return parseNearOneClickPayableInstruction(await postJson(options.endpoint, request, options)); +} + export function isMyPayTagNotification(payload: unknown): payload is NotificationEvent { return isNotificationEvent(payload); } @@ -218,6 +264,62 @@ function requireNonEmpty(value: string, fieldName: string): string { return trimmed; } +function parseNearOneClickQuoteEndpointResponse(payload: unknown): NearOneClickQuoteEndpointResponse { + if (!payload || typeof payload !== "object") { + throw new Error("invalid_near_1click_quote_response"); + } + const candidate = payload as NearOneClickQuoteEndpointResponse; + if ( + candidate.status !== "quoted" || + candidate.adapter !== "near_intents_1click" || + !candidate.resolverReference || + !candidate.selectedRouteReference || + !Array.isArray(candidate.quotes) + ) { + throw new Error("invalid_near_1click_quote_response"); + } + + return { + ...candidate, + quotes: candidate.quotes.map(parseNearOneClickQuoteOption), + }; +} + +function assertNearOneClickQuoteRequest(request: NearOneClickQuoteEndpointRequest): void { + if (!request.sourceAsset || !request.sourceAmount || !request.payorReference) { + throw new Error("invalid_near_1click_quote_request"); + } + if ( + !request.receiveRequirement?.destinationAsset || + !request.receiveRequirement.recipient || + !request.receiveRequirement.amount || + !request.receiveRequirement.expiresAt || + !request.receiveRequirement.resolverReference + ) { + throw new Error("invalid_near_1click_quote_request"); + } +} + +async function postJson( + endpoint: string, + body: unknown, + options: Pick = {}, +): Promise { + const requestFetch = options.fetch ?? globalThis.fetch; + const response = await requestFetch(endpoint, { + method: "POST", + headers: { + "content-type": "application/json", + ...(options.headers ?? {}), + }, + body: JSON.stringify(body), + }); + if (!response.ok) { + throw new Error(`mypaytag_endpoint_error:${response.status}`); + } + return await response.json(); +} + /** * Requests Phase 2 non-MVP execution quotes from caller-provided providers. * Core MyPayTag MVP integrations can resolve paytags, parse NEAR 1Click quote diff --git a/packages/sdk/src/sdk.test.ts b/packages/sdk/src/sdk.test.ts index 0f84e5a..0025aa1 100644 --- a/packages/sdk/src/sdk.test.ts +++ b/packages/sdk/src/sdk.test.ts @@ -26,7 +26,9 @@ import { isResolved, parseNotificationEvent, parseResolveResponse, + requestNearOneClickQuoteOptions, requestExecutionQuotes, + selectNearOneClickQuote, parseNearOneClickPayableInstruction, parseNearOneClickQuoteOption, type CryptoNativeExecutionSolverId, @@ -156,6 +158,57 @@ describe("@mypaytag/sdk", () => { ); }); + it("calls NEAR 1Click quote and selected-quote backend endpoints", async () => { + const calls: Array<{ endpoint: string; body: unknown }> = []; + const fakeFetch: typeof fetch = async (input, init) => { + calls.push({ + endpoint: String(input), + body: JSON.parse(String(init?.body)), + }); + if (String(input).endsWith("/near-oneclick-quotes")) { + return jsonResponse({ + status: "quoted", + adapter: "near_intents_1click", + resolverReference: validNearOneClickQuoteOption.resolverReference, + selectedRouteReference: validNearOneClickQuoteOption.selectedRouteReference, + quotes: [validNearOneClickQuoteOption], + }); + } + return jsonResponse(validNearOneClickPayableInstruction); + }; + + const quotes = await requestNearOneClickQuoteOptions({ + endpoint: "https://resolver.test/functions/v1/near-oneclick-quotes", + fetch: fakeFetch, + headers: { "x-mypaytag-dapp-id": "smartrust-wallet" }, + request: { + sourceAsset: "near/mainnet/USDC", + sourceAmount: "25.18", + payorReference: "smartrust:send_001", + receiveRequirement: { + destinationAsset: "base/mainnet/USDC", + recipient: validNearOneClickQuoteOption.selectedRouteReference, + amount: "25.00", + expiresAt: validNearOneClickQuoteOption.expiresAt, + resolverReference: validNearOneClickQuoteOption.resolverReference, + }, + }, + }); + const instruction = await selectNearOneClickQuote({ + endpoint: "https://resolver.test/functions/v1/near-oneclick-selected-quote", + fetch: fakeFetch, + request: validNearOneClickQuoteSelectionRequest, + }); + + expect(quotes.quotes).toEqual([validNearOneClickQuoteOption]); + expect(instruction).toEqual(validNearOneClickPayableInstruction); + expect(calls.map((call) => call.endpoint)).toEqual([ + "https://resolver.test/functions/v1/near-oneclick-quotes", + "https://resolver.test/functions/v1/near-oneclick-selected-quote", + ]); + expect(calls[1].body).toEqual(validNearOneClickQuoteSelectionRequest); + }); + it("requests Phase 2 extension quotes from every configured solver when none is preferred", async () => { const calls: CryptoNativeExecutionSolverId[] = []; const providers = [ @@ -246,3 +299,10 @@ function createQuoteProvider( }, }; } + +function jsonResponse(body: unknown): Response { + return new Response(JSON.stringify(body), { + status: 200, + headers: { "content-type": "application/json" }, + }); +} From dbd33ead1f73c34a3663bf44a209a77e826d92c5 Mon Sep 17 00:00:00 2001 From: Noak Date: Mon, 29 Jun 2026 01:58:23 -0400 Subject: [PATCH 4/4] test(mypaytag): guard mvp fixtures from phase two solvers --- agent-context/todo.md | 4 ++-- packages/sdk/src/sdk.test.ts | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/agent-context/todo.md b/agent-context/todo.md index 9ea25bc..19c4cf3 100644 --- a/agent-context/todo.md +++ b/agent-context/todo.md @@ -685,9 +685,9 @@ Acceptance notes: ### GPTS-S8-T3 Guard Phase 2 Solver Helpers Against MVP Import Drift -Status: Todo +Status: Complete Feature branch: codex/mypaytag-mvp-code-gap-todos-20260629 -Session log: TBD +Session log: agent-context/session-log/main.md#2026-06-29-gpts-s8-t3 Depends on: mypaytag-sdk:GPTS-S8-T2 Add a package-level guardrail proving MVP examples and helpers do not require diff --git a/packages/sdk/src/sdk.test.ts b/packages/sdk/src/sdk.test.ts index 0025aa1..ab7ca38 100644 --- a/packages/sdk/src/sdk.test.ts +++ b/packages/sdk/src/sdk.test.ts @@ -20,6 +20,7 @@ import { buildPayorAppReference, buildPayorAppResolveRequest, buildSupportedPath, + cryptoNativeExecutionSolvers, getActionUrl, isActionRequired, isMyPayTagNotification, @@ -209,6 +210,23 @@ describe("@mypaytag/sdk", () => { expect(calls[1].body).toEqual(validNearOneClickQuoteSelectionRequest); }); + it("keeps Phase 2 solver ids out of MVP happy-path fixtures", () => { + const mvpFixtures = JSON.stringify([ + validResolveRequest, + validResolvedResponse, + validRouteRegistrationRequest, + validProviderCallbackRequest, + validNearOneClickQuoteOption, + validNearOneClickQuoteSelectionRequest, + validNearOneClickPayableInstruction, + ]); + + expect(validNearOneClickQuoteOption.adapter).toBe("near_intents_1click"); + for (const solverId of cryptoNativeExecutionSolvers) { + expect(mvpFixtures).not.toContain(solverId); + } + }); + it("requests Phase 2 extension quotes from every configured solver when none is preferred", async () => { const calls: CryptoNativeExecutionSolverId[] = []; const providers = [