@puga-labs/x402-mantle-sdk 0.3.5 → 0.3.7

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.
@@ -0,0 +1,286 @@
1
+ import {
2
+ __require,
3
+ getChainIdForNetwork
4
+ } from "./chunk-HEZZ74SI.js";
5
+
6
+ // src/shared/utils.ts
7
+ function encodeJsonToBase64(value) {
8
+ const json = JSON.stringify(value);
9
+ if (typeof btoa === "function") {
10
+ const bytes = new TextEncoder().encode(json);
11
+ const binString = Array.from(
12
+ bytes,
13
+ (byte) => String.fromCodePoint(byte)
14
+ ).join("");
15
+ return btoa(binString);
16
+ }
17
+ if (typeof globalThis.Buffer !== "undefined") {
18
+ return globalThis.Buffer.from(json, "utf8").toString("base64");
19
+ }
20
+ throw new Error("No base64 implementation found in this environment");
21
+ }
22
+ function randomBytes32Hex() {
23
+ if (typeof crypto !== "undefined" && "getRandomValues" in crypto) {
24
+ const arr = new Uint8Array(32);
25
+ crypto.getRandomValues(arr);
26
+ return "0x" + Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join("");
27
+ }
28
+ try {
29
+ const nodeCrypto = __require("crypto");
30
+ const buf = nodeCrypto.randomBytes(32);
31
+ return "0x" + buf.toString("hex");
32
+ } catch {
33
+ throw new Error(
34
+ "No cryptographically secure random number generator found. This environment does not support crypto.getRandomValues or Node.js crypto module."
35
+ );
36
+ }
37
+ }
38
+
39
+ // src/client/paymentClient.ts
40
+ function joinUrl(base, path) {
41
+ const normalizedBase = base.replace(/\/+$/, "");
42
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
43
+ return `${normalizedBase}${normalizedPath}`;
44
+ }
45
+ function buildTypedDataForAuthorization(authorization, paymentRequirements) {
46
+ const chainId = getChainIdForNetwork(paymentRequirements.network);
47
+ const verifyingContract = paymentRequirements.asset;
48
+ const domain = {
49
+ name: "USD Coin",
50
+ version: "2",
51
+ chainId,
52
+ verifyingContract
53
+ };
54
+ const types = {
55
+ TransferWithAuthorization: [
56
+ { name: "from", type: "address" },
57
+ { name: "to", type: "address" },
58
+ { name: "value", type: "uint256" },
59
+ { name: "validAfter", type: "uint256" },
60
+ { name: "validBefore", type: "uint256" },
61
+ { name: "nonce", type: "bytes32" }
62
+ ]
63
+ };
64
+ return {
65
+ domain,
66
+ types,
67
+ primaryType: "TransferWithAuthorization",
68
+ message: authorization
69
+ };
70
+ }
71
+ async function signAuthorizationWithProvider(provider, authorization, paymentRequirements) {
72
+ const { BrowserProvider } = await import("ethers");
73
+ const chainId = getChainIdForNetwork(paymentRequirements.network);
74
+ const browserProvider = new BrowserProvider(provider, chainId);
75
+ const signer = await browserProvider.getSigner();
76
+ const from = await signer.getAddress();
77
+ const authWithFrom = {
78
+ ...authorization,
79
+ from
80
+ };
81
+ const typedData = buildTypedDataForAuthorization(
82
+ authWithFrom,
83
+ paymentRequirements
84
+ );
85
+ const signature = await signer.signTypedData(
86
+ typedData.domain,
87
+ typedData.types,
88
+ typedData.message
89
+ );
90
+ return { signature, from };
91
+ }
92
+ function createPaymentClient(config) {
93
+ const {
94
+ resourceUrl,
95
+ facilitatorUrl,
96
+ provider,
97
+ userAddress: userAddressOverride,
98
+ projectKey
99
+ } = config;
100
+ if (!resourceUrl) {
101
+ throw new Error("resourceUrl is required");
102
+ }
103
+ if (!facilitatorUrl) {
104
+ throw new Error("facilitatorUrl is required");
105
+ }
106
+ if (!provider) {
107
+ throw new Error("provider is required (e.g. window.ethereum)");
108
+ }
109
+ return {
110
+ async callWithPayment(path, options) {
111
+ const method = options?.method ?? "GET";
112
+ const headers = {
113
+ ...options?.headers ?? {}
114
+ };
115
+ let body;
116
+ if (options?.body !== void 0) {
117
+ headers["Content-Type"] = headers["Content-Type"] ?? "application/json";
118
+ body = JSON.stringify(options.body);
119
+ }
120
+ const initialUrl = joinUrl(resourceUrl, path);
121
+ const initialRes = await fetch(initialUrl, {
122
+ method,
123
+ headers,
124
+ body
125
+ });
126
+ if (initialRes.status !== 402) {
127
+ const json = await initialRes.json().catch((err) => {
128
+ console.error("[x402] Failed to parse initial response JSON:", err);
129
+ return null;
130
+ });
131
+ return {
132
+ response: json,
133
+ txHash: void 0
134
+ };
135
+ }
136
+ const bodyJson = await initialRes.json();
137
+ const paymentRequirements = bodyJson.paymentRequirements;
138
+ if (!paymentRequirements) {
139
+ throw new Error(
140
+ "402 response did not include paymentRequirements field"
141
+ );
142
+ }
143
+ const nowSec = Math.floor(Date.now() / 1e3);
144
+ const validAfter = "0";
145
+ const validBefore = String(nowSec + 10 * 60);
146
+ const nonce = randomBytes32Hex();
147
+ const valueAtomic = options?.valueOverrideAtomic ?? paymentRequirements.maxAmountRequired;
148
+ let authorization = {
149
+ from: "0x0000000000000000000000000000000000000000",
150
+ to: paymentRequirements.payTo,
151
+ value: valueAtomic,
152
+ validAfter,
153
+ validBefore,
154
+ nonce
155
+ };
156
+ const { signature, from } = await signAuthorizationWithProvider(
157
+ provider,
158
+ authorization,
159
+ paymentRequirements
160
+ );
161
+ authorization = {
162
+ ...authorization,
163
+ from
164
+ };
165
+ if (userAddressOverride && userAddressOverride.toLowerCase() !== from.toLowerCase()) {
166
+ console.warn(
167
+ "[SDK WARNING] userAddress override differs from signer address",
168
+ { override: userAddressOverride, signer: from }
169
+ );
170
+ }
171
+ const paymentHeaderObject = {
172
+ x402Version: 1,
173
+ scheme: paymentRequirements.scheme,
174
+ network: paymentRequirements.network,
175
+ payload: {
176
+ signature,
177
+ authorization
178
+ }
179
+ };
180
+ const paymentHeader = encodeJsonToBase64(paymentHeaderObject);
181
+ const settleUrl = joinUrl(facilitatorUrl, "/settle");
182
+ const settleRes = await fetch(settleUrl, {
183
+ method: "POST",
184
+ headers: {
185
+ "Content-Type": "application/json",
186
+ ...projectKey ? { "X-Project-Key": projectKey } : {}
187
+ },
188
+ body: JSON.stringify({
189
+ x402Version: 1,
190
+ paymentHeader,
191
+ paymentRequirements
192
+ })
193
+ });
194
+ if (!settleRes.ok) {
195
+ const text = await settleRes.text().catch((err) => {
196
+ console.error("[x402] Failed to read settle response text:", err);
197
+ return "";
198
+ });
199
+ throw new Error(
200
+ `Facilitator /settle failed with HTTP ${settleRes.status}: ${text}`
201
+ );
202
+ }
203
+ const settleJson = await settleRes.json();
204
+ if (!settleJson.success) {
205
+ throw new Error(
206
+ `Facilitator /settle returned error: ${settleJson.error ?? "unknown error"}`
207
+ );
208
+ }
209
+ const txHash = settleJson.txHash ?? void 0;
210
+ const retryHeaders = {
211
+ ...headers,
212
+ "X-PAYMENT": paymentHeader
213
+ };
214
+ const retryRes = await fetch(initialUrl, {
215
+ method,
216
+ headers: retryHeaders,
217
+ body
218
+ });
219
+ if (!retryRes.ok) {
220
+ const text = await retryRes.text().catch((err) => {
221
+ console.error("[x402] Failed to read retry response text:", err);
222
+ return "";
223
+ });
224
+ throw new Error(
225
+ `Protected request with X-PAYMENT failed: HTTP ${retryRes.status} ${text}`
226
+ );
227
+ }
228
+ const finalJson = await retryRes.json();
229
+ return {
230
+ response: finalJson,
231
+ txHash,
232
+ paymentHeader,
233
+ paymentRequirements
234
+ };
235
+ }
236
+ };
237
+ }
238
+
239
+ // src/client/createMantleClient.ts
240
+ function createMantleClient(config) {
241
+ const resourceUrl = config?.resourceUrl ?? (typeof window !== "undefined" ? window.location.origin : "");
242
+ const facilitatorUrl = config?.facilitatorUrl ?? (typeof process !== "undefined" ? process.env?.NEXT_PUBLIC_FACILITATOR_URL : void 0) ?? "http://localhost:8080";
243
+ return {
244
+ async postWithPayment(url, body) {
245
+ const provider = config?.getProvider?.();
246
+ if (!provider) {
247
+ throw new Error("Wallet provider not available");
248
+ }
249
+ let account = await config?.getAccount?.();
250
+ if (!account && provider?.request) {
251
+ try {
252
+ const accounts = await provider.request({
253
+ method: "eth_accounts"
254
+ });
255
+ if (Array.isArray(accounts) && accounts.length > 0) {
256
+ account = accounts[0];
257
+ }
258
+ } catch (err) {
259
+ console.warn("[x402] Failed to hydrate account from provider:", err);
260
+ }
261
+ }
262
+ if (!account) {
263
+ throw new Error(
264
+ "Wallet not connected. Please connect your wallet first."
265
+ );
266
+ }
267
+ const client = createPaymentClient({
268
+ resourceUrl,
269
+ facilitatorUrl,
270
+ provider,
271
+ userAddress: account,
272
+ projectKey: config?.projectKey
273
+ });
274
+ const result = await client.callWithPayment(url, {
275
+ method: "POST",
276
+ body
277
+ });
278
+ return result;
279
+ }
280
+ };
281
+ }
282
+
283
+ export {
284
+ createPaymentClient,
285
+ createMantleClient
286
+ };
package/dist/client.cjs CHANGED
@@ -206,11 +206,26 @@ function createPaymentClient(config) {
206
206
  validBefore,
207
207
  nonce
208
208
  };
