From 0fd3a4d1671140982a5f313b553a87431fb9e4cb Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Mon, 18 May 2026 19:33:12 +1200 Subject: [PATCH 01/18] Vibe code x402 client and server, example client and server --- .../src/experimental/index.ts | 13 + .../src/experimental/x402Client.ts | 127 +++ .../src/experimental/x402Server.ts | 57 ++ .../test/experimental/x402Client.test.ts | 118 +++ .../test/experimental/x402Server.test.ts | 64 ++ packages/x402-example/README.md | 41 + packages/x402-example/package.json | 25 + packages/x402-example/src/client.ts | 139 +++ packages/x402-example/src/express.d.ts | 1 + packages/x402-example/src/server.ts | 92 ++ packages/x402-example/src/x402-fetch.d.ts | 8 + packages/x402-example/tsconfig.json | 13 + yarn.lock | 842 +++++++++++++++++- 13 files changed, 1515 insertions(+), 25 deletions(-) create mode 100644 packages/smart-accounts-kit/src/experimental/x402Client.ts create mode 100644 packages/smart-accounts-kit/src/experimental/x402Server.ts create mode 100644 packages/smart-accounts-kit/test/experimental/x402Client.test.ts create mode 100644 packages/smart-accounts-kit/test/experimental/x402Server.test.ts create mode 100644 packages/x402-example/README.md create mode 100644 packages/x402-example/package.json create mode 100644 packages/x402-example/src/client.ts create mode 100644 packages/x402-example/src/express.d.ts create mode 100644 packages/x402-example/src/server.ts create mode 100644 packages/x402-example/src/x402-fetch.d.ts create mode 100644 packages/x402-example/tsconfig.json diff --git a/packages/smart-accounts-kit/src/experimental/index.ts b/packages/smart-accounts-kit/src/experimental/index.ts index 83ca0171..c4da56ff 100644 --- a/packages/smart-accounts-kit/src/experimental/index.ts +++ b/packages/smart-accounts-kit/src/experimental/index.ts @@ -5,3 +5,16 @@ export { type Environment, type DelegationStorageConfig, } from './delegationStorage'; +export { + x402Erc7710Client, + type x402DelegationProvider, + type x402DelegationPaymentPayload, + type x402PaymentRequirements, + type x402PaymentPayloadResult, + type x402SchemeNetworkClientLike, + type x402Erc7710ClientConfig, +} from './x402Client'; +export { + X402Erc7710Server, + type X402Erc7710ServerConfig, +} from './x402Server'; diff --git a/packages/smart-accounts-kit/src/experimental/x402Client.ts b/packages/smart-accounts-kit/src/experimental/x402Client.ts new file mode 100644 index 00000000..95437052 --- /dev/null +++ b/packages/smart-accounts-kit/src/experimental/x402Client.ts @@ -0,0 +1,127 @@ +import { type Hex, getAddress, isHex } from 'viem'; + +import { trackSmartAccountsKitFunctionCall } from '../analytics'; +import { encodeDelegations } from '../delegation'; +import type { PermissionContext } from '../types'; + +export type x402PaymentRequirements = { + scheme: string; + network: string; + asset: string; + amount: string; + payTo: string; + maxTimeoutSeconds: number; + extra?: Record; +}; + +export type x402PaymentPayloadResult = { + x402Version: number; + payload: Record; + extensions?: Record; +}; + +export type x402DelegationPaymentPayload = { + delegationManager: Hex; + permissionContext: PermissionContext; + delegator: Hex; +}; + +export type x402DelegationProvider = ( + paymentRequirements: x402PaymentRequirements, +) => Promise; + +export type x402SchemeNetworkClientLike = { + readonly scheme: string; + createPaymentPayload: ( + x402Version: number, + paymentRequirements: x402PaymentRequirements, + context?: Record, + ) => Promise; +}; + +export type x402Erc7710ClientConfig = { + delegationProvider: x402DelegationProvider; + fallbackClient?: x402SchemeNetworkClientLike; +}; + +function normalizeDelegationPayload( + payload: x402DelegationPaymentPayload, +): x402DelegationPaymentPayload { + const permissionContext = encodeDelegations(payload.permissionContext); + + if (!isHex(permissionContext) || permissionContext === '0x') { + throw new Error( + 'Invalid delegation payload: permissionContext must be non-empty hex data', + ); + } + + return { + delegationManager: getAddress(payload.delegationManager), + permissionContext, + delegator: getAddress(payload.delegator), + }; +} + +/** + * x402 `SchemeNetworkClient`-compatible implementation for ERC-7710 payments. + * + * This class uses structural typing and intentionally does not import x402 types, + * so it can be consumed without adding a direct dependency on x402 packages. + */ +export class x402Erc7710Client { + readonly scheme = 'exact'; + + readonly #delegationProvider: x402DelegationProvider; + + readonly #fallbackClient?: x402SchemeNetworkClientLike; + + constructor(config: x402Erc7710ClientConfig) { + this.#delegationProvider = config.delegationProvider; + this.#fallbackClient = config.fallbackClient; + } + + async createPaymentPayload( + x402Version: number, + paymentRequirements: x402PaymentRequirements, + context?: Record, + ): Promise { + const assetTransferMethod = paymentRequirements.extra?.assetTransferMethod; + + trackSmartAccountsKitFunctionCall( + 'experimental.x402Erc7710Client.createPaymentPayload', + { + x402Version, + network: paymentRequirements.network, + assetTransferMethod: + typeof assetTransferMethod === 'string' + ? assetTransferMethod + : 'undefined', + }, + ); + + if (assetTransferMethod !== 'erc7710') { + if (this.#fallbackClient) { + return this.#fallbackClient.createPaymentPayload( + x402Version, + paymentRequirements, + context, + ); + } + + throw new Error( + `x402Erc7710Client can only process assetTransferMethod "erc7710". Received: ${ + typeof assetTransferMethod === 'string' + ? `"${assetTransferMethod}"` + : 'undefined' + }`, + ); + } + + const delegation = await this.#delegationProvider(paymentRequirements); + + return { + x402Version, + payload: normalizeDelegationPayload(delegation), + }; + } +} diff --git a/packages/smart-accounts-kit/src/experimental/x402Server.ts b/packages/smart-accounts-kit/src/experimental/x402Server.ts new file mode 100644 index 00000000..ca90f207 --- /dev/null +++ b/packages/smart-accounts-kit/src/experimental/x402Server.ts @@ -0,0 +1,57 @@ +import { trackSmartAccountsKitFunctionCall } from '../analytics'; +import type { x402PaymentRequirements } from './x402Client'; + +export type X402Erc7710ServerConfig = { + allowAssetTransferMethodOverride?: boolean; +}; + +/** + * x402 `SchemeNetworkServer`-compatible implementation for publishing + * `assetTransferMethod: "erc7710"` in payment requirements. + * + * This class uses structural typing and intentionally does not import x402 types, + * so it can be consumed without adding a direct dependency on x402 packages. + */ +export class X402Erc7710Server { + readonly scheme = 'exact'; + + readonly #allowAssetTransferMethodOverride: boolean; + + constructor(config?: X402Erc7710ServerConfig) { + this.#allowAssetTransferMethodOverride = + config?.allowAssetTransferMethodOverride ?? false; + } + + async enhancePaymentRequirements( + paymentRequirements: x402PaymentRequirements, + ): Promise { + const existingMethod = paymentRequirements.extra?.assetTransferMethod; + + trackSmartAccountsKitFunctionCall( + 'experimental.X402Erc7710Server.enhancePaymentRequirements', + { + network: paymentRequirements.network, + existingAssetTransferMethod: + typeof existingMethod === 'string' ? existingMethod : 'undefined', + }, + ); + + if ( + typeof existingMethod === 'string' && + existingMethod !== 'erc7710' && + !this.#allowAssetTransferMethodOverride + ) { + throw new Error( + `Cannot overwrite existing assetTransferMethod "${existingMethod}" with "erc7710"`, + ); + } + + return { + ...paymentRequirements, + extra: { + ...(paymentRequirements.extra ?? {}), + assetTransferMethod: 'erc7710', + }, + }; + } +} diff --git a/packages/smart-accounts-kit/test/experimental/x402Client.test.ts b/packages/smart-accounts-kit/test/experimental/x402Client.test.ts new file mode 100644 index 00000000..cfb6af44 --- /dev/null +++ b/packages/smart-accounts-kit/test/experimental/x402Client.test.ts @@ -0,0 +1,118 @@ +import { stub } from 'sinon'; +import { beforeEach, describe, expect, it } from 'vitest'; +import { zeroAddress } from 'viem'; + +import { X402Erc7710Client } from '../../src/experimental/x402Client'; + +describe('X402Erc7710Client', () => { + const paymentRequirements = { + scheme: 'exact', + network: 'eip155:1', + asset: zeroAddress, + amount: '1000', + payTo: zeroAddress, + maxTimeoutSeconds: 60, + extra: { + assetTransferMethod: 'erc7710', + }, + }; + + const delegationProvider = stub(); + + beforeEach(() => { + delegationProvider.reset(); + }); + + it('creates an ERC-7710 payload when assetTransferMethod is erc7710', async () => { + delegationProvider.resolves({ + delegationManager: zeroAddress, + permissionContext: '0x1234', + delegator: zeroAddress, + }); + + const client = new X402Erc7710Client({ delegationProvider }); + + const result = await client.createPaymentPayload(2, paymentRequirements); + + expect(result).toStrictEqual({ + x402Version: 2, + payload: { + delegationManager: zeroAddress, + permissionContext: '0x1234', + delegator: zeroAddress, + }, + }); + expect(delegationProvider.calledOnceWithExactly(paymentRequirements)).toBe( + true, + ); + }); + + it('throws when transfer method is not erc7710 and no fallback is configured', async () => { + const client = new X402Erc7710Client({ delegationProvider }); + + await expect( + client.createPaymentPayload(2, { + ...paymentRequirements, + extra: { assetTransferMethod: 'permit2' }, + }), + ).rejects.toThrow( + 'X402Erc7710Client can only process assetTransferMethod "erc7710"', + ); + expect(delegationProvider.notCalled).toBe(true); + }); + + it('delegates to fallback client for non-erc7710 payment requirements', async () => { + const fallbackClient = { + scheme: 'exact', + createPaymentPayload: stub().resolves({ + x402Version: 2, + payload: { signature: '0xabc' }, + }), + }; + + const client = new X402Erc7710Client({ + delegationProvider, + fallbackClient, + }); + + const non7710Requirements = { + ...paymentRequirements, + extra: { assetTransferMethod: 'permit2' }, + }; + + const result = await client.createPaymentPayload( + 2, + non7710Requirements, + { extensions: {} }, + ); + + expect(result).toStrictEqual({ + x402Version: 2, + payload: { signature: '0xabc' }, + }); + expect( + fallbackClient.createPaymentPayload.calledOnceWithExactly( + 2, + non7710Requirements, + { extensions: {} }, + ), + ).toBe(true); + expect(delegationProvider.notCalled).toBe(true); + }); + + it('throws when delegation provider returns empty permissionContext', async () => { + delegationProvider.resolves({ + delegationManager: zeroAddress, + permissionContext: '0x', + delegator: zeroAddress, + }); + + const client = new X402Erc7710Client({ delegationProvider }); + + await expect( + client.createPaymentPayload(2, paymentRequirements), + ).rejects.toThrow( + 'Invalid delegation payload: permissionContext must be non-empty hex data', + ); + }); +}); diff --git a/packages/smart-accounts-kit/test/experimental/x402Server.test.ts b/packages/smart-accounts-kit/test/experimental/x402Server.test.ts new file mode 100644 index 00000000..b14b5a26 --- /dev/null +++ b/packages/smart-accounts-kit/test/experimental/x402Server.test.ts @@ -0,0 +1,64 @@ +import { describe, expect, it } from 'vitest'; +import { zeroAddress } from 'viem'; + +import { X402Erc7710Server } from '../../src/experimental/x402Server'; + +describe('X402Erc7710Server', () => { + const paymentRequirements = { + scheme: 'exact', + network: 'eip155:8453', + asset: zeroAddress, + amount: '10000', + payTo: zeroAddress, + maxTimeoutSeconds: 300, + extra: { + foo: 'bar', + }, + }; + + it('adds erc7710 assetTransferMethod to payment requirements', async () => { + const server = new X402Erc7710Server(); + + const result = await server.enhancePaymentRequirements(paymentRequirements); + + expect(result).toStrictEqual({ + ...paymentRequirements, + extra: { + foo: 'bar', + assetTransferMethod: 'erc7710', + }, + }); + }); + + it('throws when an incompatible assetTransferMethod already exists', async () => { + const server = new X402Erc7710Server(); + + await expect( + server.enhancePaymentRequirements({ + ...paymentRequirements, + extra: { + assetTransferMethod: 'permit2', + }, + }), + ).rejects.toThrow( + 'Cannot overwrite existing assetTransferMethod "permit2" with "erc7710"', + ); + }); + + it('allows overriding existing assetTransferMethod when configured', async () => { + const server = new X402Erc7710Server({ + allowAssetTransferMethodOverride: true, + }); + + const result = await server.enhancePaymentRequirements({ + ...paymentRequirements, + extra: { + assetTransferMethod: 'permit2', + }, + }); + + expect(result.extra).toStrictEqual({ + assetTransferMethod: 'erc7710', + }); + }); +}); diff --git a/packages/x402-example/README.md b/packages/x402-example/README.md new file mode 100644 index 00000000..c00a2c99 --- /dev/null +++ b/packages/x402-example/README.md @@ -0,0 +1,41 @@ +# x402 example + +Minimal x402 server example that publishes ERC-7710 payment requirements using: + +- x402 Foundation SDK (`@x402/core`, `@x402/express`, `@x402/evm`) +- Smart Accounts Kit experimental helper (`X402Erc7710Server`) + +## Endpoint + +- `GET /random` returns `text/plain` with a random integer in `[1, 10]` +- The route is protected by x402 with the `exact` scheme +- Payment requirements are rewritten to `extra.assetTransferMethod = "erc7710"` + +## Environment variables + +- `FACILITATOR_URL` - x402 facilitator base URL +- `EVM_PAY_TO` - recipient address +- `NETWORK` - optional CAIP-2 network (default: `eip155:84532`) +- `PORT` - optional server port (default: `4021`) + +## Run + +```bash +yarn workspace @metamask/x402-example start:server +``` + +## Client CLI + +`src/client.ts` is a minimal x402 CLI payer: + +- accepts a private key (`--private-key 0x...` or `PRIVATE_KEY`) +- requests the protected resource +- creates an exact ERC-7710 delegation with Smart Accounts Kit +- builds the x402 payment payload via experimental `X402Erc7710Client` +- retries the request with `PAYMENT-SIGNATURE` + +Run: + +```bash +yarn workspace @metamask/x402-example start:client --private-key 0x... +``` diff --git a/packages/x402-example/package.json b/packages/x402-example/package.json new file mode 100644 index 00000000..1f2982be --- /dev/null +++ b/packages/x402-example/package.json @@ -0,0 +1,25 @@ +{ + "name": "@metamask/x402-example", + "private": true, + "type": "module", + "packageManager": "yarn@4.14.1", + "scripts": { + "start:server": "tsx src/server.ts", + "dev:server": "tsx watch src/server.ts", + "start:client": "tsx src/client.ts" + }, + "dependencies": { + "@metamask/smart-accounts-kit": "workspace:^", + "@x402/core": "^2.12.0", + "@x402/evm": "^2.12.0", + "@x402/express": "^2.12.0", + "@x402/fetch": "^2.12.0", + "dotenv": "^17.4.2", + "express": "^5.2.1", + "viem": "^2.31.4" + }, + "devDependencies": { + "@types/express": "^5.0.5", + "tsx": "^4.20.5" + } +} diff --git a/packages/x402-example/src/client.ts b/packages/x402-example/src/client.ts new file mode 100644 index 00000000..b70c5dfa --- /dev/null +++ b/packages/x402-example/src/client.ts @@ -0,0 +1,139 @@ +import { config } from 'dotenv'; +import { x402Client, x402HTTPClient } from '@x402/core/client'; +import { wrapFetchWithPayment } from '@x402/fetch'; +import { + CaveatType, + createOpenDelegation, + getSmartAccountsEnvironment, + ScopeType, + signDelegation, + type Delegation, +} from '@metamask/smart-accounts-kit'; +import { x402Erc7710Client } from '@metamask/smart-accounts-kit/experimental'; +import { + getAddress, + type Hex, +} from 'viem'; +import { privateKeyToAccount } from 'viem/accounts'; +import { randomBytes } from 'node:crypto'; + +config(); + +type CliConfig = { + privateKey: Hex; + url: string; +}; + +function parseCliConfig(): CliConfig { + const args = process.argv.slice(2); + const keyArgIndex = args.findIndex((arg) => arg === '--private-key'); + const urlArgIndex = args.findIndex((arg) => arg === '--url'); + + const privateKeyFromArg = + keyArgIndex >= 0 ? (args[keyArgIndex + 1] as Hex | undefined) : undefined; + const privateKey = (privateKeyFromArg ?? + (process.env.PRIVATE_KEY as Hex | undefined)) as Hex | undefined; + + if (!privateKey || !privateKey.startsWith('0x')) { + throw new Error( + 'Missing private key. Pass --private-key 0x... or set PRIVATE_KEY', + ); + } + + const urlFromArg = urlArgIndex >= 0 ? args[urlArgIndex + 1] : undefined; + const url = urlFromArg ?? process.env.X402_URL ?? 'http://localhost:4021/random'; + + return { privateKey, url }; +} + +function parseChainIdFromNetwork(network: string): number { + const [namespace, reference] = network.split(':'); + if (namespace !== 'eip155' || !reference) { + throw new Error( + `Unsupported network "${network}". Expected CAIP-2 eip155:`, + ); + } + + const chainId = Number(reference); + if (!Number.isInteger(chainId) || chainId <= 0) { + throw new Error(`Invalid chain id in network "${network}"`); + } + return chainId; +} + + +async function main() { + const { privateKey, url } = parseCliConfig(); + const account = privateKeyToAccount(privateKey); + + const erc7710Client = new x402Erc7710Client({ + delegationProvider: async (requirements) => { + const chainId = parseChainIdFromNetwork(requirements.network); + const environment = getSmartAccountsEnvironment(chainId); + + // expires in 1 minute + const expiry = Date.now() / 1000 + 60; + + const delegation = createOpenDelegation({ + environment, + from: account.address, + scope: { + type: ScopeType.Erc20TransferAmount, + tokenAddress: getAddress(requirements.asset), + maxAmount: BigInt(requirements.amount), + }, + salt: `0x${randomBytes(32).toString('hex')}`, + caveats: [ + { + type: CaveatType.Timestamp, + afterThreshold: 0, + beforeThreshold: expiry, + } + ] + }); + + + const signature = await signDelegation({ + privateKey, + delegation, + delegationManager: environment.DelegationManager, + chainId, + }); + + const signedDelegation: Delegation = { + ...delegation, + signature, + }; + + return { + delegationManager: environment.DelegationManager, + permissionContext: [signedDelegation], + delegator: account.address, + }; + }, + }); + + const httpClient = new x402HTTPClient(new x402Client().register( + 'eip155:*', + erc7710Client + )); + + const fetchWithPayment = wrapFetchWithPayment(fetch, httpClient); + + const paidResponse = await fetchWithPayment(url, { method: 'GET' }); + + if (!paidResponse.ok) { + const bodyText = await paidResponse.text(); + throw new Error( + `Paid request failed with status ${paidResponse.status}: ${bodyText}`, + ); + } + + console.log(await paidResponse.text()); +} + +main().catch((error: unknown) => { + const message = error instanceof Error ? error.message : String(error); + console.error(`x402 client failed: ${message}`); + process.exit(1); +}); diff --git a/packages/x402-example/src/express.d.ts b/packages/x402-example/src/express.d.ts new file mode 100644 index 00000000..5df44d9e --- /dev/null +++ b/packages/x402-example/src/express.d.ts @@ -0,0 +1 @@ +declare module 'express'; diff --git a/packages/x402-example/src/server.ts b/packages/x402-example/src/server.ts new file mode 100644 index 00000000..d67f82f0 --- /dev/null +++ b/packages/x402-example/src/server.ts @@ -0,0 +1,92 @@ +import { config } from 'dotenv'; +import express from 'express'; +import { HTTPFacilitatorClient } from '@x402/core/server'; +import { paymentMiddleware, x402ResourceServer } from '@x402/express'; +import { + type Network, + type PaymentRequirements, +} from '@x402/core/types'; +import { ExactEvmScheme } from '@x402/evm/exact/server'; +import { X402Erc7710Server } from '@metamask/smart-accounts-kit/experimental'; +import type { Hex } from 'viem'; + +config(); + +const facilitatorUrl = process.env.FACILITATOR_URL; +if (!facilitatorUrl) { + throw new Error('Missing FACILITATOR_URL environment variable'); +} + +const payTo = process.env.EVM_PAY_TO as Hex | undefined; +if (!payTo) { + throw new Error('Missing EVM_PAY_TO environment variable'); +} + +const network = (process.env.NETWORK ?? 'eip155:84532') as Network; +const port = Number(process.env.PORT ?? 4021); +const acceptedToken = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' as const; + +class ExactEvmErc7710ServerScheme extends ExactEvmScheme { + readonly #erc7710Server = new X402Erc7710Server(); + + async enhancePaymentRequirements( + paymentRequirements: PaymentRequirements, + supportedKind: { + x402Version: number; + scheme: string; + network: Network; + extra?: Record; + }, + facilitatorExtensions: string[], + ): Promise { + const baseRequirements = await super.enhancePaymentRequirements( + paymentRequirements, + supportedKind, + facilitatorExtensions, + ); + + const enhancedRequirements = (await this.#erc7710Server.enhancePaymentRequirements( + baseRequirements, + )) as PaymentRequirements; + + return enhancedRequirements; + } +} + +const facilitatorClient = new HTTPFacilitatorClient({ url: facilitatorUrl }); +const app = express(); + +app.use( + paymentMiddleware( + { + 'GET /random': { + accepts: { + scheme: 'exact', + network, + payTo, + price: { + amount: '1000', + asset: acceptedToken, + }, + }, + description: 'Random integer from 1 to 10', + mimeType: 'text/plain', + }, + }, + new x402ResourceServer(facilitatorClient).register( + network, + new ExactEvmErc7710ServerScheme(), + ), + ), +); + +app.get('/random', (_req: unknown, res: { type: (value: string) => { send: (value: string) => void } }) => { + const value = Math.floor(Math.random() * 10) + 1; + res.type('text/plain').send(String(value)); +}); + +app.listen(port, () => { + console.log( + `x402 ERC-7710 example server listening on http://localhost:${port}/random`, + ); +}); diff --git a/packages/x402-example/src/x402-fetch.d.ts b/packages/x402-example/src/x402-fetch.d.ts new file mode 100644 index 00000000..043f8d2d --- /dev/null +++ b/packages/x402-example/src/x402-fetch.d.ts @@ -0,0 +1,8 @@ +import type { x402Client, x402HTTPClient } from '@x402/core/client'; + +declare module '@x402/fetch' { + export function wrapFetchWithPayment( + fetchImpl: typeof globalThis.fetch, + client: x402Client | x402HTTPClient, + ): typeof globalThis.fetch; +} diff --git a/packages/x402-example/tsconfig.json b/packages/x402-example/tsconfig.json new file mode 100644 index 00000000..9e5ed37f --- /dev/null +++ b/packages/x402-example/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../shared/config/base.tsconfig.json", + "exclude": ["./node_modules/**/*", "./dist/**/*"], + "compilerOptions": { + "baseUrl": ".", + "outDir": "dist", + "paths": { + "@metamask/smart-accounts-kit/experimental": [ + "../smart-accounts-kit/src/experimental/index.ts" + ] + } + } +} diff --git a/yarn.lock b/yarn.lock index 0cb7bfef..4b92941e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -770,7 +770,7 @@ __metadata: languageName: node linkType: hard -"@metamask/smart-accounts-kit@workspace:*, @metamask/smart-accounts-kit@workspace:packages/smart-accounts-kit": +"@metamask/smart-accounts-kit@workspace:*, @metamask/smart-accounts-kit@workspace:^, @metamask/smart-accounts-kit@workspace:packages/smart-accounts-kit": version: 0.0.0-use.local resolution: "@metamask/smart-accounts-kit@workspace:packages/smart-accounts-kit" dependencies: @@ -857,6 +857,23 @@ __metadata: languageName: node linkType: hard +"@metamask/x402-example@workspace:packages/x402-example": + version: 0.0.0-use.local + resolution: "@metamask/x402-example@workspace:packages/x402-example" + dependencies: + "@metamask/smart-accounts-kit": "workspace:^" + "@types/express": "npm:^5.0.5" + "@x402/core": "npm:^2.12.0" + "@x402/evm": "npm:^2.12.0" + "@x402/express": "npm:^2.12.0" + "@x402/fetch": "npm:^2.12.0" + dotenv: "npm:^17.4.2" + express: "npm:^5.2.1" + tsx: "npm:^4.20.5" + viem: "npm:^2.31.4" + languageName: unknown + linkType: soft + "@mswjs/interceptors@npm:^0.41.0": version: 0.41.3 resolution: "@mswjs/interceptors@npm:0.41.3" @@ -898,6 +915,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:1.9.1": + version: 1.9.1 + resolution: "@noble/curves@npm:1.9.1" + dependencies: + "@noble/hashes": "npm:1.8.0" + checksum: 10/5c82ec828ca4a4218b1666ba0ddffde17afd224d0bd5e07b64c2a0c83a3362483387f55c11cfd8db0fc046605394fe4e2c67fe024628a713e864acb541a7d2bb + languageName: node + linkType: hard + "@noble/curves@npm:1.9.2": version: 1.9.2 resolution: "@noble/curves@npm:1.9.2" @@ -907,7 +933,7 @@ __metadata: languageName: node linkType: hard -"@noble/curves@npm:^1.9.1, @noble/curves@npm:~1.9.0": +"@noble/curves@npm:^1.9.0, @noble/curves@npm:^1.9.1, @noble/curves@npm:~1.9.0": version: 1.9.7 resolution: "@noble/curves@npm:1.9.7" dependencies: @@ -923,7 +949,7 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:1.8.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.8.0, @noble/hashes@npm:~1.8.0": +"@noble/hashes@npm:1.8.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.7.0, @noble/hashes@npm:^1.8.0, @noble/hashes@npm:~1.8.0": version: 1.8.0 resolution: "@noble/hashes@npm:1.8.0" checksum: 10/474b7f56bc6fb2d5b3a42132561e221b0ea4f91e590f4655312ca13667840896b34195e2b53b7f097ec080a1fdd3b58d902c2a8d0fbdf51d2e238b53808a177e @@ -1386,7 +1412,7 @@ __metadata: languageName: node linkType: hard -"@scure/base@npm:^1.1.3, @scure/base@npm:~1.2.5": +"@scure/base@npm:^1.1.3, @scure/base@npm:^1.2.6, @scure/base@npm:~1.2.5": version: 1.2.6 resolution: "@scure/base@npm:1.2.6" checksum: 10/c1a7bd5e0b0c8f94c36fbc220f4a67cc832b00e2d2065c7d8a404ed81ab1c94c5443def6d361a70fc382db3496e9487fb9941728f0584782b274c18a4bed4187 @@ -1442,6 +1468,33 @@ __metadata: languageName: node linkType: hard +"@signinwithethereum/siwe-parser@npm:^4.2.0": + version: 4.2.0 + resolution: "@signinwithethereum/siwe-parser@npm:4.2.0" + dependencies: + "@noble/hashes": "npm:^1.7.0" + apg-js: "npm:^4.4.0" + checksum: 10/641e7b0424723a0138dcbe50a94d5c48b3cf144dc668a6c134d8e3ed5271792f87c5920c8d042af6cd7fa4d84e0a2add68f2c7e1eae03391752a145fadd9c403 + languageName: node + linkType: hard + +"@signinwithethereum/siwe@npm:^4.1.0": + version: 4.2.0 + resolution: "@signinwithethereum/siwe@npm:4.2.0" + dependencies: + "@signinwithethereum/siwe-parser": "npm:^4.2.0" + peerDependencies: + ethers: ^5.7.0 || ^6.13.0 + viem: ^2.7.0 + peerDependenciesMeta: + ethers: + optional: true + viem: + optional: true + checksum: 10/26c9faca9c6f482fecf0a845a749b700b849691247f23afaf5dc701e61b3669dc0ff3ba297f12f3d548181e86412c6bdd876af3e316ac2f7400087ce7048c29f + languageName: node + linkType: hard + "@sinonjs/commons@npm:^3.0.0, @sinonjs/commons@npm:^3.0.1": version: 3.0.1 resolution: "@sinonjs/commons@npm:3.0.1" @@ -1524,6 +1577,16 @@ __metadata: languageName: node linkType: hard +"@types/body-parser@npm:*": + version: 1.19.6 + resolution: "@types/body-parser@npm:1.19.6" + dependencies: + "@types/connect": "npm:*" + "@types/node": "npm:*" + checksum: 10/33041e88eae00af2cfa0827e951e5f1751eafab2a8b6fce06cd89ef368a988907996436b1325180edaeddd1c0c7d0d0d4c20a6c9ff294a91e0039a9db9e9b658 + languageName: node + linkType: hard + "@types/chai@npm:^5.2.2": version: 5.2.2 resolution: "@types/chai@npm:5.2.2" @@ -1533,6 +1596,15 @@ __metadata: languageName: node linkType: hard +"@types/connect@npm:*": + version: 3.4.38 + resolution: "@types/connect@npm:3.4.38" + dependencies: + "@types/node": "npm:*" + checksum: 10/7eb1bc5342a9604facd57598a6c62621e244822442976c443efb84ff745246b10d06e8b309b6e80130026a396f19bf6793b7cecd7380169f369dac3bfc46fb99 + languageName: node + linkType: hard + "@types/debug@npm:^4.1.7": version: 4.1.12 resolution: "@types/debug@npm:4.1.12" @@ -1556,6 +1628,36 @@ __metadata: languageName: node linkType: hard +"@types/express-serve-static-core@npm:^5.0.0": + version: 5.1.1 + resolution: "@types/express-serve-static-core@npm:5.1.1" + dependencies: + "@types/node": "npm:*" + "@types/qs": "npm:*" + "@types/range-parser": "npm:*" + "@types/send": "npm:*" + checksum: 10/7f3d8cf7e68764c9f3e8f6a12825b69ccf5287347fc1c20b29803d4f08a4abc1153ae11d7258852c61aad50f62ef72d4c1b9c97092b0a90462c3dddec2f6026c + languageName: node + linkType: hard + +"@types/express@npm:^5.0.5": + version: 5.0.6 + resolution: "@types/express@npm:5.0.6" + dependencies: + "@types/body-parser": "npm:*" + "@types/express-serve-static-core": "npm:^5.0.0" + "@types/serve-static": "npm:^2" + checksum: 10/da2cc3de1b1a4d7f20ed3fb6f0a8ee08e99feb3c2eb5a8d643db77017d8d0e70fee9e95da38a73f51bcdf5eda3bb6435073c0271dc04fb16fda92e55daf911fa + languageName: node + linkType: hard + +"@types/http-errors@npm:*": + version: 2.0.5 + resolution: "@types/http-errors@npm:2.0.5" + checksum: 10/a88da669366bc483e8f3b3eb3d34ada5f8d13eeeef851b1204d77e2ba6fc42aba4566d877cca5c095204a3f4349b87fe397e3e21288837bdd945dd514120755b + languageName: node + linkType: hard + "@types/json-schema@npm:^7.0.15": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" @@ -1604,6 +1706,20 @@ __metadata: languageName: node linkType: hard +"@types/qs@npm:*": + version: 6.15.1 + resolution: "@types/qs@npm:6.15.1" + checksum: 10/fd04a36c683dbb1ec5819c01773905259955bfd84d7294af178ad609990a9b8d75d458629ca3bf97b151fe2934eb12ade7fdeb98f2e3ad40d138f0a7d195ac7c + languageName: node + linkType: hard + +"@types/range-parser@npm:*": + version: 1.2.7 + resolution: "@types/range-parser@npm:1.2.7" + checksum: 10/95640233b689dfbd85b8c6ee268812a732cf36d5affead89e806fe30da9a430767af8ef2cd661024fd97e19d61f3dec75af2df5e80ec3bea000019ab7028629a + languageName: node + linkType: hard + "@types/semver@npm:^7.3.6": version: 7.7.0 resolution: "@types/semver@npm:7.7.0" @@ -1611,6 +1727,25 @@ __metadata: languageName: node linkType: hard +"@types/send@npm:*": + version: 1.2.1 + resolution: "@types/send@npm:1.2.1" + dependencies: + "@types/node": "npm:*" + checksum: 10/81ef5790037ba1d2d458392e4241501f0f8b4838cc8797e169e179e099410e12069ec68e8dbd39211cb097c4a9b1ff1682dbcea897ab4ce21dad93438b862d27 + languageName: node + linkType: hard + +"@types/serve-static@npm:^2": + version: 2.2.0 + resolution: "@types/serve-static@npm:2.2.0" + dependencies: + "@types/http-errors": "npm:*" + "@types/node": "npm:*" + checksum: 10/f2bad1304c7d0d3b7221faff3e490c40129d3803f4fb1b2fb84f31f561071c5e6a4b876c41bbbe82d5645034eea936e946bcaaf993dac1093ce68b56effad6e0 + languageName: node + linkType: hard + "@types/sinon@npm:^17.0.3": version: 17.0.3 resolution: "@types/sinon@npm:17.0.3" @@ -2007,6 +2142,68 @@ __metadata: languageName: node linkType: hard +"@x402/core@npm:^2.12.0, @x402/core@npm:~2.12.0": + version: 2.12.0 + resolution: "@x402/core@npm:2.12.0" + dependencies: + zod: "npm:^3.24.2" + checksum: 10/d9ba28deb5462bac2f60d2764b3973ac0bd3e905100b06c293cedc900802c9e1557d7ef59b0515fa82d3534e1c20099737386906432f7e8768abe6e7200398ee + languageName: node + linkType: hard + +"@x402/evm@npm:^2.12.0": + version: 2.12.0 + resolution: "@x402/evm@npm:2.12.0" + dependencies: + "@x402/core": "npm:~2.12.0" + viem: "npm:^2.48.11" + zod: "npm:^3.24.2" + checksum: 10/8832647ac6f634a07093dd3df99338bffbd9694c8ae6e605e442ad9737155ca136d791e5259f5a7abf26ddc105c325f009b6862d991d9af60dab750d7f4d38c3 + languageName: node + linkType: hard + +"@x402/express@npm:^2.12.0": + version: 2.12.0 + resolution: "@x402/express@npm:2.12.0" + dependencies: + "@x402/core": "npm:~2.12.0" + "@x402/extensions": "npm:~2.12.0" + peerDependencies: + "@x402/paywall": ^2.12.0 + express: ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + "@x402/paywall": + optional: true + checksum: 10/73ccdfffb89fd7685f69dd11700fffba6ad7e716de2863027f08cdc5d2ad378769444199043a8a8ae8c0bd65c2719063ede2c9cdc436e103b04697bd5e0216da + languageName: node + linkType: hard + +"@x402/extensions@npm:~2.12.0": + version: 2.12.0 + resolution: "@x402/extensions@npm:2.12.0" + dependencies: + "@noble/curves": "npm:^1.9.0" + "@scure/base": "npm:^1.2.6" + "@signinwithethereum/siwe": "npm:^4.1.0" + "@x402/core": "npm:~2.12.0" + ajv: "npm:^8.17.1" + jose: "npm:^5.9.6" + tweetnacl: "npm:^1.0.3" + viem: "npm:^2.48.11" + zod: "npm:^3.24.2" + checksum: 10/4bf92b3de8547f861f282912ffd518ec974c4e9ba4bfc375b8930781dca62d72d1970f95545bc94c5aaaf3e3da132786c0486fbc6745e2cfb4756a48272ae6a1 + languageName: node + linkType: hard + +"@x402/fetch@npm:^2.12.0": + version: 2.12.0 + resolution: "@x402/fetch@npm:2.12.0" + dependencies: + "@x402/core": "npm:~2.12.0" + checksum: 10/7f30e6e88d8a6132766fb49db23b38a0b332850c11e7d87ee58edb0b91704e5ac0de20e7ec1b23daca05b6a59efb5354caae4c8d3b97554341a6679bcad179f2 + languageName: node + linkType: hard + "@yarnpkg/types@npm:^4.0.1": version: 4.0.1 resolution: "@yarnpkg/types@npm:4.0.1" @@ -2038,7 +2235,7 @@ __metadata: languageName: node linkType: hard -"abitype@npm:^1.0.2, abitype@npm:^1.0.8": +"abitype@npm:1.2.3, abitype@npm:^1.0.2, abitype@npm:^1.0.8": version: 1.2.3 resolution: "abitype@npm:1.2.3" peerDependencies: @@ -2053,6 +2250,31 @@ __metadata: languageName: node linkType: hard +"abitype@npm:^1.2.3": + version: 1.2.4 + resolution: "abitype@npm:1.2.4" + peerDependencies: + typescript: ">=5.0.4" + zod: ^3.22.0 || ^4.0.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + checksum: 10/500b317a53b34cb6ffe3e4f090e135972b43cd2fbdfebe64fc497dfd8515d9117919e5f88f0aaede332d29a21c1826be64a3ffa620b0b91c16e8b560b6635714 + languageName: node + linkType: hard + +"accepts@npm:^2.0.0": + version: 2.0.0 + resolution: "accepts@npm:2.0.0" + dependencies: + mime-types: "npm:^3.0.0" + negotiator: "npm:^1.0.0" + checksum: 10/ea1343992b40b2bfb3a3113fa9c3c2f918ba0f9197ae565c48d3f84d44b174f6b1d5cd9989decd7655963eb03a272abc36968cc439c2907f999bd5ef8653d5a7 + languageName: node + linkType: hard + "accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" @@ -2121,6 +2343,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:^8.17.1": + version: 8.20.0 + resolution: "ajv@npm:8.20.0" + dependencies: + fast-deep-equal: "npm:^3.1.3" + fast-uri: "npm:^3.0.1" + json-schema-traverse: "npm:^1.0.0" + require-from-string: "npm:^2.0.2" + checksum: 10/5ce59c0537f4c2aca9a758b412659ec70acb4d5dde971c10ecf21d2e3d799f99acdb4a08e1f5fb2e067c8542930398aae793bb996bb07d3feb81dae22fe2ada9 + languageName: node + linkType: hard + "ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" @@ -2168,6 +2402,13 @@ __metadata: languageName: node linkType: hard +"apg-js@npm:^4.4.0": + version: 4.4.0 + resolution: "apg-js@npm:4.4.0" + checksum: 10/425f19096026742f5f156f26542b68f55602aa60f0c4ae2d72a0a888cf15fe9622223191202262dd8979d76a6125de9d8fd164d56c95fb113f49099f405eb08c + languageName: node + linkType: hard + "are-docs-informative@npm:^0.0.2": version: 0.0.2 resolution: "are-docs-informative@npm:0.0.2" @@ -2214,6 +2455,20 @@ __metadata: languageName: node linkType: hard +"async-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-function@npm:1.0.0" + checksum: 10/1a09379937d846f0ce7614e75071c12826945d4e417db634156bf0e4673c495989302f52186dfa9767a1d9181794554717badd193ca2bbab046ef1da741d8efd + languageName: node + linkType: hard + +"async-generator-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-generator-function@npm:1.0.0" + checksum: 10/3d49e7acbeee9e84537f4cb0e0f91893df8eba976759875ae8ee9e3d3c82f6ecdebdb347c2fad9926b92596d93cdfc78ecc988bcdf407e40433e8e8e6fe5d78e + languageName: node + linkType: hard + "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" @@ -2267,6 +2522,23 @@ __metadata: languageName: node linkType: hard +"body-parser@npm:^2.2.1": + version: 2.2.2 + resolution: "body-parser@npm:2.2.2" + dependencies: + bytes: "npm:^3.1.2" + content-type: "npm:^1.0.5" + debug: "npm:^4.4.3" + http-errors: "npm:^2.0.0" + iconv-lite: "npm:^0.7.0" + on-finished: "npm:^2.4.1" + qs: "npm:^6.14.1" + raw-body: "npm:^3.0.1" + type-is: "npm:^2.0.1" + checksum: 10/69671f67d4d5ae5974593901a92d639757231da1725ed6de4d35e86cde9ce7650afdf1cd28df9b6f7892ea7f9eb03ccb30c70fe27d679275ae4cb4aae5ce1b21 + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": version: 1.1.12 resolution: "brace-expansion@npm:1.1.12" @@ -2315,7 +2587,7 @@ __metadata: languageName: node linkType: hard -"bytes@npm:3.1.2": +"bytes@npm:3.1.2, bytes@npm:^3.1.2, bytes@npm:~3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" checksum: 10/a10abf2ba70c784471d6b4f58778c0beeb2b5d405148e66affa91f23a9f13d07603d0a0354667310ae1d6dc141474ffd44e2a074be0f6e2254edb8fc21445388 @@ -2349,6 +2621,16 @@ __metadata: languageName: node linkType: hard +"call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind-apply-helpers@npm:1.0.2" + dependencies: + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + checksum: 10/00482c1f6aa7cfb30fb1dbeb13873edf81cfac7c29ed67a5957d60635a56b2a4a480f1016ddbdb3395cc37900d46037fb965043a51c5c789ffeab4fc535d18b5 + languageName: node + linkType: hard + "call-bind@npm:^1.0.7": version: 1.0.7 resolution: "call-bind@npm:1.0.7" @@ -2362,6 +2644,16 @@ __metadata: languageName: node linkType: hard +"call-bound@npm:^1.0.2": + version: 1.0.4 + resolution: "call-bound@npm:1.0.4" + dependencies: + call-bind-apply-helpers: "npm:^1.0.2" + get-intrinsic: "npm:^1.3.0" + checksum: 10/ef2b96e126ec0e58a7ff694db43f4d0d44f80e641370c21549ed911fecbdbc2df3ebc9bddad918d6bbdefeafb60bb3337902006d5176d72bcd2da74820991af7 + languageName: node + linkType: hard + "callsites@npm:^3.0.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" @@ -2526,13 +2818,27 @@ __metadata: languageName: node linkType: hard -"content-type@npm:~1.0.4, content-type@npm:~1.0.5": +"content-disposition@npm:^1.0.0": + version: 1.1.0 + resolution: "content-disposition@npm:1.1.0" + checksum: 10/c4f65e3c001a4a8eb87d0d24c0f112abb139836fb13b8ea67276715e7dce09570ef666ba7848ee8b660d467e6588d030c8ed7e8d0128db6ca78a0800dcd8c7a8 + languageName: node + linkType: hard + +"content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" checksum: 10/585847d98dc7fb8035c02ae2cb76c7a9bd7b25f84c447e5ed55c45c2175e83617c8813871b4ee22f368126af6b2b167df655829007b21aa10302873ea9c62662 languageName: node linkType: hard +"content-type@npm:^2.0.0": + version: 2.0.0 + resolution: "content-type@npm:2.0.0" + checksum: 10/0bbb276b790ba7e86c479c7d69fae1861b2e908ff3ce2cb01975b516f93eede2216d242902ed6c5b15cd554014611ce9dfdcf51cd35b16569e45a979e50d0cef + languageName: node + linkType: hard + "cookie-signature@npm:1.0.6": version: 1.0.6 resolution: "cookie-signature@npm:1.0.6" @@ -2540,6 +2846,13 @@ __metadata: languageName: node linkType: hard +"cookie-signature@npm:^1.2.1": + version: 1.2.2 + resolution: "cookie-signature@npm:1.2.2" + checksum: 10/be44a3c9a56f3771aea3a8bd8ad8f0a8e2679bcb967478267f41a510b4eb5ec55085386ba79c706c4ac21605ca76f4251973444b90283e0eb3eeafe8a92c7708 + languageName: node + linkType: hard + "cookie@npm:0.7.1": version: 0.7.1 resolution: "cookie@npm:0.7.1" @@ -2547,6 +2860,13 @@ __metadata: languageName: node linkType: hard +"cookie@npm:^0.7.1": + version: 0.7.2 + resolution: "cookie@npm:0.7.2" + checksum: 10/24b286c556420d4ba4e9bc09120c9d3db7d28ace2bd0f8ccee82422ce42322f73c8312441271e5eefafbead725980e5996cc02766dbb89a90ac7f5636ede608f + languageName: node + linkType: hard + "crc-32@npm:^1.2.0": version: 1.2.2 resolution: "crc-32@npm:1.2.2" @@ -2604,6 +2924,18 @@ __metadata: languageName: node linkType: hard +"debug@npm:^4.4.3": + version: 4.4.3 + resolution: "debug@npm:4.4.3" + dependencies: + ms: "npm:^2.1.3" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10/9ada3434ea2993800bd9a1e320bd4aa7af69659fb51cca685d390949434bc0a8873c21ed7c9b852af6f2455a55c6d050aa3937d52b3c69f796dab666f762acad + languageName: node + linkType: hard + "deep-eql@npm:^5.0.1": version: 5.0.2 resolution: "deep-eql@npm:5.0.2" @@ -2686,7 +3018,7 @@ __metadata: languageName: unknown linkType: soft -"depd@npm:2.0.0": +"depd@npm:2.0.0, depd@npm:^2.0.0, depd@npm:~2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" checksum: 10/c0c8ff36079ce5ada64f46cc9d6fd47ebcf38241105b6e0c98f412e8ad91f084bcf906ff644cc3a4bd876ca27a62accb8b0fff72ea6ed1a414b89d8506f4a5ca @@ -2735,6 +3067,24 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:^17.4.2": + version: 17.4.2 + resolution: "dotenv@npm:17.4.2" + checksum: 10/ca1b6f54d58e39914901e1518958e86083aca8deb5aa2e7f2a51acd53291d97852479b0ab26ed949b6a45a0e9adcc7b0d1c3c72375e8ea670f7005e341c6daba + languageName: node + linkType: hard + +"dunder-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "dunder-proto@npm:1.0.1" + dependencies: + call-bind-apply-helpers: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.2.0" + checksum: 10/5add88a3d68d42d6e6130a0cac450b7c2edbe73364bbd2fc334564418569bea97c6943a8fcd70e27130bf32afc236f30982fc4905039b703f23e9e0433c29934 + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -2763,6 +3113,13 @@ __metadata: languageName: node linkType: hard +"encodeurl@npm:^2.0.0, encodeurl@npm:~2.0.0": + version: 2.0.0 + resolution: "encodeurl@npm:2.0.0" + checksum: 10/abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe + languageName: node + linkType: hard + "encodeurl@npm:~1.0.2": version: 1.0.2 resolution: "encodeurl@npm:1.0.2" @@ -2770,13 +3127,6 @@ __metadata: languageName: node linkType: hard -"encodeurl@npm:~2.0.0": - version: 2.0.0 - resolution: "encodeurl@npm:2.0.0" - checksum: 10/abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe - languageName: node - linkType: hard - "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -2819,6 +3169,13 @@ __metadata: languageName: node linkType: hard +"es-define-property@npm:^1.0.1": + version: 1.0.1 + resolution: "es-define-property@npm:1.0.1" + checksum: 10/f8dc9e660d90919f11084db0a893128f3592b781ce967e4fccfb8f3106cb83e400a4032c559184ec52ee1dbd4b01e7776c7cd0b3327b1961b1a4a7008920fe78 + languageName: node + linkType: hard + "es-errors@npm:^1.3.0": version: 1.3.0 resolution: "es-errors@npm:1.3.0" @@ -2833,6 +3190,15 @@ __metadata: languageName: node linkType: hard +"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": + version: 1.1.1 + resolution: "es-object-atoms@npm:1.1.1" + dependencies: + es-errors: "npm:^1.3.0" + checksum: 10/54fe77de288451dae51c37bfbfe3ec86732dc3778f98f3eb3bdb4bf48063b2c0b8f9c93542656986149d08aa5be3204286e2276053d19582b76753f1a2728867 + languageName: node + linkType: hard + "esbuild@npm:^0.25.0, esbuild@npm:~0.25.0": version: 0.25.6 resolution: "esbuild@npm:0.25.6" @@ -2929,7 +3295,7 @@ __metadata: languageName: node linkType: hard -"escape-html@npm:~1.0.3": +"escape-html@npm:^1.0.3, escape-html@npm:~1.0.3": version: 1.0.3 resolution: "escape-html@npm:1.0.3" checksum: 10/6213ca9ae00d0ab8bccb6d8d4e0a98e76237b2410302cf7df70aaa6591d509a2a37ce8998008cbecae8fc8ffaadf3fb0229535e6a145f3ce0b211d060decbb24 @@ -3273,7 +3639,7 @@ __metadata: languageName: node linkType: hard -"etag@npm:~1.8.1": +"etag@npm:^1.8.1, etag@npm:~1.8.1": version: 1.8.1 resolution: "etag@npm:1.8.1" checksum: 10/571aeb3dbe0f2bbd4e4fadbdb44f325fc75335cd5f6f6b6a091e6a06a9f25ed5392f0863c5442acb0646787446e816f13cbfc6edce5b07658541dff573cab1ff @@ -3386,6 +3752,42 @@ __metadata: languageName: node linkType: hard +"express@npm:^5.2.1": + version: 5.2.1 + resolution: "express@npm:5.2.1" + dependencies: + accepts: "npm:^2.0.0" + body-parser: "npm:^2.2.1" + content-disposition: "npm:^1.0.0" + content-type: "npm:^1.0.5" + cookie: "npm:^0.7.1" + cookie-signature: "npm:^1.2.1" + debug: "npm:^4.4.0" + depd: "npm:^2.0.0" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + etag: "npm:^1.8.1" + finalhandler: "npm:^2.1.0" + fresh: "npm:^2.0.0" + http-errors: "npm:^2.0.0" + merge-descriptors: "npm:^2.0.0" + mime-types: "npm:^3.0.0" + on-finished: "npm:^2.4.1" + once: "npm:^1.4.0" + parseurl: "npm:^1.3.3" + proxy-addr: "npm:^2.0.7" + qs: "npm:^6.14.0" + range-parser: "npm:^1.2.1" + router: "npm:^2.2.0" + send: "npm:^1.1.0" + serve-static: "npm:^2.2.0" + statuses: "npm:^2.0.1" + type-is: "npm:^2.0.1" + vary: "npm:^1.1.2" + checksum: 10/4aa545d89702ac83f645c77abda1b57bcabe288f0b380fb5580fac4e323ea0eb533005c8e666b4e19152fb16d4abf11ba87b22aa9a10857a0485cd86b94639bd + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -3427,6 +3829,13 @@ __metadata: languageName: node linkType: hard +"fast-uri@npm:^3.0.1": + version: 3.1.2 + resolution: "fast-uri@npm:3.1.2" + checksum: 10/1dff04865b2a38d3e0659deadfbf72efdf83a776bfbf9667e4aa9e5a3ec31bc341cda9622136b32b7652a857c8ba11896794186e8f876f8b2b72731fce8622f6 + languageName: node + linkType: hard + "fastq@npm:^1.6.0": version: 1.17.1 resolution: "fastq@npm:1.17.1" @@ -3481,6 +3890,20 @@ __metadata: languageName: node linkType: hard +"finalhandler@npm:^2.1.0": + version: 2.1.1 + resolution: "finalhandler@npm:2.1.1" + dependencies: + debug: "npm:^4.4.0" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + on-finished: "npm:^2.4.1" + parseurl: "npm:^1.3.3" + statuses: "npm:^2.0.1" + checksum: 10/f4ba75c23408d8f9d393c3e875b9452e84d68c925411a6e67b7efa678b0bed5075ef33def4bb65ed8e0dd37c92a3ea354bcbde07303cd4dc2550e12b95885067 + languageName: node + linkType: hard + "find-up@npm:^5.0.0": version: 5.0.0 resolution: "find-up@npm:5.0.0" @@ -3543,6 +3966,13 @@ __metadata: languageName: node linkType: hard +"fresh@npm:^2.0.0": + version: 2.0.0 + resolution: "fresh@npm:2.0.0" + checksum: 10/44e1468488363074641991c1340d2a10c5a6f6d7c353d89fd161c49d120c58ebf9890720f7584f509058385836e3ce50ddb60e9f017315a4ba8c6c3461813bfc + languageName: node + linkType: hard + "fs-minipass@npm:^2.0.0": version: 2.1.0 resolution: "fs-minipass@npm:2.1.0" @@ -3594,6 +4024,13 @@ __metadata: languageName: node linkType: hard +"generator-function@npm:^2.0.0": + version: 2.0.1 + resolution: "generator-function@npm:2.0.1" + checksum: 10/eb7e7eb896c5433f3d40982b2ccacdb3dd990dd3499f14040e002b5d54572476513be8a2e6f9609f6e41ab29f2c4469307611ddbfc37ff4e46b765c326663805 + languageName: node + linkType: hard + "get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" @@ -3614,6 +4051,37 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.3.0": + version: 1.3.1 + resolution: "get-intrinsic@npm:1.3.1" + dependencies: + async-function: "npm:^1.0.0" + async-generator-function: "npm:^1.0.0" + call-bind-apply-helpers: "npm:^1.0.2" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.1" + function-bind: "npm:^1.1.2" + generator-function: "npm:^2.0.0" + get-proto: "npm:^1.0.1" + gopd: "npm:^1.2.0" + has-symbols: "npm:^1.1.0" + hasown: "npm:^2.0.2" + math-intrinsics: "npm:^1.1.0" + checksum: 10/bb579dda84caa4a3a41611bdd483dade7f00f246f2a7992eb143c5861155290df3fdb48a8406efa3dfb0b434e2c8fafa4eebd469e409d0439247f85fc3fa2cc1 + languageName: node + linkType: hard + +"get-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "get-proto@npm:1.0.1" + dependencies: + dunder-proto: "npm:^1.0.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10/4fc96afdb58ced9a67558698b91433e6b037aaa6f1493af77498d7c85b141382cf223c0e5946f334fb328ee85dfe6edd06d218eaf09556f4bc4ec6005d7f5f7b + languageName: node + linkType: hard + "get-stream@npm:^6.0.0": version: 6.0.1 resolution: "get-stream@npm:6.0.1" @@ -3715,6 +4183,13 @@ __metadata: languageName: node linkType: hard +"gopd@npm:^1.2.0": + version: 1.2.0 + resolution: "gopd@npm:1.2.0" + checksum: 10/94e296d69f92dc1c0768fcfeecfb3855582ab59a7c75e969d5f96ce50c3d201fd86d5a2857c22565764d5bb8a816c7b1e58f133ec318cd56274da36c5e3fb1a1 + languageName: node + linkType: hard + "graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" @@ -3759,6 +4234,13 @@ __metadata: languageName: node linkType: hard +"has-symbols@npm:^1.1.0": + version: 1.1.0 + resolution: "has-symbols@npm:1.1.0" + checksum: 10/959385c98696ebbca51e7534e0dc723ada325efa3475350951363cce216d27373e0259b63edb599f72eb94d6cde8577b4b2375f080b303947e560f85692834fa + languageName: node + linkType: hard + "hasown@npm:^2.0.0, hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" @@ -3804,6 +4286,19 @@ __metadata: languageName: node linkType: hard +"http-errors@npm:^2.0.0, http-errors@npm:^2.0.1, http-errors@npm:~2.0.1": + version: 2.0.1 + resolution: "http-errors@npm:2.0.1" + dependencies: + depd: "npm:~2.0.0" + inherits: "npm:~2.0.4" + setprototypeof: "npm:~1.2.0" + statuses: "npm:~2.0.2" + toidentifier: "npm:~1.0.1" + checksum: 10/9fe31bc0edf36566c87048aed1d3d0cbe03552564adc3541626a0613f542d753fbcb13bdfcec0a3a530dbe1714bb566c89d46244616b66bddd26ac413b06a207 + languageName: node + linkType: hard + "http-proxy-agent@npm:^7.0.0": version: 7.0.2 resolution: "http-proxy-agent@npm:7.0.2" @@ -3856,6 +4351,15 @@ __metadata: languageName: node linkType: hard +"iconv-lite@npm:^0.7.0, iconv-lite@npm:~0.7.0": + version: 0.7.2 + resolution: "iconv-lite@npm:0.7.2" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10/24c937b532f868e938386b62410b303b7c767ce3d08dc2829cbe59464d5a26ef86ae5ad1af6b34eec43ddfea39e7d101638644b0178d67262fa87015d59f983a + languageName: node + linkType: hard + "ignore-by-default@npm:^1.0.1": version: 1.0.1 resolution: "ignore-by-default@npm:1.0.1" @@ -3911,7 +4415,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.3": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.3, inherits@npm:~2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 10/cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 @@ -4033,6 +4537,13 @@ __metadata: languageName: node linkType: hard +"is-promise@npm:^4.0.0": + version: 4.0.0 + resolution: "is-promise@npm:4.0.0" + checksum: 10/0b46517ad47b00b6358fd6553c83ec1f6ba9acd7ffb3d30a0bf519c5c69e7147c132430452351b8a9fc198f8dd6c4f76f8e6f5a7f100f8c77d57d9e0f4261a8a + languageName: node + linkType: hard + "is-stream@npm:^2.0.0": version: 2.0.1 resolution: "is-stream@npm:2.0.1" @@ -4131,6 +4642,13 @@ __metadata: languageName: node linkType: hard +"jose@npm:^5.9.6": + version: 5.10.0 + resolution: "jose@npm:5.10.0" + checksum: 10/03881d1dfb390dcf50926402edcfe233bf557b5a77321fcb1bdb53453bc1cdd26d2d0a9ab28c7445cbb826881f84fdf5074179700f10c2711ccb9880f51065d7 + languageName: node + linkType: hard + "joycon@npm:^3.1.1": version: 3.1.1 resolution: "joycon@npm:3.1.1" @@ -4191,6 +4709,13 @@ __metadata: languageName: node linkType: hard +"json-schema-traverse@npm:^1.0.0": + version: 1.0.0 + resolution: "json-schema-traverse@npm:1.0.0" + checksum: 10/02f2f466cdb0362558b2f1fd5e15cce82ef55d60cd7f8fa828cf35ba74330f8d767fcae5c5c2adb7851fa811766c694b9405810879bc4e1ddd78a7c0e03658ad + languageName: node + linkType: hard + "json-stable-stringify-without-jsonify@npm:^1.0.1": version: 1.0.1 resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" @@ -4380,6 +4905,13 @@ __metadata: languageName: node linkType: hard +"math-intrinsics@npm:^1.1.0": + version: 1.1.0 + resolution: "math-intrinsics@npm:1.1.0" + checksum: 10/11df2eda46d092a6035479632e1ec865b8134bdfc4bd9e571a656f4191525404f13a283a515938c3a8de934dbfd9c09674d9da9fa831e6eb7e22b50b197d2edd + languageName: node + linkType: hard + "media-typer@npm:0.3.0": version: 0.3.0 resolution: "media-typer@npm:0.3.0" @@ -4387,6 +4919,13 @@ __metadata: languageName: node linkType: hard +"media-typer@npm:^1.1.0": + version: 1.1.0 + resolution: "media-typer@npm:1.1.0" + checksum: 10/a58dd60804df73c672942a7253ccc06815612326dc1c0827984b1a21704466d7cde351394f47649e56cf7415e6ee2e26e000e81b51b3eebb5a93540e8bf93cbd + languageName: node + linkType: hard + "merge-descriptors@npm:1.0.3": version: 1.0.3 resolution: "merge-descriptors@npm:1.0.3" @@ -4394,6 +4933,13 @@ __metadata: languageName: node linkType: hard +"merge-descriptors@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-descriptors@npm:2.0.0" + checksum: 10/e383332e700a94682d0125a36c8be761142a1320fc9feeb18e6e36647c9edf064271645f5669b2c21cf352116e561914fd8aa831b651f34db15ef4038c86696a + languageName: node + linkType: hard + "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -4439,6 +4985,22 @@ __metadata: languageName: node linkType: hard +"mime-db@npm:^1.54.0": + version: 1.54.0 + resolution: "mime-db@npm:1.54.0" + checksum: 10/9e7834be3d66ae7f10eaa69215732c6d389692b194f876198dca79b2b90cbf96688d9d5d05ef7987b20f749b769b11c01766564264ea5f919c88b32a29011311 + languageName: node + linkType: hard + +"mime-types@npm:^3.0.0, mime-types@npm:^3.0.2": + version: 3.0.2 + resolution: "mime-types@npm:3.0.2" + dependencies: + mime-db: "npm:^1.54.0" + checksum: 10/9db0ad31f5eff10ee8f848130779b7f2d056ddfdb6bda696cb69be68d486d33a3457b4f3f9bdeb60d0736edb471bd5a7c0a384375c011c51c889fd0d5c3b893e + languageName: node + linkType: hard + "mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" @@ -4667,6 +5229,13 @@ __metadata: languageName: node linkType: hard +"negotiator@npm:^1.0.0": + version: 1.0.0 + resolution: "negotiator@npm:1.0.0" + checksum: 10/b5734e87295324fabf868e36fb97c84b7d7f3156ec5f4ee5bf6e488079c11054f818290fc33804cef7b1ee21f55eeb14caea83e7dafae6492a409b3e573153e5 + languageName: node + linkType: hard + "nise@npm:^6.0.0": version: 6.1.1 resolution: "nise@npm:6.1.1" @@ -4872,7 +5441,14 @@ __metadata: languageName: node linkType: hard -"on-finished@npm:2.4.1": +"object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": + version: 1.13.4 + resolution: "object-inspect@npm:1.13.4" + checksum: 10/aa13b1190ad3e366f6c83ad8a16ed37a19ed57d267385aa4bfdccda833d7b90465c057ff6c55d035a6b2e52c1a2295582b294217a0a3a1ae7abdd6877ef781fb + languageName: node + linkType: hard + +"on-finished@npm:2.4.1, on-finished@npm:^2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" dependencies: @@ -4957,6 +5533,27 @@ __metadata: languageName: node linkType: hard +"ox@npm:0.14.20": + version: 0.14.20 + resolution: "ox@npm:0.14.20" + dependencies: + "@adraffy/ens-normalize": "npm:^1.11.0" + "@noble/ciphers": "npm:^1.3.0" + "@noble/curves": "npm:1.9.1" + "@noble/hashes": "npm:^1.8.0" + "@scure/bip32": "npm:^1.7.0" + "@scure/bip39": "npm:^1.6.0" + abitype: "npm:^1.2.3" + eventemitter3: "npm:5.0.1" + peerDependencies: + typescript: ">=5.4.0" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10/96526073193f3a6dd2ccd21bcc255e82c7226d6de63fa17a2021c75232fdc9bc969e75e2cbc0c8d5163d88c575e08dc4c75dec7333b1727f080585f07fc6c1ed + languageName: node + linkType: hard + "ox@npm:0.8.1": version: 0.8.1 resolution: "ox@npm:0.8.1" @@ -5037,7 +5634,7 @@ __metadata: languageName: node linkType: hard -"parseurl@npm:~1.3.3": +"parseurl@npm:^1.3.3, parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" checksum: 10/407cee8e0a3a4c5cd472559bca8b6a45b82c124e9a4703302326e9ab60fc1081442ada4e02628efef1eb16197ddc7f8822f5a91fd7d7c86b51f530aedb17dfa2 @@ -5096,6 +5693,13 @@ __metadata: languageName: node linkType: hard +"path-to-regexp@npm:^8.0.0": + version: 8.4.2 + resolution: "path-to-regexp@npm:8.4.2" + checksum: 10/70fd2cbce0b962cbcf4d312af07818bfce2bae11c09cf3bd86be99c0e30168238a1a7b02b18b452e73f075897df04597d30d63e56da7be41eecfc37998693389 + languageName: node + linkType: hard + "path-to-regexp@npm:^8.1.0": version: 8.2.0 resolution: "path-to-regexp@npm:8.2.0" @@ -5253,7 +5857,7 @@ __metadata: languageName: node linkType: hard -"proxy-addr@npm:~2.0.7": +"proxy-addr@npm:^2.0.7, proxy-addr@npm:~2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" dependencies: @@ -5286,6 +5890,15 @@ __metadata: languageName: node linkType: hard +"qs@npm:^6.14.0, qs@npm:^6.14.1": + version: 6.15.1 + resolution: "qs@npm:6.15.1" + dependencies: + side-channel: "npm:^1.1.0" + checksum: 10/ec10b9957446b3f4a38000940f6374720b4e2985209b89df197066038c951472ea24cd98d6bc6df73a0cbec75bc056f638032e3fb447345017ff7e0f0a2693ac + languageName: node + linkType: hard + "queue-microtask@npm:^1.2.2": version: 1.2.3 resolution: "queue-microtask@npm:1.2.3" @@ -5293,7 +5906,7 @@ __metadata: languageName: node linkType: hard -"range-parser@npm:~1.2.1": +"range-parser@npm:^1.2.1, range-parser@npm:~1.2.1": version: 1.2.1 resolution: "range-parser@npm:1.2.1" checksum: 10/ce21ef2a2dd40506893157970dc76e835c78cf56437e26e19189c48d5291e7279314477b06ac38abd6a401b661a6840f7b03bd0b1249da9b691deeaa15872c26 @@ -5312,6 +5925,18 @@ __metadata: languageName: node linkType: hard +"raw-body@npm:^3.0.1": + version: 3.0.2 + resolution: "raw-body@npm:3.0.2" + dependencies: + bytes: "npm:~3.1.2" + http-errors: "npm:~2.0.1" + iconv-lite: "npm:~0.7.0" + unpipe: "npm:~1.0.0" + checksum: 10/4168c82157bd69175d5bd960e59b74e253e237b358213694946a427a6f750a18b8e150f036fed3421b3e83294b071a4e2bb01037a79ccacdac05360c63d3ebba + languageName: node + linkType: hard + "read-cmd-shim@npm:^4.0.0": version: 4.0.0 resolution: "read-cmd-shim@npm:4.0.0" @@ -5353,6 +5978,13 @@ __metadata: languageName: node linkType: hard +"require-from-string@npm:^2.0.2": + version: 2.0.2 + resolution: "require-from-string@npm:2.0.2" + checksum: 10/839a3a890102a658f4cb3e7b2aa13a1f80a3a976b512020c3d1efc418491c48a886b6e481ea56afc6c4cb5eef678f23b2a4e70575e7534eccadf5e30ed2e56eb + languageName: node + linkType: hard + "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -5504,6 +6136,19 @@ __metadata: languageName: node linkType: hard +"router@npm:^2.2.0": + version: 2.2.0 + resolution: "router@npm:2.2.0" + dependencies: + debug: "npm:^4.4.0" + depd: "npm:^2.0.0" + is-promise: "npm:^4.0.0" + parseurl: "npm:^1.3.3" + path-to-regexp: "npm:^8.0.0" + checksum: 10/8949bd1d3da5403cc024e2989fee58d7fda0f3ffe9f2dc5b8a192f295f400b3cde307b0b554f7d44851077640f36962ca469a766b3d57410d7d96245a7ba6c91 + languageName: node + linkType: hard + "run-applescript@npm:^7.0.0": version: 7.0.0 resolution: "run-applescript@npm:7.0.0" @@ -5564,6 +6209,25 @@ __metadata: languageName: node linkType: hard +"send@npm:^1.1.0, send@npm:^1.2.0": + version: 1.2.1 + resolution: "send@npm:1.2.1" + dependencies: + debug: "npm:^4.4.3" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + etag: "npm:^1.8.1" + fresh: "npm:^2.0.0" + http-errors: "npm:^2.0.1" + mime-types: "npm:^3.0.2" + ms: "npm:^2.1.3" + on-finished: "npm:^2.4.1" + range-parser: "npm:^1.2.1" + statuses: "npm:^2.0.2" + checksum: 10/274f842d69ccfa49d4940a85598c6825da58dee6cb8ea33b08d5bd3988e6a82267c4d7c32b23d0e4706aad076ee95b1edfa13f859877db9b589829019397e355 + languageName: node + linkType: hard + "serve-static@npm:1.16.2": version: 1.16.2 resolution: "serve-static@npm:1.16.2" @@ -5576,6 +6240,18 @@ __metadata: languageName: node linkType: hard +"serve-static@npm:^2.2.0": + version: 2.2.1 + resolution: "serve-static@npm:2.2.1" + dependencies: + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + parseurl: "npm:^1.3.3" + send: "npm:^1.2.0" + checksum: 10/71500fe80cc7163fec04e4297de7591ad1cb682d137fc030e7a53e57040fda5187e8082a9c1b2ef37f1d3f9c27c9a94d4ba61806ebc28938ba4a7c8947c9f71e + languageName: node + linkType: hard + "set-function-length@npm:^1.2.1": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" @@ -5590,7 +6266,7 @@ __metadata: languageName: node linkType: hard -"setprototypeof@npm:1.2.0": +"setprototypeof@npm:1.2.0, setprototypeof@npm:~1.2.0": version: 1.2.0 resolution: "setprototypeof@npm:1.2.0" checksum: 10/fde1630422502fbbc19e6844346778f99d449986b2f9cdcceb8326730d2f3d9964dbcb03c02aaadaefffecd0f2c063315ebea8b3ad895914bf1afc1747fc172e @@ -5613,6 +6289,41 @@ __metadata: languageName: node linkType: hard +"side-channel-list@npm:^1.0.0": + version: 1.0.1 + resolution: "side-channel-list@npm:1.0.1" + dependencies: + es-errors: "npm:^1.3.0" + object-inspect: "npm:^1.13.4" + checksum: 10/3499671cd52adaee739eac1e14d07530b8e3530192741aeb05e7fe4ad1b51d1368ceea2cd3c21b0f62b05410a5c70a7c4d997ba4b143303ef73d0c65dfd1c252 + languageName: node + linkType: hard + +"side-channel-map@npm:^1.0.1": + version: 1.0.1 + resolution: "side-channel-map@npm:1.0.1" + dependencies: + call-bound: "npm:^1.0.2" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.5" + object-inspect: "npm:^1.13.3" + checksum: 10/5771861f77feefe44f6195ed077a9e4f389acc188f895f570d56445e251b861754b547ea9ef73ecee4e01fdada6568bfe9020d2ec2dfc5571e9fa1bbc4a10615 + languageName: node + linkType: hard + +"side-channel-weakmap@npm:^1.0.2": + version: 1.0.2 + resolution: "side-channel-weakmap@npm:1.0.2" + dependencies: + call-bound: "npm:^1.0.2" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.5" + object-inspect: "npm:^1.13.3" + side-channel-map: "npm:^1.0.1" + checksum: 10/a815c89bc78c5723c714ea1a77c938377ea710af20d4fb886d362b0d1f8ac73a17816a5f6640f354017d7e292a43da9c5e876c22145bac00b76cfb3468001736 + languageName: node + linkType: hard + "side-channel@npm:^1.0.6": version: 1.0.6 resolution: "side-channel@npm:1.0.6" @@ -5625,6 +6336,19 @@ __metadata: languageName: node linkType: hard +"side-channel@npm:^1.1.0": + version: 1.1.0 + resolution: "side-channel@npm:1.1.0" + dependencies: + es-errors: "npm:^1.3.0" + object-inspect: "npm:^1.13.3" + side-channel-list: "npm:^1.0.0" + side-channel-map: "npm:^1.0.1" + side-channel-weakmap: "npm:^1.0.2" + checksum: 10/7d53b9db292c6262f326b6ff3bc1611db84ece36c2c7dc0e937954c13c73185b0406c56589e2bb8d071d6fee468e14c39fb5d203ee39be66b7b8174f179afaba + languageName: node + linkType: hard + "siginfo@npm:^2.0.0": version: 2.0.0 resolution: "siginfo@npm:2.0.0" @@ -5794,6 +6518,13 @@ __metadata: languageName: node linkType: hard +"statuses@npm:^2.0.1, statuses@npm:^2.0.2, statuses@npm:~2.0.2": + version: 2.0.2 + resolution: "statuses@npm:2.0.2" + checksum: 10/6927feb50c2a75b2a4caab2c565491f7a93ad3d8dbad7b1398d52359e9243a20e2ebe35e33726dee945125ef7a515e9097d8a1b910ba2bbd818265a2f6c39879 + languageName: node + linkType: hard + "std-env@npm:^3.9.0": version: 3.9.0 resolution: "std-env@npm:3.9.0" @@ -6050,7 +6781,7 @@ __metadata: languageName: node linkType: hard -"toidentifier@npm:1.0.1": +"toidentifier@npm:1.0.1, toidentifier@npm:~1.0.1": version: 1.0.1 resolution: "toidentifier@npm:1.0.1" checksum: 10/952c29e2a85d7123239b5cfdd889a0dde47ab0497f0913d70588f19c53f7e0b5327c95f4651e413c74b785147f9637b17410ac8c846d5d4a20a5a33eb6dc3a45 @@ -6296,6 +7027,13 @@ __metadata: languageName: node linkType: hard +"tweetnacl@npm:^1.0.3": + version: 1.0.3 + resolution: "tweetnacl@npm:1.0.3" + checksum: 10/ca122c2f86631f3c0f6d28efb44af2a301d4a557a62a3e2460286b08e97567b258c2212e4ad1cfa22bd6a57edcdc54ba76ebe946847450ab0999e6d48ccae332 + languageName: node + linkType: hard + "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -6326,6 +7064,17 @@ __metadata: languageName: node linkType: hard +"type-is@npm:^2.0.1": + version: 2.1.0 + resolution: "type-is@npm:2.1.0" + dependencies: + content-type: "npm:^2.0.0" + media-typer: "npm:^1.1.0" + mime-types: "npm:^3.0.0" + checksum: 10/f011885fefb6c6882f36fab89cc596596b96eab1d208a3774628537cad7ce1f91232a6d758115e1a6ed03f0f8c21e9654bb6d280a5c6827ff72a35f6df0fa182 + languageName: node + linkType: hard + "type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" @@ -6554,7 +7303,7 @@ __metadata: languageName: node linkType: hard -"vary@npm:~1.1.2": +"vary@npm:^1.1.2, vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" checksum: 10/31389debef15a480849b8331b220782230b9815a8e0dbb7b9a8369559aed2e9a7800cd904d4371ea74f4c3527db456dc8e7ac5befce5f0d289014dbdf47b2242 @@ -6582,6 +7331,27 @@ __metadata: languageName: node linkType: hard +"viem@npm:^2.31.4, viem@npm:^2.48.11": + version: 2.49.2 + resolution: "viem@npm:2.49.2" + dependencies: + "@noble/curves": "npm:1.9.1" + "@noble/hashes": "npm:1.8.0" + "@scure/bip32": "npm:1.7.0" + "@scure/bip39": "npm:1.6.0" + abitype: "npm:1.2.3" + isows: "npm:1.0.7" + ox: "npm:0.14.20" + ws: "npm:8.18.3" + peerDependencies: + typescript: ">=5.0.4" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10/c3a89196c422932c1c0d0071e7ff231fcaa8518d8ae2c8462b15384efa9ad8632797b09e0a164ec83aac909532647086a505fb01a78ace2a001edc5b35ff4ce9 + languageName: node + linkType: hard + "vite-node@npm:3.2.4": version: 3.2.4 resolution: "vite-node@npm:3.2.4" @@ -6832,6 +7602,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:8.18.3": + version: 8.18.3 + resolution: "ws@npm:8.18.3" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10/725964438d752f0ab0de582cd48d6eeada58d1511c3f613485b5598a83680bedac6187c765b0fe082e2d8cc4341fc57707c813ae780feee82d0c5efe6a4c61b6 + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" @@ -6890,3 +7675,10 @@ __metadata: checksum: 10/f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 languageName: node linkType: hard + +"zod@npm:^3.24.2": + version: 3.25.76 + resolution: "zod@npm:3.25.76" + checksum: 10/f0c963ec40cd96858451d1690404d603d36507c1fc9682f2dae59ab38b578687d542708a7fdbf645f77926f78c9ed558f57c3d3aa226c285f798df0c4da16995 + languageName: node + linkType: hard From 94ffc3a01f869c90cb43dc347176ed75bdb109f6 Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Tue, 19 May 2026 11:24:44 +1200 Subject: [PATCH 02/18] Update server - add extra.facilitatorAddress if provided by facilitator's response --- .../src/experimental/index.ts | 4 +-- .../src/experimental/x402Server.ts | 26 ++++++++++++++++--- .../test/experimental/x402Server.test.ts | 10 +++---- packages/x402-example/README.md | 2 +- packages/x402-example/src/server.ts | 5 ++-- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/packages/smart-accounts-kit/src/experimental/index.ts b/packages/smart-accounts-kit/src/experimental/index.ts index c4da56ff..ba0a20d3 100644 --- a/packages/smart-accounts-kit/src/experimental/index.ts +++ b/packages/smart-accounts-kit/src/experimental/index.ts @@ -15,6 +15,6 @@ export { type x402Erc7710ClientConfig, } from './x402Client'; export { - X402Erc7710Server, - type X402Erc7710ServerConfig, + x402Erc7710Server, + type x402Erc7710ServerConfig, } from './x402Server'; diff --git a/packages/smart-accounts-kit/src/experimental/x402Server.ts b/packages/smart-accounts-kit/src/experimental/x402Server.ts index ca90f207..bf599e51 100644 --- a/packages/smart-accounts-kit/src/experimental/x402Server.ts +++ b/packages/smart-accounts-kit/src/experimental/x402Server.ts @@ -1,7 +1,8 @@ +import { getAddress } from 'viem'; import { trackSmartAccountsKitFunctionCall } from '../analytics'; import type { x402PaymentRequirements } from './x402Client'; -export type X402Erc7710ServerConfig = { +export type x402Erc7710ServerConfig = { allowAssetTransferMethodOverride?: boolean; }; @@ -12,23 +13,26 @@ export type X402Erc7710ServerConfig = { * This class uses structural typing and intentionally does not import x402 types, * so it can be consumed without adding a direct dependency on x402 packages. */ -export class X402Erc7710Server { +export class x402Erc7710Server { readonly scheme = 'exact'; readonly #allowAssetTransferMethodOverride: boolean; - constructor(config?: X402Erc7710ServerConfig) { + constructor(config?: x402Erc7710ServerConfig) { this.#allowAssetTransferMethodOverride = config?.allowAssetTransferMethodOverride ?? false; } async enhancePaymentRequirements( paymentRequirements: x402PaymentRequirements, + supportedKind: { + extra?: Record; + }, ): Promise { const existingMethod = paymentRequirements.extra?.assetTransferMethod; trackSmartAccountsKitFunctionCall( - 'experimental.X402Erc7710Server.enhancePaymentRequirements', + 'experimental.x402Erc7710Server.enhancePaymentRequirements', { network: paymentRequirements.network, existingAssetTransferMethod: @@ -46,10 +50,24 @@ export class X402Erc7710Server { ); } + const facilitatorAddress = (() => { + const publishedAddress = supportedKind.extra?.facilitatorAddress; + if (typeof publishedAddress !== 'string') { + return undefined; + } + + try { + return getAddress(publishedAddress); + } catch { + return undefined; + } + })(); + return { ...paymentRequirements, extra: { ...(paymentRequirements.extra ?? {}), + ...(facilitatorAddress ? { facilitatorAddress } : {}), assetTransferMethod: 'erc7710', }, }; diff --git a/packages/smart-accounts-kit/test/experimental/x402Server.test.ts b/packages/smart-accounts-kit/test/experimental/x402Server.test.ts index b14b5a26..2c6efaf3 100644 --- a/packages/smart-accounts-kit/test/experimental/x402Server.test.ts +++ b/packages/smart-accounts-kit/test/experimental/x402Server.test.ts @@ -1,9 +1,9 @@ import { describe, expect, it } from 'vitest'; import { zeroAddress } from 'viem'; -import { X402Erc7710Server } from '../../src/experimental/x402Server'; +import { x402Erc7710Server } from '../../src/experimental/x402Server'; -describe('X402Erc7710Server', () => { +describe('x402Erc7710Server', () => { const paymentRequirements = { scheme: 'exact', network: 'eip155:8453', @@ -17,7 +17,7 @@ describe('X402Erc7710Server', () => { }; it('adds erc7710 assetTransferMethod to payment requirements', async () => { - const server = new X402Erc7710Server(); + const server = new x402Erc7710Server(); const result = await server.enhancePaymentRequirements(paymentRequirements); @@ -31,7 +31,7 @@ describe('X402Erc7710Server', () => { }); it('throws when an incompatible assetTransferMethod already exists', async () => { - const server = new X402Erc7710Server(); + const server = new x402Erc7710Server(); await expect( server.enhancePaymentRequirements({ @@ -46,7 +46,7 @@ describe('X402Erc7710Server', () => { }); it('allows overriding existing assetTransferMethod when configured', async () => { - const server = new X402Erc7710Server({ + const server = new x402Erc7710Server({ allowAssetTransferMethodOverride: true, }); diff --git a/packages/x402-example/README.md b/packages/x402-example/README.md index c00a2c99..2404e006 100644 --- a/packages/x402-example/README.md +++ b/packages/x402-example/README.md @@ -3,7 +3,7 @@ Minimal x402 server example that publishes ERC-7710 payment requirements using: - x402 Foundation SDK (`@x402/core`, `@x402/express`, `@x402/evm`) -- Smart Accounts Kit experimental helper (`X402Erc7710Server`) +- Smart Accounts Kit experimental helper (`x402Erc7710Server`) ## Endpoint diff --git a/packages/x402-example/src/server.ts b/packages/x402-example/src/server.ts index d67f82f0..42949aec 100644 --- a/packages/x402-example/src/server.ts +++ b/packages/x402-example/src/server.ts @@ -7,7 +7,7 @@ import { type PaymentRequirements, } from '@x402/core/types'; import { ExactEvmScheme } from '@x402/evm/exact/server'; -import { X402Erc7710Server } from '@metamask/smart-accounts-kit/experimental'; +import { x402Erc7710Server } from '@metamask/smart-accounts-kit/experimental'; import type { Hex } from 'viem'; config(); @@ -27,7 +27,7 @@ const port = Number(process.env.PORT ?? 4021); const acceptedToken = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' as const; class ExactEvmErc7710ServerScheme extends ExactEvmScheme { - readonly #erc7710Server = new X402Erc7710Server(); + readonly #erc7710Server = new x402Erc7710Server(); async enhancePaymentRequirements( paymentRequirements: PaymentRequirements, @@ -47,6 +47,7 @@ class ExactEvmErc7710ServerScheme extends ExactEvmScheme { const enhancedRequirements = (await this.#erc7710Server.enhancePaymentRequirements( baseRequirements, + supportedKind, )) as PaymentRequirements; return enhancedRequirements; From 8ee224fbbae14948a06eb4d0ceea02a8c641a9f7 Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Tue, 19 May 2026 11:51:34 +1200 Subject: [PATCH 03/18] Move implementation into @metamask/smart-accounts-kit-x402 package --- .github/CODEOWNERS | 2 + packages/smart-accounts-kit-x402/CHANGELOG.md | 3 + .../smart-accounts-kit-x402/LICENSE.APACHE2 | 3 + packages/smart-accounts-kit-x402/LICENSE.MIT0 | 1 + packages/smart-accounts-kit-x402/README.md | 21 ++++ .../smart-accounts-kit-x402/eslint.config.mjs | 2 + packages/smart-accounts-kit-x402/package.json | 71 +++++++++++ packages/smart-accounts-kit-x402/src/index.ts | 14 +++ .../src}/x402Client.ts | 24 +--- .../src/x402ExactEvmErc7710ServerScheme.ts | 35 ++++++ .../src}/x402Server.ts | 11 +- .../smart-accounts-kit-x402/tsconfig.json | 8 ++ .../smart-accounts-kit-x402/tsup.config.ts | 12 ++ .../src/experimental/index.ts | 13 -- .../test/experimental/x402Client.test.ts | 118 ------------------ .../test/experimental/x402Server.test.ts | 64 ---------- packages/x402-example/README.md | 4 +- packages/x402-example/package.json | 1 + packages/x402-example/src/client.ts | 5 +- packages/x402-example/src/server.ts | 40 +----- packages/x402-example/tsconfig.json | 4 +- yarn.config.cjs | 6 +- yarn.lock | 17 +++ 23 files changed, 210 insertions(+), 269 deletions(-) create mode 100644 packages/smart-accounts-kit-x402/CHANGELOG.md create mode 100644 packages/smart-accounts-kit-x402/LICENSE.APACHE2 create mode 100644 packages/smart-accounts-kit-x402/LICENSE.MIT0 create mode 100644 packages/smart-accounts-kit-x402/README.md create mode 100644 packages/smart-accounts-kit-x402/eslint.config.mjs create mode 100644 packages/smart-accounts-kit-x402/package.json create mode 100644 packages/smart-accounts-kit-x402/src/index.ts rename packages/{smart-accounts-kit/src/experimental => smart-accounts-kit-x402/src}/x402Client.ts (80%) create mode 100644 packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts rename packages/{smart-accounts-kit/src/experimental => smart-accounts-kit-x402/src}/x402Server.ts (83%) create mode 100644 packages/smart-accounts-kit-x402/tsconfig.json create mode 100644 packages/smart-accounts-kit-x402/tsup.config.ts delete mode 100644 packages/smart-accounts-kit/test/experimental/x402Client.test.ts delete mode 100644 packages/smart-accounts-kit/test/experimental/x402Server.test.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d767f2f4..cf5e1f38 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -13,4 +13,6 @@ /packages/delegation-core @MetaMask/delegation /packages/delegation-deployments @MetaMask/delegation /packages/smart-accounts-kit @MetaMask/delegation +/packages/smart-accounts-kit-x402 @MetaMask/delegation /packages/7715-permission-types @MetaMask/delegation +/packages/x402-example @MetaMask/delegation diff --git a/packages/smart-accounts-kit-x402/CHANGELOG.md b/packages/smart-accounts-kit-x402/CHANGELOG.md new file mode 100644 index 00000000..5e4e559c --- /dev/null +++ b/packages/smart-accounts-kit-x402/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +All notable changes to `@metamask/smart-accounts-kit-x402` will be documented in this file. diff --git a/packages/smart-accounts-kit-x402/LICENSE.APACHE2 b/packages/smart-accounts-kit-x402/LICENSE.APACHE2 new file mode 100644 index 00000000..f6b06388 --- /dev/null +++ b/packages/smart-accounts-kit-x402/LICENSE.APACHE2 @@ -0,0 +1,3 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ diff --git a/packages/smart-accounts-kit-x402/LICENSE.MIT0 b/packages/smart-accounts-kit-x402/LICENSE.MIT0 new file mode 100644 index 00000000..61e7a4d6 --- /dev/null +++ b/packages/smart-accounts-kit-x402/LICENSE.MIT0 @@ -0,0 +1 @@ +MIT No Attribution License (MIT-0) diff --git a/packages/smart-accounts-kit-x402/README.md b/packages/smart-accounts-kit-x402/README.md new file mode 100644 index 00000000..1f342f29 --- /dev/null +++ b/packages/smart-accounts-kit-x402/README.md @@ -0,0 +1,21 @@ +# @metamask/smart-accounts-kit-x402 + +x402 adapters for ERC-7710 payment requirement publishing and payload creation. + +## Installation + +```bash +yarn add @metamask/smart-accounts-kit-x402 +npm install @metamask/smart-accounts-kit-x402 +``` + +## Exports + +- `x402Erc7710Client` +- `x402Erc7710Server` +- `x402ExactEvmErc7710ServerScheme` + +## Notes + +This package intentionally does not depend on `@metamask/smart-accounts-kit`. +Consumers provide delegation payloads via `x402DelegationProvider`. diff --git a/packages/smart-accounts-kit-x402/eslint.config.mjs b/packages/smart-accounts-kit-x402/eslint.config.mjs new file mode 100644 index 00000000..253f98a3 --- /dev/null +++ b/packages/smart-accounts-kit-x402/eslint.config.mjs @@ -0,0 +1,2 @@ +// eslint-disable-next-line +export { default } from '../../shared/config/base.eslint.mjs'; diff --git a/packages/smart-accounts-kit-x402/package.json b/packages/smart-accounts-kit-x402/package.json new file mode 100644 index 00000000..ba1c93b4 --- /dev/null +++ b/packages/smart-accounts-kit-x402/package.json @@ -0,0 +1,71 @@ +{ + "name": "@metamask/smart-accounts-kit-x402", + "version": "0.1.0", + "description": "x402 adapters for MetaMask smart accounts and ERC-7710", + "license": "(MIT-0 OR Apache-2.0)", + "type": "module", + "keywords": [ + "MetaMask", + "Ethereum" + ], + "homepage": "https://github.com/metamask/smart-accounts-kit/tree/main/packages/smart-accounts-kit-x402#readme", + "bugs": { + "url": "https://github.com/metamask/smart-accounts-kit/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/metamask/smart-accounts-kit.git" + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist/**", + "dist/" + ], + "exports": { + ".": { + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + }, + "import": { + "types": "./dist/index.d.ts", + "default": "./dist/index.mjs" + } + }, + "./package.json": "./package.json" + }, + "engines": { + "node": "^18.18 || >=20" + }, + "sideEffects": false, + "scripts": { + "build": "yarn typecheck && tsup", + "typecheck": "tsc --noEmit", + "lint": "yarn lint:eslint", + "lint:eslint": "eslint . --cache --ext js,ts", + "lint:fix": "yarn lint:eslint --fix", + "changelog:update": "../../scripts/update-changelog.sh @metamask/smart-accounts-kit-x402", + "changelog:validate": "../../scripts/validate-changelog.sh @metamask/smart-accounts-kit-x402" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + }, + "peerDependencies": { + "@x402/core": "^2.12.0", + "@x402/evm": "^2.12.0", + "viem": "^2.31.4" + }, + "devDependencies": { + "@x402/core": "^2.12.0", + "@x402/evm": "^2.12.0", + "@metamask/auto-changelog": "^5.0.2", + "eslint": "^9.39.2", + "prettier": "^3.5.3", + "tsup": "^8.5.0", + "typescript": "5.5.4", + "viem": "2.31.4" + } +} diff --git a/packages/smart-accounts-kit-x402/src/index.ts b/packages/smart-accounts-kit-x402/src/index.ts new file mode 100644 index 00000000..39f9dbec --- /dev/null +++ b/packages/smart-accounts-kit-x402/src/index.ts @@ -0,0 +1,14 @@ +export { + x402Erc7710Client, + type x402DelegationProvider, + type x402DelegationPaymentPayload, + type x402PaymentRequirements, + type x402PaymentPayloadResult, + type x402SchemeNetworkClientLike, + type x402Erc7710ClientConfig, +} from './x402Client'; +export { + x402Erc7710Server, + type x402Erc7710ServerConfig, +} from './x402Server'; +export { x402ExactEvmErc7710ServerScheme } from './x402ExactEvmErc7710ServerScheme'; diff --git a/packages/smart-accounts-kit/src/experimental/x402Client.ts b/packages/smart-accounts-kit-x402/src/x402Client.ts similarity index 80% rename from packages/smart-accounts-kit/src/experimental/x402Client.ts rename to packages/smart-accounts-kit-x402/src/x402Client.ts index 95437052..7a79072f 100644 --- a/packages/smart-accounts-kit/src/experimental/x402Client.ts +++ b/packages/smart-accounts-kit-x402/src/x402Client.ts @@ -1,9 +1,5 @@ import { type Hex, getAddress, isHex } from 'viem'; -import { trackSmartAccountsKitFunctionCall } from '../analytics'; -import { encodeDelegations } from '../delegation'; -import type { PermissionContext } from '../types'; - export type x402PaymentRequirements = { scheme: string; network: string; @@ -22,7 +18,7 @@ export type x402PaymentPayloadResult = { export type x402DelegationPaymentPayload = { delegationManager: Hex; - permissionContext: PermissionContext; + permissionContext: Hex; delegator: Hex; }; @@ -47,9 +43,7 @@ export type x402Erc7710ClientConfig = { function normalizeDelegationPayload( payload: x402DelegationPaymentPayload, ): x402DelegationPaymentPayload { - const permissionContext = encodeDelegations(payload.permissionContext); - - if (!isHex(permissionContext) || permissionContext === '0x') { + if (!isHex(payload.permissionContext) || payload.permissionContext === '0x') { throw new Error( 'Invalid delegation payload: permissionContext must be non-empty hex data', ); @@ -57,7 +51,7 @@ function normalizeDelegationPayload( return { delegationManager: getAddress(payload.delegationManager), - permissionContext, + permissionContext: payload.permissionContext, delegator: getAddress(payload.delegator), }; } @@ -87,18 +81,6 @@ export class x402Erc7710Client { ): Promise { const assetTransferMethod = paymentRequirements.extra?.assetTransferMethod; - trackSmartAccountsKitFunctionCall( - 'experimental.x402Erc7710Client.createPaymentPayload', - { - x402Version, - network: paymentRequirements.network, - assetTransferMethod: - typeof assetTransferMethod === 'string' - ? assetTransferMethod - : 'undefined', - }, - ); - if (assetTransferMethod !== 'erc7710') { if (this.#fallbackClient) { return this.#fallbackClient.createPaymentPayload( diff --git a/packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts b/packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts new file mode 100644 index 00000000..1557a685 --- /dev/null +++ b/packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts @@ -0,0 +1,35 @@ +import type { Network, PaymentRequirements } from '@x402/core/types'; +import { ExactEvmScheme } from '@x402/evm/exact/server'; + +import { x402Erc7710Server } from './x402Server'; + +/** + * Exact EVM server scheme that injects ERC-7710 payment requirement fields. + */ +export class x402ExactEvmErc7710ServerScheme extends ExactEvmScheme { + readonly #erc7710Server = new x402Erc7710Server(); + + async enhancePaymentRequirements( + paymentRequirements: PaymentRequirements, + supportedKind: { + x402Version: number; + scheme: string; + network: Network; + extra?: Record; + }, + facilitatorExtensions: string[], + ): Promise { + const baseRequirements = await super.enhancePaymentRequirements( + paymentRequirements, + supportedKind, + facilitatorExtensions, + ); + + const enhancedRequirements = await this.#erc7710Server.enhancePaymentRequirements( + baseRequirements, + supportedKind, + ); + + return enhancedRequirements as PaymentRequirements; + } +} diff --git a/packages/smart-accounts-kit/src/experimental/x402Server.ts b/packages/smart-accounts-kit-x402/src/x402Server.ts similarity index 83% rename from packages/smart-accounts-kit/src/experimental/x402Server.ts rename to packages/smart-accounts-kit-x402/src/x402Server.ts index bf599e51..346fceea 100644 --- a/packages/smart-accounts-kit/src/experimental/x402Server.ts +++ b/packages/smart-accounts-kit-x402/src/x402Server.ts @@ -1,5 +1,5 @@ import { getAddress } from 'viem'; -import { trackSmartAccountsKitFunctionCall } from '../analytics'; + import type { x402PaymentRequirements } from './x402Client'; export type x402Erc7710ServerConfig = { @@ -31,15 +31,6 @@ export class x402Erc7710Server { ): Promise { const existingMethod = paymentRequirements.extra?.assetTransferMethod; - trackSmartAccountsKitFunctionCall( - 'experimental.x402Erc7710Server.enhancePaymentRequirements', - { - network: paymentRequirements.network, - existingAssetTransferMethod: - typeof existingMethod === 'string' ? existingMethod : 'undefined', - }, - ); - if ( typeof existingMethod === 'string' && existingMethod !== 'erc7710' && diff --git a/packages/smart-accounts-kit-x402/tsconfig.json b/packages/smart-accounts-kit-x402/tsconfig.json new file mode 100644 index 00000000..946266aa --- /dev/null +++ b/packages/smart-accounts-kit-x402/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../shared/config/base.tsconfig.json", + "exclude": ["./node_modules/**/*", "./dist/**/*"], + "compilerOptions": { + "baseUrl": ".", + "outDir": "dist" + } +} diff --git a/packages/smart-accounts-kit-x402/tsup.config.ts b/packages/smart-accounts-kit-x402/tsup.config.ts new file mode 100644 index 00000000..d1d31001 --- /dev/null +++ b/packages/smart-accounts-kit-x402/tsup.config.ts @@ -0,0 +1,12 @@ +import type { Options } from 'tsup'; +import config from '../../shared/config/base.tsup.config'; + +const options: Options = { + ...config, + entry: ['src/index.ts'], + dts: { + entry: ['src/index.ts'], + }, +}; + +export default options; diff --git a/packages/smart-accounts-kit/src/experimental/index.ts b/packages/smart-accounts-kit/src/experimental/index.ts index ba0a20d3..83ca0171 100644 --- a/packages/smart-accounts-kit/src/experimental/index.ts +++ b/packages/smart-accounts-kit/src/experimental/index.ts @@ -5,16 +5,3 @@ export { type Environment, type DelegationStorageConfig, } from './delegationStorage'; -export { - x402Erc7710Client, - type x402DelegationProvider, - type x402DelegationPaymentPayload, - type x402PaymentRequirements, - type x402PaymentPayloadResult, - type x402SchemeNetworkClientLike, - type x402Erc7710ClientConfig, -} from './x402Client'; -export { - x402Erc7710Server, - type x402Erc7710ServerConfig, -} from './x402Server'; diff --git a/packages/smart-accounts-kit/test/experimental/x402Client.test.ts b/packages/smart-accounts-kit/test/experimental/x402Client.test.ts deleted file mode 100644 index cfb6af44..00000000 --- a/packages/smart-accounts-kit/test/experimental/x402Client.test.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { stub } from 'sinon'; -import { beforeEach, describe, expect, it } from 'vitest'; -import { zeroAddress } from 'viem'; - -import { X402Erc7710Client } from '../../src/experimental/x402Client'; - -describe('X402Erc7710Client', () => { - const paymentRequirements = { - scheme: 'exact', - network: 'eip155:1', - asset: zeroAddress, - amount: '1000', - payTo: zeroAddress, - maxTimeoutSeconds: 60, - extra: { - assetTransferMethod: 'erc7710', - }, - }; - - const delegationProvider = stub(); - - beforeEach(() => { - delegationProvider.reset(); - }); - - it('creates an ERC-7710 payload when assetTransferMethod is erc7710', async () => { - delegationProvider.resolves({ - delegationManager: zeroAddress, - permissionContext: '0x1234', - delegator: zeroAddress, - }); - - const client = new X402Erc7710Client({ delegationProvider }); - - const result = await client.createPaymentPayload(2, paymentRequirements); - - expect(result).toStrictEqual({ - x402Version: 2, - payload: { - delegationManager: zeroAddress, - permissionContext: '0x1234', - delegator: zeroAddress, - }, - }); - expect(delegationProvider.calledOnceWithExactly(paymentRequirements)).toBe( - true, - ); - }); - - it('throws when transfer method is not erc7710 and no fallback is configured', async () => { - const client = new X402Erc7710Client({ delegationProvider }); - - await expect( - client.createPaymentPayload(2, { - ...paymentRequirements, - extra: { assetTransferMethod: 'permit2' }, - }), - ).rejects.toThrow( - 'X402Erc7710Client can only process assetTransferMethod "erc7710"', - ); - expect(delegationProvider.notCalled).toBe(true); - }); - - it('delegates to fallback client for non-erc7710 payment requirements', async () => { - const fallbackClient = { - scheme: 'exact', - createPaymentPayload: stub().resolves({ - x402Version: 2, - payload: { signature: '0xabc' }, - }), - }; - - const client = new X402Erc7710Client({ - delegationProvider, - fallbackClient, - }); - - const non7710Requirements = { - ...paymentRequirements, - extra: { assetTransferMethod: 'permit2' }, - }; - - const result = await client.createPaymentPayload( - 2, - non7710Requirements, - { extensions: {} }, - ); - - expect(result).toStrictEqual({ - x402Version: 2, - payload: { signature: '0xabc' }, - }); - expect( - fallbackClient.createPaymentPayload.calledOnceWithExactly( - 2, - non7710Requirements, - { extensions: {} }, - ), - ).toBe(true); - expect(delegationProvider.notCalled).toBe(true); - }); - - it('throws when delegation provider returns empty permissionContext', async () => { - delegationProvider.resolves({ - delegationManager: zeroAddress, - permissionContext: '0x', - delegator: zeroAddress, - }); - - const client = new X402Erc7710Client({ delegationProvider }); - - await expect( - client.createPaymentPayload(2, paymentRequirements), - ).rejects.toThrow( - 'Invalid delegation payload: permissionContext must be non-empty hex data', - ); - }); -}); diff --git a/packages/smart-accounts-kit/test/experimental/x402Server.test.ts b/packages/smart-accounts-kit/test/experimental/x402Server.test.ts deleted file mode 100644 index 2c6efaf3..00000000 --- a/packages/smart-accounts-kit/test/experimental/x402Server.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { describe, expect, it } from 'vitest'; -import { zeroAddress } from 'viem'; - -import { x402Erc7710Server } from '../../src/experimental/x402Server'; - -describe('x402Erc7710Server', () => { - const paymentRequirements = { - scheme: 'exact', - network: 'eip155:8453', - asset: zeroAddress, - amount: '10000', - payTo: zeroAddress, - maxTimeoutSeconds: 300, - extra: { - foo: 'bar', - }, - }; - - it('adds erc7710 assetTransferMethod to payment requirements', async () => { - const server = new x402Erc7710Server(); - - const result = await server.enhancePaymentRequirements(paymentRequirements); - - expect(result).toStrictEqual({ - ...paymentRequirements, - extra: { - foo: 'bar', - assetTransferMethod: 'erc7710', - }, - }); - }); - - it('throws when an incompatible assetTransferMethod already exists', async () => { - const server = new x402Erc7710Server(); - - await expect( - server.enhancePaymentRequirements({ - ...paymentRequirements, - extra: { - assetTransferMethod: 'permit2', - }, - }), - ).rejects.toThrow( - 'Cannot overwrite existing assetTransferMethod "permit2" with "erc7710"', - ); - }); - - it('allows overriding existing assetTransferMethod when configured', async () => { - const server = new x402Erc7710Server({ - allowAssetTransferMethodOverride: true, - }); - - const result = await server.enhancePaymentRequirements({ - ...paymentRequirements, - extra: { - assetTransferMethod: 'permit2', - }, - }); - - expect(result.extra).toStrictEqual({ - assetTransferMethod: 'erc7710', - }); - }); -}); diff --git a/packages/x402-example/README.md b/packages/x402-example/README.md index 2404e006..c6d56e24 100644 --- a/packages/x402-example/README.md +++ b/packages/x402-example/README.md @@ -3,7 +3,7 @@ Minimal x402 server example that publishes ERC-7710 payment requirements using: - x402 Foundation SDK (`@x402/core`, `@x402/express`, `@x402/evm`) -- Smart Accounts Kit experimental helper (`x402Erc7710Server`) +- `@metamask/smart-accounts-kit-x402` helpers (`x402Erc7710Server`, `x402Erc7710Client`) ## Endpoint @@ -31,7 +31,7 @@ yarn workspace @metamask/x402-example start:server - accepts a private key (`--private-key 0x...` or `PRIVATE_KEY`) - requests the protected resource - creates an exact ERC-7710 delegation with Smart Accounts Kit -- builds the x402 payment payload via experimental `X402Erc7710Client` +- builds the x402 payment payload via `x402Erc7710Client` - retries the request with `PAYMENT-SIGNATURE` Run: diff --git a/packages/x402-example/package.json b/packages/x402-example/package.json index 1f2982be..9902ca60 100644 --- a/packages/x402-example/package.json +++ b/packages/x402-example/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@metamask/smart-accounts-kit": "workspace:^", + "@metamask/smart-accounts-kit-x402": "workspace:^", "@x402/core": "^2.12.0", "@x402/evm": "^2.12.0", "@x402/express": "^2.12.0", diff --git a/packages/x402-example/src/client.ts b/packages/x402-example/src/client.ts index b70c5dfa..2b11f21f 100644 --- a/packages/x402-example/src/client.ts +++ b/packages/x402-example/src/client.ts @@ -9,7 +9,8 @@ import { signDelegation, type Delegation, } from '@metamask/smart-accounts-kit'; -import { x402Erc7710Client } from '@metamask/smart-accounts-kit/experimental'; +import { encodeDelegations } from '@metamask/smart-accounts-kit/utils'; +import { x402Erc7710Client } from '@metamask/smart-accounts-kit-x402'; import { getAddress, type Hex, @@ -107,7 +108,7 @@ async function main() { return { delegationManager: environment.DelegationManager, - permissionContext: [signedDelegation], + permissionContext: encodeDelegations([signedDelegation]), delegator: account.address, }; }, diff --git a/packages/x402-example/src/server.ts b/packages/x402-example/src/server.ts index 42949aec..863d6bd3 100644 --- a/packages/x402-example/src/server.ts +++ b/packages/x402-example/src/server.ts @@ -4,11 +4,8 @@ import { HTTPFacilitatorClient } from '@x402/core/server'; import { paymentMiddleware, x402ResourceServer } from '@x402/express'; import { type Network, - type PaymentRequirements, } from '@x402/core/types'; -import { ExactEvmScheme } from '@x402/evm/exact/server'; -import { x402Erc7710Server } from '@metamask/smart-accounts-kit/experimental'; -import type { Hex } from 'viem'; +import { x402ExactEvmErc7710ServerScheme } from '@metamask/smart-accounts-kit-x402'; config(); @@ -17,43 +14,16 @@ if (!facilitatorUrl) { throw new Error('Missing FACILITATOR_URL environment variable'); } -const payTo = process.env.EVM_PAY_TO as Hex | undefined; +const payTo = process.env.EVM_PAY_TO as string | undefined; if (!payTo) { throw new Error('Missing EVM_PAY_TO environment variable'); } const network = (process.env.NETWORK ?? 'eip155:84532') as Network; const port = Number(process.env.PORT ?? 4021); +const price = '1000' as const; const acceptedToken = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' as const; -class ExactEvmErc7710ServerScheme extends ExactEvmScheme { - readonly #erc7710Server = new x402Erc7710Server(); - - async enhancePaymentRequirements( - paymentRequirements: PaymentRequirements, - supportedKind: { - x402Version: number; - scheme: string; - network: Network; - extra?: Record; - }, - facilitatorExtensions: string[], - ): Promise { - const baseRequirements = await super.enhancePaymentRequirements( - paymentRequirements, - supportedKind, - facilitatorExtensions, - ); - - const enhancedRequirements = (await this.#erc7710Server.enhancePaymentRequirements( - baseRequirements, - supportedKind, - )) as PaymentRequirements; - - return enhancedRequirements; - } -} - const facilitatorClient = new HTTPFacilitatorClient({ url: facilitatorUrl }); const app = express(); @@ -66,7 +36,7 @@ app.use( network, payTo, price: { - amount: '1000', + amount: price, asset: acceptedToken, }, }, @@ -76,7 +46,7 @@ app.use( }, new x402ResourceServer(facilitatorClient).register( network, - new ExactEvmErc7710ServerScheme(), + new x402ExactEvmErc7710ServerScheme(), ), ), ); diff --git a/packages/x402-example/tsconfig.json b/packages/x402-example/tsconfig.json index 9e5ed37f..c829f9b9 100644 --- a/packages/x402-example/tsconfig.json +++ b/packages/x402-example/tsconfig.json @@ -5,8 +5,8 @@ "baseUrl": ".", "outDir": "dist", "paths": { - "@metamask/smart-accounts-kit/experimental": [ - "../smart-accounts-kit/src/experimental/index.ts" + "@metamask/smart-accounts-kit-x402": [ + "../smart-accounts-kit-x402/src/index.ts" ] } } diff --git a/yarn.config.cjs b/yarn.config.cjs index bf1af083..85a186f5 100644 --- a/yarn.config.cjs +++ b/yarn.config.cjs @@ -47,9 +47,11 @@ module.exports = defineConfig({ '', ); - // filter out the e2e package, as it is likely going to be removed or reworked + // filter out packages that are examples or likely to be reworked const workspaces = Yarn.workspaces().filter( - (workspace) => getWorkspaceBasename(workspace) !== 'delegator-e2e', + (workspace) => + getWorkspaceBasename(workspace) !== 'delegator-e2e' && + getWorkspaceBasename(workspace) !== 'x402-example', ); for (const workspace of workspaces) { diff --git a/yarn.lock b/yarn.lock index 4b92941e..e4801012 100644 --- a/yarn.lock +++ b/yarn.lock @@ -770,6 +770,22 @@ __metadata: languageName: node linkType: hard +"@metamask/smart-accounts-kit-x402@workspace:^, @metamask/smart-accounts-kit-x402@workspace:packages/smart-accounts-kit-x402": + version: 0.0.0-use.local + resolution: "@metamask/smart-accounts-kit-x402@workspace:packages/smart-accounts-kit-x402" + dependencies: + "@metamask/auto-changelog": "npm:^5.0.2" + eslint: "npm:^9.39.2" + prettier: "npm:^3.5.3" + tsup: "npm:^8.5.0" + typescript: "npm:5.5.4" + peerDependencies: + "@x402/core": ^2.12.0 + "@x402/evm": ^2.12.0 + viem: ^2.31.4 + languageName: unknown + linkType: soft + "@metamask/smart-accounts-kit@workspace:*, @metamask/smart-accounts-kit@workspace:^, @metamask/smart-accounts-kit@workspace:packages/smart-accounts-kit": version: 0.0.0-use.local resolution: "@metamask/smart-accounts-kit@workspace:packages/smart-accounts-kit" @@ -862,6 +878,7 @@ __metadata: resolution: "@metamask/x402-example@workspace:packages/x402-example" dependencies: "@metamask/smart-accounts-kit": "workspace:^" + "@metamask/smart-accounts-kit-x402": "workspace:^" "@types/express": "npm:^5.0.5" "@x402/core": "npm:^2.12.0" "@x402/evm": "npm:^2.12.0" From 3f26a7d5dce898ab5e5f632fa7b550d5713f7984 Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Tue, 19 May 2026 12:01:13 +1200 Subject: [PATCH 04/18] Passthrough for non-7710 payment methods --- .../src/x402ExactEvmErc7710ServerScheme.ts | 4 +++ packages/x402-example/src/server.ts | 34 ++++++++++++++----- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts b/packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts index 1557a685..10ea9772 100644 --- a/packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts +++ b/packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts @@ -25,6 +25,10 @@ export class x402ExactEvmErc7710ServerScheme extends ExactEvmScheme { facilitatorExtensions, ); + if (baseRequirements.extra?.assetTransferMethod !== 'erc7710') { + return baseRequirements; + } + const enhancedRequirements = await this.#erc7710Server.enhancePaymentRequirements( baseRequirements, supportedKind, diff --git a/packages/x402-example/src/server.ts b/packages/x402-example/src/server.ts index 863d6bd3..c1b70451 100644 --- a/packages/x402-example/src/server.ts +++ b/packages/x402-example/src/server.ts @@ -2,6 +2,7 @@ import { config } from 'dotenv'; import express from 'express'; import { HTTPFacilitatorClient } from '@x402/core/server'; import { paymentMiddleware, x402ResourceServer } from '@x402/express'; +import { ExactEvmScheme } from '@x402/evm/exact/server'; import { type Network, } from '@x402/core/types'; @@ -31,15 +32,32 @@ app.use( paymentMiddleware( { 'GET /random': { - accepts: { - scheme: 'exact', - network, - payTo, - price: { - amount: price, - asset: acceptedToken, + accepts: [ + { + scheme: 'exact', + network, + payTo, + price: { + amount: price, + asset: acceptedToken, + }, + extra: { + assetTransferMethod: 'erc7710', + }, }, - }, + { + scheme: 'exact', + network, + payTo, + price: { + amount: price, + asset: acceptedToken, + }, + extra: { + assetTransferMethod: 'eip3009', + }, + }, + ], description: 'Random integer from 1 to 10', mimeType: 'text/plain', }, From 0d695376da19e63272040c3ac4a07a0788070f48 Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Tue, 19 May 2026 12:04:45 +1200 Subject: [PATCH 05/18] Math.floor the expiry --- packages/x402-example/src/client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/x402-example/src/client.ts b/packages/x402-example/src/client.ts index 2b11f21f..5d4735c2 100644 --- a/packages/x402-example/src/client.ts +++ b/packages/x402-example/src/client.ts @@ -72,8 +72,8 @@ async function main() { const chainId = parseChainIdFromNetwork(requirements.network); const environment = getSmartAccountsEnvironment(chainId); - // expires in 1 minute - const expiry = Date.now() / 1000 + 60; + // expires in 1 minute (must be an integer unix timestamp) + const expiry = Math.floor(Date.now() / 1000) + 60; const delegation = createOpenDelegation({ environment, From f22ef5425eb016046923ad8f25140409da8cdd9d Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Tue, 19 May 2026 12:26:46 +1200 Subject: [PATCH 06/18] Server now accepts both eip-3009 and erc-7710 payments --- packages/x402-example/src/client.ts | 7 +++---- packages/x402-example/src/server.ts | 8 ++++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/x402-example/src/client.ts b/packages/x402-example/src/client.ts index 5d4735c2..e30ae2ef 100644 --- a/packages/x402-example/src/client.ts +++ b/packages/x402-example/src/client.ts @@ -114,10 +114,9 @@ async function main() { }, }); - const httpClient = new x402HTTPClient(new x402Client().register( - 'eip155:*', - erc7710Client - )); + const coreClient = new x402Client().register('eip155:*', erc7710Client); + + const httpClient = new x402HTTPClient(coreClient); const fetchWithPayment = wrapFetchWithPayment(fetch, httpClient); diff --git a/packages/x402-example/src/server.ts b/packages/x402-example/src/server.ts index c1b70451..cb060494 100644 --- a/packages/x402-example/src/server.ts +++ b/packages/x402-example/src/server.ts @@ -2,7 +2,6 @@ import { config } from 'dotenv'; import express from 'express'; import { HTTPFacilitatorClient } from '@x402/core/server'; import { paymentMiddleware, x402ResourceServer } from '@x402/express'; -import { ExactEvmScheme } from '@x402/evm/exact/server'; import { type Network, } from '@x402/core/types'; @@ -24,6 +23,10 @@ const network = (process.env.NETWORK ?? 'eip155:84532') as Network; const port = Number(process.env.PORT ?? 4021); const price = '1000' as const; const acceptedToken = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' as const; +const acceptedTokenEip712Domain = { + name: 'USD Coin', + version: '2', +} as const; const facilitatorClient = new HTTPFacilitatorClient({ url: facilitatorUrl }); const app = express(); @@ -55,6 +58,7 @@ app.use( }, extra: { assetTransferMethod: 'eip3009', + ...acceptedTokenEip712Domain, }, }, ], @@ -76,6 +80,6 @@ app.get('/random', (_req: unknown, res: { type: (value: string) => { send: (valu app.listen(port, () => { console.log( - `x402 ERC-7710 example server listening on http://localhost:${port}/random`, + `x402 ERC-7710 + EIP-3009 example server listening on http://localhost:${port}/random`, ); }); From d240346a6be93ea969f8c195e3467d784c2a8a14 Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Wed, 20 May 2026 09:11:04 +1200 Subject: [PATCH 07/18] Update yarn.lock --- packages/smart-accounts-kit-x402/package.json | 2 +- yarn.lock | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/smart-accounts-kit-x402/package.json b/packages/smart-accounts-kit-x402/package.json index ba1c93b4..a4e2ce64 100644 --- a/packages/smart-accounts-kit-x402/package.json +++ b/packages/smart-accounts-kit-x402/package.json @@ -59,9 +59,9 @@ "viem": "^2.31.4" }, "devDependencies": { + "@metamask/auto-changelog": "^5.0.2", "@x402/core": "^2.12.0", "@x402/evm": "^2.12.0", - "@metamask/auto-changelog": "^5.0.2", "eslint": "^9.39.2", "prettier": "^3.5.3", "tsup": "^8.5.0", diff --git a/yarn.lock b/yarn.lock index e4801012..4072015c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -775,10 +775,13 @@ __metadata: resolution: "@metamask/smart-accounts-kit-x402@workspace:packages/smart-accounts-kit-x402" dependencies: "@metamask/auto-changelog": "npm:^5.0.2" + "@x402/core": "npm:^2.12.0" + "@x402/evm": "npm:^2.12.0" eslint: "npm:^9.39.2" prettier: "npm:^3.5.3" tsup: "npm:^8.5.0" typescript: "npm:5.5.4" + viem: "npm:2.31.4" peerDependencies: "@x402/core": ^2.12.0 "@x402/evm": ^2.12.0 From 02e12be9e6f765b1762e6b0e413c5acb25fccf1d Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Wed, 20 May 2026 11:22:49 +1200 Subject: [PATCH 08/18] Remove example project --- .github/CODEOWNERS | 1 - packages/x402-example/README.md | 41 ------- packages/x402-example/package.json | 26 ---- packages/x402-example/src/client.ts | 139 ---------------------- packages/x402-example/src/express.d.ts | 1 - packages/x402-example/src/server.ts | 85 ------------- packages/x402-example/src/x402-fetch.d.ts | 8 -- packages/x402-example/tsconfig.json | 13 -- 8 files changed, 314 deletions(-) delete mode 100644 packages/x402-example/README.md delete mode 100644 packages/x402-example/package.json delete mode 100644 packages/x402-example/src/client.ts delete mode 100644 packages/x402-example/src/express.d.ts delete mode 100644 packages/x402-example/src/server.ts delete mode 100644 packages/x402-example/src/x402-fetch.d.ts delete mode 100644 packages/x402-example/tsconfig.json diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cf5e1f38..53cbb700 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -15,4 +15,3 @@ /packages/smart-accounts-kit @MetaMask/delegation /packages/smart-accounts-kit-x402 @MetaMask/delegation /packages/7715-permission-types @MetaMask/delegation -/packages/x402-example @MetaMask/delegation diff --git a/packages/x402-example/README.md b/packages/x402-example/README.md deleted file mode 100644 index c6d56e24..00000000 --- a/packages/x402-example/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# x402 example - -Minimal x402 server example that publishes ERC-7710 payment requirements using: - -- x402 Foundation SDK (`@x402/core`, `@x402/express`, `@x402/evm`) -- `@metamask/smart-accounts-kit-x402` helpers (`x402Erc7710Server`, `x402Erc7710Client`) - -## Endpoint - -- `GET /random` returns `text/plain` with a random integer in `[1, 10]` -- The route is protected by x402 with the `exact` scheme -- Payment requirements are rewritten to `extra.assetTransferMethod = "erc7710"` - -## Environment variables - -- `FACILITATOR_URL` - x402 facilitator base URL -- `EVM_PAY_TO` - recipient address -- `NETWORK` - optional CAIP-2 network (default: `eip155:84532`) -- `PORT` - optional server port (default: `4021`) - -## Run - -```bash -yarn workspace @metamask/x402-example start:server -``` - -## Client CLI - -`src/client.ts` is a minimal x402 CLI payer: - -- accepts a private key (`--private-key 0x...` or `PRIVATE_KEY`) -- requests the protected resource -- creates an exact ERC-7710 delegation with Smart Accounts Kit -- builds the x402 payment payload via `x402Erc7710Client` -- retries the request with `PAYMENT-SIGNATURE` - -Run: - -```bash -yarn workspace @metamask/x402-example start:client --private-key 0x... -``` diff --git a/packages/x402-example/package.json b/packages/x402-example/package.json deleted file mode 100644 index 9902ca60..00000000 --- a/packages/x402-example/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "@metamask/x402-example", - "private": true, - "type": "module", - "packageManager": "yarn@4.14.1", - "scripts": { - "start:server": "tsx src/server.ts", - "dev:server": "tsx watch src/server.ts", - "start:client": "tsx src/client.ts" - }, - "dependencies": { - "@metamask/smart-accounts-kit": "workspace:^", - "@metamask/smart-accounts-kit-x402": "workspace:^", - "@x402/core": "^2.12.0", - "@x402/evm": "^2.12.0", - "@x402/express": "^2.12.0", - "@x402/fetch": "^2.12.0", - "dotenv": "^17.4.2", - "express": "^5.2.1", - "viem": "^2.31.4" - }, - "devDependencies": { - "@types/express": "^5.0.5", - "tsx": "^4.20.5" - } -} diff --git a/packages/x402-example/src/client.ts b/packages/x402-example/src/client.ts deleted file mode 100644 index e30ae2ef..00000000 --- a/packages/x402-example/src/client.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { config } from 'dotenv'; -import { x402Client, x402HTTPClient } from '@x402/core/client'; -import { wrapFetchWithPayment } from '@x402/fetch'; -import { - CaveatType, - createOpenDelegation, - getSmartAccountsEnvironment, - ScopeType, - signDelegation, - type Delegation, -} from '@metamask/smart-accounts-kit'; -import { encodeDelegations } from '@metamask/smart-accounts-kit/utils'; -import { x402Erc7710Client } from '@metamask/smart-accounts-kit-x402'; -import { - getAddress, - type Hex, -} from 'viem'; -import { privateKeyToAccount } from 'viem/accounts'; -import { randomBytes } from 'node:crypto'; - -config(); - -type CliConfig = { - privateKey: Hex; - url: string; -}; - -function parseCliConfig(): CliConfig { - const args = process.argv.slice(2); - const keyArgIndex = args.findIndex((arg) => arg === '--private-key'); - const urlArgIndex = args.findIndex((arg) => arg === '--url'); - - const privateKeyFromArg = - keyArgIndex >= 0 ? (args[keyArgIndex + 1] as Hex | undefined) : undefined; - const privateKey = (privateKeyFromArg ?? - (process.env.PRIVATE_KEY as Hex | undefined)) as Hex | undefined; - - if (!privateKey || !privateKey.startsWith('0x')) { - throw new Error( - 'Missing private key. Pass --private-key 0x... or set PRIVATE_KEY', - ); - } - - const urlFromArg = urlArgIndex >= 0 ? args[urlArgIndex + 1] : undefined; - const url = urlFromArg ?? process.env.X402_URL ?? 'http://localhost:4021/random'; - - return { privateKey, url }; -} - -function parseChainIdFromNetwork(network: string): number { - const [namespace, reference] = network.split(':'); - if (namespace !== 'eip155' || !reference) { - throw new Error( - `Unsupported network "${network}". Expected CAIP-2 eip155:`, - ); - } - - const chainId = Number(reference); - if (!Number.isInteger(chainId) || chainId <= 0) { - throw new Error(`Invalid chain id in network "${network}"`); - } - return chainId; -} - - -async function main() { - const { privateKey, url } = parseCliConfig(); - const account = privateKeyToAccount(privateKey); - - const erc7710Client = new x402Erc7710Client({ - delegationProvider: async (requirements) => { - const chainId = parseChainIdFromNetwork(requirements.network); - const environment = getSmartAccountsEnvironment(chainId); - - // expires in 1 minute (must be an integer unix timestamp) - const expiry = Math.floor(Date.now() / 1000) + 60; - - const delegation = createOpenDelegation({ - environment, - from: account.address, - scope: { - type: ScopeType.Erc20TransferAmount, - tokenAddress: getAddress(requirements.asset), - maxAmount: BigInt(requirements.amount), - }, - salt: `0x${randomBytes(32).toString('hex')}`, - caveats: [ - { - type: CaveatType.Timestamp, - afterThreshold: 0, - beforeThreshold: expiry, - } - ] - }); - - - const signature = await signDelegation({ - privateKey, - delegation, - delegationManager: environment.DelegationManager, - chainId, - }); - - const signedDelegation: Delegation = { - ...delegation, - signature, - }; - - return { - delegationManager: environment.DelegationManager, - permissionContext: encodeDelegations([signedDelegation]), - delegator: account.address, - }; - }, - }); - - const coreClient = new x402Client().register('eip155:*', erc7710Client); - - const httpClient = new x402HTTPClient(coreClient); - - const fetchWithPayment = wrapFetchWithPayment(fetch, httpClient); - - const paidResponse = await fetchWithPayment(url, { method: 'GET' }); - - if (!paidResponse.ok) { - const bodyText = await paidResponse.text(); - throw new Error( - `Paid request failed with status ${paidResponse.status}: ${bodyText}`, - ); - } - - console.log(await paidResponse.text()); -} - -main().catch((error: unknown) => { - const message = error instanceof Error ? error.message : String(error); - console.error(`x402 client failed: ${message}`); - process.exit(1); -}); diff --git a/packages/x402-example/src/express.d.ts b/packages/x402-example/src/express.d.ts deleted file mode 100644 index 5df44d9e..00000000 --- a/packages/x402-example/src/express.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'express'; diff --git a/packages/x402-example/src/server.ts b/packages/x402-example/src/server.ts deleted file mode 100644 index cb060494..00000000 --- a/packages/x402-example/src/server.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { config } from 'dotenv'; -import express from 'express'; -import { HTTPFacilitatorClient } from '@x402/core/server'; -import { paymentMiddleware, x402ResourceServer } from '@x402/express'; -import { - type Network, -} from '@x402/core/types'; -import { x402ExactEvmErc7710ServerScheme } from '@metamask/smart-accounts-kit-x402'; - -config(); - -const facilitatorUrl = process.env.FACILITATOR_URL; -if (!facilitatorUrl) { - throw new Error('Missing FACILITATOR_URL environment variable'); -} - -const payTo = process.env.EVM_PAY_TO as string | undefined; -if (!payTo) { - throw new Error('Missing EVM_PAY_TO environment variable'); -} - -const network = (process.env.NETWORK ?? 'eip155:84532') as Network; -const port = Number(process.env.PORT ?? 4021); -const price = '1000' as const; -const acceptedToken = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' as const; -const acceptedTokenEip712Domain = { - name: 'USD Coin', - version: '2', -} as const; - -const facilitatorClient = new HTTPFacilitatorClient({ url: facilitatorUrl }); -const app = express(); - -app.use( - paymentMiddleware( - { - 'GET /random': { - accepts: [ - { - scheme: 'exact', - network, - payTo, - price: { - amount: price, - asset: acceptedToken, - }, - extra: { - assetTransferMethod: 'erc7710', - }, - }, - { - scheme: 'exact', - network, - payTo, - price: { - amount: price, - asset: acceptedToken, - }, - extra: { - assetTransferMethod: 'eip3009', - ...acceptedTokenEip712Domain, - }, - }, - ], - description: 'Random integer from 1 to 10', - mimeType: 'text/plain', - }, - }, - new x402ResourceServer(facilitatorClient).register( - network, - new x402ExactEvmErc7710ServerScheme(), - ), - ), -); - -app.get('/random', (_req: unknown, res: { type: (value: string) => { send: (value: string) => void } }) => { - const value = Math.floor(Math.random() * 10) + 1; - res.type('text/plain').send(String(value)); -}); - -app.listen(port, () => { - console.log( - `x402 ERC-7710 + EIP-3009 example server listening on http://localhost:${port}/random`, - ); -}); diff --git a/packages/x402-example/src/x402-fetch.d.ts b/packages/x402-example/src/x402-fetch.d.ts deleted file mode 100644 index 043f8d2d..00000000 --- a/packages/x402-example/src/x402-fetch.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { x402Client, x402HTTPClient } from '@x402/core/client'; - -declare module '@x402/fetch' { - export function wrapFetchWithPayment( - fetchImpl: typeof globalThis.fetch, - client: x402Client | x402HTTPClient, - ): typeof globalThis.fetch; -} diff --git a/packages/x402-example/tsconfig.json b/packages/x402-example/tsconfig.json deleted file mode 100644 index c829f9b9..00000000 --- a/packages/x402-example/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../../shared/config/base.tsconfig.json", - "exclude": ["./node_modules/**/*", "./dist/**/*"], - "compilerOptions": { - "baseUrl": ".", - "outDir": "dist", - "paths": { - "@metamask/smart-accounts-kit-x402": [ - "../smart-accounts-kit-x402/src/index.ts" - ] - } - } -} From a8ecef613c3862281325c8975ba11a116012d382 Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Wed, 20 May 2026 11:25:08 +1200 Subject: [PATCH 09/18] update yarn.lock --- yarn.lock | 737 ++---------------------------------------------------- 1 file changed, 26 insertions(+), 711 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4072015c..7643c7fa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -770,7 +770,7 @@ __metadata: languageName: node linkType: hard -"@metamask/smart-accounts-kit-x402@workspace:^, @metamask/smart-accounts-kit-x402@workspace:packages/smart-accounts-kit-x402": +"@metamask/smart-accounts-kit-x402@workspace:packages/smart-accounts-kit-x402": version: 0.0.0-use.local resolution: "@metamask/smart-accounts-kit-x402@workspace:packages/smart-accounts-kit-x402" dependencies: @@ -789,7 +789,7 @@ __metadata: languageName: unknown linkType: soft -"@metamask/smart-accounts-kit@workspace:*, @metamask/smart-accounts-kit@workspace:^, @metamask/smart-accounts-kit@workspace:packages/smart-accounts-kit": +"@metamask/smart-accounts-kit@workspace:*, @metamask/smart-accounts-kit@workspace:packages/smart-accounts-kit": version: 0.0.0-use.local resolution: "@metamask/smart-accounts-kit@workspace:packages/smart-accounts-kit" dependencies: @@ -876,24 +876,6 @@ __metadata: languageName: node linkType: hard -"@metamask/x402-example@workspace:packages/x402-example": - version: 0.0.0-use.local - resolution: "@metamask/x402-example@workspace:packages/x402-example" - dependencies: - "@metamask/smart-accounts-kit": "workspace:^" - "@metamask/smart-accounts-kit-x402": "workspace:^" - "@types/express": "npm:^5.0.5" - "@x402/core": "npm:^2.12.0" - "@x402/evm": "npm:^2.12.0" - "@x402/express": "npm:^2.12.0" - "@x402/fetch": "npm:^2.12.0" - dotenv: "npm:^17.4.2" - express: "npm:^5.2.1" - tsx: "npm:^4.20.5" - viem: "npm:^2.31.4" - languageName: unknown - linkType: soft - "@mswjs/interceptors@npm:^0.41.0": version: 0.41.3 resolution: "@mswjs/interceptors@npm:0.41.3" @@ -953,7 +935,7 @@ __metadata: languageName: node linkType: hard -"@noble/curves@npm:^1.9.0, @noble/curves@npm:^1.9.1, @noble/curves@npm:~1.9.0": +"@noble/curves@npm:^1.9.1, @noble/curves@npm:~1.9.0": version: 1.9.7 resolution: "@noble/curves@npm:1.9.7" dependencies: @@ -969,7 +951,7 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:1.8.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.7.0, @noble/hashes@npm:^1.8.0, @noble/hashes@npm:~1.8.0": +"@noble/hashes@npm:1.8.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.8.0, @noble/hashes@npm:~1.8.0": version: 1.8.0 resolution: "@noble/hashes@npm:1.8.0" checksum: 10/474b7f56bc6fb2d5b3a42132561e221b0ea4f91e590f4655312ca13667840896b34195e2b53b7f097ec080a1fdd3b58d902c2a8d0fbdf51d2e238b53808a177e @@ -1432,7 +1414,7 @@ __metadata: languageName: node linkType: hard -"@scure/base@npm:^1.1.3, @scure/base@npm:^1.2.6, @scure/base@npm:~1.2.5": +"@scure/base@npm:^1.1.3, @scure/base@npm:~1.2.5": version: 1.2.6 resolution: "@scure/base@npm:1.2.6" checksum: 10/c1a7bd5e0b0c8f94c36fbc220f4a67cc832b00e2d2065c7d8a404ed81ab1c94c5443def6d361a70fc382db3496e9487fb9941728f0584782b274c18a4bed4187 @@ -1488,33 +1470,6 @@ __metadata: languageName: node linkType: hard -"@signinwithethereum/siwe-parser@npm:^4.2.0": - version: 4.2.0 - resolution: "@signinwithethereum/siwe-parser@npm:4.2.0" - dependencies: - "@noble/hashes": "npm:^1.7.0" - apg-js: "npm:^4.4.0" - checksum: 10/641e7b0424723a0138dcbe50a94d5c48b3cf144dc668a6c134d8e3ed5271792f87c5920c8d042af6cd7fa4d84e0a2add68f2c7e1eae03391752a145fadd9c403 - languageName: node - linkType: hard - -"@signinwithethereum/siwe@npm:^4.1.0": - version: 4.2.0 - resolution: "@signinwithethereum/siwe@npm:4.2.0" - dependencies: - "@signinwithethereum/siwe-parser": "npm:^4.2.0" - peerDependencies: - ethers: ^5.7.0 || ^6.13.0 - viem: ^2.7.0 - peerDependenciesMeta: - ethers: - optional: true - viem: - optional: true - checksum: 10/26c9faca9c6f482fecf0a845a749b700b849691247f23afaf5dc701e61b3669dc0ff3ba297f12f3d548181e86412c6bdd876af3e316ac2f7400087ce7048c29f - languageName: node - linkType: hard - "@sinonjs/commons@npm:^3.0.0, @sinonjs/commons@npm:^3.0.1": version: 3.0.1 resolution: "@sinonjs/commons@npm:3.0.1" @@ -1597,16 +1552,6 @@ __metadata: languageName: node linkType: hard -"@types/body-parser@npm:*": - version: 1.19.6 - resolution: "@types/body-parser@npm:1.19.6" - dependencies: - "@types/connect": "npm:*" - "@types/node": "npm:*" - checksum: 10/33041e88eae00af2cfa0827e951e5f1751eafab2a8b6fce06cd89ef368a988907996436b1325180edaeddd1c0c7d0d0d4c20a6c9ff294a91e0039a9db9e9b658 - languageName: node - linkType: hard - "@types/chai@npm:^5.2.2": version: 5.2.2 resolution: "@types/chai@npm:5.2.2" @@ -1616,15 +1561,6 @@ __metadata: languageName: node linkType: hard -"@types/connect@npm:*": - version: 3.4.38 - resolution: "@types/connect@npm:3.4.38" - dependencies: - "@types/node": "npm:*" - checksum: 10/7eb1bc5342a9604facd57598a6c62621e244822442976c443efb84ff745246b10d06e8b309b6e80130026a396f19bf6793b7cecd7380169f369dac3bfc46fb99 - languageName: node - linkType: hard - "@types/debug@npm:^4.1.7": version: 4.1.12 resolution: "@types/debug@npm:4.1.12" @@ -1648,36 +1584,6 @@ __metadata: languageName: node linkType: hard -"@types/express-serve-static-core@npm:^5.0.0": - version: 5.1.1 - resolution: "@types/express-serve-static-core@npm:5.1.1" - dependencies: - "@types/node": "npm:*" - "@types/qs": "npm:*" - "@types/range-parser": "npm:*" - "@types/send": "npm:*" - checksum: 10/7f3d8cf7e68764c9f3e8f6a12825b69ccf5287347fc1c20b29803d4f08a4abc1153ae11d7258852c61aad50f62ef72d4c1b9c97092b0a90462c3dddec2f6026c - languageName: node - linkType: hard - -"@types/express@npm:^5.0.5": - version: 5.0.6 - resolution: "@types/express@npm:5.0.6" - dependencies: - "@types/body-parser": "npm:*" - "@types/express-serve-static-core": "npm:^5.0.0" - "@types/serve-static": "npm:^2" - checksum: 10/da2cc3de1b1a4d7f20ed3fb6f0a8ee08e99feb3c2eb5a8d643db77017d8d0e70fee9e95da38a73f51bcdf5eda3bb6435073c0271dc04fb16fda92e55daf911fa - languageName: node - linkType: hard - -"@types/http-errors@npm:*": - version: 2.0.5 - resolution: "@types/http-errors@npm:2.0.5" - checksum: 10/a88da669366bc483e8f3b3eb3d34ada5f8d13eeeef851b1204d77e2ba6fc42aba4566d877cca5c095204a3f4349b87fe397e3e21288837bdd945dd514120755b - languageName: node - linkType: hard - "@types/json-schema@npm:^7.0.15": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" @@ -1726,20 +1632,6 @@ __metadata: languageName: node linkType: hard -"@types/qs@npm:*": - version: 6.15.1 - resolution: "@types/qs@npm:6.15.1" - checksum: 10/fd04a36c683dbb1ec5819c01773905259955bfd84d7294af178ad609990a9b8d75d458629ca3bf97b151fe2934eb12ade7fdeb98f2e3ad40d138f0a7d195ac7c - languageName: node - linkType: hard - -"@types/range-parser@npm:*": - version: 1.2.7 - resolution: "@types/range-parser@npm:1.2.7" - checksum: 10/95640233b689dfbd85b8c6ee268812a732cf36d5affead89e806fe30da9a430767af8ef2cd661024fd97e19d61f3dec75af2df5e80ec3bea000019ab7028629a - languageName: node - linkType: hard - "@types/semver@npm:^7.3.6": version: 7.7.0 resolution: "@types/semver@npm:7.7.0" @@ -1747,25 +1639,6 @@ __metadata: languageName: node linkType: hard -"@types/send@npm:*": - version: 1.2.1 - resolution: "@types/send@npm:1.2.1" - dependencies: - "@types/node": "npm:*" - checksum: 10/81ef5790037ba1d2d458392e4241501f0f8b4838cc8797e169e179e099410e12069ec68e8dbd39211cb097c4a9b1ff1682dbcea897ab4ce21dad93438b862d27 - languageName: node - linkType: hard - -"@types/serve-static@npm:^2": - version: 2.2.0 - resolution: "@types/serve-static@npm:2.2.0" - dependencies: - "@types/http-errors": "npm:*" - "@types/node": "npm:*" - checksum: 10/f2bad1304c7d0d3b7221faff3e490c40129d3803f4fb1b2fb84f31f561071c5e6a4b876c41bbbe82d5645034eea936e946bcaaf993dac1093ce68b56effad6e0 - languageName: node - linkType: hard - "@types/sinon@npm:^17.0.3": version: 17.0.3 resolution: "@types/sinon@npm:17.0.3" @@ -2182,48 +2055,6 @@ __metadata: languageName: node linkType: hard -"@x402/express@npm:^2.12.0": - version: 2.12.0 - resolution: "@x402/express@npm:2.12.0" - dependencies: - "@x402/core": "npm:~2.12.0" - "@x402/extensions": "npm:~2.12.0" - peerDependencies: - "@x402/paywall": ^2.12.0 - express: ^4.0.0 || ^5.0.0 - peerDependenciesMeta: - "@x402/paywall": - optional: true - checksum: 10/73ccdfffb89fd7685f69dd11700fffba6ad7e716de2863027f08cdc5d2ad378769444199043a8a8ae8c0bd65c2719063ede2c9cdc436e103b04697bd5e0216da - languageName: node - linkType: hard - -"@x402/extensions@npm:~2.12.0": - version: 2.12.0 - resolution: "@x402/extensions@npm:2.12.0" - dependencies: - "@noble/curves": "npm:^1.9.0" - "@scure/base": "npm:^1.2.6" - "@signinwithethereum/siwe": "npm:^4.1.0" - "@x402/core": "npm:~2.12.0" - ajv: "npm:^8.17.1" - jose: "npm:^5.9.6" - tweetnacl: "npm:^1.0.3" - viem: "npm:^2.48.11" - zod: "npm:^3.24.2" - checksum: 10/4bf92b3de8547f861f282912ffd518ec974c4e9ba4bfc375b8930781dca62d72d1970f95545bc94c5aaaf3e3da132786c0486fbc6745e2cfb4756a48272ae6a1 - languageName: node - linkType: hard - -"@x402/fetch@npm:^2.12.0": - version: 2.12.0 - resolution: "@x402/fetch@npm:2.12.0" - dependencies: - "@x402/core": "npm:~2.12.0" - checksum: 10/7f30e6e88d8a6132766fb49db23b38a0b332850c11e7d87ee58edb0b91704e5ac0de20e7ec1b23daca05b6a59efb5354caae4c8d3b97554341a6679bcad179f2 - languageName: node - linkType: hard - "@yarnpkg/types@npm:^4.0.1": version: 4.0.1 resolution: "@yarnpkg/types@npm:4.0.1" @@ -2285,16 +2116,6 @@ __metadata: languageName: node linkType: hard -"accepts@npm:^2.0.0": - version: 2.0.0 - resolution: "accepts@npm:2.0.0" - dependencies: - mime-types: "npm:^3.0.0" - negotiator: "npm:^1.0.0" - checksum: 10/ea1343992b40b2bfb3a3113fa9c3c2f918ba0f9197ae565c48d3f84d44b174f6b1d5cd9989decd7655963eb03a272abc36968cc439c2907f999bd5ef8653d5a7 - languageName: node - linkType: hard - "accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" @@ -2363,18 +2184,6 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.17.1": - version: 8.20.0 - resolution: "ajv@npm:8.20.0" - dependencies: - fast-deep-equal: "npm:^3.1.3" - fast-uri: "npm:^3.0.1" - json-schema-traverse: "npm:^1.0.0" - require-from-string: "npm:^2.0.2" - checksum: 10/5ce59c0537f4c2aca9a758b412659ec70acb4d5dde971c10ecf21d2e3d799f99acdb4a08e1f5fb2e067c8542930398aae793bb996bb07d3feb81dae22fe2ada9 - languageName: node - linkType: hard - "ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" @@ -2422,13 +2231,6 @@ __metadata: languageName: node linkType: hard -"apg-js@npm:^4.4.0": - version: 4.4.0 - resolution: "apg-js@npm:4.4.0" - checksum: 10/425f19096026742f5f156f26542b68f55602aa60f0c4ae2d72a0a888cf15fe9622223191202262dd8979d76a6125de9d8fd164d56c95fb113f49099f405eb08c - languageName: node - linkType: hard - "are-docs-informative@npm:^0.0.2": version: 0.0.2 resolution: "are-docs-informative@npm:0.0.2" @@ -2475,20 +2277,6 @@ __metadata: languageName: node linkType: hard -"async-function@npm:^1.0.0": - version: 1.0.0 - resolution: "async-function@npm:1.0.0" - checksum: 10/1a09379937d846f0ce7614e75071c12826945d4e417db634156bf0e4673c495989302f52186dfa9767a1d9181794554717badd193ca2bbab046ef1da741d8efd - languageName: node - linkType: hard - -"async-generator-function@npm:^1.0.0": - version: 1.0.0 - resolution: "async-generator-function@npm:1.0.0" - checksum: 10/3d49e7acbeee9e84537f4cb0e0f91893df8eba976759875ae8ee9e3d3c82f6ecdebdb347c2fad9926b92596d93cdfc78ecc988bcdf407e40433e8e8e6fe5d78e - languageName: node - linkType: hard - "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" @@ -2542,23 +2330,6 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:^2.2.1": - version: 2.2.2 - resolution: "body-parser@npm:2.2.2" - dependencies: - bytes: "npm:^3.1.2" - content-type: "npm:^1.0.5" - debug: "npm:^4.4.3" - http-errors: "npm:^2.0.0" - iconv-lite: "npm:^0.7.0" - on-finished: "npm:^2.4.1" - qs: "npm:^6.14.1" - raw-body: "npm:^3.0.1" - type-is: "npm:^2.0.1" - checksum: 10/69671f67d4d5ae5974593901a92d639757231da1725ed6de4d35e86cde9ce7650afdf1cd28df9b6f7892ea7f9eb03ccb30c70fe27d679275ae4cb4aae5ce1b21 - languageName: node - linkType: hard - "brace-expansion@npm:^1.1.7": version: 1.1.12 resolution: "brace-expansion@npm:1.1.12" @@ -2607,7 +2378,7 @@ __metadata: languageName: node linkType: hard -"bytes@npm:3.1.2, bytes@npm:^3.1.2, bytes@npm:~3.1.2": +"bytes@npm:3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" checksum: 10/a10abf2ba70c784471d6b4f58778c0beeb2b5d405148e66affa91f23a9f13d07603d0a0354667310ae1d6dc141474ffd44e2a074be0f6e2254edb8fc21445388 @@ -2641,16 +2412,6 @@ __metadata: languageName: node linkType: hard -"call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": - version: 1.0.2 - resolution: "call-bind-apply-helpers@npm:1.0.2" - dependencies: - es-errors: "npm:^1.3.0" - function-bind: "npm:^1.1.2" - checksum: 10/00482c1f6aa7cfb30fb1dbeb13873edf81cfac7c29ed67a5957d60635a56b2a4a480f1016ddbdb3395cc37900d46037fb965043a51c5c789ffeab4fc535d18b5 - languageName: node - linkType: hard - "call-bind@npm:^1.0.7": version: 1.0.7 resolution: "call-bind@npm:1.0.7" @@ -2664,16 +2425,6 @@ __metadata: languageName: node linkType: hard -"call-bound@npm:^1.0.2": - version: 1.0.4 - resolution: "call-bound@npm:1.0.4" - dependencies: - call-bind-apply-helpers: "npm:^1.0.2" - get-intrinsic: "npm:^1.3.0" - checksum: 10/ef2b96e126ec0e58a7ff694db43f4d0d44f80e641370c21549ed911fecbdbc2df3ebc9bddad918d6bbdefeafb60bb3337902006d5176d72bcd2da74820991af7 - languageName: node - linkType: hard - "callsites@npm:^3.0.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" @@ -2838,27 +2589,13 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:^1.0.0": - version: 1.1.0 - resolution: "content-disposition@npm:1.1.0" - checksum: 10/c4f65e3c001a4a8eb87d0d24c0f112abb139836fb13b8ea67276715e7dce09570ef666ba7848ee8b660d467e6588d030c8ed7e8d0128db6ca78a0800dcd8c7a8 - languageName: node - linkType: hard - -"content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": +"content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" checksum: 10/585847d98dc7fb8035c02ae2cb76c7a9bd7b25f84c447e5ed55c45c2175e83617c8813871b4ee22f368126af6b2b167df655829007b21aa10302873ea9c62662 languageName: node linkType: hard -"content-type@npm:^2.0.0": - version: 2.0.0 - resolution: "content-type@npm:2.0.0" - checksum: 10/0bbb276b790ba7e86c479c7d69fae1861b2e908ff3ce2cb01975b516f93eede2216d242902ed6c5b15cd554014611ce9dfdcf51cd35b16569e45a979e50d0cef - languageName: node - linkType: hard - "cookie-signature@npm:1.0.6": version: 1.0.6 resolution: "cookie-signature@npm:1.0.6" @@ -2866,13 +2603,6 @@ __metadata: languageName: node linkType: hard -"cookie-signature@npm:^1.2.1": - version: 1.2.2 - resolution: "cookie-signature@npm:1.2.2" - checksum: 10/be44a3c9a56f3771aea3a8bd8ad8f0a8e2679bcb967478267f41a510b4eb5ec55085386ba79c706c4ac21605ca76f4251973444b90283e0eb3eeafe8a92c7708 - languageName: node - linkType: hard - "cookie@npm:0.7.1": version: 0.7.1 resolution: "cookie@npm:0.7.1" @@ -2880,13 +2610,6 @@ __metadata: languageName: node linkType: hard -"cookie@npm:^0.7.1": - version: 0.7.2 - resolution: "cookie@npm:0.7.2" - checksum: 10/24b286c556420d4ba4e9bc09120c9d3db7d28ace2bd0f8ccee82422ce42322f73c8312441271e5eefafbead725980e5996cc02766dbb89a90ac7f5636ede608f - languageName: node - linkType: hard - "crc-32@npm:^1.2.0": version: 1.2.2 resolution: "crc-32@npm:1.2.2" @@ -2944,18 +2667,6 @@ __metadata: languageName: node linkType: hard -"debug@npm:^4.4.3": - version: 4.4.3 - resolution: "debug@npm:4.4.3" - dependencies: - ms: "npm:^2.1.3" - peerDependenciesMeta: - supports-color: - optional: true - checksum: 10/9ada3434ea2993800bd9a1e320bd4aa7af69659fb51cca685d390949434bc0a8873c21ed7c9b852af6f2455a55c6d050aa3937d52b3c69f796dab666f762acad - languageName: node - linkType: hard - "deep-eql@npm:^5.0.1": version: 5.0.2 resolution: "deep-eql@npm:5.0.2" @@ -3038,7 +2749,7 @@ __metadata: languageName: unknown linkType: soft -"depd@npm:2.0.0, depd@npm:^2.0.0, depd@npm:~2.0.0": +"depd@npm:2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" checksum: 10/c0c8ff36079ce5ada64f46cc9d6fd47ebcf38241105b6e0c98f412e8ad91f084bcf906ff644cc3a4bd876ca27a62accb8b0fff72ea6ed1a414b89d8506f4a5ca @@ -3087,24 +2798,6 @@ __metadata: languageName: node linkType: hard -"dotenv@npm:^17.4.2": - version: 17.4.2 - resolution: "dotenv@npm:17.4.2" - checksum: 10/ca1b6f54d58e39914901e1518958e86083aca8deb5aa2e7f2a51acd53291d97852479b0ab26ed949b6a45a0e9adcc7b0d1c3c72375e8ea670f7005e341c6daba - languageName: node - linkType: hard - -"dunder-proto@npm:^1.0.1": - version: 1.0.1 - resolution: "dunder-proto@npm:1.0.1" - dependencies: - call-bind-apply-helpers: "npm:^1.0.1" - es-errors: "npm:^1.3.0" - gopd: "npm:^1.2.0" - checksum: 10/5add88a3d68d42d6e6130a0cac450b7c2edbe73364bbd2fc334564418569bea97c6943a8fcd70e27130bf32afc236f30982fc4905039b703f23e9e0433c29934 - languageName: node - linkType: hard - "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -3133,13 +2826,6 @@ __metadata: languageName: node linkType: hard -"encodeurl@npm:^2.0.0, encodeurl@npm:~2.0.0": - version: 2.0.0 - resolution: "encodeurl@npm:2.0.0" - checksum: 10/abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe - languageName: node - linkType: hard - "encodeurl@npm:~1.0.2": version: 1.0.2 resolution: "encodeurl@npm:1.0.2" @@ -3147,6 +2833,13 @@ __metadata: languageName: node linkType: hard +"encodeurl@npm:~2.0.0": + version: 2.0.0 + resolution: "encodeurl@npm:2.0.0" + checksum: 10/abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe + languageName: node + linkType: hard + "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -3189,13 +2882,6 @@ __metadata: languageName: node linkType: hard -"es-define-property@npm:^1.0.1": - version: 1.0.1 - resolution: "es-define-property@npm:1.0.1" - checksum: 10/f8dc9e660d90919f11084db0a893128f3592b781ce967e4fccfb8f3106cb83e400a4032c559184ec52ee1dbd4b01e7776c7cd0b3327b1961b1a4a7008920fe78 - languageName: node - linkType: hard - "es-errors@npm:^1.3.0": version: 1.3.0 resolution: "es-errors@npm:1.3.0" @@ -3210,15 +2896,6 @@ __metadata: languageName: node linkType: hard -"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": - version: 1.1.1 - resolution: "es-object-atoms@npm:1.1.1" - dependencies: - es-errors: "npm:^1.3.0" - checksum: 10/54fe77de288451dae51c37bfbfe3ec86732dc3778f98f3eb3bdb4bf48063b2c0b8f9c93542656986149d08aa5be3204286e2276053d19582b76753f1a2728867 - languageName: node - linkType: hard - "esbuild@npm:^0.25.0, esbuild@npm:~0.25.0": version: 0.25.6 resolution: "esbuild@npm:0.25.6" @@ -3315,7 +2992,7 @@ __metadata: languageName: node linkType: hard -"escape-html@npm:^1.0.3, escape-html@npm:~1.0.3": +"escape-html@npm:~1.0.3": version: 1.0.3 resolution: "escape-html@npm:1.0.3" checksum: 10/6213ca9ae00d0ab8bccb6d8d4e0a98e76237b2410302cf7df70aaa6591d509a2a37ce8998008cbecae8fc8ffaadf3fb0229535e6a145f3ce0b211d060decbb24 @@ -3659,7 +3336,7 @@ __metadata: languageName: node linkType: hard -"etag@npm:^1.8.1, etag@npm:~1.8.1": +"etag@npm:~1.8.1": version: 1.8.1 resolution: "etag@npm:1.8.1" checksum: 10/571aeb3dbe0f2bbd4e4fadbdb44f325fc75335cd5f6f6b6a091e6a06a9f25ed5392f0863c5442acb0646787446e816f13cbfc6edce5b07658541dff573cab1ff @@ -3772,42 +3449,6 @@ __metadata: languageName: node linkType: hard -"express@npm:^5.2.1": - version: 5.2.1 - resolution: "express@npm:5.2.1" - dependencies: - accepts: "npm:^2.0.0" - body-parser: "npm:^2.2.1" - content-disposition: "npm:^1.0.0" - content-type: "npm:^1.0.5" - cookie: "npm:^0.7.1" - cookie-signature: "npm:^1.2.1" - debug: "npm:^4.4.0" - depd: "npm:^2.0.0" - encodeurl: "npm:^2.0.0" - escape-html: "npm:^1.0.3" - etag: "npm:^1.8.1" - finalhandler: "npm:^2.1.0" - fresh: "npm:^2.0.0" - http-errors: "npm:^2.0.0" - merge-descriptors: "npm:^2.0.0" - mime-types: "npm:^3.0.0" - on-finished: "npm:^2.4.1" - once: "npm:^1.4.0" - parseurl: "npm:^1.3.3" - proxy-addr: "npm:^2.0.7" - qs: "npm:^6.14.0" - range-parser: "npm:^1.2.1" - router: "npm:^2.2.0" - send: "npm:^1.1.0" - serve-static: "npm:^2.2.0" - statuses: "npm:^2.0.1" - type-is: "npm:^2.0.1" - vary: "npm:^1.1.2" - checksum: 10/4aa545d89702ac83f645c77abda1b57bcabe288f0b380fb5580fac4e323ea0eb533005c8e666b4e19152fb16d4abf11ba87b22aa9a10857a0485cd86b94639bd - languageName: node - linkType: hard - "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -3849,13 +3490,6 @@ __metadata: languageName: node linkType: hard -"fast-uri@npm:^3.0.1": - version: 3.1.2 - resolution: "fast-uri@npm:3.1.2" - checksum: 10/1dff04865b2a38d3e0659deadfbf72efdf83a776bfbf9667e4aa9e5a3ec31bc341cda9622136b32b7652a857c8ba11896794186e8f876f8b2b72731fce8622f6 - languageName: node - linkType: hard - "fastq@npm:^1.6.0": version: 1.17.1 resolution: "fastq@npm:1.17.1" @@ -3910,20 +3544,6 @@ __metadata: languageName: node linkType: hard -"finalhandler@npm:^2.1.0": - version: 2.1.1 - resolution: "finalhandler@npm:2.1.1" - dependencies: - debug: "npm:^4.4.0" - encodeurl: "npm:^2.0.0" - escape-html: "npm:^1.0.3" - on-finished: "npm:^2.4.1" - parseurl: "npm:^1.3.3" - statuses: "npm:^2.0.1" - checksum: 10/f4ba75c23408d8f9d393c3e875b9452e84d68c925411a6e67b7efa678b0bed5075ef33def4bb65ed8e0dd37c92a3ea354bcbde07303cd4dc2550e12b95885067 - languageName: node - linkType: hard - "find-up@npm:^5.0.0": version: 5.0.0 resolution: "find-up@npm:5.0.0" @@ -3986,13 +3606,6 @@ __metadata: languageName: node linkType: hard -"fresh@npm:^2.0.0": - version: 2.0.0 - resolution: "fresh@npm:2.0.0" - checksum: 10/44e1468488363074641991c1340d2a10c5a6f6d7c353d89fd161c49d120c58ebf9890720f7584f509058385836e3ce50ddb60e9f017315a4ba8c6c3461813bfc - languageName: node - linkType: hard - "fs-minipass@npm:^2.0.0": version: 2.1.0 resolution: "fs-minipass@npm:2.1.0" @@ -4044,13 +3657,6 @@ __metadata: languageName: node linkType: hard -"generator-function@npm:^2.0.0": - version: 2.0.1 - resolution: "generator-function@npm:2.0.1" - checksum: 10/eb7e7eb896c5433f3d40982b2ccacdb3dd990dd3499f14040e002b5d54572476513be8a2e6f9609f6e41ab29f2c4469307611ddbfc37ff4e46b765c326663805 - languageName: node - linkType: hard - "get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" @@ -4071,37 +3677,6 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.3.0": - version: 1.3.1 - resolution: "get-intrinsic@npm:1.3.1" - dependencies: - async-function: "npm:^1.0.0" - async-generator-function: "npm:^1.0.0" - call-bind-apply-helpers: "npm:^1.0.2" - es-define-property: "npm:^1.0.1" - es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.1.1" - function-bind: "npm:^1.1.2" - generator-function: "npm:^2.0.0" - get-proto: "npm:^1.0.1" - gopd: "npm:^1.2.0" - has-symbols: "npm:^1.1.0" - hasown: "npm:^2.0.2" - math-intrinsics: "npm:^1.1.0" - checksum: 10/bb579dda84caa4a3a41611bdd483dade7f00f246f2a7992eb143c5861155290df3fdb48a8406efa3dfb0b434e2c8fafa4eebd469e409d0439247f85fc3fa2cc1 - languageName: node - linkType: hard - -"get-proto@npm:^1.0.1": - version: 1.0.1 - resolution: "get-proto@npm:1.0.1" - dependencies: - dunder-proto: "npm:^1.0.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10/4fc96afdb58ced9a67558698b91433e6b037aaa6f1493af77498d7c85b141382cf223c0e5946f334fb328ee85dfe6edd06d218eaf09556f4bc4ec6005d7f5f7b - languageName: node - linkType: hard - "get-stream@npm:^6.0.0": version: 6.0.1 resolution: "get-stream@npm:6.0.1" @@ -4203,13 +3778,6 @@ __metadata: languageName: node linkType: hard -"gopd@npm:^1.2.0": - version: 1.2.0 - resolution: "gopd@npm:1.2.0" - checksum: 10/94e296d69f92dc1c0768fcfeecfb3855582ab59a7c75e969d5f96ce50c3d201fd86d5a2857c22565764d5bb8a816c7b1e58f133ec318cd56274da36c5e3fb1a1 - languageName: node - linkType: hard - "graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" @@ -4254,13 +3822,6 @@ __metadata: languageName: node linkType: hard -"has-symbols@npm:^1.1.0": - version: 1.1.0 - resolution: "has-symbols@npm:1.1.0" - checksum: 10/959385c98696ebbca51e7534e0dc723ada325efa3475350951363cce216d27373e0259b63edb599f72eb94d6cde8577b4b2375f080b303947e560f85692834fa - languageName: node - linkType: hard - "hasown@npm:^2.0.0, hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" @@ -4306,19 +3867,6 @@ __metadata: languageName: node linkType: hard -"http-errors@npm:^2.0.0, http-errors@npm:^2.0.1, http-errors@npm:~2.0.1": - version: 2.0.1 - resolution: "http-errors@npm:2.0.1" - dependencies: - depd: "npm:~2.0.0" - inherits: "npm:~2.0.4" - setprototypeof: "npm:~1.2.0" - statuses: "npm:~2.0.2" - toidentifier: "npm:~1.0.1" - checksum: 10/9fe31bc0edf36566c87048aed1d3d0cbe03552564adc3541626a0613f542d753fbcb13bdfcec0a3a530dbe1714bb566c89d46244616b66bddd26ac413b06a207 - languageName: node - linkType: hard - "http-proxy-agent@npm:^7.0.0": version: 7.0.2 resolution: "http-proxy-agent@npm:7.0.2" @@ -4371,15 +3919,6 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:^0.7.0, iconv-lite@npm:~0.7.0": - version: 0.7.2 - resolution: "iconv-lite@npm:0.7.2" - dependencies: - safer-buffer: "npm:>= 2.1.2 < 3.0.0" - checksum: 10/24c937b532f868e938386b62410b303b7c767ce3d08dc2829cbe59464d5a26ef86ae5ad1af6b34eec43ddfea39e7d101638644b0178d67262fa87015d59f983a - languageName: node - linkType: hard - "ignore-by-default@npm:^1.0.1": version: 1.0.1 resolution: "ignore-by-default@npm:1.0.1" @@ -4435,7 +3974,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.3, inherits@npm:~2.0.4": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 10/cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 @@ -4557,13 +4096,6 @@ __metadata: languageName: node linkType: hard -"is-promise@npm:^4.0.0": - version: 4.0.0 - resolution: "is-promise@npm:4.0.0" - checksum: 10/0b46517ad47b00b6358fd6553c83ec1f6ba9acd7ffb3d30a0bf519c5c69e7147c132430452351b8a9fc198f8dd6c4f76f8e6f5a7f100f8c77d57d9e0f4261a8a - languageName: node - linkType: hard - "is-stream@npm:^2.0.0": version: 2.0.1 resolution: "is-stream@npm:2.0.1" @@ -4662,13 +4194,6 @@ __metadata: languageName: node linkType: hard -"jose@npm:^5.9.6": - version: 5.10.0 - resolution: "jose@npm:5.10.0" - checksum: 10/03881d1dfb390dcf50926402edcfe233bf557b5a77321fcb1bdb53453bc1cdd26d2d0a9ab28c7445cbb826881f84fdf5074179700f10c2711ccb9880f51065d7 - languageName: node - linkType: hard - "joycon@npm:^3.1.1": version: 3.1.1 resolution: "joycon@npm:3.1.1" @@ -4729,13 +4254,6 @@ __metadata: languageName: node linkType: hard -"json-schema-traverse@npm:^1.0.0": - version: 1.0.0 - resolution: "json-schema-traverse@npm:1.0.0" - checksum: 10/02f2f466cdb0362558b2f1fd5e15cce82ef55d60cd7f8fa828cf35ba74330f8d767fcae5c5c2adb7851fa811766c694b9405810879bc4e1ddd78a7c0e03658ad - languageName: node - linkType: hard - "json-stable-stringify-without-jsonify@npm:^1.0.1": version: 1.0.1 resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" @@ -4925,13 +4443,6 @@ __metadata: languageName: node linkType: hard -"math-intrinsics@npm:^1.1.0": - version: 1.1.0 - resolution: "math-intrinsics@npm:1.1.0" - checksum: 10/11df2eda46d092a6035479632e1ec865b8134bdfc4bd9e571a656f4191525404f13a283a515938c3a8de934dbfd9c09674d9da9fa831e6eb7e22b50b197d2edd - languageName: node - linkType: hard - "media-typer@npm:0.3.0": version: 0.3.0 resolution: "media-typer@npm:0.3.0" @@ -4939,13 +4450,6 @@ __metadata: languageName: node linkType: hard -"media-typer@npm:^1.1.0": - version: 1.1.0 - resolution: "media-typer@npm:1.1.0" - checksum: 10/a58dd60804df73c672942a7253ccc06815612326dc1c0827984b1a21704466d7cde351394f47649e56cf7415e6ee2e26e000e81b51b3eebb5a93540e8bf93cbd - languageName: node - linkType: hard - "merge-descriptors@npm:1.0.3": version: 1.0.3 resolution: "merge-descriptors@npm:1.0.3" @@ -4953,13 +4457,6 @@ __metadata: languageName: node linkType: hard -"merge-descriptors@npm:^2.0.0": - version: 2.0.0 - resolution: "merge-descriptors@npm:2.0.0" - checksum: 10/e383332e700a94682d0125a36c8be761142a1320fc9feeb18e6e36647c9edf064271645f5669b2c21cf352116e561914fd8aa831b651f34db15ef4038c86696a - languageName: node - linkType: hard - "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -5005,22 +4502,6 @@ __metadata: languageName: node linkType: hard -"mime-db@npm:^1.54.0": - version: 1.54.0 - resolution: "mime-db@npm:1.54.0" - checksum: 10/9e7834be3d66ae7f10eaa69215732c6d389692b194f876198dca79b2b90cbf96688d9d5d05ef7987b20f749b769b11c01766564264ea5f919c88b32a29011311 - languageName: node - linkType: hard - -"mime-types@npm:^3.0.0, mime-types@npm:^3.0.2": - version: 3.0.2 - resolution: "mime-types@npm:3.0.2" - dependencies: - mime-db: "npm:^1.54.0" - checksum: 10/9db0ad31f5eff10ee8f848130779b7f2d056ddfdb6bda696cb69be68d486d33a3457b4f3f9bdeb60d0736edb471bd5a7c0a384375c011c51c889fd0d5c3b893e - languageName: node - linkType: hard - "mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" @@ -5249,13 +4730,6 @@ __metadata: languageName: node linkType: hard -"negotiator@npm:^1.0.0": - version: 1.0.0 - resolution: "negotiator@npm:1.0.0" - checksum: 10/b5734e87295324fabf868e36fb97c84b7d7f3156ec5f4ee5bf6e488079c11054f818290fc33804cef7b1ee21f55eeb14caea83e7dafae6492a409b3e573153e5 - languageName: node - linkType: hard - "nise@npm:^6.0.0": version: 6.1.1 resolution: "nise@npm:6.1.1" @@ -5461,14 +4935,7 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": - version: 1.13.4 - resolution: "object-inspect@npm:1.13.4" - checksum: 10/aa13b1190ad3e366f6c83ad8a16ed37a19ed57d267385aa4bfdccda833d7b90465c057ff6c55d035a6b2e52c1a2295582b294217a0a3a1ae7abdd6877ef781fb - languageName: node - linkType: hard - -"on-finished@npm:2.4.1, on-finished@npm:^2.4.1": +"on-finished@npm:2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" dependencies: @@ -5654,7 +5121,7 @@ __metadata: languageName: node linkType: hard -"parseurl@npm:^1.3.3, parseurl@npm:~1.3.3": +"parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" checksum: 10/407cee8e0a3a4c5cd472559bca8b6a45b82c124e9a4703302326e9ab60fc1081442ada4e02628efef1eb16197ddc7f8822f5a91fd7d7c86b51f530aedb17dfa2 @@ -5713,13 +5180,6 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:^8.0.0": - version: 8.4.2 - resolution: "path-to-regexp@npm:8.4.2" - checksum: 10/70fd2cbce0b962cbcf4d312af07818bfce2bae11c09cf3bd86be99c0e30168238a1a7b02b18b452e73f075897df04597d30d63e56da7be41eecfc37998693389 - languageName: node - linkType: hard - "path-to-regexp@npm:^8.1.0": version: 8.2.0 resolution: "path-to-regexp@npm:8.2.0" @@ -5877,7 +5337,7 @@ __metadata: languageName: node linkType: hard -"proxy-addr@npm:^2.0.7, proxy-addr@npm:~2.0.7": +"proxy-addr@npm:~2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" dependencies: @@ -5910,15 +5370,6 @@ __metadata: languageName: node linkType: hard -"qs@npm:^6.14.0, qs@npm:^6.14.1": - version: 6.15.1 - resolution: "qs@npm:6.15.1" - dependencies: - side-channel: "npm:^1.1.0" - checksum: 10/ec10b9957446b3f4a38000940f6374720b4e2985209b89df197066038c951472ea24cd98d6bc6df73a0cbec75bc056f638032e3fb447345017ff7e0f0a2693ac - languageName: node - linkType: hard - "queue-microtask@npm:^1.2.2": version: 1.2.3 resolution: "queue-microtask@npm:1.2.3" @@ -5926,7 +5377,7 @@ __metadata: languageName: node linkType: hard -"range-parser@npm:^1.2.1, range-parser@npm:~1.2.1": +"range-parser@npm:~1.2.1": version: 1.2.1 resolution: "range-parser@npm:1.2.1" checksum: 10/ce21ef2a2dd40506893157970dc76e835c78cf56437e26e19189c48d5291e7279314477b06ac38abd6a401b661a6840f7b03bd0b1249da9b691deeaa15872c26 @@ -5945,18 +5396,6 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:^3.0.1": - version: 3.0.2 - resolution: "raw-body@npm:3.0.2" - dependencies: - bytes: "npm:~3.1.2" - http-errors: "npm:~2.0.1" - iconv-lite: "npm:~0.7.0" - unpipe: "npm:~1.0.0" - checksum: 10/4168c82157bd69175d5bd960e59b74e253e237b358213694946a427a6f750a18b8e150f036fed3421b3e83294b071a4e2bb01037a79ccacdac05360c63d3ebba - languageName: node - linkType: hard - "read-cmd-shim@npm:^4.0.0": version: 4.0.0 resolution: "read-cmd-shim@npm:4.0.0" @@ -5998,13 +5437,6 @@ __metadata: languageName: node linkType: hard -"require-from-string@npm:^2.0.2": - version: 2.0.2 - resolution: "require-from-string@npm:2.0.2" - checksum: 10/839a3a890102a658f4cb3e7b2aa13a1f80a3a976b512020c3d1efc418491c48a886b6e481ea56afc6c4cb5eef678f23b2a4e70575e7534eccadf5e30ed2e56eb - languageName: node - linkType: hard - "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -6156,19 +5588,6 @@ __metadata: languageName: node linkType: hard -"router@npm:^2.2.0": - version: 2.2.0 - resolution: "router@npm:2.2.0" - dependencies: - debug: "npm:^4.4.0" - depd: "npm:^2.0.0" - is-promise: "npm:^4.0.0" - parseurl: "npm:^1.3.3" - path-to-regexp: "npm:^8.0.0" - checksum: 10/8949bd1d3da5403cc024e2989fee58d7fda0f3ffe9f2dc5b8a192f295f400b3cde307b0b554f7d44851077640f36962ca469a766b3d57410d7d96245a7ba6c91 - languageName: node - linkType: hard - "run-applescript@npm:^7.0.0": version: 7.0.0 resolution: "run-applescript@npm:7.0.0" @@ -6229,25 +5648,6 @@ __metadata: languageName: node linkType: hard -"send@npm:^1.1.0, send@npm:^1.2.0": - version: 1.2.1 - resolution: "send@npm:1.2.1" - dependencies: - debug: "npm:^4.4.3" - encodeurl: "npm:^2.0.0" - escape-html: "npm:^1.0.3" - etag: "npm:^1.8.1" - fresh: "npm:^2.0.0" - http-errors: "npm:^2.0.1" - mime-types: "npm:^3.0.2" - ms: "npm:^2.1.3" - on-finished: "npm:^2.4.1" - range-parser: "npm:^1.2.1" - statuses: "npm:^2.0.2" - checksum: 10/274f842d69ccfa49d4940a85598c6825da58dee6cb8ea33b08d5bd3988e6a82267c4d7c32b23d0e4706aad076ee95b1edfa13f859877db9b589829019397e355 - languageName: node - linkType: hard - "serve-static@npm:1.16.2": version: 1.16.2 resolution: "serve-static@npm:1.16.2" @@ -6260,18 +5660,6 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:^2.2.0": - version: 2.2.1 - resolution: "serve-static@npm:2.2.1" - dependencies: - encodeurl: "npm:^2.0.0" - escape-html: "npm:^1.0.3" - parseurl: "npm:^1.3.3" - send: "npm:^1.2.0" - checksum: 10/71500fe80cc7163fec04e4297de7591ad1cb682d137fc030e7a53e57040fda5187e8082a9c1b2ef37f1d3f9c27c9a94d4ba61806ebc28938ba4a7c8947c9f71e - languageName: node - linkType: hard - "set-function-length@npm:^1.2.1": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" @@ -6286,7 +5674,7 @@ __metadata: languageName: node linkType: hard -"setprototypeof@npm:1.2.0, setprototypeof@npm:~1.2.0": +"setprototypeof@npm:1.2.0": version: 1.2.0 resolution: "setprototypeof@npm:1.2.0" checksum: 10/fde1630422502fbbc19e6844346778f99d449986b2f9cdcceb8326730d2f3d9964dbcb03c02aaadaefffecd0f2c063315ebea8b3ad895914bf1afc1747fc172e @@ -6309,41 +5697,6 @@ __metadata: languageName: node linkType: hard -"side-channel-list@npm:^1.0.0": - version: 1.0.1 - resolution: "side-channel-list@npm:1.0.1" - dependencies: - es-errors: "npm:^1.3.0" - object-inspect: "npm:^1.13.4" - checksum: 10/3499671cd52adaee739eac1e14d07530b8e3530192741aeb05e7fe4ad1b51d1368ceea2cd3c21b0f62b05410a5c70a7c4d997ba4b143303ef73d0c65dfd1c252 - languageName: node - linkType: hard - -"side-channel-map@npm:^1.0.1": - version: 1.0.1 - resolution: "side-channel-map@npm:1.0.1" - dependencies: - call-bound: "npm:^1.0.2" - es-errors: "npm:^1.3.0" - get-intrinsic: "npm:^1.2.5" - object-inspect: "npm:^1.13.3" - checksum: 10/5771861f77feefe44f6195ed077a9e4f389acc188f895f570d56445e251b861754b547ea9ef73ecee4e01fdada6568bfe9020d2ec2dfc5571e9fa1bbc4a10615 - languageName: node - linkType: hard - -"side-channel-weakmap@npm:^1.0.2": - version: 1.0.2 - resolution: "side-channel-weakmap@npm:1.0.2" - dependencies: - call-bound: "npm:^1.0.2" - es-errors: "npm:^1.3.0" - get-intrinsic: "npm:^1.2.5" - object-inspect: "npm:^1.13.3" - side-channel-map: "npm:^1.0.1" - checksum: 10/a815c89bc78c5723c714ea1a77c938377ea710af20d4fb886d362b0d1f8ac73a17816a5f6640f354017d7e292a43da9c5e876c22145bac00b76cfb3468001736 - languageName: node - linkType: hard - "side-channel@npm:^1.0.6": version: 1.0.6 resolution: "side-channel@npm:1.0.6" @@ -6356,19 +5709,6 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.1.0": - version: 1.1.0 - resolution: "side-channel@npm:1.1.0" - dependencies: - es-errors: "npm:^1.3.0" - object-inspect: "npm:^1.13.3" - side-channel-list: "npm:^1.0.0" - side-channel-map: "npm:^1.0.1" - side-channel-weakmap: "npm:^1.0.2" - checksum: 10/7d53b9db292c6262f326b6ff3bc1611db84ece36c2c7dc0e937954c13c73185b0406c56589e2bb8d071d6fee468e14c39fb5d203ee39be66b7b8174f179afaba - languageName: node - linkType: hard - "siginfo@npm:^2.0.0": version: 2.0.0 resolution: "siginfo@npm:2.0.0" @@ -6538,13 +5878,6 @@ __metadata: languageName: node linkType: hard -"statuses@npm:^2.0.1, statuses@npm:^2.0.2, statuses@npm:~2.0.2": - version: 2.0.2 - resolution: "statuses@npm:2.0.2" - checksum: 10/6927feb50c2a75b2a4caab2c565491f7a93ad3d8dbad7b1398d52359e9243a20e2ebe35e33726dee945125ef7a515e9097d8a1b910ba2bbd818265a2f6c39879 - languageName: node - linkType: hard - "std-env@npm:^3.9.0": version: 3.9.0 resolution: "std-env@npm:3.9.0" @@ -6801,7 +6134,7 @@ __metadata: languageName: node linkType: hard -"toidentifier@npm:1.0.1, toidentifier@npm:~1.0.1": +"toidentifier@npm:1.0.1": version: 1.0.1 resolution: "toidentifier@npm:1.0.1" checksum: 10/952c29e2a85d7123239b5cfdd889a0dde47ab0497f0913d70588f19c53f7e0b5327c95f4651e413c74b785147f9637b17410ac8c846d5d4a20a5a33eb6dc3a45 @@ -7047,13 +6380,6 @@ __metadata: languageName: node linkType: hard -"tweetnacl@npm:^1.0.3": - version: 1.0.3 - resolution: "tweetnacl@npm:1.0.3" - checksum: 10/ca122c2f86631f3c0f6d28efb44af2a301d4a557a62a3e2460286b08e97567b258c2212e4ad1cfa22bd6a57edcdc54ba76ebe946847450ab0999e6d48ccae332 - languageName: node - linkType: hard - "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -7084,17 +6410,6 @@ __metadata: languageName: node linkType: hard -"type-is@npm:^2.0.1": - version: 2.1.0 - resolution: "type-is@npm:2.1.0" - dependencies: - content-type: "npm:^2.0.0" - media-typer: "npm:^1.1.0" - mime-types: "npm:^3.0.0" - checksum: 10/f011885fefb6c6882f36fab89cc596596b96eab1d208a3774628537cad7ce1f91232a6d758115e1a6ed03f0f8c21e9654bb6d280a5c6827ff72a35f6df0fa182 - languageName: node - linkType: hard - "type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" @@ -7323,7 +6638,7 @@ __metadata: languageName: node linkType: hard -"vary@npm:^1.1.2, vary@npm:~1.1.2": +"vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" checksum: 10/31389debef15a480849b8331b220782230b9815a8e0dbb7b9a8369559aed2e9a7800cd904d4371ea74f4c3527db456dc8e7ac5befce5f0d289014dbdf47b2242 @@ -7351,7 +6666,7 @@ __metadata: languageName: node linkType: hard -"viem@npm:^2.31.4, viem@npm:^2.48.11": +"viem@npm:^2.48.11": version: 2.49.2 resolution: "viem@npm:2.49.2" dependencies: From e01d71e2a7b729b720c247ecfaaeab2e4159d240 Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Wed, 20 May 2026 11:35:43 +1200 Subject: [PATCH 10/18] Kind.extras may have 'facilitatorAddresses' (plural) instead of singular --- .../smart-accounts-kit-x402/src/x402Server.ts | 63 +++++++++++++++---- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/packages/smart-accounts-kit-x402/src/x402Server.ts b/packages/smart-accounts-kit-x402/src/x402Server.ts index 346fceea..02e71c5b 100644 --- a/packages/smart-accounts-kit-x402/src/x402Server.ts +++ b/packages/smart-accounts-kit-x402/src/x402Server.ts @@ -6,6 +6,52 @@ export type x402Erc7710ServerConfig = { allowAssetTransferMethodOverride?: boolean; }; +function validateFacilitatorAddresses( + publishedAddresses: unknown, +): string[] | undefined { + if (publishedAddresses === undefined) { + return undefined; + } + + if (!Array.isArray(publishedAddresses)) { + throw new Error( + 'Invalid facilitatorAddresses specified: expected an array of addresses', + ); + } + + if (publishedAddresses.length === 0) { + throw new Error( + 'Invalid facilitatorAddresses specified: expected at least one address', + ); + } + + const normalizedAddresses: string[] = []; + const validationErrors: string[] = []; + + publishedAddresses.forEach((address, index) => { + if (typeof address !== 'string') { + validationErrors.push(`facilitatorAddresses[${index}] must be a string`); + return; + } + + try { + normalizedAddresses.push(getAddress(address)); + } catch { + validationErrors.push( + `facilitatorAddresses[${index}] is not a valid address: "${address}"`, + ); + } + }); + + if (validationErrors.length > 0) { + throw new Error( + `Invalid facilitatorAddresses specified: ${validationErrors.join('; ')}`, + ); + } + + return normalizedAddresses; +} + /** * x402 `SchemeNetworkServer`-compatible implementation for publishing * `assetTransferMethod: "erc7710"` in payment requirements. @@ -41,24 +87,15 @@ export class x402Erc7710Server { ); } - const facilitatorAddress = (() => { - const publishedAddress = supportedKind.extra?.facilitatorAddress; - if (typeof publishedAddress !== 'string') { - return undefined; - } - - try { - return getAddress(publishedAddress); - } catch { - return undefined; - } - })(); + const facilitatorAddresses = validateFacilitatorAddresses( + supportedKind.extra?.facilitatorAddresses, + ); return { ...paymentRequirements, extra: { ...(paymentRequirements.extra ?? {}), - ...(facilitatorAddress ? { facilitatorAddress } : {}), + ...(facilitatorAddresses ? { facilitatorAddresses } : {}), assetTransferMethod: 'erc7710', }, }; From d2b25750012c2c2112a9bac9197fb2d1d183df48 Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Wed, 20 May 2026 11:46:53 +1200 Subject: [PATCH 11/18] Add unit tests --- packages/smart-accounts-kit-x402/package.json | 5 +- .../test/x402Client.test.ts | 132 +++++++++++++++ .../x402ExactEvmErc7710ServerScheme.test.ts | 95 +++++++++++ .../test/x402Server.test.ts | 154 ++++++++++++++++++ yarn.lock | 1 + 5 files changed, 386 insertions(+), 1 deletion(-) create mode 100644 packages/smart-accounts-kit-x402/test/x402Client.test.ts create mode 100644 packages/smart-accounts-kit-x402/test/x402ExactEvmErc7710ServerScheme.test.ts create mode 100644 packages/smart-accounts-kit-x402/test/x402Server.test.ts diff --git a/packages/smart-accounts-kit-x402/package.json b/packages/smart-accounts-kit-x402/package.json index a4e2ce64..dd8b9738 100644 --- a/packages/smart-accounts-kit-x402/package.json +++ b/packages/smart-accounts-kit-x402/package.json @@ -43,6 +43,8 @@ "scripts": { "build": "yarn typecheck && tsup", "typecheck": "tsc --noEmit", + "test": "vitest run --coverage", + "test:watch": "vitest watch", "lint": "yarn lint:eslint", "lint:eslint": "eslint . --cache --ext js,ts", "lint:fix": "yarn lint:eslint --fix", @@ -66,6 +68,7 @@ "prettier": "^3.5.3", "tsup": "^8.5.0", "typescript": "5.5.4", - "viem": "2.31.4" + "viem": "2.31.4", + "vitest": "^3.2.4" } } diff --git a/packages/smart-accounts-kit-x402/test/x402Client.test.ts b/packages/smart-accounts-kit-x402/test/x402Client.test.ts new file mode 100644 index 00000000..12a669ec --- /dev/null +++ b/packages/smart-accounts-kit-x402/test/x402Client.test.ts @@ -0,0 +1,132 @@ +import { describe, expect, it, vi } from 'vitest'; + +import type { x402PaymentRequirements } from '../src/x402Client'; +import { x402Erc7710Client } from '../src/x402Client'; + +const baseRequirements: x402PaymentRequirements = { + scheme: 'exact', + network: 'eip155:8453', + asset: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + amount: '1000', + payTo: '0x1111111111111111111111111111111111111111', + maxTimeoutSeconds: 300, + extra: { + assetTransferMethod: 'erc7710', + }, +}; + +describe('x402Erc7710Client', () => { + it('exposes the exact scheme identifier', () => { + const client = new x402Erc7710Client({ + delegationProvider: vi.fn(), + }); + + expect(client.scheme).toBe('exact'); + }); + + it('creates an ERC-7710 payload and normalizes addresses', async () => { + const delegationProvider = vi.fn().mockResolvedValue({ + delegationManager: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + permissionContext: '0x1234', + delegator: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', + }); + const client = new x402Erc7710Client({ delegationProvider }); + + const payload = await client.createPaymentPayload(2, baseRequirements); + + expect(delegationProvider).toHaveBeenCalledWith(baseRequirements); + expect(payload).toEqual({ + x402Version: 2, + payload: { + delegationManager: '0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa', + permissionContext: '0x1234', + delegator: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + }); + }); + + it('throws when permissionContext is empty hex', async () => { + const client = new x402Erc7710Client({ + delegationProvider: vi.fn().mockResolvedValue({ + delegationManager: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + permissionContext: '0x', + delegator: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', + }), + }); + + await expect(client.createPaymentPayload(2, baseRequirements)).rejects.toThrow( + 'Invalid delegation payload: permissionContext must be non-empty hex data', + ); + }); + + it('throws when permissionContext is not hex', async () => { + const client = new x402Erc7710Client({ + delegationProvider: vi.fn().mockResolvedValue({ + delegationManager: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + permissionContext: 'not-hex', + delegator: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', + }), + }); + + await expect(client.createPaymentPayload(2, baseRequirements)).rejects.toThrow( + 'Invalid delegation payload: permissionContext must be non-empty hex data', + ); + }); + + it('delegates to fallback client for non-erc7710 methods', async () => { + const fallbackResult = { + x402Version: 2, + payload: { kind: 'fallback' }, + }; + const fallbackClient = { + scheme: 'exact', + createPaymentPayload: vi.fn().mockResolvedValue(fallbackResult), + }; + const client = new x402Erc7710Client({ + delegationProvider: vi.fn(), + fallbackClient, + }); + const requirements: x402PaymentRequirements = { + ...baseRequirements, + extra: { assetTransferMethod: 'eip3009' }, + }; + const context = { marker: 'ctx' }; + + const result = await client.createPaymentPayload(2, requirements, context); + + expect(fallbackClient.createPaymentPayload).toHaveBeenCalledWith( + 2, + requirements, + context, + ); + expect(result).toEqual(fallbackResult); + }); + + it('throws for non-erc7710 methods without fallback', async () => { + const client = new x402Erc7710Client({ + delegationProvider: vi.fn(), + }); + const requirements: x402PaymentRequirements = { + ...baseRequirements, + extra: { assetTransferMethod: 'eip3009' }, + }; + + await expect(client.createPaymentPayload(2, requirements)).rejects.toThrow( + 'x402Erc7710Client can only process assetTransferMethod "erc7710". Received: "eip3009"', + ); + }); + + it('throws with undefined method when extra is missing', async () => { + const client = new x402Erc7710Client({ + delegationProvider: vi.fn(), + }); + const requirements: x402PaymentRequirements = { + ...baseRequirements, + extra: undefined, + }; + + await expect(client.createPaymentPayload(2, requirements)).rejects.toThrow( + 'x402Erc7710Client can only process assetTransferMethod "erc7710". Received: undefined', + ); + }); +}); diff --git a/packages/smart-accounts-kit-x402/test/x402ExactEvmErc7710ServerScheme.test.ts b/packages/smart-accounts-kit-x402/test/x402ExactEvmErc7710ServerScheme.test.ts new file mode 100644 index 00000000..96f0cc0a --- /dev/null +++ b/packages/smart-accounts-kit-x402/test/x402ExactEvmErc7710ServerScheme.test.ts @@ -0,0 +1,95 @@ +import type { PaymentRequirements } from '@x402/core/types'; +import { ExactEvmScheme } from '@x402/evm/exact/server'; +import { afterEach, describe, expect, it, vi } from 'vitest'; + +import { x402ExactEvmErc7710ServerScheme } from '../src/x402ExactEvmErc7710ServerScheme'; +import { x402Erc7710Server } from '../src/x402Server'; + +describe('x402ExactEvmErc7710ServerScheme', () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('returns base requirements unchanged for non-erc7710 methods', async () => { + const baseRequirements = { + scheme: 'exact', + network: 'eip155:8453', + asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + amount: '1000', + payTo: '0x1111111111111111111111111111111111111111', + maxTimeoutSeconds: 300, + extra: { assetTransferMethod: 'eip3009' }, + } as unknown as PaymentRequirements; + const superSpy = vi + .spyOn(ExactEvmScheme.prototype, 'enhancePaymentRequirements') + .mockResolvedValue(baseRequirements); + const erc7710Spy = vi.spyOn( + x402Erc7710Server.prototype, + 'enhancePaymentRequirements', + ); + const scheme = new x402ExactEvmErc7710ServerScheme(); + const supportedKind = { + x402Version: 2, + scheme: 'exact', + network: 'eip155:8453' as const, + }; + const facilitatorExtensions = ['extension']; + + const result = await scheme.enhancePaymentRequirements( + baseRequirements, + supportedKind, + facilitatorExtensions, + ); + + expect(superSpy).toHaveBeenCalledWith( + baseRequirements, + supportedKind, + facilitatorExtensions, + ); + expect(erc7710Spy).not.toHaveBeenCalled(); + expect(result).toBe(baseRequirements); + }); + + it('enhances requirements for erc7710 methods', async () => { + const baseRequirements = { + scheme: 'exact', + network: 'eip155:8453', + asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + amount: '1000', + payTo: '0x1111111111111111111111111111111111111111', + maxTimeoutSeconds: 300, + extra: { assetTransferMethod: 'erc7710' }, + } as unknown as PaymentRequirements; + const enhancedRequirements = { + ...baseRequirements, + extra: { + ...baseRequirements.extra, + facilitatorAddresses: ['0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa'], + }, + } as unknown as PaymentRequirements; + vi.spyOn(ExactEvmScheme.prototype, 'enhancePaymentRequirements').mockResolvedValue( + baseRequirements, + ); + const erc7710Spy = vi + .spyOn(x402Erc7710Server.prototype, 'enhancePaymentRequirements') + .mockResolvedValue(enhancedRequirements); + const scheme = new x402ExactEvmErc7710ServerScheme(); + const supportedKind = { + x402Version: 2, + scheme: 'exact', + network: 'eip155:8453' as const, + extra: { + facilitatorAddresses: ['0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'], + }, + }; + + const result = await scheme.enhancePaymentRequirements( + baseRequirements, + supportedKind, + [], + ); + + expect(erc7710Spy).toHaveBeenCalledWith(baseRequirements, supportedKind); + expect(result).toEqual(enhancedRequirements); + }); +}); diff --git a/packages/smart-accounts-kit-x402/test/x402Server.test.ts b/packages/smart-accounts-kit-x402/test/x402Server.test.ts new file mode 100644 index 00000000..3a1138ab --- /dev/null +++ b/packages/smart-accounts-kit-x402/test/x402Server.test.ts @@ -0,0 +1,154 @@ +import { describe, expect, it } from 'vitest'; + +import type { x402PaymentRequirements } from '../src/x402Client'; +import { x402Erc7710Server } from '../src/x402Server'; + +const baseRequirements: x402PaymentRequirements = { + scheme: 'exact', + network: 'eip155:8453', + asset: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + amount: '1000', + payTo: '0x1111111111111111111111111111111111111111', + maxTimeoutSeconds: 300, + extra: {}, +}; + +describe('x402Erc7710Server', () => { + it('exposes the exact scheme identifier', () => { + const server = new x402Erc7710Server(); + + expect(server.scheme).toBe('exact'); + }); + + it('sets assetTransferMethod to erc7710', async () => { + const server = new x402Erc7710Server(); + + const result = await server.enhancePaymentRequirements(baseRequirements, {}); + + expect(result.extra?.assetTransferMethod).toBe('erc7710'); + }); + + it('handles payment requirements with no extra', async () => { + const server = new x402Erc7710Server(); + const requirementsWithoutExtra: x402PaymentRequirements = { + ...baseRequirements, + extra: undefined, + }; + + const result = await server.enhancePaymentRequirements( + requirementsWithoutExtra, + {}, + ); + + expect(result.extra).toEqual({ + assetTransferMethod: 'erc7710', + }); + }); + + it('preserves existing extra fields', async () => { + const server = new x402Erc7710Server(); + const requirements: x402PaymentRequirements = { + ...baseRequirements, + extra: { existing: 'value' }, + }; + + const result = await server.enhancePaymentRequirements(requirements, {}); + + expect(result.extra).toMatchObject({ + existing: 'value', + assetTransferMethod: 'erc7710', + }); + }); + + it('throws when overwriting a different method is not allowed', async () => { + const server = new x402Erc7710Server(); + const requirements: x402PaymentRequirements = { + ...baseRequirements, + extra: { assetTransferMethod: 'eip3009' }, + }; + + await expect(server.enhancePaymentRequirements(requirements, {})).rejects.toThrow( + 'Cannot overwrite existing assetTransferMethod "eip3009" with "erc7710"', + ); + }); + + it('allows overwriting when configured', async () => { + const server = new x402Erc7710Server({ + allowAssetTransferMethodOverride: true, + }); + const requirements: x402PaymentRequirements = { + ...baseRequirements, + extra: { assetTransferMethod: 'eip3009' }, + }; + + const result = await server.enhancePaymentRequirements(requirements, {}); + + expect(result.extra?.assetTransferMethod).toBe('erc7710'); + }); + + it('does not set facilitatorAddresses when field is missing', async () => { + const server = new x402Erc7710Server(); + + const result = await server.enhancePaymentRequirements(baseRequirements, { + extra: {}, + }); + + expect(result.extra?.facilitatorAddresses).toBeUndefined(); + }); + + it('normalizes and sets facilitatorAddresses when valid', async () => { + const server = new x402Erc7710Server(); + + const result = await server.enhancePaymentRequirements(baseRequirements, { + extra: { + facilitatorAddresses: [ + '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', + ], + }, + }); + + expect(result.extra?.facilitatorAddresses).toEqual([ + '0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa', + '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + ]); + }); + + it('throws when facilitatorAddresses is not an array', async () => { + const server = new x402Erc7710Server(); + + await expect( + server.enhancePaymentRequirements(baseRequirements, { + extra: { facilitatorAddresses: 'not-array' }, + }), + ).rejects.toThrow( + 'Invalid facilitatorAddresses specified: expected an array of addresses', + ); + }); + + it('throws when facilitatorAddresses is empty', async () => { + const server = new x402Erc7710Server(); + + await expect( + server.enhancePaymentRequirements(baseRequirements, { + extra: { facilitatorAddresses: [] }, + }), + ).rejects.toThrow( + 'Invalid facilitatorAddresses specified: expected at least one address', + ); + }); + + it('throws detailed errors for invalid facilitatorAddresses values', async () => { + const server = new x402Erc7710Server(); + + await expect( + server.enhancePaymentRequirements(baseRequirements, { + extra: { + facilitatorAddresses: [123, 'not-an-address'], + }, + }), + ).rejects.toThrow( + 'Invalid facilitatorAddresses specified: facilitatorAddresses[0] must be a string; facilitatorAddresses[1] is not a valid address: "not-an-address"', + ); + }); +}); diff --git a/yarn.lock b/yarn.lock index 7643c7fa..bbcea1d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -782,6 +782,7 @@ __metadata: tsup: "npm:^8.5.0" typescript: "npm:5.5.4" viem: "npm:2.31.4" + vitest: "npm:^3.2.4" peerDependencies: "@x402/core": ^2.12.0 "@x402/evm": ^2.12.0 From 228e1201df136c6c1ad3d921ad81736308d44ae1 Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Wed, 20 May 2026 11:58:58 +1200 Subject: [PATCH 12/18] Fix linting --- .../smart-accounts-kit-x402/eslint.config.mjs | 52 ++++++++++++++++++- packages/smart-accounts-kit-x402/src/index.ts | 5 +- .../smart-accounts-kit-x402/src/x402Client.ts | 6 +++ .../src/x402ExactEvmErc7710ServerScheme.ts | 9 ++-- .../smart-accounts-kit-x402/src/x402Server.ts | 6 +++ .../test/x402Client.test.ts | 8 ++- .../x402ExactEvmErc7710ServerScheme.test.ts | 7 +-- .../test/x402Server.test.ts | 9 +++- 8 files changed, 86 insertions(+), 16 deletions(-) diff --git a/packages/smart-accounts-kit-x402/eslint.config.mjs b/packages/smart-accounts-kit-x402/eslint.config.mjs index 253f98a3..b80d3437 100644 --- a/packages/smart-accounts-kit-x402/eslint.config.mjs +++ b/packages/smart-accounts-kit-x402/eslint.config.mjs @@ -1,2 +1,52 @@ // eslint-disable-next-line -export { default } from '../../shared/config/base.eslint.mjs'; +import baseConfig from '../../shared/config/base.eslint.mjs'; + +const withX402NamingExceptions = baseConfig.map((entry) => { + const namingConventionRule = + entry.rules?.['@typescript-eslint/naming-convention']; + + if (!Array.isArray(namingConventionRule)) { + return entry; + } + + const [level, ...conventions] = namingConventionRule; + + return { + ...entry, + rules: { + ...entry.rules, + '@typescript-eslint/naming-convention': [ + level, + { + selector: ['class', 'typeAlias'], + filter: { + regex: '^x402[A-Z].*$', + match: true, + }, + format: null, + }, + ...conventions, + ], + }, + }; +}); + +const config = [ + ...withX402NamingExceptions, + { + files: ['**/*.ts', '**/*.tsx'], + rules: { + 'new-cap': [ + 'error', + { + newIsCap: true, + newIsCapExceptionPattern: '^x402[A-Z]', + capIsNew: true, + properties: true, + }, + ], + }, + }, +]; + +export default config; diff --git a/packages/smart-accounts-kit-x402/src/index.ts b/packages/smart-accounts-kit-x402/src/index.ts index 39f9dbec..03c9dfb3 100644 --- a/packages/smart-accounts-kit-x402/src/index.ts +++ b/packages/smart-accounts-kit-x402/src/index.ts @@ -7,8 +7,5 @@ export { type x402SchemeNetworkClientLike, type x402Erc7710ClientConfig, } from './x402Client'; -export { - x402Erc7710Server, - type x402Erc7710ServerConfig, -} from './x402Server'; +export { x402Erc7710Server, type x402Erc7710ServerConfig } from './x402Server'; export { x402ExactEvmErc7710ServerScheme } from './x402ExactEvmErc7710ServerScheme'; diff --git a/packages/smart-accounts-kit-x402/src/x402Client.ts b/packages/smart-accounts-kit-x402/src/x402Client.ts index 7a79072f..021e6050 100644 --- a/packages/smart-accounts-kit-x402/src/x402Client.ts +++ b/packages/smart-accounts-kit-x402/src/x402Client.ts @@ -40,6 +40,12 @@ export type x402Erc7710ClientConfig = { fallbackClient?: x402SchemeNetworkClientLike; }; +/** + * Normalize and validate a delegation payload before publishing it. + * + * @param payload - Delegation payload returned by the configured provider. + * @returns The normalized payload with checksum addresses. + */ function normalizeDelegationPayload( payload: x402DelegationPaymentPayload, ): x402DelegationPaymentPayload { diff --git a/packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts b/packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts index 10ea9772..380ccb76 100644 --- a/packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts +++ b/packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts @@ -29,10 +29,11 @@ export class x402ExactEvmErc7710ServerScheme extends ExactEvmScheme { return baseRequirements; } - const enhancedRequirements = await this.#erc7710Server.enhancePaymentRequirements( - baseRequirements, - supportedKind, - ); + const enhancedRequirements = + await this.#erc7710Server.enhancePaymentRequirements( + baseRequirements, + supportedKind, + ); return enhancedRequirements as PaymentRequirements; } diff --git a/packages/smart-accounts-kit-x402/src/x402Server.ts b/packages/smart-accounts-kit-x402/src/x402Server.ts index 02e71c5b..72d0b158 100644 --- a/packages/smart-accounts-kit-x402/src/x402Server.ts +++ b/packages/smart-accounts-kit-x402/src/x402Server.ts @@ -6,6 +6,12 @@ export type x402Erc7710ServerConfig = { allowAssetTransferMethodOverride?: boolean; }; +/** + * Validate and normalize optional facilitator address metadata. + * + * @param publishedAddresses - Optional facilitator address list from `supportedKind.extra`. + * @returns A normalized checksum address list, or `undefined` when no list is provided. + */ function validateFacilitatorAddresses( publishedAddresses: unknown, ): string[] | undefined { diff --git a/packages/smart-accounts-kit-x402/test/x402Client.test.ts b/packages/smart-accounts-kit-x402/test/x402Client.test.ts index 12a669ec..f9e50b0c 100644 --- a/packages/smart-accounts-kit-x402/test/x402Client.test.ts +++ b/packages/smart-accounts-kit-x402/test/x402Client.test.ts @@ -54,7 +54,9 @@ describe('x402Erc7710Client', () => { }), }); - await expect(client.createPaymentPayload(2, baseRequirements)).rejects.toThrow( + await expect( + client.createPaymentPayload(2, baseRequirements), + ).rejects.toThrow( 'Invalid delegation payload: permissionContext must be non-empty hex data', ); }); @@ -68,7 +70,9 @@ describe('x402Erc7710Client', () => { }), }); - await expect(client.createPaymentPayload(2, baseRequirements)).rejects.toThrow( + await expect( + client.createPaymentPayload(2, baseRequirements), + ).rejects.toThrow( 'Invalid delegation payload: permissionContext must be non-empty hex data', ); }); diff --git a/packages/smart-accounts-kit-x402/test/x402ExactEvmErc7710ServerScheme.test.ts b/packages/smart-accounts-kit-x402/test/x402ExactEvmErc7710ServerScheme.test.ts index 96f0cc0a..2a4721fb 100644 --- a/packages/smart-accounts-kit-x402/test/x402ExactEvmErc7710ServerScheme.test.ts +++ b/packages/smart-accounts-kit-x402/test/x402ExactEvmErc7710ServerScheme.test.ts @@ -67,9 +67,10 @@ describe('x402ExactEvmErc7710ServerScheme', () => { facilitatorAddresses: ['0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa'], }, } as unknown as PaymentRequirements; - vi.spyOn(ExactEvmScheme.prototype, 'enhancePaymentRequirements').mockResolvedValue( - baseRequirements, - ); + vi.spyOn( + ExactEvmScheme.prototype, + 'enhancePaymentRequirements', + ).mockResolvedValue(baseRequirements); const erc7710Spy = vi .spyOn(x402Erc7710Server.prototype, 'enhancePaymentRequirements') .mockResolvedValue(enhancedRequirements); diff --git a/packages/smart-accounts-kit-x402/test/x402Server.test.ts b/packages/smart-accounts-kit-x402/test/x402Server.test.ts index 3a1138ab..1946817d 100644 --- a/packages/smart-accounts-kit-x402/test/x402Server.test.ts +++ b/packages/smart-accounts-kit-x402/test/x402Server.test.ts @@ -23,7 +23,10 @@ describe('x402Erc7710Server', () => { it('sets assetTransferMethod to erc7710', async () => { const server = new x402Erc7710Server(); - const result = await server.enhancePaymentRequirements(baseRequirements, {}); + const result = await server.enhancePaymentRequirements( + baseRequirements, + {}, + ); expect(result.extra?.assetTransferMethod).toBe('erc7710'); }); @@ -67,7 +70,9 @@ describe('x402Erc7710Server', () => { extra: { assetTransferMethod: 'eip3009' }, }; - await expect(server.enhancePaymentRequirements(requirements, {})).rejects.toThrow( + await expect( + server.enhancePaymentRequirements(requirements, {}), + ).rejects.toThrow( 'Cannot overwrite existing assetTransferMethod "eip3009" with "erc7710"', ); }); From d0d8131c62c9d7b5370bdab45556bb0d5a0bb9ab Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Wed, 20 May 2026 11:59:05 +1200 Subject: [PATCH 13/18] Update changelog --- packages/smart-accounts-kit-x402/CHANGELOG.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/smart-accounts-kit-x402/CHANGELOG.md b/packages/smart-accounts-kit-x402/CHANGELOG.md index 5e4e559c..14fbac25 100644 --- a/packages/smart-accounts-kit-x402/CHANGELOG.md +++ b/packages/smart-accounts-kit-x402/CHANGELOG.md @@ -1,3 +1,14 @@ # Changelog -All notable changes to `@metamask/smart-accounts-kit-x402` will be documented in this file. +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +- New @metamask/smart-accounts-kit-x402 package providing plugins to @x402 packages ([#236](https://github.com/MetaMask/smart-accounts-kit/pull/236)) + +[Unreleased]: https://github.com/metamask/smart-accounts-kit/ From 1af3006504de630a8e5273f13746e421f8b38a9d Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Wed, 20 May 2026 12:03:08 +1200 Subject: [PATCH 14/18] @metamask/smart-accounts-kit-x402 version changed to 0.0.0 --- packages/smart-accounts-kit-x402/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/smart-accounts-kit-x402/package.json b/packages/smart-accounts-kit-x402/package.json index dd8b9738..448aa126 100644 --- a/packages/smart-accounts-kit-x402/package.json +++ b/packages/smart-accounts-kit-x402/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/smart-accounts-kit-x402", - "version": "0.1.0", + "version": "0.0.0", "description": "x402 adapters for MetaMask smart accounts and ERC-7710", "license": "(MIT-0 OR Apache-2.0)", "type": "module", From 30085fa3507fc66e4bebbbd4993b4adc728c050c Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Wed, 20 May 2026 13:08:37 +1200 Subject: [PATCH 15/18] Revert yarn.config.cjs --- yarn.config.cjs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/yarn.config.cjs b/yarn.config.cjs index 85a186f5..bf1af083 100644 --- a/yarn.config.cjs +++ b/yarn.config.cjs @@ -47,11 +47,9 @@ module.exports = defineConfig({ '', ); - // filter out packages that are examples or likely to be reworked + // filter out the e2e package, as it is likely going to be removed or reworked const workspaces = Yarn.workspaces().filter( - (workspace) => - getWorkspaceBasename(workspace) !== 'delegator-e2e' && - getWorkspaceBasename(workspace) !== 'x402-example', + (workspace) => getWorkspaceBasename(workspace) !== 'delegator-e2e', ); for (const workspace of workspaces) { From 66cc06abdefe252387e70e53100ce2d94601944a Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Wed, 20 May 2026 16:36:18 +1200 Subject: [PATCH 16/18] Stringify invalid transfer method when creating error object --- packages/smart-accounts-kit-x402/src/x402Client.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/smart-accounts-kit-x402/src/x402Client.ts b/packages/smart-accounts-kit-x402/src/x402Client.ts index 021e6050..6318dceb 100644 --- a/packages/smart-accounts-kit-x402/src/x402Client.ts +++ b/packages/smart-accounts-kit-x402/src/x402Client.ts @@ -96,12 +96,13 @@ export class x402Erc7710Client { ); } + const invalidAssetTransferMethod = + typeof assetTransferMethod === 'string' + ? `"${assetTransferMethod}"` + : JSON.stringify(assetTransferMethod); + throw new Error( - `x402Erc7710Client can only process assetTransferMethod "erc7710". Received: ${ - typeof assetTransferMethod === 'string' - ? `"${assetTransferMethod}"` - : 'undefined' - }`, + `x402Erc7710Client can only process assetTransferMethod "erc7710". Received: ${invalidAssetTransferMethod}$`, ); } From f3a507044571e5e97357ddf56c3d1bd428d66fa5 Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Wed, 20 May 2026 17:19:20 +1200 Subject: [PATCH 17/18] PR fixes: - License files - Incorrect error string literal template - Correct typing of validateFacilitatorAddresses return type --- .../smart-accounts-kit-x402/LICENSE.APACHE2 | 204 +++++++++++++++++- packages/smart-accounts-kit-x402/LICENSE.MIT0 | 17 +- .../smart-accounts-kit-x402/src/x402Client.ts | 2 +- .../smart-accounts-kit-x402/src/x402Server.ts | 6 +- 4 files changed, 221 insertions(+), 8 deletions(-) diff --git a/packages/smart-accounts-kit-x402/LICENSE.APACHE2 b/packages/smart-accounts-kit-x402/LICENSE.APACHE2 index f6b06388..49966a71 100644 --- a/packages/smart-accounts-kit-x402/LICENSE.APACHE2 +++ b/packages/smart-accounts-kit-x402/LICENSE.APACHE2 @@ -1,3 +1,201 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2022 ConsenSys Software Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/smart-accounts-kit-x402/LICENSE.MIT0 b/packages/smart-accounts-kit-x402/LICENSE.MIT0 index 61e7a4d6..74e1d3df 100644 --- a/packages/smart-accounts-kit-x402/LICENSE.MIT0 +++ b/packages/smart-accounts-kit-x402/LICENSE.MIT0 @@ -1 +1,16 @@ -MIT No Attribution License (MIT-0) +MIT No Attribution + +Copyright 2022 ConsenSys Software Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/smart-accounts-kit-x402/src/x402Client.ts b/packages/smart-accounts-kit-x402/src/x402Client.ts index 6318dceb..c2b0b02d 100644 --- a/packages/smart-accounts-kit-x402/src/x402Client.ts +++ b/packages/smart-accounts-kit-x402/src/x402Client.ts @@ -102,7 +102,7 @@ export class x402Erc7710Client { : JSON.stringify(assetTransferMethod); throw new Error( - `x402Erc7710Client can only process assetTransferMethod "erc7710". Received: ${invalidAssetTransferMethod}$`, + `x402Erc7710Client can only process assetTransferMethod "erc7710". Received: ${invalidAssetTransferMethod}`, ); } diff --git a/packages/smart-accounts-kit-x402/src/x402Server.ts b/packages/smart-accounts-kit-x402/src/x402Server.ts index 72d0b158..784958a7 100644 --- a/packages/smart-accounts-kit-x402/src/x402Server.ts +++ b/packages/smart-accounts-kit-x402/src/x402Server.ts @@ -1,4 +1,4 @@ -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import type { x402PaymentRequirements } from './x402Client'; @@ -14,7 +14,7 @@ export type x402Erc7710ServerConfig = { */ function validateFacilitatorAddresses( publishedAddresses: unknown, -): string[] | undefined { +): Address[] | undefined { if (publishedAddresses === undefined) { return undefined; } @@ -31,7 +31,7 @@ function validateFacilitatorAddresses( ); } - const normalizedAddresses: string[] = []; + const normalizedAddresses: Address[] = []; const validationErrors: string[] = []; publishedAddresses.forEach((address, index) => { From 6ce7ce8de4c68abdf1ebfc0b79c9deabeec44ca3 Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Wed, 20 May 2026 19:53:21 +1200 Subject: [PATCH 18/18] Rename @metamask/smart-accounts-kit-x402 to @metamask/x402 --- .github/CODEOWNERS | 2 +- .../CHANGELOG.md | 2 +- .../LICENSE.APACHE2 | 0 .../LICENSE.MIT0 | 0 .../README.md | 6 +-- .../eslint.config.mjs | 0 .../package.json | 8 ++-- .../src/index.ts | 0 .../src/x402Client.ts | 0 .../src/x402ExactEvmErc7710ServerScheme.ts | 0 .../src/x402Server.ts | 0 .../test/x402Client.test.ts | 0 .../x402ExactEvmErc7710ServerScheme.test.ts | 0 .../test/x402Server.test.ts | 0 .../tsconfig.json | 0 .../tsup.config.ts | 0 yarn.lock | 40 +++++++++---------- 17 files changed, 29 insertions(+), 29 deletions(-) rename packages/{smart-accounts-kit-x402 => x402}/CHANGELOG.md (69%) rename packages/{smart-accounts-kit-x402 => x402}/LICENSE.APACHE2 (100%) rename packages/{smart-accounts-kit-x402 => x402}/LICENSE.MIT0 (100%) rename packages/{smart-accounts-kit-x402 => x402}/README.md (74%) rename packages/{smart-accounts-kit-x402 => x402}/eslint.config.mjs (100%) rename packages/{smart-accounts-kit-x402 => x402}/package.json (91%) rename packages/{smart-accounts-kit-x402 => x402}/src/index.ts (100%) rename packages/{smart-accounts-kit-x402 => x402}/src/x402Client.ts (100%) rename packages/{smart-accounts-kit-x402 => x402}/src/x402ExactEvmErc7710ServerScheme.ts (100%) rename packages/{smart-accounts-kit-x402 => x402}/src/x402Server.ts (100%) rename packages/{smart-accounts-kit-x402 => x402}/test/x402Client.test.ts (100%) rename packages/{smart-accounts-kit-x402 => x402}/test/x402ExactEvmErc7710ServerScheme.test.ts (100%) rename packages/{smart-accounts-kit-x402 => x402}/test/x402Server.test.ts (100%) rename packages/{smart-accounts-kit-x402 => x402}/tsconfig.json (100%) rename packages/{smart-accounts-kit-x402 => x402}/tsup.config.ts (100%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 53cbb700..2e8915e1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -13,5 +13,5 @@ /packages/delegation-core @MetaMask/delegation /packages/delegation-deployments @MetaMask/delegation /packages/smart-accounts-kit @MetaMask/delegation -/packages/smart-accounts-kit-x402 @MetaMask/delegation +/packages/x402 @MetaMask/delegation /packages/7715-permission-types @MetaMask/delegation diff --git a/packages/smart-accounts-kit-x402/CHANGELOG.md b/packages/x402/CHANGELOG.md similarity index 69% rename from packages/smart-accounts-kit-x402/CHANGELOG.md rename to packages/x402/CHANGELOG.md index 14fbac25..c10aef61 100644 --- a/packages/smart-accounts-kit-x402/CHANGELOG.md +++ b/packages/x402/CHANGELOG.md @@ -9,6 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- New @metamask/smart-accounts-kit-x402 package providing plugins to @x402 packages ([#236](https://github.com/MetaMask/smart-accounts-kit/pull/236)) +- New @metamask/x402 package providing plugins to @x402 packages ([#236](https://github.com/MetaMask/smart-accounts-kit/pull/236)) [Unreleased]: https://github.com/metamask/smart-accounts-kit/ diff --git a/packages/smart-accounts-kit-x402/LICENSE.APACHE2 b/packages/x402/LICENSE.APACHE2 similarity index 100% rename from packages/smart-accounts-kit-x402/LICENSE.APACHE2 rename to packages/x402/LICENSE.APACHE2 diff --git a/packages/smart-accounts-kit-x402/LICENSE.MIT0 b/packages/x402/LICENSE.MIT0 similarity index 100% rename from packages/smart-accounts-kit-x402/LICENSE.MIT0 rename to packages/x402/LICENSE.MIT0 diff --git a/packages/smart-accounts-kit-x402/README.md b/packages/x402/README.md similarity index 74% rename from packages/smart-accounts-kit-x402/README.md rename to packages/x402/README.md index 1f342f29..e4dbb775 100644 --- a/packages/smart-accounts-kit-x402/README.md +++ b/packages/x402/README.md @@ -1,12 +1,12 @@ -# @metamask/smart-accounts-kit-x402 +# @metamask/x402 x402 adapters for ERC-7710 payment requirement publishing and payload creation. ## Installation ```bash -yarn add @metamask/smart-accounts-kit-x402 -npm install @metamask/smart-accounts-kit-x402 +yarn add @metamask/x402 +npm install @metamask/x402 ``` ## Exports diff --git a/packages/smart-accounts-kit-x402/eslint.config.mjs b/packages/x402/eslint.config.mjs similarity index 100% rename from packages/smart-accounts-kit-x402/eslint.config.mjs rename to packages/x402/eslint.config.mjs diff --git a/packages/smart-accounts-kit-x402/package.json b/packages/x402/package.json similarity index 91% rename from packages/smart-accounts-kit-x402/package.json rename to packages/x402/package.json index 448aa126..0ad24c9f 100644 --- a/packages/smart-accounts-kit-x402/package.json +++ b/packages/x402/package.json @@ -1,5 +1,5 @@ { - "name": "@metamask/smart-accounts-kit-x402", + "name": "@metamask/x402", "version": "0.0.0", "description": "x402 adapters for MetaMask smart accounts and ERC-7710", "license": "(MIT-0 OR Apache-2.0)", @@ -8,7 +8,7 @@ "MetaMask", "Ethereum" ], - "homepage": "https://github.com/metamask/smart-accounts-kit/tree/main/packages/smart-accounts-kit-x402#readme", + "homepage": "https://github.com/metamask/smart-accounts-kit/tree/main/packages/x402#readme", "bugs": { "url": "https://github.com/metamask/smart-accounts-kit/issues" }, @@ -48,8 +48,8 @@ "lint": "yarn lint:eslint", "lint:eslint": "eslint . --cache --ext js,ts", "lint:fix": "yarn lint:eslint --fix", - "changelog:update": "../../scripts/update-changelog.sh @metamask/smart-accounts-kit-x402", - "changelog:validate": "../../scripts/validate-changelog.sh @metamask/smart-accounts-kit-x402" + "changelog:update": "../../scripts/update-changelog.sh @metamask/x402", + "changelog:validate": "../../scripts/validate-changelog.sh @metamask/x402" }, "publishConfig": { "access": "public", diff --git a/packages/smart-accounts-kit-x402/src/index.ts b/packages/x402/src/index.ts similarity index 100% rename from packages/smart-accounts-kit-x402/src/index.ts rename to packages/x402/src/index.ts diff --git a/packages/smart-accounts-kit-x402/src/x402Client.ts b/packages/x402/src/x402Client.ts similarity index 100% rename from packages/smart-accounts-kit-x402/src/x402Client.ts rename to packages/x402/src/x402Client.ts diff --git a/packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts b/packages/x402/src/x402ExactEvmErc7710ServerScheme.ts similarity index 100% rename from packages/smart-accounts-kit-x402/src/x402ExactEvmErc7710ServerScheme.ts rename to packages/x402/src/x402ExactEvmErc7710ServerScheme.ts diff --git a/packages/smart-accounts-kit-x402/src/x402Server.ts b/packages/x402/src/x402Server.ts similarity index 100% rename from packages/smart-accounts-kit-x402/src/x402Server.ts rename to packages/x402/src/x402Server.ts diff --git a/packages/smart-accounts-kit-x402/test/x402Client.test.ts b/packages/x402/test/x402Client.test.ts similarity index 100% rename from packages/smart-accounts-kit-x402/test/x402Client.test.ts rename to packages/x402/test/x402Client.test.ts diff --git a/packages/smart-accounts-kit-x402/test/x402ExactEvmErc7710ServerScheme.test.ts b/packages/x402/test/x402ExactEvmErc7710ServerScheme.test.ts similarity index 100% rename from packages/smart-accounts-kit-x402/test/x402ExactEvmErc7710ServerScheme.test.ts rename to packages/x402/test/x402ExactEvmErc7710ServerScheme.test.ts diff --git a/packages/smart-accounts-kit-x402/test/x402Server.test.ts b/packages/x402/test/x402Server.test.ts similarity index 100% rename from packages/smart-accounts-kit-x402/test/x402Server.test.ts rename to packages/x402/test/x402Server.test.ts diff --git a/packages/smart-accounts-kit-x402/tsconfig.json b/packages/x402/tsconfig.json similarity index 100% rename from packages/smart-accounts-kit-x402/tsconfig.json rename to packages/x402/tsconfig.json diff --git a/packages/smart-accounts-kit-x402/tsup.config.ts b/packages/x402/tsup.config.ts similarity index 100% rename from packages/smart-accounts-kit-x402/tsup.config.ts rename to packages/x402/tsup.config.ts diff --git a/yarn.lock b/yarn.lock index bbcea1d5..fe1b270b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -770,26 +770,6 @@ __metadata: languageName: node linkType: hard -"@metamask/smart-accounts-kit-x402@workspace:packages/smart-accounts-kit-x402": - version: 0.0.0-use.local - resolution: "@metamask/smart-accounts-kit-x402@workspace:packages/smart-accounts-kit-x402" - dependencies: - "@metamask/auto-changelog": "npm:^5.0.2" - "@x402/core": "npm:^2.12.0" - "@x402/evm": "npm:^2.12.0" - eslint: "npm:^9.39.2" - prettier: "npm:^3.5.3" - tsup: "npm:^8.5.0" - typescript: "npm:5.5.4" - viem: "npm:2.31.4" - vitest: "npm:^3.2.4" - peerDependencies: - "@x402/core": ^2.12.0 - "@x402/evm": ^2.12.0 - viem: ^2.31.4 - languageName: unknown - linkType: soft - "@metamask/smart-accounts-kit@workspace:*, @metamask/smart-accounts-kit@workspace:packages/smart-accounts-kit": version: 0.0.0-use.local resolution: "@metamask/smart-accounts-kit@workspace:packages/smart-accounts-kit" @@ -877,6 +857,26 @@ __metadata: languageName: node linkType: hard +"@metamask/x402@workspace:packages/x402": + version: 0.0.0-use.local + resolution: "@metamask/x402@workspace:packages/x402" + dependencies: + "@metamask/auto-changelog": "npm:^5.0.2" + "@x402/core": "npm:^2.12.0" + "@x402/evm": "npm:^2.12.0" + eslint: "npm:^9.39.2" + prettier: "npm:^3.5.3" + tsup: "npm:^8.5.0" + typescript: "npm:5.5.4" + viem: "npm:2.31.4" + vitest: "npm:^3.2.4" + peerDependencies: + "@x402/core": ^2.12.0 + "@x402/evm": ^2.12.0 + viem: ^2.31.4 + languageName: unknown + linkType: soft + "@mswjs/interceptors@npm:^0.41.0": version: 0.41.3 resolution: "@mswjs/interceptors@npm:0.41.3"