powertools-x402 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/stripe.js ADDED
@@ -0,0 +1,80 @@
1
+ import {
2
+ coinbaseFacilitator
3
+ } from "./chunk-FLK2T35N.js";
4
+ import {
5
+ createX402
6
+ } from "./chunk-4ZP7AJJC.js";
7
+
8
+ // src/stripe.ts
9
+ import Stripe from "stripe";
10
+ var BASE_MAINNET = "eip155:8453";
11
+ var BASE_USDC = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
12
+ var STRIPE_PREVIEW_API_VERSION = "2026-05-27.preview";
13
+ function createStripeX402(options = {}) {
14
+ const {
15
+ depositAddress = process.env.STRIPE_DEPOSIT_ADDRESS,
16
+ stripeSecretKey = process.env.STRIPE_SECRET_KEY,
17
+ stripe,
18
+ cdpApiKeyId,
19
+ cdpApiKeySecret,
20
+ facilitator,
21
+ ...rest
22
+ } = options;
23
+ if (!depositAddress) {
24
+ throw new Error(
25
+ "createStripeX402 requires a depositAddress (or STRIPE_DEPOSIT_ADDRESS). Create one with POST /v1/crypto/deposit_addresses."
26
+ );
27
+ }
28
+ if (!stripe && !stripeSecretKey) {
29
+ throw new Error("createStripeX402 requires a stripe client or stripeSecretKey (or STRIPE_SECRET_KEY).");
30
+ }
31
+ const stripeClient = stripe ?? new Stripe(stripeSecretKey, {
32
+ apiVersion: STRIPE_PREVIEW_API_VERSION
33
+ });
34
+ const x402 = createX402({
35
+ ...rest,
36
+ network: BASE_MAINNET,
37
+ facilitator: facilitator ?? coinbaseFacilitator(cdpApiKeyId, cdpApiKeySecret),
38
+ payTo: depositAddress
39
+ });
40
+ x402.resourceServer.onAfterSettle(async ({ result, requirements }) => {
41
+ if (!result.success || !result.transaction) return;
42
+ if (requirements.network !== BASE_MAINNET) return;
43
+ if (requirements.asset.toLowerCase() !== BASE_USDC.toLowerCase()) return;
44
+ const amountInCents = Math.round(Number(requirements.amount) / 1e4);
45
+ if (amountInCents < 1) return;
46
+ try {
47
+ await stripeClient.paymentIntents.create(
48
+ {
49
+ amount: amountInCents,
50
+ currency: "usd",
51
+ confirm: true,
52
+ payment_method_data: { type: "crypto" },
53
+ payment_method_types: ["crypto"],
54
+ payment_method_options: {
55
+ // transaction_verification ships in the 2026-05-27.preview API
56
+ // version and is not yet in stripe-node's stable types
57
+ crypto: {
58
+ mode: "transaction_verification",
59
+ transaction_verification_options: {
60
+ network: "base",
61
+ transaction_hash: result.transaction
62
+ }
63
+ }
64
+ }
65
+ },
66
+ { idempotencyKey: result.transaction }
67
+ );
68
+ } catch (error) {
69
+ (rest.logger ?? console).error("stripe payment intent recording failed", {
70
+ transaction: result.transaction,
71
+ amountInCents,
72
+ error: error instanceof Error ? error.message : String(error)
73
+ });
74
+ }
75
+ });
76
+ return x402;
77
+ }
78
+ export {
79
+ createStripeX402
80
+ };
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/testing.ts
21
+ var testing_exports = {};
22
+ __export(testing_exports, {
23
+ TEST_PAYER_ADDRESS: () => TEST_PAYER_ADDRESS,
24
+ TEST_TRANSACTION_HASH: () => TEST_TRANSACTION_HASH,
25
+ stubFacilitator: () => stubFacilitator,
26
+ testPayer: () => testPayer
27
+ });
28
+ module.exports = __toCommonJS(testing_exports);
29
+ var import_client = require("@x402/core/client");
30
+ var import_client2 = require("@x402/evm/exact/client");
31
+ var import_accounts = require("viem/accounts");
32
+ var TEST_PAYER_ADDRESS = "0x0000000000000000000000000000000000C0FFEE";
33
+ var TEST_TRANSACTION_HASH = `0x${"ab".repeat(32)}`;
34
+ function stubFacilitator(options = {}) {
35
+ const networks = [options.network ?? "eip155:84532"].flat();
36
+ const payer = options.payer ?? TEST_PAYER_ADDRESS;
37
+ return {
38
+ async getSupported() {
39
+ return {
40
+ kinds: networks.map((network) => ({ x402Version: 2, scheme: "exact", network })),
41
+ extensions: [],
42
+ signers: {}
43
+ };
44
+ },
45
+ async verify() {
46
+ return { isValid: true, payer, ...options.verify };
47
+ },
48
+ async settle() {
49
+ return {
50
+ success: true,
51
+ transaction: TEST_TRANSACTION_HASH,
52
+ network: networks[0],
53
+ payer,
54
+ ...options.settle
55
+ };
56
+ }
57
+ };
58
+ }
59
+ var getHeaderFrom = (challenge) => (name) => {
60
+ if (challenge.headers instanceof Headers) return challenge.headers.get(name) ?? void 0;
61
+ const value = challenge.headers?.[name.toLowerCase()];
62
+ return value === void 0 ? void 0 : String(value);
63
+ };
64
+ function testPayer(privateKey) {
65
+ const account = (0, import_accounts.privateKeyToAccount)(privateKey ?? (0, import_accounts.generatePrivateKey)());
66
+ const client = new import_client.x402HTTPClient(
67
+ (0, import_client2.registerExactEvmScheme)(new import_client.x402Client(), { signer: account })
68
+ );
69
+ return {
70
+ address: account.address,
71
+ async payFor(challenge) {
72
+ const paymentRequired = client.getPaymentRequiredResponse(getHeaderFrom(challenge));
73
+ const payload = await client.createPaymentPayload(paymentRequired);
74
+ return client.encodePaymentSignatureHeader(payload);
75
+ }
76
+ };
77
+ }
78
+ // Annotate the CommonJS export names for ESM import in node:
79
+ 0 && (module.exports = {
80
+ TEST_PAYER_ADDRESS,
81
+ TEST_TRANSACTION_HASH,
82
+ stubFacilitator,
83
+ testPayer
84
+ });
@@ -0,0 +1,29 @@
1
+ import { FacilitatorClient } from '@x402/core/server';
2
+ import { Network, VerifyResponse, SettleResponse } from '@x402/core/types';
3
+
4
+ declare const TEST_PAYER_ADDRESS = "0x0000000000000000000000000000000000C0FFEE";
5
+ declare const TEST_TRANSACTION_HASH: string;
6
+ interface StubFacilitatorOptions {
7
+ network?: Network | Network[];
8
+ payer?: string;
9
+ verify?: Partial<VerifyResponse>;
10
+ settle?: Partial<SettleResponse>;
11
+ }
12
+ /**
13
+ * In-memory facilitator that approves every payment. Spy on its methods or
14
+ * override verify/settle responses to exercise failure paths.
15
+ */
16
+ declare function stubFacilitator(options?: StubFacilitatorOptions): FacilitatorClient;
17
+ type ChallengeLike = Response | {
18
+ headers?: Record<string, unknown>;
19
+ };
20
+ /**
21
+ * A payment client backed by a throwaway account. Feed it a 402 response and
22
+ * it returns the headers that make the retried request a valid paid request.
23
+ */
24
+ declare function testPayer(privateKey?: `0x${string}`): {
25
+ address: `0x${string}`;
26
+ payFor(challenge: ChallengeLike): Promise<Record<string, string>>;
27
+ };
28
+
29
+ export { type StubFacilitatorOptions, TEST_PAYER_ADDRESS, TEST_TRANSACTION_HASH, stubFacilitator, testPayer };
@@ -0,0 +1,29 @@
1
+ import { FacilitatorClient } from '@x402/core/server';
2
+ import { Network, VerifyResponse, SettleResponse } from '@x402/core/types';
3
+
4
+ declare const TEST_PAYER_ADDRESS = "0x0000000000000000000000000000000000C0FFEE";
5
+ declare const TEST_TRANSACTION_HASH: string;
6
+ interface StubFacilitatorOptions {
7
+ network?: Network | Network[];
8
+ payer?: string;
9
+ verify?: Partial<VerifyResponse>;
10
+ settle?: Partial<SettleResponse>;
11
+ }
12
+ /**
13
+ * In-memory facilitator that approves every payment. Spy on its methods or
14
+ * override verify/settle responses to exercise failure paths.
15
+ */
16
+ declare function stubFacilitator(options?: StubFacilitatorOptions): FacilitatorClient;
17
+ type ChallengeLike = Response | {
18
+ headers?: Record<string, unknown>;
19
+ };
20
+ /**
21
+ * A payment client backed by a throwaway account. Feed it a 402 response and
22
+ * it returns the headers that make the retried request a valid paid request.
23
+ */
24
+ declare function testPayer(privateKey?: `0x${string}`): {
25
+ address: `0x${string}`;
26
+ payFor(challenge: ChallengeLike): Promise<Record<string, string>>;
27
+ };
28
+
29
+ export { type StubFacilitatorOptions, TEST_PAYER_ADDRESS, TEST_TRANSACTION_HASH, stubFacilitator, testPayer };
@@ -0,0 +1,56 @@
1
+ // src/testing.ts
2
+ import { x402Client, x402HTTPClient } from "@x402/core/client";
3
+ import { registerExactEvmScheme } from "@x402/evm/exact/client";
4
+ import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
5
+ var TEST_PAYER_ADDRESS = "0x0000000000000000000000000000000000C0FFEE";
6
+ var TEST_TRANSACTION_HASH = `0x${"ab".repeat(32)}`;
7
+ function stubFacilitator(options = {}) {
8
+ const networks = [options.network ?? "eip155:84532"].flat();
9
+ const payer = options.payer ?? TEST_PAYER_ADDRESS;
10
+ return {
11
+ async getSupported() {
12
+ return {
13
+ kinds: networks.map((network) => ({ x402Version: 2, scheme: "exact", network })),
14
+ extensions: [],
15
+ signers: {}
16
+ };
17
+ },
18
+ async verify() {
19
+ return { isValid: true, payer, ...options.verify };
20
+ },
21
+ async settle() {
22
+ return {
23
+ success: true,
24
+ transaction: TEST_TRANSACTION_HASH,
25
+ network: networks[0],
26
+ payer,
27
+ ...options.settle
28
+ };
29
+ }
30
+ };
31
+ }
32
+ var getHeaderFrom = (challenge) => (name) => {
33
+ if (challenge.headers instanceof Headers) return challenge.headers.get(name) ?? void 0;
34
+ const value = challenge.headers?.[name.toLowerCase()];
35
+ return value === void 0 ? void 0 : String(value);
36
+ };
37
+ function testPayer(privateKey) {
38
+ const account = privateKeyToAccount(privateKey ?? generatePrivateKey());
39
+ const client = new x402HTTPClient(
40
+ registerExactEvmScheme(new x402Client(), { signer: account })
41
+ );
42
+ return {
43
+ address: account.address,
44
+ async payFor(challenge) {
45
+ const paymentRequired = client.getPaymentRequiredResponse(getHeaderFrom(challenge));
46
+ const payload = await client.createPaymentPayload(paymentRequired);
47
+ return client.encodePaymentSignatureHeader(payload);
48
+ }
49
+ };
50
+ }
51
+ export {
52
+ TEST_PAYER_ADDRESS,
53
+ TEST_TRANSACTION_HASH,
54
+ stubFacilitator,
55
+ testPayer
56
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "powertools-x402",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "x402 payment middleware for AWS Lambda Powertools Event Handler",
5
5
  "license": "MIT",
6
6
  "author": "Allen Helton <allenheltondev@gmail.com>",
@@ -30,6 +30,36 @@
30
30
  "types": "./dist/index.d.cts",
31
31
  "default": "./dist/index.cjs"
32
32
  }
