thirdweb 5.116.0 → 5.116.1

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 (47) hide show
  1. package/dist/cjs/react/core/hooks/x402/useFetchWithPaymentCore.js +5 -1
  2. package/dist/cjs/react/core/hooks/x402/useFetchWithPaymentCore.js.map +1 -1
  3. package/dist/cjs/react/native/hooks/x402/useFetchWithPayment.js +6 -1
  4. package/dist/cjs/react/native/hooks/x402/useFetchWithPayment.js.map +1 -1
  5. package/dist/cjs/react/web/hooks/x402/useFetchWithPayment.js +7 -1
  6. package/dist/cjs/react/web/hooks/x402/useFetchWithPayment.js.map +1 -1
  7. package/dist/cjs/version.js +1 -1
  8. package/dist/cjs/x402/fetchWithPayment.js +13 -1
  9. package/dist/cjs/x402/fetchWithPayment.js.map +1 -1
  10. package/dist/cjs/x402/permitSignatureStorage.js +70 -0
  11. package/dist/cjs/x402/permitSignatureStorage.js.map +1 -0
  12. package/dist/cjs/x402/sign.js +51 -4
  13. package/dist/cjs/x402/sign.js.map +1 -1
  14. package/dist/esm/react/core/hooks/x402/useFetchWithPaymentCore.js +5 -1
  15. package/dist/esm/react/core/hooks/x402/useFetchWithPaymentCore.js.map +1 -1
  16. package/dist/esm/react/native/hooks/x402/useFetchWithPayment.js +6 -1
  17. package/dist/esm/react/native/hooks/x402/useFetchWithPayment.js.map +1 -1
  18. package/dist/esm/react/web/hooks/x402/useFetchWithPayment.js +8 -2
  19. package/dist/esm/react/web/hooks/x402/useFetchWithPayment.js.map +1 -1
  20. package/dist/esm/version.js +1 -1
  21. package/dist/esm/x402/fetchWithPayment.js +13 -1
  22. package/dist/esm/x402/fetchWithPayment.js.map +1 -1
  23. package/dist/esm/x402/permitSignatureStorage.js +65 -0
  24. package/dist/esm/x402/permitSignatureStorage.js.map +1 -0
  25. package/dist/esm/x402/sign.js +51 -4
  26. package/dist/esm/x402/sign.js.map +1 -1
  27. package/dist/scripts/bridge-widget.js +2 -2
  28. package/dist/types/react/core/hooks/x402/useFetchWithPaymentCore.d.ts +6 -0
  29. package/dist/types/react/core/hooks/x402/useFetchWithPaymentCore.d.ts.map +1 -1
  30. package/dist/types/react/native/hooks/x402/useFetchWithPayment.d.ts +1 -0
  31. package/dist/types/react/native/hooks/x402/useFetchWithPayment.d.ts.map +1 -1
  32. package/dist/types/react/web/hooks/x402/useFetchWithPayment.d.ts.map +1 -1
  33. package/dist/types/version.d.ts +1 -1
  34. package/dist/types/x402/fetchWithPayment.d.ts +6 -0
  35. package/dist/types/x402/fetchWithPayment.d.ts.map +1 -1
  36. package/dist/types/x402/permitSignatureStorage.d.ts +43 -0
  37. package/dist/types/x402/permitSignatureStorage.d.ts.map +1 -0
  38. package/dist/types/x402/sign.d.ts +3 -1
  39. package/dist/types/x402/sign.d.ts.map +1 -1
  40. package/package.json +1 -1
  41. package/src/react/core/hooks/x402/useFetchWithPaymentCore.ts +11 -1
  42. package/src/react/native/hooks/x402/useFetchWithPayment.ts +6 -1
  43. package/src/react/web/hooks/x402/useFetchWithPayment.tsx +12 -2
  44. package/src/version.ts +1 -1
  45. package/src/x402/fetchWithPayment.ts +21 -0
  46. package/src/x402/permitSignatureStorage.ts +99 -0
  47. package/src/x402/sign.ts +76 -1
@@ -1,4 +1,5 @@
1
1
  import type { ThirdwebClient } from "../../../../client/client.js";
2
+ import type { AsyncStorage } from "../../../../utils/storage/AsyncStorage.js";
2
3
  import type { Wallet } from "../../../../wallets/interfaces/wallet.js";
3
4
  import type { RequestedPaymentRequirements } from "../../../../x402/schemas.js";
4
5
  import type { PaymentRequiredResult } from "../../../../x402/types.js";