209
- const { signature, from } = await signAuthorizationWithProvider(
210
- provider,
211
- authorization,
212
- paymentRequirements
213
- );
209
+ let signature;
210
+ let from;
211
+ try {
212
+ const signed = await signAuthorizationWithProvider(
213
+ provider,
214
+ authorization,
215
+ paymentRequirements
216
+ );
217
+ signature = signed.signature;
218
+ from = signed.from;
219
+ } catch (err) {
220
+ const code = err?.code;
221
+ if (code === 4001 || code === "ACTION_REJECTED") {
222
+ const userErr = new Error("User rejected payment signature");
223
+ userErr.code = "USER_REJECTED_SIGNATURE";
224
+ userErr.userRejected = true;
225
+ throw userErr;
226
+ }
227
+ throw err;
228
+ }
214
229
  authorization = {
215
230
  ...authorization,
216
231
  from
@@ -295,16 +310,28 @@ function createMantleClient(config) {
295
310
  const facilitatorUrl = config?.facilitatorUrl ?? (typeof process !== "undefined" ? process.env?.NEXT_PUBLIC_FACILITATOR_URL : void 0) ?? "http://localhost:8080";
296
311
  return {
297
312
  async postWithPayment(url, body) {
298
- const account = await config?.getAccount?.();
313
+ const provider = config?.getProvider?.();
314
+ if (!provider) {
315
+ throw new Error("Wallet provider not available");
316
+ }
317
+ let account = await config?.getAccount?.();
318
+ if (!account && provider?.request) {
319
+ try {
320
+ const accounts = await provider.request({
321
+ method: "eth_accounts"
322
+ });
323
+ if (Array.isArray(accounts) && accounts.length > 0) {
324
+ account = accounts[0];
325
+ }
326
+ } catch (err) {
327
+ console.warn("[x402] Failed to hydrate account from provider:", err);
328
+ }
329
+ }
299
330
  if (!account) {
300
331
  throw new Error(
301
332
  "Wallet not connected. Please connect your wallet first."
302
333
  );
303
334
  }
304
- const provider = config?.getProvider?.();
305
- if (!provider) {
306
- throw new Error("Wallet provider not available");
307
- }
308
335
  const client = createPaymentClient({
309
336
  resourceUrl,
310
337
  facilitatorUrl,
package/dist/client.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createMantleClient,
3
3
  createPaymentClient
4
- } from "./chunk-E46A7I6B.js";
4
+ } from "./chunk-7SOCLVGM.js";
5
5
  import {
6
6
  MANTLE_DEFAULTS
7
7
  } from "./chunk-HEZZ74SI.js";
package/dist/index.cjs CHANGED
@@ -131,7 +131,7 @@ function buildRouteKey(method, path) {
131
131
  }
132
132
 
133
133
  // src/server/constants.ts
134
- var DEFAULT_TELEMETRY_ENDPOINT = void 0;
134
+ var DEFAULT_TELEMETRY_ENDPOINT = "https://x402mantlesdk.xyz/api/telemetry/settled";
135
135
 
136
136
  // src/server/telemetry.ts
137
137
  function createTelemetryEvent(entry, config) {
@@ -533,11 +533,26 @@ function createPaymentClient(config) {
533
533
  validBefore,
534
534
  nonce
535
535
  };
536
- const { signature, from } = await signAuthorizationWithProvider(
537
- provider,
538
- authorization,
539
- paymentRequirements
540
- );
536
+ let signature;
537
+ let from;
538
+ try {
539
+ const signed = await signAuthorizationWithProvider(
540
+ provider,
541
+ authorization,
542
+ paymentRequirements
543
+ );
544
+ signature = signed.signature;
545
+ from = signed.from;
546
+ } catch (err) {
547
+ const code = err?.code;
548
+ if (code === 4001 || code === "ACTION_REJECTED") {
549
+ const userErr = new Error("User rejected payment signature");
550
+ userErr.code = "USER_REJECTED_SIGNATURE";
551
+ userErr.userRejected = true;
552
+ throw userErr;
553
+ }
554
+ throw err;
555
+ }
541
556
  authorization = {
542
557
  ...authorization,
543
558
  from
@@ -622,16 +637,28 @@ function createMantleClient(config) {
622
637
  const facilitatorUrl = config?.facilitatorUrl ?? (typeof process !== "undefined" ? process.env?.NEXT_PUBLIC_FACILITATOR_URL : void 0) ?? "http://localhost:8080";
623
638
  return {
624
639
  async postWithPayment(url, body) {
625
- const account = await config?.getAccount?.();
640
+ const provider = config?.getProvider?.();
641
+ if (!provider) {
642
+ throw new Error("Wallet provider not available");
643
+ }
644
+ let account = await config?.getAccount?.();
645
+ if (!account && provider?.request) {
646
+ try {
647
+ const accounts = await provider.request({
648
+ method: "eth_accounts"
649
+ });
650
+ if (Array.isArray(accounts) && accounts.length > 0) {
651
+ account = accounts[0];
652
+ }
653
+ } catch (err) {
654
+ console.warn("[x402] Failed to hydrate account from provider:", err);
655
+ }
656
+ }
626
657
  if (!account) {
627
658
  throw new Error(
628
659
  "Wallet not connected. Please connect your wallet first."
629
660
  );
630
661
  }
631
- const provider = config?.getProvider?.();
632
- if (!provider) {
633
- throw new Error("Wallet provider not available");
634
- }
635
662
  const client = createPaymentClient({
636
663
  resourceUrl,
637
664
  facilitatorUrl,
@@ -659,6 +686,31 @@ function useEthersWallet(options) {
659
686
  );
660
687
  const [chainId, setChainId] = (0, import_react.useState)(void 0);
661
688
  const [error, setError] = (0, import_react.useState)(void 0);
689
+ const setProviderAndChain = (0, import_react.useCallback)(async () => {
690
+ if (typeof window === "undefined" || !window.ethereum) return;
691
+ const browserProvider = new import_ethers.ethers.BrowserProvider(
692
+ window.ethereum
693
+ );
694
+ setProvider(browserProvider);
695
+ const network = await browserProvider.getNetwork();
696
+ setChainId(Number(network.chainId));
697
+ }, []);
698
+ const hydrateFromPermissions = (0, import_react.useCallback)(async () => {
699
+ if (typeof window === "undefined" || !window.ethereum) return;
700
+ try {
701
+ const accounts = await window.ethereum.request({
702
+ method: "eth_accounts"
703
+ });
704
+ if (accounts && accounts.length > 0) {
705
+ const userAddress = accounts[0];
706
+ setAddress(userAddress);
707
+ setIsConnected(true);
708
+ await setProviderAndChain();
709
+ }
710
+ } catch (err) {
711
+ console.warn("[useEthersWallet] Failed to hydrate from permissions:", err);
712
+ }
713
+ }, [setProviderAndChain]);
662
714
  const connect = (0, import_react.useCallback)(async () => {
663
715
  try {
664
716
  setError(void 0);
@@ -707,6 +759,7 @@ function useEthersWallet(options) {
707
759
  } else {
708
760
  setAddress(accountsArray[0]);
709
761
  setIsConnected(true);
762
+ void setProviderAndChain();
710
763
  }
711
764
  };
712
765
  if (ethereum.on) {
@@ -717,7 +770,22 @@ function useEthersWallet(options) {
717
770
  ethereum.removeListener("accountsChanged", handleAccountsChanged);
718
771
  }
719
772
  };
720
- }, [disconnect]);
773
+ }, [disconnect, setProviderAndChain]);
774
+ (0, import_react.useEffect)(() => {
775
+ if (typeof window === "undefined" || !window.ethereum) return;
776
+ const ethereum = window.ethereum;
777
+ const handleConnect = () => {
778
+ void hydrateFromPermissions();
779
+ };
780
+ if (ethereum.on) {
781
+ ethereum.on("connect", handleConnect);
782
+ }
783
+ return () => {
784
+ if (ethereum.removeListener) {
785
+ ethereum.removeListener("connect", handleConnect);
786
+ }
787
+ };
788
+ }, [hydrateFromPermissions]);
721
789
  (0, import_react.useEffect)(() => {
722
790
  if (typeof window === "undefined" || !window.ethereum) return;
723
791
  const ethereum = window.ethereum;
@@ -734,14 +802,16 @@ function useEthersWallet(options) {
734
802
  }
735
803
  };
736
804
  }, []);
737
- const shouldAutoConnect = options?.autoConnect !== false;
738
805
  (0, import_react.useEffect)(() => {
739
- if (shouldAutoConnect) {
806
+ void hydrateFromPermissions();
807
+ }, [hydrateFromPermissions]);
808
+ (0, import_react.useEffect)(() => {
809
+ if (options?.autoConnect) {
740
810
  connect().catch((err) => {
741
811
  console.warn("[useEthersWallet] Auto-connect failed:", err);
742
812
  });
743
813
  }
744
- }, [shouldAutoConnect, connect]);
814
+ }, [options?.autoConnect, connect]);
745
815
  return {
746
816
  address,
747
817
  isConnected,
package/dist/index.js CHANGED
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  useEthersWallet,
3
3
  useMantleX402
4
- } from "./chunk-23QNUJIB.js";
4
+ } from "./chunk-26OQ36EN.js";
5
5
  import {
6
6
  createMantleClient,
7
7
  createPaymentClient
8
- } from "./chunk-E46A7I6B.js";
8
+ } from "./chunk-7SOCLVGM.js";
9
9
  import "./chunk-WO2MYZXT.js";
10
10
  import {
11
11
  createPaymentMiddleware,
12
12
  mantlePaywall
13
- } from "./chunk-QWQUSRLY.js";
14
- import "./chunk-ZLCKBFVJ.js";
13
+ } from "./chunk-MBJTUNDL.js";
14
+ import "./chunk-EKEVUVF3.js";
15
15
  import {
16
16
  MANTLE_DEFAULTS
17
17
  } from "./chunk-HEZZ74SI.js";
package/dist/react.cjs CHANGED
@@ -46,6 +46,31 @@ function useEthersWallet(options) {
46
46
  );
47
47
  const [chainId, setChainId] = (0, import_react.useState)(void 0);
48
48
  const [error, setError] = (0, import_react.useState)(void 0);
49
+ const setProviderAndChain = (0, import_react.useCallback)(async () => {
50
+ if (typeof window === "undefined" || !window.ethereum) return;
51
+ const browserProvider = new import_ethers.ethers.BrowserProvider(
52
+ window.ethereum
53
+ );
54
+ setProvider(browserProvider);
55
+ const network = await browserProvider.getNetwork();
56
+ setChainId(Number(network.chainId));
57
+ }, []);
58
+ const hydrateFromPermissions = (0, import_react.useCallback)(async () => {
59
+ if (typeof window === "undefined" || !window.ethereum) return;
60
+ try {
61
+ const accounts = await window.ethereum.request({
62
+ method: "eth_accounts"
63
+ });
64
+ if (accounts && accounts.length > 0) {
65
+ const userAddress = accounts[0];
66
+ setAddress(userAddress);
67
+ setIsConnected(true);
68
+ await setProviderAndChain();
69
+ }
70
+ } catch (err) {
71
+ console.warn("[useEthersWallet] Failed to hydrate from permissions:", err);
72
+ }
73
+ }, [setProviderAndChain]);
49
74
  const connect = (0, import_react.useCallback)(async () => {
50
75
  try {
51
76
  setError(void 0);
@@ -94,6 +119,7 @@ function useEthersWallet(options) {
94
119
  } else {
95
120
  setAddress(accountsArray[0]);
96
121
  setIsConnected(true);
122
+ void setProviderAndChain();
97
123
  }
98
124
  };
99
125
  if (ethereum.on) {
@@ -104,7 +130,22 @@ function useEthersWallet(options) {
104
130
  ethereum.removeListener("accountsChanged", handleAccountsChanged);
105
131
  }
106
132
  };
107
- }, [disconnect]);
133
+ }, [disconnect, setProviderAndChain]);
134
+ (0, import_react.useEffect)(() => {
135
+ if (typeof window === "undefined" || !window.ethereum) return;
136
+ const ethereum = window.ethereum;
137
+ const handleConnect = () => {
138
+ void hydrateFromPermissions();
139
+ };
140
+ if (ethereum.on) {
141
+ ethereum.on("connect", handleConnect);
142
+ }
143
+ return () => {
144
+ if (ethereum.removeListener) {
145
+ ethereum.removeListener("connect", handleConnect);
146
+ }
147
+ };
148
+ }, [hydrateFromPermissions]);
108
149
  (0, import_react.useEffect)(() => {
109
150
  if (typeof window === "undefined" || !window.ethereum) return;
110
151
  const ethereum = window.ethereum;
@@ -121,14 +162,16 @@ function useEthersWallet(options) {
121
162
  }
122
163
  };
123
164
  }, []);
124
- const shouldAutoConnect = options?.autoConnect !== false;
125
165
  (0, import_react.useEffect)(() => {
126
- if (shouldAutoConnect) {
166
+ void hydrateFromPermissions();
167
+ }, [hydrateFromPermissions]);
168
+ (0, import_react.useEffect)(() => {
169
+ if (options?.autoConnect) {
127
170
  connect().catch((err) => {
128
171
  console.warn("[useEthersWallet] Auto-connect failed:", err);
129
172
  });
130
173
  }
131
- }, [shouldAutoConnect, connect]);
174
+ }, [options?.autoConnect, connect]);
132
175
  return {
133
176
  address,
134
177
  isConnected,
@@ -310,11 +353,26 @@ function createPaymentClient(config) {
310
353
  validBefore,
311
354
  nonce
312
355
  };
313
- const { signature, from } = await signAuthorizationWithProvider(
314
- provider,
315
- authorization,
316
- paymentRequirements
317
- );
356
+ let signature;
357
+ let from;
358
+ try {
359
+ const signed = await signAuthorizationWithProvider(
360
+ provider,
361
+ authorization,
362
+ paymentRequirements
363
+ );
364
+ signature = signed.signature;
365
+ from = signed.from;
366
+ } catch (err) {
367
+ const code = err?.code;
368
+ if (code === 4001 || code === "ACTION_REJECTED") {
369
+ const userErr = new Error("User rejected payment signature");
370
+ userErr.code = "USER_REJECTED_SIGNATURE";
371
+ userErr.userRejected = true;
372
+ throw userErr;
373
+ }
374
+ throw err;
375
+ }
318
376
  authorization = {
319
377
  ...authorization,
320
378
  from
@@ -399,16 +457,28 @@ function createMantleClient(config) {
399
457
  const facilitatorUrl = config?.facilitatorUrl ?? (typeof process !== "undefined" ? process.env?.NEXT_PUBLIC_FACILITATOR_URL : void 0) ?? "http://localhost:8080";
400
458
  return {
401
459
  async postWithPayment(url, body) {
402
- const account = await config?.getAccount?.();
460
+ const provider = config?.getProvider?.();
461
+ if (!provider) {
462
+ throw new Error("Wallet provider not available");
463
+ }
464
+ let account = await config?.getAccount?.();
465
+ if (!account && provider?.request) {
466
+ try {
467
+ const accounts = await provider.request({
468
+ method: "eth_accounts"
469
+ });
470
+ if (Array.isArray(accounts) && accounts.length > 0) {
471
+ account = accounts[0];
472
+ }
473
+ } catch (err) {
474
+ console.warn("[x402] Failed to hydrate account from provider:", err);
475
+ }
476
+ }
403
477
  if (!account) {
404
478
  throw new Error(
405
479
  "Wallet not connected. Please connect your wallet first."
406
480
  );
407
481
  }
408
- const provider = config?.getProvider?.();
409
- if (!provider) {
410
- throw new Error("Wallet provider not available");
411
- }
412
482
  const client = createPaymentClient({
413
483
  resourceUrl,
414
484
  facilitatorUrl,
package/dist/react.d.cts CHANGED
@@ -44,7 +44,7 @@ declare function useMantleX402(opts?: UseMantleX402Options): MantleClient;
44
44
  interface UseEthersWalletOptions {
45
45
  /**
46
46
  * Auto-connect to existing MetaMask connection on mount.
47
- * @default true
47
+ * @default false
48
48
  */
49
49
  autoConnect?: boolean;
50
50
  }