thirdweb 5.112.4 → 5.114.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.
Files changed (111) hide show
  1. package/dist/cjs/exports/react.js +4 -1
  2. package/dist/cjs/exports/react.js.map +1 -1
  3. package/dist/cjs/exports/react.native.js +4 -1
  4. package/dist/cjs/exports/react.native.js.map +1 -1
  5. package/dist/cjs/react/core/hooks/x402/useFetchWithPaymentCore.js +110 -0
  6. package/dist/cjs/react/core/hooks/x402/useFetchWithPaymentCore.js.map +1 -0
  7. package/dist/cjs/react/native/hooks/x402/useFetchWithPayment.js +89 -0
  8. package/dist/cjs/react/native/hooks/x402/useFetchWithPayment.js.map +1 -0
  9. package/dist/cjs/react/web/hooks/x402/useFetchWithPayment.js +168 -0
  10. package/dist/cjs/react/web/hooks/x402/useFetchWithPayment.js.map +1 -0
  11. package/dist/cjs/react/web/ui/components/basic.js +1 -1
  12. package/dist/cjs/react/web/ui/x402/PaymentErrorModal.js +107 -0
  13. package/dist/cjs/react/web/ui/x402/PaymentErrorModal.js.map +1 -0
  14. package/dist/cjs/react/web/ui/x402/SignInRequiredModal.js +28 -0
  15. package/dist/cjs/react/web/ui/x402/SignInRequiredModal.js.map +1 -0
  16. package/dist/cjs/version.js +1 -1
  17. package/dist/cjs/wallets/coinbase/coinbase-web.js +9 -0
  18. package/dist/cjs/wallets/coinbase/coinbase-web.js.map +1 -1
  19. package/dist/cjs/x402/common.js +2 -10
  20. package/dist/cjs/x402/common.js.map +1 -1
  21. package/dist/cjs/x402/facilitator.js +2 -1
  22. package/dist/cjs/x402/facilitator.js.map +1 -1
  23. package/dist/cjs/x402/fetchWithPayment.js +13 -14
  24. package/dist/cjs/x402/fetchWithPayment.js.map +1 -1
  25. package/dist/cjs/x402/schemas.js +4 -1
  26. package/dist/cjs/x402/schemas.js.map +1 -1
  27. package/dist/cjs/x402/settle-payment.js +13 -2
  28. package/dist/cjs/x402/settle-payment.js.map +1 -1
  29. package/dist/cjs/x402/types.js +6 -1
  30. package/dist/cjs/x402/types.js.map +1 -1
  31. package/dist/cjs/x402/verify-payment.js +12 -2
  32. package/dist/cjs/x402/verify-payment.js.map +1 -1
  33. package/dist/esm/exports/react.js +2 -0
  34. package/dist/esm/exports/react.js.map +1 -1
  35. package/dist/esm/exports/react.native.js +2 -0
  36. package/dist/esm/exports/react.native.js.map +1 -1
  37. package/dist/esm/react/core/hooks/x402/useFetchWithPaymentCore.js +107 -0
  38. package/dist/esm/react/core/hooks/x402/useFetchWithPaymentCore.js.map +1 -0
  39. package/dist/esm/react/native/hooks/x402/useFetchWithPayment.js +86 -0
  40. package/dist/esm/react/native/hooks/x402/useFetchWithPayment.js.map +1 -0
  41. package/dist/esm/react/web/hooks/x402/useFetchWithPayment.js +165 -0
  42. package/dist/esm/react/web/hooks/x402/useFetchWithPayment.js.map +1 -0
  43. package/dist/esm/react/web/ui/components/basic.js +1 -1
  44. package/dist/esm/react/web/ui/x402/PaymentErrorModal.js +104 -0
  45. package/dist/esm/react/web/ui/x402/PaymentErrorModal.js.map +1 -0
  46. package/dist/esm/react/web/ui/x402/SignInRequiredModal.js +25 -0
  47. package/dist/esm/react/web/ui/x402/SignInRequiredModal.js.map +1 -0
  48. package/dist/esm/version.js +1 -1
  49. package/dist/esm/wallets/coinbase/coinbase-web.js +9 -0
  50. package/dist/esm/wallets/coinbase/coinbase-web.js.map +1 -1
  51. package/dist/esm/x402/common.js +2 -10
  52. package/dist/esm/x402/common.js.map +1 -1
  53. package/dist/esm/x402/facilitator.js +2 -1
  54. package/dist/esm/x402/facilitator.js.map +1 -1
  55. package/dist/esm/x402/fetchWithPayment.js +13 -14
  56. package/dist/esm/x402/fetchWithPayment.js.map +1 -1
  57. package/dist/esm/x402/schemas.js +4 -1
  58. package/dist/esm/x402/schemas.js.map +1 -1
  59. package/dist/esm/x402/settle-payment.js +13 -2
  60. package/dist/esm/x402/settle-payment.js.map +1 -1
  61. package/dist/esm/x402/types.js +5 -0
  62. package/dist/esm/x402/types.js.map +1 -1
  63. package/dist/esm/x402/verify-payment.js +12 -2
  64. package/dist/esm/x402/verify-payment.js.map +1 -1
  65. package/dist/scripts/bridge-widget.js +50 -50
  66. package/dist/types/exports/react.d.ts +1 -0
  67. package/dist/types/exports/react.d.ts.map +1 -1
  68. package/dist/types/exports/react.native.d.ts +1 -0
  69. package/dist/types/exports/react.native.d.ts.map +1 -1
  70. package/dist/types/react/core/hooks/x402/useFetchWithPaymentCore.d.ts +131 -0
  71. package/dist/types/react/core/hooks/x402/useFetchWithPaymentCore.d.ts.map +1 -0
  72. package/dist/types/react/native/hooks/x402/useFetchWithPayment.d.ts +189 -0
  73. package/dist/types/react/native/hooks/x402/useFetchWithPayment.d.ts.map +1 -0
  74. package/dist/types/react/web/hooks/x402/useFetchWithPayment.d.ts +248 -0
  75. package/dist/types/react/web/hooks/x402/useFetchWithPayment.d.ts.map +1 -0
  76. package/dist/types/react/web/ui/x402/PaymentErrorModal.d.ts +20 -0
  77. package/dist/types/react/web/ui/x402/PaymentErrorModal.d.ts.map +1 -0
  78. package/dist/types/react/web/ui/x402/SignInRequiredModal.d.ts +12 -0
  79. package/dist/types/react/web/ui/x402/SignInRequiredModal.d.ts.map +1 -0
  80. package/dist/types/version.d.ts +1 -1
  81. package/dist/types/x402/common.d.ts.map +1 -1
  82. package/dist/types/x402/facilitator.d.ts +1 -1
  83. package/dist/types/x402/facilitator.d.ts.map +1 -1
  84. package/dist/types/x402/fetchWithPayment.d.ts +7 -3
  85. package/dist/types/x402/fetchWithPayment.d.ts.map +1 -1
  86. package/dist/types/x402/schemas.d.ts +17 -17
  87. package/dist/types/x402/schemas.d.ts.map +1 -1
  88. package/dist/types/x402/settle-payment.d.ts +13 -2
  89. package/dist/types/x402/settle-payment.d.ts.map +1 -1
  90. package/dist/types/x402/types.d.ts +13 -1
  91. package/dist/types/x402/types.d.ts.map +1 -1
  92. package/dist/types/x402/verify-payment.d.ts +12 -2
  93. package/dist/types/x402/verify-payment.d.ts.map +1 -1
  94. package/package.json +3 -3
  95. package/src/exports/react.native.ts +5 -0
  96. package/src/exports/react.ts +5 -0
  97. package/src/react/core/hooks/x402/useFetchWithPaymentCore.ts +160 -0
  98. package/src/react/native/hooks/x402/useFetchWithPayment.ts +96 -0
  99. package/src/react/web/hooks/x402/useFetchWithPayment.tsx +238 -0
  100. package/src/react/web/ui/components/basic.tsx +1 -1
  101. package/src/react/web/ui/x402/PaymentErrorModal.tsx +261 -0
  102. package/src/react/web/ui/x402/SignInRequiredModal.tsx +75 -0
  103. package/src/version.ts +1 -1
  104. package/src/wallets/coinbase/coinbase-web.ts +10 -0
  105. package/src/x402/common.ts +2 -20
  106. package/src/x402/facilitator.ts +2 -1
  107. package/src/x402/fetchWithPayment.ts +23 -22
  108. package/src/x402/schemas.ts +4 -1
  109. package/src/x402/settle-payment.ts +13 -2
  110. package/src/x402/types.ts +16 -1
  111. package/src/x402/verify-payment.ts +12 -2
