|
1 | 1 | import type { WalletAdapter } from "@opensea/wallet-adapters" |
2 | 2 | import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" |
3 | 3 | import { describe, expect, it } from "vitest" |
4 | | -import type { PaymentRequirements } from "../lib/client/x402-payment.js" |
| 4 | +import { |
| 5 | + createX402Client, |
| 6 | + type PaymentRequirements, |
| 7 | +} from "../lib/client/x402-payment.js" |
5 | 8 | import { |
6 | 9 | ExactEip3009Scheme, |
7 | 10 | signEip3009Authorization, |
8 | 11 | toX402PaymentRequired, |
| 12 | + UptoEip3009Scheme, |
9 | 13 | } from "../lib/client/x402-scheme.js" |
10 | 14 |
|
11 | 15 | const signer = privateKeyToAccount(generatePrivateKey()) |
@@ -182,6 +186,96 @@ describe("signEip3009Authorization", () => { |
182 | 186 | }) |
183 | 187 | }) |
184 | 188 |
|
| 189 | +describe("UptoEip3009Scheme", () => { |
| 190 | + it("creates a v1 payload with upto scheme identifier", async () => { |
| 191 | + const scheme = new UptoEip3009Scheme(signer) |
| 192 | + const result = await scheme.createPaymentPayload(1, { |
| 193 | + scheme: "upto", |
| 194 | + network: "eip155:8453", |
| 195 | + asset: baseRequirements.asset, |
| 196 | + amount: "10000", |
| 197 | + payTo: baseRequirements.payTo, |
| 198 | + maxTimeoutSeconds: 600, |
| 199 | + extra: {}, |
| 200 | + }) |
| 201 | + |
| 202 | + const payload = result.payload as { |
| 203 | + signature: string |
| 204 | + authorization: Record<string, string> |
| 205 | + } |
| 206 | + expect(result.x402Version).toBe(1) |
| 207 | + expect((result as Record<string, unknown>).scheme).toBe("upto") |
| 208 | + expect((result as Record<string, unknown>).network).toBe("eip155:8453") |
| 209 | + expect(payload.signature).toMatch(/^0x[0-9a-f]+$/i) |
| 210 | + expect(payload.authorization.from).toBe(signer.address) |
| 211 | + expect(payload.authorization.to).toBe(baseRequirements.payTo) |
| 212 | + expect(payload.authorization.value).toBe("10000") |
| 213 | + }) |
| 214 | + |
| 215 | + it("creates a v2 payload without scheme/network fields", async () => { |
| 216 | + const scheme = new UptoEip3009Scheme(signer) |
| 217 | + const result = await scheme.createPaymentPayload(2, { |
| 218 | + scheme: "upto", |
| 219 | + network: "eip155:8453", |
| 220 | + asset: baseRequirements.asset, |
| 221 | + amount: "10000", |
| 222 | + payTo: baseRequirements.payTo, |
| 223 | + maxTimeoutSeconds: 600, |
| 224 | + extra: {}, |
| 225 | + }) |
| 226 | + |
| 227 | + expect(result.x402Version).toBe(2) |
| 228 | + expect((result as Record<string, unknown>).scheme).toBeUndefined() |
| 229 | + expect((result as Record<string, unknown>).network).toBeUndefined() |
| 230 | + expect(result.payload.signature).toMatch(/^0x[0-9a-f]+$/i) |
| 231 | + }) |
| 232 | + |
| 233 | + it("has scheme property set to upto", () => { |
| 234 | + const scheme = new UptoEip3009Scheme(signer) |
| 235 | + expect(scheme.scheme).toBe("upto") |
| 236 | + }) |
| 237 | +}) |
| 238 | + |
| 239 | +describe("createX402Client", () => { |
| 240 | + const v2Requirements: PaymentRequirements = { |
| 241 | + ...baseRequirements, |
| 242 | + network: "eip155:8453", |
| 243 | + } |
| 244 | + |
| 245 | + it("routes to exact scheme for exact requirements", async () => { |
| 246 | + const client = createX402Client(signer, "eip155:8453", 2) |
| 247 | + const paymentRequired = toX402PaymentRequired({ |
| 248 | + requirements: { ...v2Requirements, scheme: "exact" }, |
| 249 | + x402Version: 2, |
| 250 | + raw: { scheme: "exact", network: "eip155:8453", amount: "10000" }, |
| 251 | + }) |
| 252 | + const result = await client.createPaymentPayload(paymentRequired) |
| 253 | + expect(result.payload.signature).toMatch(/^0x[0-9a-f]+$/i) |
| 254 | + }) |
| 255 | + |
| 256 | + it("routes to upto scheme for upto requirements", async () => { |
| 257 | + const client = createX402Client(signer, "eip155:8453", 2) |
| 258 | + const paymentRequired = toX402PaymentRequired({ |
| 259 | + requirements: { ...v2Requirements, scheme: "upto" }, |
| 260 | + x402Version: 2, |
| 261 | + raw: { scheme: "upto", network: "eip155:8453", amount: "10000" }, |
| 262 | + }) |
| 263 | + const result = await client.createPaymentPayload(paymentRequired) |
| 264 | + expect(result.payload.signature).toMatch(/^0x[0-9a-f]+$/i) |
| 265 | + }) |
| 266 | + |
| 267 | + it("registers both schemes for v1", async () => { |
| 268 | + const client = createX402Client(signer, "base", 1) |
| 269 | + const paymentRequired = toX402PaymentRequired({ |
| 270 | + requirements: { ...baseRequirements, scheme: "upto" }, |
| 271 | + x402Version: 1, |
| 272 | + raw: { scheme: "upto", network: "base", amount: "10000" }, |
| 273 | + }) |
| 274 | + const result = await client.createPaymentPayload(paymentRequired) |
| 275 | + expect(result.payload.signature).toMatch(/^0x[0-9a-f]+$/i) |
| 276 | + }) |
| 277 | +}) |
| 278 | + |
185 | 279 | describe("toX402PaymentRequired", () => { |
186 | 280 | it("builds a PaymentRequired with correct fields", () => { |
187 | 281 | const result = toX402PaymentRequired({ |
|
0 commit comments