@@ -6,6 +7,11 @@ export type UseFetchWithPaymentOptions = {
6
7
  maxValue?: bigint;
7
8
  paymentRequirementsSelector?: (paymentRequirements: RequestedPaymentRequirements[]) => RequestedPaymentRequirements | undefined;
8
9
  parseAs?: "json" | "text" | "raw";
10
+ /**
11
+ * Storage for caching permit signatures (for "upto" scheme).
12
+ * When provided, permit signatures will be cached and reused if the on-chain allowance is sufficient.
13
+ */
14
+ storage?: AsyncStorage;
9
15
  };
10
16
  type ShowErrorModalCallback = (data: {
11
17
  errorData: PaymentRequiredResult["responseBody"];
@@ -1 +1 @@
1
- {"version":3,"file":"useFetchWithPaymentCore.d.ts","sourceRoot":"","sources":["../../../../../../src/react/core/hooks/x402/useFetchWithPaymentCore.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0CAA0C,CAAC;AAEvE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAChF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAGvE,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2BAA2B,CAAC,EAAE,CAC5B,mBAAmB,EAAE,4BAA4B,EAAE,KAChD,4BAA4B,GAAG,SAAS,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;CACnC,CAAC;AAEF,KAAK,sBAAsB,GAAG,CAAC,IAAI,EAAE;IACnC,SAAS,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,KAAK,IAAI,CAAC;AAEX,KAAK,wBAAwB,GAAG,CAAC,IAAI,EAAE;IACrC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,KAAK,IAAI,CAAC;AAEX;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE,0BAA0B,EACpC,cAAc,CAAC,EAAE,sBAAsB,EACvC,gBAAgB,CAAC,EAAE,wBAAwB;;;;;;;;;;eAShC,WAAW;eACX,WAAW;;;;;;;;;eADX,WAAW;eACX,WAAW;;8BA+FY,WAAW,SAAS,WAAW;;;;eAhGtD,WAAW;eACX,WAAW;;;;;;;;;eADX,WAAW;eACX,WAAW;;;;;;;;;eADX,WAAW;eACX,WAAW;;8BA+FY,WAAW,SAAS,WAAW;;;;;eAhGtD,WAAW;eACX,WAAW;;;;;;;;eADX,WAAW;eACX,WAAW;;;;;;;;;eADX,WAAW;eACX,WAAW;;8BA+FY,WAAW,SAAS,WAAW;;;;;eAhGtD,WAAW;eACX,WAAW;;;;;;;;eADX,WAAW;eACX,WAAW;;;;;;;;;eADX,WAAW;eACX,WAAW;;8BA+FY,WAAW,SAAS,WAAW;EAKlE"}
1
+ {"version":3,"file":"useFetchWithPaymentCore.d.ts","sourceRoot":"","sources":["../../../../../../src/react/core/hooks/x402/useFetchWithPaymentCore.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AAC9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0CAA0C,CAAC;AAEvE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAChF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAGvE,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2BAA2B,CAAC,EAAE,CAC5B,mBAAmB,EAAE,4BAA4B,EAAE,KAChD,4BAA4B,GAAG,SAAS,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IAClC;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB,CAAC;AAEF,KAAK,sBAAsB,GAAG,CAAC,IAAI,EAAE;IACnC,SAAS,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,KAAK,IAAI,CAAC;AAEX,KAAK,wBAAwB,GAAG,CAAC,IAAI,EAAE;IACrC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,KAAK,IAAI,CAAC;AAEX;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE,0BAA0B,EACpC,cAAc,CAAC,EAAE,sBAAsB,EACvC,gBAAgB,CAAC,EAAE,wBAAwB;;;;;;;;;;eAShC,WAAW;eACX,WAAW;;;;;;;;;eADX,WAAW;eACX,WAAW;;8BAmGY,WAAW,SAAS,WAAW;;;;eApGtD,WAAW;eACX,WAAW;;;;;;;;;eADX,WAAW;eACX,WAAW;;;;;;;;;eADX,WAAW;eACX,WAAW;;8BAmGY,WAAW,SAAS,WAAW;;;;;eApGtD,WAAW;eACX,WAAW;;;;;;;;eADX,WAAW;eACX,WAAW;;;;;;;;;eADX,WAAW;eACX,WAAW;;8BAmGY,WAAW,SAAS,WAAW;;;;;eApGtD,WAAW;eACX,WAAW;;;;;;;;eADX,WAAW;eACX,WAAW;;;;;;;;;eADX,WAAW;eACX,WAAW;;8BAmGY,WAAW,SAAS,WAAW;EAKlE"}
@@ -22,6 +22,7 @@ export type { UseFetchWithPaymentOptions };
22
22
  * @param options.maxValue - The maximum allowed payment amount in base units
23
23
  * @param options.paymentRequirementsSelector - Custom function to select payment requirements from available options
24
24
  * @param options.parseAs - How to parse the response: "json" (default), "text", or "raw"
25
+ * @param options.storage - Storage for caching permit signatures (for "upto" scheme). Provide your own AsyncStorage implementation for React Native.
25
26
  * @returns An object containing:
26
27
  * - `fetchWithPayment`: Function to make fetch requests with automatic payment handling (returns parsed data)
27
28
  * - `isPending`: Boolean indicating if a request is in progress
@@ -1 +1 @@
1
- {"version":3,"file":"useFetchWithPayment.d.ts","sourceRoot":"","sources":["../../../../../../src/react/native/hooks/x402/useFetchWithPayment.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EACL,KAAK,0BAA0B,EAEhC,MAAM,qDAAqD,CAAC;AAE7D,YAAY,EAAE,0BAA0B,EAAE,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIrC"}
1
+ {"version":3,"file":"useFetchWithPayment.d.ts","sourceRoot":"","sources":["../../../../../../src/react/native/hooks/x402/useFetchWithPayment.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,EACL,KAAK,0BAA0B,EAEhC,MAAM,qDAAqD,CAAC;AAE7D,YAAY,EAAE,0BAA0B,EAAE,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useFetchWithPayment.d.ts","sourceRoot":"","sources":["../../../../../../src/react/web/hooks/x402/useFetchWithPayment.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sCAAsC,CAAC;AAClE,OAAO,EACL,KAAK,0BAA0B,EAEhC,MAAM,qDAAqD,CAAC;AAE7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EACL,KAAK,sBAAsB,EAE5B,MAAM,2CAA2C,CAAC;AAInD,YAAY,EAAE,0BAA0B,EAAE,CAAC;AAE3C,KAAK,yBAAyB,GAAG,0BAA0B,GAAG;IAC5D;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;IACjC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CACzB,IAAI,CACF,cAAc,EACd,QAAQ,GAAG,OAAO,GAAG,cAAc,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CACzE,CACF,CAAC;IACF;;;OAGG;IACH,cAAc,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC;IAClE;;OAEG;IACH,mBAAmB,CAAC,EAAE;QACpB,wCAAwC;QACxC,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,8BAA8B;QAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,0CAA0C;QAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2HG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4EpC"}
1
+ {"version":3,"file":"useFetchWithPayment.d.ts","sourceRoot":"","sources":["../../../../../../src/react/web/hooks/x402/useFetchWithPayment.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sCAAsC,CAAC;AAClE,OAAO,EACL,KAAK,0BAA0B,EAEhC,MAAM,qDAAqD,CAAC;AAE7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EACL,KAAK,sBAAsB,EAE5B,MAAM,2CAA2C,CAAC;AAInD,YAAY,EAAE,0BAA0B,EAAE,CAAC;AAE3C,KAAK,yBAAyB,GAAG,0BAA0B,GAAG;IAC5D;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;IACjC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CACzB,IAAI,CACF,cAAc,EACd,QAAQ,GAAG,OAAO,GAAG,cAAc,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CACzE,CACF,CAAC;IACF;;;OAGG;IACH,cAAc,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC;IAClE;;OAEG;IACH,mBAAmB,CAAC,EAAE;QACpB,wCAAwC;QACxC,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,8BAA8B;QAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,0CAA0C;QAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2HG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqFpC"}
@@ -1,2 +1,2 @@
1
- export declare const version = "5.116.0";
1
+ export declare const version = "5.116.1";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import type { ThirdwebClient } from "../client/client.js";
2
+ import type { AsyncStorage } from "../utils/storage/AsyncStorage.js";
2
3
  import type { Wallet } from "../wallets/interfaces/wallet.js";
3
4
  import { type RequestedPaymentRequirements } from "./schemas.js";
4
5
  /**
@@ -43,5 +44,10 @@ import { type RequestedPaymentRequirements } from "./schemas.js";
43
44
  export declare function wrapFetchWithPayment(fetch: typeof globalThis.fetch, client: ThirdwebClient, wallet: Wallet, options?: {
44
45
  maxValue?: bigint;
45
46
  paymentRequirementsSelector?: (paymentRequirements: RequestedPaymentRequirements[]) => RequestedPaymentRequirements | undefined;
47
+ /**
48
+ * Storage for caching permit signatures (for "upto" scheme).
49
+ * When provided, permit signatures will be cached and reused if the on-chain allowance is sufficient.
50
+ */
51
+ storage?: AsyncStorage;
46
52
  }): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
47
53
  //# sourceMappingURL=fetchWithPayment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetchWithPayment.d.ts","sourceRoot":"","sources":["../../../src/x402/fetchWithPayment.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAGL,KAAK,4BAA4B,EAElC,MAAM,cAAc,CAAC;AAGtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,EAC9B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IACR,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2BAA2B,CAAC,EAAE,CAC5B,mBAAmB,EAAE,4BAA4B,EAAE,KAChD,4BAA4B,GAAG,SAAS,CAAC;CAC/C,IAEa,OAAO,WAAW,EAAE,OAAO,WAAW,uBA6FrD"}
1
+ {"version":3,"file":"fetchWithPayment.d.ts","sourceRoot":"","sources":["../../../src/x402/fetchWithPayment.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAErE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,EAGL,KAAK,4BAA4B,EAElC,MAAM,cAAc,CAAC;AAGtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,EAC9B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IACR,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2BAA2B,CAAC,EAAE,CAC5B,mBAAmB,EAAE,4BAA4B,EAAE,KAChD,4BAA4B,GAAG,SAAS,CAAC;IAC9C;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB,IAEa,OAAO,WAAW,EAAE,OAAO,WAAW,uBAyGrD"}
@@ -0,0 +1,43 @@
1
+ import type { AsyncStorage } from "../utils/storage/AsyncStorage.js";
2
+ import type { RequestedPaymentPayload } from "./schemas.js";
3
+ /**
4
+ * Cached permit signature data structure
5
+ */
6
+ type CachedPermitSignature = {
7
+ payload: RequestedPaymentPayload;
8
+ deadline: string;
9
+ maxAmount: string;
10
+ };
11
+ /**
12
+ * Parameters for generating a permit cache key
13
+ */
14
+ export type PermitCacheKeyParams = {
15
+ chainId: number;
16
+ asset: string;
17
+ owner: string;
18
+ spender: string;
19
+ };
20
+ /**
21
+ * Retrieves a cached permit signature from storage
22
+ * @param storage - The AsyncStorage instance to use
23
+ * @param params - The parameters identifying the cached signature
24
+ * @returns The cached signature data or null if not found
25
+ */
26
+ export declare function getPermitSignatureFromCache(storage: AsyncStorage, params: PermitCacheKeyParams): Promise<CachedPermitSignature | null>;
27
+ /**
28
+ * Saves a permit signature to storage cache
29
+ * @param storage - The AsyncStorage instance to use
30
+ * @param params - The parameters identifying the signature
31
+ * @param payload - The signed payment payload to cache
32
+ * @param deadline - The deadline timestamp of the permit
33
+ * @param maxAmount - The maximum amount authorized
34
+ */
35
+ export declare function savePermitSignatureToCache(storage: AsyncStorage, params: PermitCacheKeyParams, payload: RequestedPaymentPayload, deadline: string, maxAmount: string): Promise<void>;
36
+ /**
37
+ * Clears a cached permit signature from storage
38
+ * @param storage - The AsyncStorage instance to use
39
+ * @param params - The parameters identifying the cached signature
40
+ */
41
+ export declare function clearPermitSignatureFromCache(storage: AsyncStorage, params: PermitCacheKeyParams): Promise<void>;
42
+ export {};
43
+ //# sourceMappingURL=permitSignatureStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permitSignatureStorage.d.ts","sourceRoot":"","sources":["../../../src/x402/permitSignatureStorage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAE5D;;GAEG;AACH,KAAK,qBAAqB,GAAG;IAC3B,OAAO,EAAE,uBAAuB,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAaF;;;;;GAKG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAWvC;AAED;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE,uBAAuB,EAChC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAOf"}
@@ -1,4 +1,5 @@
1
1
  import type { ThirdwebClient } from "../client/client.js";
2
+ import type { AsyncStorage } from "../utils/storage/AsyncStorage.js";
2
3
  import type { Account } from "../wallets/interfaces/wallet.js";
3
4
  import { type RequestedPaymentRequirements } from "./schemas.js";
4
5
  /**
@@ -7,7 +8,8 @@ import { type RequestedPaymentRequirements } from "./schemas.js";
7
8
  * @param client - The signer wallet instance used to create the payment header
8
9
  * @param x402Version - The version of the X402 protocol to use
9
10
  * @param paymentRequirements - The payment requirements containing scheme and network information
11
+ * @param storage - Optional storage for caching permit signatures (for "upto" scheme)
10
12
  * @returns A promise that resolves to the encoded payment header string
11
13
  */
12
- export declare function createPaymentHeader(client: ThirdwebClient, account: Account, paymentRequirements: RequestedPaymentRequirements, x402Version: number): Promise<string>;
14
+ export declare function createPaymentHeader(client: ThirdwebClient, account: Account, paymentRequirements: RequestedPaymentRequirements, x402Version: number, storage?: AsyncStorage): Promise<string>;
13
15
  //# sourceMappingURL=sign.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../../../src/x402/sign.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAK1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAG/D,OAAO,EAIL,KAAK,4BAA4B,EAElC,MAAM,cAAc,CAAC;AAoItB;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,OAAO,EAChB,mBAAmB,EAAE,4BAA4B,EACjD,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAQjB"}
1
+ {"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../../../src/x402/sign.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAM1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAQ/D,OAAO,EAIL,KAAK,4BAA4B,EAElC,MAAM,cAAc,CAAC;AAqMtB;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,OAAO,EAChB,mBAAmB,EAAE,4BAA4B,EACjD,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,MAAM,CAAC,CASjB"}
package/package.json CHANGED
@@ -399,7 +399,7 @@
399
399
  }
400
400
  },
401
401
  "typings": "./dist/types/exports/thirdweb.d.ts",
402
- "version": "5.116.0",
402
+ "version": "5.116.1",
403
403
  "scripts": {
404
404
  "bench": "vitest -c ./test/vitest.config.ts bench",
405
405
  "bench:compare": "bun run ./benchmarks/run.ts",
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { useMutation } from "@tanstack/react-query";
4
4
  import type { ThirdwebClient } from "../../../../client/client.js";
5
+ import type { AsyncStorage } from "../../../../utils/storage/AsyncStorage.js";
5
6
  import type { Wallet } from "../../../../wallets/interfaces/wallet.js";
6
7
  import { wrapFetchWithPayment } from "../../../../x402/fetchWithPayment.js";
7
8
  import type { RequestedPaymentRequirements } from "../../../../x402/schemas.js";
@@ -14,6 +15,11 @@ export type UseFetchWithPaymentOptions = {
14
15
  paymentRequirements: RequestedPaymentRequirements[],
15
16
  ) => RequestedPaymentRequirements | undefined;
16
17
  parseAs?: "json" | "text" | "raw";
18
+ /**
19
+ * Storage for caching permit signatures (for "upto" scheme).
20
+ * When provided, permit signatures will be cached and reused if the on-chain allowance is sufficient.
21
+ */
22
+ storage?: AsyncStorage;
17
23
  };
18
24
 
19
25
  type ShowErrorModalCallback = (data: {
@@ -81,7 +87,11 @@ export function useFetchWithPaymentCore(
81
87
  globalThis.fetch,
82
88
  client,
83
89
  currentWallet,
84
- options,
90
+ {
91
+ maxValue: options?.maxValue,
92
+ paymentRequirementsSelector: options?.paymentRequirementsSelector,
93
+ storage: options?.storage,
94
+ },
85
95
  );
86
96
 
87
97
  const response = await wrappedFetch(input, init);
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import type { ThirdwebClient } from "../../../../client/client.js";
4
+ import { nativeLocalStorage } from "../../../../utils/storage/nativeStorage.js";
4
5
  import {
5
6
  type UseFetchWithPaymentOptions,
6
7
  useFetchWithPaymentCore,
@@ -29,6 +30,7 @@ export type { UseFetchWithPaymentOptions };
29
30
  * @param options.maxValue - The maximum allowed payment amount in base units
30
31
  * @param options.paymentRequirementsSelector - Custom function to select payment requirements from available options
31
32
  * @param options.parseAs - How to parse the response: "json" (default), "text", or "raw"
33
+ * @param options.storage - Storage for caching permit signatures (for "upto" scheme). Provide your own AsyncStorage implementation for React Native.
32
34
  * @returns An object containing:
33
35
  * - `fetchWithPayment`: Function to make fetch requests with automatic payment handling (returns parsed data)
34
36
  * - `isPending`: Boolean indicating if a request is in progress
@@ -92,5 +94,8 @@ export function useFetchWithPayment(
92
94
  options?: UseFetchWithPaymentOptions,
93
95
  ) {
94
96
  // Native version doesn't show modal, errors bubble up naturally
95
- return useFetchWithPaymentCore(client, options);
97
+ return useFetchWithPaymentCore(client, {
98
+ ...options,
99
+ storage: options?.storage ?? nativeLocalStorage,
100
+ });
96
101
  }
@@ -1,7 +1,8 @@
1
1
  "use client";
2
2
 
3
- import { useContext } from "react";
3
+ import { useContext, useMemo } from "react";
4
4
  import type { ThirdwebClient } from "../../../../client/client.js";
5
+ import { webLocalStorage } from "../../../../utils/storage/webStorage.js";
5
6
  import type { Wallet } from "../../../../wallets/interfaces/wallet.js";
6
7
  import type { Theme } from "../../../core/design-system/index.js";
7
8
  import {
@@ -255,9 +256,18 @@ export function useFetchWithPayment(
255
256
  }
256
257
  : undefined;
257
258
 
259
+ // Default to webLocalStorage for permit signature caching
260
+ const resolvedOptions = useMemo(
261
+ () => ({
262
+ ...(options ?? {}),
263
+ storage: options?.storage ?? webLocalStorage,
264
+ }),
265
+ [options],
266
+ );
267
+
258
268
  return useFetchWithPaymentCore(
259
269
  client,
260
- options,
270
+ resolvedOptions,
261
271
  showErrorModal,
262
272
  showConnectModal,
263
273
  );
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.116.0";
1
+ export const version = "5.116.1";
@@ -1,6 +1,10 @@
1
1
  import { getCachedChain } from "../chains/utils.js";
2
2
  import type { ThirdwebClient } from "../client/client.js";
3
+ import { getAddress } from "../utils/address.js";
4
+ import type { AsyncStorage } from "../utils/storage/AsyncStorage.js";
5
+ import { webLocalStorage } from "../utils/storage/webStorage.js";
3
6
  import type { Wallet } from "../wallets/interfaces/wallet.js";
7
+ import { clearPermitSignatureFromCache } from "./permitSignatureStorage.js";
4
8
  import {
5
9
  extractEvmChainId,
6
10
  networkToCaip2ChainId,
@@ -57,6 +61,11 @@ export function wrapFetchWithPayment(
57
61
  paymentRequirementsSelector?: (
58
62
  paymentRequirements: RequestedPaymentRequirements[],
59
63
  ) => RequestedPaymentRequirements | undefined;
64
+ /**
65
+ * Storage for caching permit signatures (for "upto" scheme).
66
+ * When provided, permit signatures will be cached and reused if the on-chain allowance is sufficient.
67
+ */
68
+ storage?: AsyncStorage;
60
69
  },
61
70
  ) {
62
71
  return async (input: RequestInfo, init?: RequestInit) => {
@@ -131,6 +140,7 @@ export function wrapFetchWithPayment(
131
140
  account,
132
141
  selectedPaymentRequirements,
133
142
  x402Version,
143
+ options?.storage ?? webLocalStorage,
134
144
  );
135
145
 
136
146
  const initParams = init || {};
@@ -150,6 +160,17 @@ export function wrapFetchWithPayment(
150
160
  };
151
161
 
152
162
  const secondResponse = await fetch(input, newInit);
163
+
164
+ // If payment was rejected (still 402), clear cached signature
165
+ if (secondResponse.status === 402 && options?.storage) {
166
+ await clearPermitSignatureFromCache(options.storage, {
167
+ chainId: paymentChainId,
168
+ asset: selectedPaymentRequirements.asset,
169
+ owner: getAddress(account.address),
170
+ spender: getAddress(selectedPaymentRequirements.payTo),
171
+ });
172
+ }
173
+
153
174
  return secondResponse;
154
175
  };
155
176
  }
@@ -0,0 +1,99 @@
1
+ import type { AsyncStorage } from "../utils/storage/AsyncStorage.js";
2
+ import type { RequestedPaymentPayload } from "./schemas.js";
3
+
4
+ /**
5
+ * Cached permit signature data structure
6
+ */
7
+ type CachedPermitSignature = {
8
+ payload: RequestedPaymentPayload;
9
+ deadline: string;
10
+ maxAmount: string;
11
+ };
12
+
13
+ /**
14
+ * Parameters for generating a permit cache key
15
+ */
16
+ export type PermitCacheKeyParams = {
17
+ chainId: number;
18
+ asset: string;
19
+ owner: string;
20
+ spender: string;
21
+ };
22
+
23
+ const CACHE_KEY_PREFIX = "x402:permit";
24
+
25
+ /**
26
+ * Generates a cache key for permit signature storage
27
+ * @param params - The parameters to generate the cache key from
28
+ * @returns The cache key string
29
+ */
30
+ function getPermitCacheKey(params: PermitCacheKeyParams): string {
31
+ return `${CACHE_KEY_PREFIX}:${params.chainId}:${params.asset.toLowerCase()}:${params.owner.toLowerCase()}:${params.spender.toLowerCase()}`;
32
+ }
33
+
34
+ /**
35
+ * Retrieves a cached permit signature from storage
36
+ * @param storage - The AsyncStorage instance to use
37
+ * @param params - The parameters identifying the cached signature
38
+ * @returns The cached signature data or null if not found
39
+ */
40
+ export async function getPermitSignatureFromCache(
41
+ storage: AsyncStorage,
42
+ params: PermitCacheKeyParams,
43
+ ): Promise<CachedPermitSignature | null> {
44
+ try {
45
+ const key = getPermitCacheKey(params);
46
+ const cached = await storage.getItem(key);
47
+ if (!cached) {
48
+ return null;
49
+ }
50
+ return JSON.parse(cached) as CachedPermitSignature;
51
+ } catch {
52
+ return null;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Saves a permit signature to storage cache
58
+ * @param storage - The AsyncStorage instance to use
59
+ * @param params - The parameters identifying the signature
60
+ * @param payload - The signed payment payload to cache
61
+ * @param deadline - The deadline timestamp of the permit
62
+ * @param maxAmount - The maximum amount authorized
63
+ */
64
+ export async function savePermitSignatureToCache(
65
+ storage: AsyncStorage,
66
+ params: PermitCacheKeyParams,
67
+ payload: RequestedPaymentPayload,
68
+ deadline: string,
69
+ maxAmount: string,
70
+ ): Promise<void> {
71
+ try {
72
+ const key = getPermitCacheKey(params);
73
+ const data: CachedPermitSignature = {
74
+ payload,
75
+ deadline,
76
+ maxAmount,
77
+ };
78
+ await storage.setItem(key, JSON.stringify(data));
79
+ } catch {
80
+ // Silently fail - caching is optional
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Clears a cached permit signature from storage
86
+ * @param storage - The AsyncStorage instance to use
87
+ * @param params - The parameters identifying the cached signature
88
+ */
89
+ export async function clearPermitSignatureFromCache(
90
+ storage: AsyncStorage,
91
+ params: PermitCacheKeyParams,
92
+ ): Promise<void> {
93
+ try {
94
+ const key = getPermitCacheKey(params);
95
+ await storage.removeItem(key);
96
+ } catch {
97
+ // Silently fail
98
+ }
99
+ }
package/src/x402/sign.ts CHANGED
@@ -3,12 +3,19 @@ import type { ExactEvmPayloadAuthorization } from "x402/types";
3
3
  import { getCachedChain } from "../chains/utils.js";
4
4
  import type { ThirdwebClient } from "../client/client.js";
5
5
  import { getContract } from "../contract/contract.js";
6
+ import { allowance } from "../extensions/erc20/__generated__/IERC20/read/allowance.js";
6
7
  import { nonces } from "../extensions/erc20/__generated__/IERC20Permit/read/nonces.js";
7
8
  import { type Address, getAddress } from "../utils/address.js";
8
9
  import { type Hex, toHex } from "../utils/encoding/hex.js";
10
+ import type { AsyncStorage } from "../utils/storage/AsyncStorage.js";
9
11
  import type { Account } from "../wallets/interfaces/wallet.js";
10
12
  import { getSupportedSignatureType } from "./common.js";
11
13
  import { encodePayment } from "./encode.js";
14
+ import {
15
+ getPermitSignatureFromCache,
16
+ type PermitCacheKeyParams,
17
+ savePermitSignatureToCache,
18
+ } from "./permitSignatureStorage.js";
12
19
  import {
13
20
  extractEvmChainId,
14
21
  networkToCaip2ChainId,
@@ -63,6 +70,7 @@ function preparePaymentHeader(
63
70
  * @param client - The signer wallet instance used to sign the payment header
64
71
  * @param paymentRequirements - The payment requirements containing scheme and network information
65
72
  * @param unsignedPaymentHeader - The unsigned payment payload to be signed
73
+ * @param storage - Optional storage for caching permit signatures (for "upto" scheme)
66
74
  * @returns A promise that resolves to the signed payment payload
67
75
  */
68
76
  async function signPaymentHeader(
@@ -70,6 +78,7 @@ async function signPaymentHeader(
70
78
  account: Account,
71
79
  paymentRequirements: RequestedPaymentRequirements,
72
80
  x402Version: number,
81
+ storage?: AsyncStorage,
73
82
  ): Promise<RequestedPaymentPayload> {
74
83
  const from = getAddress(account.address);
75
84
  const caip2ChainId = networkToCaip2ChainId(paymentRequirements.network);
@@ -91,6 +100,55 @@ async function signPaymentHeader(
91
100
 
92
101
  switch (supportedSignatureType) {
93
102
  case "Permit": {
103
+ const shouldCache =
104
+ paymentRequirements.scheme === "upto" && storage !== undefined;
105
+ const spender = getAddress(paymentRequirements.payTo);
106
+
107
+ const cacheParams: PermitCacheKeyParams = {
108
+ chainId,
109
+ asset: paymentRequirements.asset,
110
+ owner: from,
111
+ spender,
112
+ };
113
+
114
+ // Try to reuse cached signature for "upto" scheme
115
+ if (shouldCache && storage) {
116
+ const cached = await getPermitSignatureFromCache(storage, cacheParams);
117
+
118
+ if (cached) {
119
+ // Validate deadline hasn't passed
120
+ const now = BigInt(Math.floor(Date.now() / 1000));
121
+ if (BigInt(cached.deadline) > now) {
122
+ // Check on-chain allowance
123
+ const currentAllowance = await allowance({
124
+ contract: getContract({
125
+ address: paymentRequirements.asset,
126
+ chain: getCachedChain(chainId),
127
+ client,
128
+ }),
129
+ owner: from,
130
+ spender,
131
+ });
132
+
133
+ // Determine threshold - use minAmountRequired if present, else maxAmountRequired
134
+ const extra = paymentRequirements.extra as
135
+ | (ERC20TokenAmount["asset"]["eip712"] & {
136
+ minAmountRequired?: string;
137
+ })
138
+ | undefined;
139
+ const threshold = extra?.minAmountRequired
140
+ ? BigInt(extra.minAmountRequired)
141
+ : BigInt(paymentRequirements.maxAmountRequired);
142
+
143
+ // If allowance >= threshold, reuse signature
144
+ if (currentAllowance >= threshold) {
145
+ return cached.payload;
146
+ }
147
+ }
148
+ }
149
+ }
150
+
151
+ // Generate new signature
94
152
  const nonce = await nonces({
95
153
  contract: getContract({
96
154
  address: paymentRequirements.asset,
@@ -110,13 +168,27 @@ async function signPaymentHeader(
110
168
  unsignedPaymentHeader.payload.authorization,
111
169
  paymentRequirements,
112
170
  );
113
- return {
171
+
172
+ const signedPayload: RequestedPaymentPayload = {
114
173
  ...unsignedPaymentHeader,
115
174
  payload: {
116
175
  ...unsignedPaymentHeader.payload,
117
176
  signature,
118
177
  },
119
178
  };
179
+
180
+ // Cache the signature for "upto" scheme
181
+ if (shouldCache && storage) {
182
+ await savePermitSignatureToCache(
183
+ storage,
184
+ cacheParams,
185
+ signedPayload,
186
+ unsignedPaymentHeader.payload.authorization.validBefore,
187
+ paymentRequirements.maxAmountRequired,
188
+ );
189
+ }
190
+
191
+ return signedPayload;
120
192
  }
121
193
  case "TransferWithAuthorization": {
122
194
  // default to transfer with authorization
@@ -153,6 +225,7 @@ async function signPaymentHeader(
153
225
  * @param client - The signer wallet instance used to create the payment header
154
226
  * @param x402Version - The version of the X402 protocol to use
155
227
  * @param paymentRequirements - The payment requirements containing scheme and network information
228
+ * @param storage - Optional storage for caching permit signatures (for "upto" scheme)
156
229
  * @returns A promise that resolves to the encoded payment header string
157
230
  */
158
231
  export async function createPaymentHeader(
@@ -160,12 +233,14 @@ export async function createPaymentHeader(
160
233
  account: Account,
161
234
  paymentRequirements: RequestedPaymentRequirements,
162
235
  x402Version: number,
236
+ storage?: AsyncStorage,
163
237
  ): Promise<string> {
164
238
  const payment = await signPaymentHeader(
165
239
  client,
166
240
  account,
167
241
  paymentRequirements,
168
242
  x402Version,
243
+ storage,
169
244
  );
170
245
  return encodePayment(payment);
171
246
  }