33
+ },
34
+ "./stripe": {
35
+ "import": {
36
+ "types": "./dist/stripe.d.ts",
37
+ "default": "./dist/stripe.js"
38
+ },
39
+ "require": {
40
+ "types": "./dist/stripe.d.cts",
41
+ "default": "./dist/stripe.cjs"
42
+ }
43
+ },
44
+ "./coinbase": {
45
+ "import": {
46
+ "types": "./dist/coinbase.d.ts",
47
+ "default": "./dist/coinbase.js"
48
+ },
49
+ "require": {
50
+ "types": "./dist/coinbase.d.cts",
51
+ "default": "./dist/coinbase.cjs"
52
+ }
53
+ },
54
+ "./testing": {
55
+ "import": {
56
+ "types": "./dist/testing.d.ts",
57
+ "default": "./dist/testing.js"
58
+ },
59
+ "require": {
60
+ "types": "./dist/testing.d.cts",
61
+ "default": "./dist/testing.cjs"
62
+ }
33
63
  }
34
64
  },
35
65
  "files": [
@@ -52,7 +82,21 @@
52
82
  "@x402/evm": "^2.23.0"
53
83
  },
54
84
  "peerDependencies": {
55
- "@aws-lambda-powertools/event-handler": "^2.35.0"
85
+ "@aws-lambda-powertools/event-handler": "^2.35.0",
86
+ "@coinbase/x402": "^2.1.0",
87
+ "stripe": "^22.0.0",
88
+ "viem": "^2.0.0"
89
+ },
90
+ "peerDependenciesMeta": {
91
+ "@coinbase/x402": {
92
+ "optional": true
93
+ },
94
+ "stripe": {
95
+ "optional": true
96
+ },
97
+ "viem": {
98
+ "optional": true
99
+ }
56
100
  },
57
101
  "devDependencies": {
58
102
  "@aws-lambda-powertools/event-handler": "^2.35.0",