@@ -35,28 +35,10 @@ type GetPaymentRequirementsResult = {
35
35
  export async function decodePaymentRequest(
36
36
  args: PaymentArgs,
37
37
  ): Promise<GetPaymentRequirementsResult | PaymentRequiredResult> {
38
- const {
39
- price,
40
- network,
41
- facilitator,
42
- payTo,
43
- resourceUrl,
44
- routeConfig = {},
45
- method,
46
- paymentData,
47
- extraMetadata,
48
- } = args;
38
+ const { facilitator, routeConfig = {}, paymentData } = args;
49
39
  const { errorMessages } = routeConfig;
50
40
 
51
- const paymentRequirementsResult = await facilitator.accepts({
52
- resourceUrl,
53
- method,
54
- network,
55
- price,
56
- routeConfig,
57
- payTo,
58
- extraMetadata,
59
- });
41
+ const paymentRequirementsResult = await facilitator.accepts(args);
60
42
 
61
43
  // Check for payment header, if none, return the payment requirements
62
44
  if (!paymentData) {
@@ -107,7 +107,7 @@ const DEFAULT_BASE_URL = "https://api.thirdweb.com/v1/payments/x402";
107
107
 
108
108
  * ```
109
109
  *
110
- * @bridge x402
110
+ * @x402
111
111
  */
112
112
  export function facilitator(
113
113
  config: ThirdwebX402FacilitatorConfig,
@@ -278,6 +278,7 @@ export function facilitator(
278
278
  method: args.method,
279
279
  network: caip2ChainId,
280
280
  price: args.price,
281
+ scheme: args.scheme,
281
282
  routeConfig: args.routeConfig,
282
283
  serverWalletAddress: facilitator.address,
283
284
  recipientAddress: args.payTo,
@@ -23,7 +23,7 @@ import { createPaymentHeader } from "./sign.js";
23
23
  * @param fetch - The fetch function to wrap (typically globalThis.fetch)
24
24
  * @param client - The thirdweb client used to access RPC infrastructure
25
25
  * @param wallet - The wallet used to sign payment messages
26
- * @param maxValue - The maximum allowed payment amount in base units (defaults to 1 USDC)
26
+ * @param maxValue - The maximum allowed payment amount in base units
27
27
  * @returns A wrapped fetch function that handles 402 responses automatically
28
28
  *
29
29
  * @example
@@ -46,13 +46,18 @@ import { createPaymentHeader } from "./sign.js";
46
46
  * @throws {Error} If a payment has already been attempted for this request
47
47
  * @throws {Error} If there's an error creating the payment header
48
48
  *
49
- * @bridge x402
49
+ * @x402
50
50
  */
51
51
  export function wrapFetchWithPayment(
52
52
  fetch: typeof globalThis.fetch,
53
53
  client: ThirdwebClient,
54
54
  wallet: Wallet,
55
- maxValue?: bigint,
55
+ options?: {
56
+ maxValue?: bigint;
57
+ paymentRequirementsSelector?: (
58
+ paymentRequirements: RequestedPaymentRequirements[],
59
+ ) => RequestedPaymentRequirements | undefined;
60
+ },
56
61
  ) {
57
62
  return async (input: RequestInfo, init?: RequestInit) => {
58
63
  const response = await fetch(input, init);
@@ -66,9 +71,9 @@ export function wrapFetchWithPayment(
66
71
  accepts: unknown[];
67
72
  error?: string;
68
73
  };
69
- const parsedPaymentRequirements = accepts
70
- .map((x) => RequestedPaymentRequirementsSchema.parse(x))
71
- .filter((x) => x.scheme === "exact"); // TODO (402): accept other schemes
74
+ const parsedPaymentRequirements = accepts.map((x) =>
75
+ RequestedPaymentRequirementsSchema.parse(x),
76
+ );
72
77
 
73
78
  const account = wallet.getAccount();
74
79
  let chain = wallet.getChain();
@@ -78,12 +83,13 @@ export function wrapFetchWithPayment(
78
83
  "Wallet not connected. Please connect your wallet to continue.",
79
84
  );
80
85
  }
81
- const selectedPaymentRequirements = defaultPaymentRequirementsSelector(
82
- parsedPaymentRequirements,
83
- chain.id,
84
- "exact",
85
- error,
86
- );
86
+ const selectedPaymentRequirements = options?.paymentRequirementsSelector
87
+ ? options.paymentRequirementsSelector(parsedPaymentRequirements)
88
+ : defaultPaymentRequirementsSelector(
89
+ parsedPaymentRequirements,
90
+ chain.id,
91
+ error,
92
+ );
87
93
 
88
94
  if (!selectedPaymentRequirements) {
89
95
  throw new Error(
@@ -92,11 +98,11 @@ export function wrapFetchWithPayment(
92
98
  }
93
99
 
94
100
  if (
95
- maxValue &&
96
- BigInt(selectedPaymentRequirements.maxAmountRequired) > maxValue
101
+ options?.maxValue &&
102
+ BigInt(selectedPaymentRequirements.maxAmountRequired) > options.maxValue
97
103
  ) {
98
104
  throw new Error(
99
- `Payment amount exceeds maximum allowed (currently set to ${maxValue} in base units)`,
105
+ `Payment amount exceeds maximum allowed (currently set to ${options.maxValue} in base units)`,
100
106
  );
101
107
  }
102
108
 
@@ -151,7 +157,6 @@ export function wrapFetchWithPayment(
151
157
  function defaultPaymentRequirementsSelector(
152
158
  paymentRequirements: RequestedPaymentRequirements[],
153
159
  chainId: number,
154
- scheme: "exact",
155
160
  error?: string,
156
161
  ) {
157
162
  if (!paymentRequirements.length) {
@@ -161,9 +166,7 @@ function defaultPaymentRequirementsSelector(
161
166
  }
162
167
  // find the payment requirements matching the connected wallet chain
163
168
  const matchingPaymentRequirements = paymentRequirements.find(
164
- (x) =>
165
- extractEvmChainId(networkToCaip2ChainId(x.network)) === chainId &&
166
- x.scheme === scheme,
169
+ (x) => extractEvmChainId(networkToCaip2ChainId(x.network)) === chainId,
167
170
  );
168
171
 
169
172
  if (matchingPaymentRequirements) {
@@ -171,9 +174,7 @@ function defaultPaymentRequirementsSelector(
171
174
  } else {
172
175
  // if no matching payment requirements, use the first payment requirement
173
176
  // and switch the wallet to that chain
174
- const firstPaymentRequirement = paymentRequirements.find(
175
- (x) => x.scheme === scheme,
176
- );
177
+ const firstPaymentRequirement = paymentRequirements[0];
177
178
  return firstPaymentRequirement;
178
179
  }
179
180
  }
@@ -10,6 +10,7 @@ import {
10
10
  } from "x402/types";
11
11
  import { z } from "zod";
12
12
  import type { Chain } from "../chains/types.js";
13
+ import { PaymentSchemeSchema } from "./types.js";
13
14
 
14
15
  const FacilitatorNetworkSchema = z.string();
15
16
 
@@ -17,6 +18,7 @@ export type FacilitatorNetwork = z.infer<typeof FacilitatorNetworkSchema>;
17
18
 
18
19
  const RequestedPaymentPayloadSchema = PaymentPayloadSchema.extend({
19
20
  network: FacilitatorNetworkSchema,
21
+ scheme: PaymentSchemeSchema,
20
22
  });
21
23
 
22
24
  export type RequestedPaymentPayload = z.infer<
@@ -32,6 +34,7 @@ export type UnsignedPaymentPayload = Omit<
32
34
  export const RequestedPaymentRequirementsSchema =
33
35
  PaymentRequirementsSchema.extend({
34
36
  network: FacilitatorNetworkSchema,
37
+ scheme: PaymentSchemeSchema,
35
38
  });
36
39
 
37
40
  export type RequestedPaymentRequirements = z.infer<
@@ -76,7 +79,7 @@ const FacilitatorSupportedResponseSchema =
76
79
  kinds: z.array(
77
80
  z.object({
78
81
  x402Version: z.literal(1),
79
- scheme: z.literal("exact"),
82
+ scheme: PaymentSchemeSchema,
80
83
  network: FacilitatorNetworkSchema,
81
84
  extra: z
82
85
  .object({
@@ -51,7 +51,6 @@ import {
51
51
  * routeConfig: {
52
52
  * description: "Access to premium API content",
53
53
  * mimeType: "application/json",
54
- * maxTimeoutSeconds: 300,
55
54
  * },
56
55
  * });
57
56
  *
@@ -68,6 +67,18 @@ import {
68
67
  * }
69
68
  * ```
70
69
  *
70
+ * ### Upto Payment Scheme
71
+ *
72
+ * You can also use the `upto` payment scheme to settle the payment dynamically based on the usage.
73
+ *
74
+ * ```ts
75
+ * const result = await settlePayment({
76
+ * ...paymentArgs,
77
+ * scheme: "upto",
78
+ * price: "$0.10", // max payable amount
79
+ * });
80
+ * ```
81
+ *
71
82
  * ### Express middleware example
72
83
  *
73
84
  * ```ts
@@ -122,7 +133,7 @@ import {
122
133
  *
123
134
  * @public
124
135
  * @beta
125
- * @bridge x402
136
+ * @x402
126
137
  */
127
138
  export async function settlePayment(
128
139
  args: SettlePaymentArgs,
package/src/x402/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Money, PaymentMiddlewareConfig } from "x402/types";
2
- import type z from "zod";
2
+ import z from "zod";
3
3
  import type { Chain } from "../chains/types.js";
4
4
  import type { Prettify } from "../utils/type-utils.js";
5
5
  import type { ThirdwebX402Facilitator, WaitUntil } from "./facilitator.js";
@@ -31,6 +31,8 @@ export type PaymentArgs = {
31
31
  price: Money | ERC20TokenAmount;
32
32
  /** The payment facilitator instance used to verify and settle payments */
33
33
  facilitator: ThirdwebX402Facilitator;
34
+ /** The scheme of the payment, either "exact" or "upto", defaults to "exact" */
35
+ scheme?: PaymentScheme;
34
36
  /** Optional configuration for the payment middleware route */
35
37
  routeConfig?: PaymentMiddlewareConfig;
36
38
  /** Optional recipient address to receive the payment if different from your facilitator address */
@@ -91,7 +93,9 @@ export type VerifyPaymentResult = Prettify<
91
93
  | {
92
94
  /** HTTP 200 - Payment was successfully verified */
93
95
  status: 200;
96
+ /** The decoded payment payload */
94
97
  decodedPayment: RequestedPaymentPayload;
98
+ /** The selected payment requirements */
95
99
  selectedPaymentRequirements: RequestedPaymentRequirements;
96
100
  }
97
101
  | PaymentRequiredResult
@@ -101,8 +105,19 @@ export type SupportedSignatureType = z.infer<
101
105
  typeof SupportedSignatureTypeSchema
102
106
  >;
103
107
 
108
+ export const PaymentSchemeSchema = z.union([
109
+ z.literal("exact"),
110
+ z.literal("upto"),
111
+ ]);
112
+ type PaymentScheme = z.infer<typeof PaymentSchemeSchema>;
113
+
114
+ /**
115
+ * The asset, scheme and amount for the payment in base units
116
+ */
104
117
  export type ERC20TokenAmount = {
118
+ /** The amount of the payment in base units */
105
119
  amount: string;
120
+ /** The asset of the payment, decimals and eip712 data are optional and will be inferred from the address if not provided */
106
121
  asset: {
107
122
  address: `0x${string}`;
108
123
  decimals?: number;
@@ -42,7 +42,6 @@ import {
42
42
  * routeConfig: {
43
43
  * description: "Access to premium API content",
44
44
  * mimeType: "application/json",
45
- * maxTimeoutSeconds: 300,
46
45
  * },
47
46
  * };
48
47
  *
@@ -68,9 +67,20 @@ import {
68
67
  * }
69
68
  * ```
70
69
  *
70
+ * ### Upto Payment Scheme
71
+ *
72
+ * You can also use the `upto` payment scheme to verify a payment where the final price is dynamically calculated based on the usage.
73
+ *
74
+ * ```ts
75
+ * const result = await verifyPayment({
76
+ * ...paymentArgs,
77
+ * scheme: "upto",
78
+ * price: "$0.10", // max payable amount
79
+ * });
80
+ * ```
71
81
  * @public
72
82
  * @beta
73
- * @bridge x402
83
+ * @x402
74
84
  */
75
85
  export async function verifyPayment(
76
86
  args: PaymentArgs,