@worldcoin/minikit-js 2.0.2 → 2.0.3

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.
@@ -34,6 +34,179 @@ __export(connector_exports, {
34
34
  });
35
35
  module.exports = __toCommonJS(connector_exports);
36
36
 
37
+ // src/global-keys.ts
38
+ var WAGMI_CONFIG_KEY = "__minikit_wagmi_config__";
39
+ var WAGMI_INSTALL_HOOK_KEY = "__minikit_install_wagmi_fallback__";
40
+
41
+ // src/helpers/hex.ts
42
+ var HEX_ADDRESS_REGEX = /^0x[0-9a-fA-F]{40}$/;
43
+ var HEX_STRING_REGEX = /^0x[0-9a-fA-F]*$/;
44
+ function isHexAddress(value) {
45
+ return typeof value === "string" && HEX_ADDRESS_REGEX.test(value);
46
+ }
47
+ function isHexString(value) {
48
+ return typeof value === "string" && HEX_STRING_REGEX.test(value);
49
+ }
50
+
51
+ // src/commands/types.ts
52
+ var COMMAND_VERSIONS = {
53
+ ["attestation" /* Attestation */]: 1,
54
+ ["pay" /* Pay */]: 1,
55
+ ["wallet-auth" /* WalletAuth */]: 2,
56
+ ["send-transaction" /* SendTransaction */]: 2,
57
+ ["sign-message" /* SignMessage */]: 1,
58
+ ["sign-typed-data" /* SignTypedData */]: 1,
59
+ ["share-contacts" /* ShareContacts */]: 1,
60
+ ["request-permission" /* RequestPermission */]: 1,
61
+ ["get-permissions" /* GetPermissions */]: 1,
62
+ ["send-haptic-feedback" /* SendHapticFeedback */]: 1,
63
+ ["share" /* Share */]: 1,
64
+ ["chat" /* Chat */]: 1,
65
+ ["close-miniapp" /* CloseMiniApp */]: 1
66
+ };
67
+ var commandAvailability = {
68
+ ["attestation" /* Attestation */]: false,
69
+ ["pay" /* Pay */]: false,
70
+ ["wallet-auth" /* WalletAuth */]: false,
71
+ ["send-transaction" /* SendTransaction */]: false,
72
+ ["sign-message" /* SignMessage */]: false,
73
+ ["sign-typed-data" /* SignTypedData */]: false,
74
+ ["share-contacts" /* ShareContacts */]: false,
75
+ ["request-permission" /* RequestPermission */]: false,
76
+ ["get-permissions" /* GetPermissions */]: false,
77
+ ["send-haptic-feedback" /* SendHapticFeedback */]: false,
78
+ ["share" /* Share */]: false,
79
+ ["chat" /* Chat */]: false,
80
+ ["close-miniapp" /* CloseMiniApp */]: false
81
+ };
82
+ function isCommandAvailable(command) {
83
+ return commandAvailability[command] ?? false;
84
+ }
85
+ function setCommandAvailable(command, available) {
86
+ commandAvailability[command] = available;
87
+ }
88
+ function validateCommands(worldAppSupportedCommands) {
89
+ let allCommandsValid = true;
90
+ Object.entries(COMMAND_VERSIONS).forEach(([commandName, version]) => {
91
+ const commandInput = worldAppSupportedCommands.find(
92
+ (cmd) => cmd.name === commandName
93
+ );
94
+ let isCommandValid = false;
95
+ if (!commandInput) {
96
+ console.warn(
97
+ `Command ${commandName} is not supported by the app. Try updating the app version`
98
+ );
99
+ } else {
100
+ if (commandInput.supported_versions.includes(version)) {
101
+ setCommandAvailable(commandName, true);
102
+ isCommandValid = true;
103
+ } else {
104
+ isCommandValid = true;
105
+ console.warn(
106
+ `Command ${commandName} version ${version} is not supported by the app. Supported versions: ${commandInput.supported_versions.join(", ")}. This is not an error, but it is recommended to update the World App version.`
107
+ );
108
+ setCommandAvailable(commandName, true);
109
+ }
110
+ }
111
+ if (!isCommandValid) {
112
+ allCommandsValid = false;
113
+ }
114
+ });
115
+ return allCommandsValid;
116
+ }
117
+ function sendMiniKitEvent(payload) {
118
+ if (window.webkit) {
119
+ window.webkit?.messageHandlers?.minikit?.postMessage?.(payload);
120
+ } else if (window.Android) {
121
+ window.Android?.postMessage?.(JSON.stringify(payload));
122
+ }
123
+ }
124
+ function isInWorldApp() {
125
+ return typeof window !== "undefined" && Boolean(window.WorldApp);
126
+ }
127
+ var FallbackRequiredError = class extends Error {
128
+ constructor(command) {
129
+ super(
130
+ `${command} requires a fallback function when running outside World App. Provide a fallback option: MiniKit.${command}({ ..., fallback: () => yourFallback() })`
131
+ );
132
+ this.name = "FallbackRequiredError";
133
+ }
134
+ };
135
+ var CommandUnavailableError = class extends Error {
136
+ constructor(command, reason) {
137
+ const messages = {
138
+ notInWorldApp: "Not running inside World App",
139
+ commandNotSupported: "Command not supported in this environment",
140
+ oldAppVersion: "World App version does not support this command"
141
+ };
142
+ super(`${command} is unavailable: ${messages[reason]}`);
143
+ this.name = "CommandUnavailableError";
144
+ this.reason = reason;
145
+ }
146
+ };
147
+
148
+ // src/commands/fallback.ts
149
+ var PartialExecutionError = class extends Error {
150
+ constructor(message, submitted, cause) {
151
+ super(message);
152
+ this.name = "PartialExecutionError";
153
+ this.submitted = submitted;
154
+ this.cause = cause;
155
+ }
156
+ };
157
+ async function executeWithFallback(options) {
158
+ const {
159
+ command,
160
+ nativeExecutor,
161
+ wagmiFallback,
162
+ customFallback,
163
+ requiresFallback = false
164
+ } = options;
165
+ const inWorldApp = isInWorldApp();
166
+ const commandAvailable = isCommandAvailable(command);
167
+ let nativeError;
168
+ if (inWorldApp && commandAvailable) {
169
+ try {
170
+ const data = await nativeExecutor();
171
+ return { data, executedWith: "minikit" };
172
+ } catch (error) {
173
+ nativeError = error;
174
+ console.warn(`Native ${command} failed, attempting fallback:`, error);
175
+ }
176
+ }
177
+ if (!inWorldApp && wagmiFallback) {
178
+ try {
179
+ const data = await wagmiFallback();
180
+ return { data, executedWith: "wagmi" };
181
+ } catch (error) {
182
+ if (error instanceof PartialExecutionError || error instanceof Error && error.name === "PartialExecutionError") {
183
+ throw error;
184
+ }
185
+ console.warn(`Wagmi fallback for ${command} failed:`, error);
186
+ }
187
+ }
188
+ if (!inWorldApp && customFallback) {
189
+ const data = await customFallback();
190
+ return { data, executedWith: "fallback" };
191
+ }
192
+ if (nativeError) {
193
+ throw nativeError;
194
+ }
195
+ if (requiresFallback && !inWorldApp) {
196
+ throw new FallbackRequiredError(command);
197
+ }
198
+ throw new CommandUnavailableError(command, determineFallbackReason(command));
199
+ }
200
+ function determineFallbackReason(command) {
201
+ if (!isInWorldApp()) {
202
+ return "notInWorldApp";
203
+ }
204
+ if (!isCommandAvailable(command)) {
205
+ return "oldAppVersion";
206
+ }
207
+ return "commandNotSupported";
208
+ }
209
+
37
210
  // src/commands/fallback-adapter-registry.ts
38
211
  var FALLBACK_ADAPTER_KEY = "__minikit_fallback_adapter__";
39
212
  function setFallbackAdapter(adapter) {
@@ -45,16 +218,13 @@ function getFallbackAdapter() {
45
218
 
46
219
  // src/commands/wagmi-fallback.ts
47
220
  var SIWE_NONCE_REGEX = /^[a-zA-Z0-9]{8,}$/;
48
- var WAGMI_KEY = "__minikit_wagmi_config__";
49
221
  function setWagmiConfig(config) {
50
- globalThis[WAGMI_KEY] = config;
222
+ globalThis[WAGMI_CONFIG_KEY] = config;
51
223
  registerWagmiFallbacks();
52
224
  }
225
+ globalThis[WAGMI_INSTALL_HOOK_KEY] = setWagmiConfig;
53
226
  function getWagmiConfig() {
54
- return globalThis[WAGMI_KEY];
55
- }
56
- function hasWagmiConfig() {
57
- return globalThis[WAGMI_KEY] !== void 0;
227
+ return globalThis[WAGMI_CONFIG_KEY];
58
228
  }
59
229
  function registerWagmiFallbacks() {
60
230
  setFallbackAdapter({
@@ -65,21 +235,9 @@ function registerWagmiFallbacks() {
65
235
  });
66
236
  }
67
237
  async function loadWagmiActions() {
68
- console.log("[MiniKit WagmiFallback] loadWagmiActions:start", {
69
- hasWindow: typeof window !== "undefined",
70
- hasWagmiConfig: hasWagmiConfig()
71
- });
72
238
  try {
73
- const actions = await import(
74
- /* webpackIgnore: true */
75
- "wagmi/actions"
76
- );
77
- console.log("[MiniKit WagmiFallback] loadWagmiActions:success");
78
- return actions;
239
+ return await import("wagmi/actions");
79
240
  } catch (error) {
80
- console.log("[MiniKit WagmiFallback] loadWagmiActions:error", {
81
- message: error instanceof Error ? error.message : String(error)
82
- });
83
241
  const wrappedError = new Error(
84
242
  'Wagmi fallback requires the "wagmi" package. Install wagmi or provide a custom fallback.'
85
243
  );
@@ -89,10 +247,7 @@ async function loadWagmiActions() {
89
247
  }
90
248
  async function loadSiwe() {
91
249
  try {
92
- return await import(
93
- /* webpackIgnore: true */
94
- "siwe"
95
- );
250
+ return await import("siwe");
96
251
  } catch (error) {
97
252
  const wrappedError = new Error(
98
253
  'Wagmi walletAuth fallback requires the "siwe" package. Install siwe or provide a custom fallback.'
@@ -103,10 +258,7 @@ async function loadSiwe() {
103
258
  }
104
259
  async function checksumAddress(addr) {
105
260
  try {
106
- const { getAddress: getAddress2 } = await import(
107
- /* webpackIgnore: true */
108
- "viem"
109
- );
261
+ const { getAddress: getAddress2 } = await import("viem");
110
262
  return getAddress2(addr);
111
263
  } catch {
112
264
  return addr;
@@ -119,7 +271,10 @@ async function ensureConnected(config) {
119
271
  (connection) => connection.accounts && connection.accounts.length > 0 && (isWorldApp || connection.connector?.id !== "worldApp")
120
272
  );
121
273
  if (existingConnection && existingConnection.accounts) {
122
- return checksumAddress(existingConnection.accounts[0]);
274
+ return {
275
+ address: await checksumAddress(existingConnection.accounts[0]),
276
+ connector: existingConnection.connector
277
+ };
123
278
  }
124
279
  const connectors = config.connectors;
125
280
  if (!connectors || connectors.length === 0) {
@@ -140,7 +295,10 @@ async function ensureConnected(config) {
140
295
  const account = result.accounts[0];
141
296
  const address = typeof account === "string" ? account : account.address;
142
297
  if (address) {
143
- return checksumAddress(address);
298
+ return {
299
+ address: await checksumAddress(address),
300
+ connector: selectedConnector
301
+ };
144
302
  }
145
303
  }
146
304
  } catch (error) {
@@ -154,20 +312,15 @@ async function ensureConnected(config) {
154
312
  throw new Error("Failed to connect wallet");
155
313
  }
156
314
  async function wagmiWalletAuth(params) {
157
- console.log("[MiniKit WagmiFallback] walletAuth:start", {
158
- hasWagmiConfig: hasWagmiConfig(),
159
- nonceLength: params.nonce?.length ?? 0
160
- });
161
315
  const config = getWagmiConfig();
162
316
  if (!config) {
163
- console.log("[MiniKit WagmiFallback] walletAuth:error:no-config");
164
317
  throw new Error(
165
318
  "Wagmi config not available. Pass wagmiConfig to MiniKitProvider."
166
319
  );
167
320
  }
168
321
  const { signMessage: signMessage2 } = await loadWagmiActions();
169
322
  const { SiweMessage } = await loadSiwe();
170
- const address = await ensureConnected(config);
323
+ const { address, connector } = await ensureConnected(config);
171
324
  if (!SIWE_NONCE_REGEX.test(params.nonce)) {
172
325
  throw new Error(
173
326
  "Invalid nonce: must be alphanumeric and at least 8 characters (EIP-4361)"
@@ -185,7 +338,11 @@ async function wagmiWalletAuth(params) {
185
338
  expirationTime: params.expirationTime?.toISOString()
186
339
  });
187
340
  const message = siweMessage.prepareMessage();
188
- const signature = await signMessage2(config, { message });
341
+ const signature = await signMessage2(config, {
342
+ connector,
343
+ account: address,
344
+ message
345
+ });
189
346
  return {
190
347
  address,
191
348
  message,
@@ -193,19 +350,16 @@ async function wagmiWalletAuth(params) {
193
350
  };
194
351
  }
195
352
  async function wagmiSignMessage(params) {
196
- console.log("[MiniKit WagmiFallback] signMessage:start", {
197
- hasWagmiConfig: hasWagmiConfig()
198
- });
199
353
  const config = getWagmiConfig();
200
354
  if (!config) {
201
- console.log("[MiniKit WagmiFallback] signMessage:error:no-config");
202
355
  throw new Error(
203
356
  "Wagmi config not available. Pass wagmiConfig to MiniKitProvider."
204
357
  );
205
358
  }
206
359
  const { signMessage: signMessage2 } = await loadWagmiActions();
207
- const address = await ensureConnected(config);
360
+ const { address, connector } = await ensureConnected(config);
208
361
  const signature = await signMessage2(config, {
362
+ connector,
209
363
  account: address,
210
364
  message: params.message
211
365
  });
@@ -217,26 +371,22 @@ async function wagmiSignMessage(params) {
217
371
  };
218
372
  }
219
373
  async function wagmiSignTypedData(params) {
220
- console.log("[MiniKit WagmiFallback] signTypedData:start", {
221
- hasWagmiConfig: hasWagmiConfig(),
222
- hasChainId: params.chainId !== void 0
223
- });
224
374
  const config = getWagmiConfig();
225
375
  if (!config) {
226
- console.log("[MiniKit WagmiFallback] signTypedData:error:no-config");
227
376
  throw new Error(
228
377
  "Wagmi config not available. Pass wagmiConfig to MiniKitProvider."
229
378
  );
230
379
  }
231
380
  const { getChainId, signTypedData: signTypedData2, switchChain } = await loadWagmiActions();
232
- const address = await ensureConnected(config);
381
+ const { address, connector } = await ensureConnected(config);
233
382
  if (params.chainId !== void 0) {
234
383
  const currentChainId = await getChainId(config);
235
384
  if (currentChainId !== params.chainId) {
236
- await switchChain(config, { chainId: params.chainId });
385
+ await switchChain(config, { chainId: params.chainId, connector });
237
386
  }
238
387
  }
239
388
  const signature = await signTypedData2(config, {
389
+ connector,
240
390
  account: address,
241
391
  types: params.types,
242
392
  primaryType: params.primaryType,
@@ -254,27 +404,59 @@ function isChainMismatchError(error) {
254
404
  const message = error instanceof Error ? error.message : String(error);
255
405
  return message.includes("does not match the target chain");
256
406
  }
257
- async function wagmiSendTransaction(params) {
258
- console.log("[MiniKit WagmiFallback] sendTransaction:start", {
259
- hasWagmiConfig: hasWagmiConfig(),
260
- chainId: params.chainId,
261
- hasData: Boolean(params.transaction.data)
407
+ function validateBatch(transactions) {
408
+ return transactions.map((tx, i) => {
409
+ if (!isHexAddress(tx.address)) {
410
+ throw new Error(
411
+ `Transaction ${i + 1}: invalid address "${tx.address}". Must be a 0x-prefixed 20-byte hex string.`
412
+ );
413
+ }
414
+ if (tx.data !== void 0 && !isHexString(tx.data)) {
415
+ throw new Error(
416
+ `Transaction ${i + 1}: invalid data "${tx.data}". Must be a 0x-prefixed hex string.`
417
+ );
418
+ }
419
+ let value;
420
+ if (tx.value !== void 0 && tx.value !== "") {
421
+ try {
422
+ value = BigInt(tx.value);
423
+ } catch {
424
+ throw new Error(
425
+ `Transaction ${i + 1}: invalid value "${tx.value}". Must be a decimal or hex string parseable as BigInt.`
426
+ );
427
+ }
428
+ if (value < 0n) {
429
+ throw new Error(
430
+ `Transaction ${i + 1}: value cannot be negative (got "${tx.value}").`
431
+ );
432
+ }
433
+ }
434
+ return {
435
+ to: tx.address,
436
+ ...tx.data !== void 0 ? { data: tx.data } : {},
437
+ ...value !== void 0 ? { value } : {}
438
+ };
262
439
  });
440
+ }
441
+ async function wagmiSendTransaction(params) {
442
+ if (params.transactions.length === 0) {
443
+ throw new Error("At least one transaction is required");
444
+ }
445
+ const normalizedTxs = validateBatch(params.transactions);
263
446
  const config = getWagmiConfig();
264
447
  if (!config) {
265
- console.log("[MiniKit WagmiFallback] sendTransaction:error:no-config");
266
448
  throw new Error(
267
449
  "Wagmi config not available. Pass wagmiConfig to MiniKitProvider."
268
450
  );
269
451
  }
270
452
  const { getChainId, getWalletClient, sendTransaction: sendTransaction2, switchChain } = await loadWagmiActions();
271
- await ensureConnected(config);
453
+ const { address, connector } = await ensureConnected(config);
272
454
  const targetChainId = params.chainId ?? config.chains?.[0]?.id;
273
455
  const ensureTargetChain = async () => {
274
456
  if (targetChainId === void 0) return;
275
457
  const currentChainId = await getChainId(config);
276
458
  if (currentChainId !== targetChainId) {
277
- await switchChain(config, { chainId: targetChainId });
459
+ await switchChain(config, { chainId: targetChainId, connector });
278
460
  }
279
461
  const walletClient = await getWalletClient(config);
280
462
  const providerChainId = walletClient ? await walletClient.getChainId() : await getChainId(config);
@@ -285,125 +467,42 @@ async function wagmiSendTransaction(params) {
285
467
  }
286
468
  };
287
469
  await ensureTargetChain();
288
- let transactionHash;
289
- try {
290
- transactionHash = await sendTransaction2(config, {
470
+ const sendWithChainRetry = async (tx) => {
471
+ const send = () => sendTransaction2(config, {
472
+ connector,
473
+ account: address,
291
474
  chainId: targetChainId,
292
- to: params.transaction.address,
293
- data: params.transaction.data,
294
- value: params.transaction.value ? BigInt(params.transaction.value) : void 0
475
+ to: tx.to,
476
+ data: tx.data,
477
+ value: tx.value
295
478
  });
296
- } catch (error) {
297
- if (targetChainId === void 0 || !isChainMismatchError(error)) {
479
+ try {
480
+ return await send();
481
+ } catch (error) {
482
+ if (targetChainId !== void 0 && isChainMismatchError(error)) {
483
+ await ensureTargetChain();
484
+ return await send();
485
+ }
298
486
  throw error;
299
487
  }
300
- await ensureTargetChain();
301
- transactionHash = await sendTransaction2(config, {
302
- chainId: targetChainId,
303
- to: params.transaction.address,
304
- data: params.transaction.data,
305
- value: params.transaction.value ? BigInt(params.transaction.value) : void 0
306
- });
307
- }
308
- return { transactionHash };
309
- }
310
-
311
- // src/commands/types.ts
312
- var COMMAND_VERSIONS = {
313
- ["attestation" /* Attestation */]: 1,
314
- ["pay" /* Pay */]: 1,
315
- ["wallet-auth" /* WalletAuth */]: 2,
316
- ["send-transaction" /* SendTransaction */]: 2,
317
- ["sign-message" /* SignMessage */]: 1,
318
- ["sign-typed-data" /* SignTypedData */]: 1,
319
- ["share-contacts" /* ShareContacts */]: 1,
320
- ["request-permission" /* RequestPermission */]: 1,
321
- ["get-permissions" /* GetPermissions */]: 1,
322
- ["send-haptic-feedback" /* SendHapticFeedback */]: 1,
323
- ["share" /* Share */]: 1,
324
- ["chat" /* Chat */]: 1,
325
- ["close-miniapp" /* CloseMiniApp */]: 1
326
- };
327
- var commandAvailability = {
328
- ["attestation" /* Attestation */]: false,
329
- ["pay" /* Pay */]: false,
330
- ["wallet-auth" /* WalletAuth */]: false,
331
- ["send-transaction" /* SendTransaction */]: false,
332
- ["sign-message" /* SignMessage */]: false,
333
- ["sign-typed-data" /* SignTypedData */]: false,
334
- ["share-contacts" /* ShareContacts */]: false,
335
- ["request-permission" /* RequestPermission */]: false,
336
- ["get-permissions" /* GetPermissions */]: false,
337
- ["send-haptic-feedback" /* SendHapticFeedback */]: false,
338
- ["share" /* Share */]: false,
339
- ["chat" /* Chat */]: false,
340
- ["close-miniapp" /* CloseMiniApp */]: false
341
- };
342
- function isCommandAvailable(command) {
343
- return commandAvailability[command] ?? false;
344
- }
345
- function setCommandAvailable(command, available) {
346
- commandAvailability[command] = available;
347
- }
348
- function validateCommands(worldAppSupportedCommands) {
349
- let allCommandsValid = true;
350
- Object.entries(COMMAND_VERSIONS).forEach(([commandName, version]) => {
351
- const commandInput = worldAppSupportedCommands.find(
352
- (cmd) => cmd.name === commandName
353
- );
354
- let isCommandValid = false;
355
- if (!commandInput) {
356
- console.warn(
357
- `Command ${commandName} is not supported by the app. Try updating the app version`
358
- );
359
- } else {
360
- if (commandInput.supported_versions.includes(version)) {
361
- setCommandAvailable(commandName, true);
362
- isCommandValid = true;
363
- } else {
364
- isCommandValid = true;
365
- console.warn(
366
- `Command ${commandName} version ${version} is not supported by the app. Supported versions: ${commandInput.supported_versions.join(", ")}. This is not an error, but it is recommended to update the World App version.`
488
+ };
489
+ const submitted = [];
490
+ for (let i = 0; i < normalizedTxs.length; i++) {
491
+ try {
492
+ submitted.push(await sendWithChainRetry(normalizedTxs[i]));
493
+ } catch (error) {
494
+ if (submitted.length > 0) {
495
+ throw new PartialExecutionError(
496
+ `Transaction ${i + 1}/${normalizedTxs.length} failed after ${submitted.length} tx(s) were already submitted. Resolve manually.`,
497
+ submitted,
498
+ error
367
499
  );
368
- setCommandAvailable(commandName, true);
369
500
  }
501
+ throw error;
370
502
  }
371
- if (!isCommandValid) {
372
- allCommandsValid = false;
373
- }
374
- });
375
- return allCommandsValid;
376
- }
377
- function sendMiniKitEvent(payload) {
378
- if (window.webkit) {
379
- window.webkit?.messageHandlers?.minikit?.postMessage?.(payload);
380
- } else if (window.Android) {
381
- window.Android?.postMessage?.(JSON.stringify(payload));
382
503
  }
504
+ return { transactionHash: submitted[submitted.length - 1] };
383
505
  }
384
- function isInWorldApp() {
385
- return typeof window !== "undefined" && Boolean(window.WorldApp);
386
- }
387
- var FallbackRequiredError = class extends Error {
388
- constructor(command) {
389
- super(
390
- `${command} requires a fallback function when running outside World App. Provide a fallback option: MiniKit.${command}({ ..., fallback: () => yourFallback() })`
391
- );
392
- this.name = "FallbackRequiredError";
393
- }
394
- };
395
- var CommandUnavailableError = class extends Error {
396
- constructor(command, reason) {
397
- const messages = {
398
- notInWorldApp: "Not running inside World App",
399
- commandNotSupported: "Command not supported in this environment",
400
- oldAppVersion: "World App version does not support this command"
401
- };
402
- super(`${command} is unavailable: ${messages[reason]}`);
403
- this.name = "CommandUnavailableError";
404
- this.reason = reason;
405
- }
406
- };
407
506
 
408
507
  // src/events.ts
409
508
  var EventManager = class {
@@ -454,57 +553,6 @@ var EventManager = class {
454
553
  }
455
554
  };
456
555
 
457
- // src/commands/fallback.ts
458
- async function executeWithFallback(options) {
459
- const {
460
- command,
461
- nativeExecutor,
462
- wagmiFallback,
463
- customFallback,
464
- requiresFallback = false
465
- } = options;
466
- const inWorldApp = isInWorldApp();
467
- const commandAvailable = isCommandAvailable(command);
468
- let nativeError;
469
- if (inWorldApp && commandAvailable) {
470
- try {
471
- const data = await nativeExecutor();
472
- return { data, executedWith: "minikit" };
473
- } catch (error) {
474
- nativeError = error;
475
- console.warn(`Native ${command} failed, attempting fallback:`, error);
476
- }
477
- }
478
- if (!inWorldApp && wagmiFallback) {
479
- try {
480
- const data = await wagmiFallback();
481
- return { data, executedWith: "wagmi" };
482
- } catch (error) {
483
- console.warn(`Wagmi fallback for ${command} failed:`, error);
484
- }
485
- }
486
- if (!inWorldApp && customFallback) {
487
- const data = await customFallback();
488
- return { data, executedWith: "fallback" };
489
- }
490
- if (nativeError) {
491
- throw nativeError;
492
- }
493
- if (requiresFallback && !inWorldApp) {
494
- throw new FallbackRequiredError(command);
495
- }
496
- throw new CommandUnavailableError(command, determineFallbackReason(command));
497
- }
498
- function determineFallbackReason(command) {
499
- if (!isInWorldApp()) {
500
- return "notInWorldApp";
501
- }
502
- if (!isCommandAvailable(command)) {
503
- return "oldAppVersion";
504
- }
505
- return "commandNotSupported";
506
- }
507
-
508
556
  // src/commands/attestation/types.ts
509
557
  var AttestationError = class extends Error {
510
558
  constructor(error_code) {
@@ -997,7 +1045,6 @@ var validateSendTransactionPayload = (payload) => {
997
1045
 
998
1046
  // src/commands/send-transaction/index.ts
999
1047
  var WORLD_CHAIN_ID = 480;
1000
- var WAGMI_MULTI_TX_ERROR_MESSAGE = "Wagmi fallback does not support multi-transaction execution. Pass a single transaction, run inside World App for batching, or provide a custom fallback.";
1001
1048
  function resolveChainId(options) {
1002
1049
  return options.chainId;
1003
1050
  }
@@ -1024,12 +1071,6 @@ function normalizeSendTransactionOptions(options) {
1024
1071
  async function sendTransaction(options, ctx) {
1025
1072
  const normalizedOptions = normalizeSendTransactionOptions(options);
1026
1073
  const fallbackAdapter = getFallbackAdapter();
1027
- const isWagmiFallbackPath = !isInWorldApp() && Boolean(fallbackAdapter?.sendTransaction);
1028
- if (isWagmiFallbackPath && normalizedOptions.transactions.length > 1 && !options.fallback) {
1029
- throw new SendTransactionError("invalid_operation" /* InvalidOperation */, {
1030
- reason: WAGMI_MULTI_TX_ERROR_MESSAGE
1031
- });
1032
- }
1033
1074
  const result = await executeWithFallback({
1034
1075
  command: "send-transaction" /* SendTransaction */,
1035
1076
  nativeExecutor: () => nativeSendTransaction(normalizedOptions, ctx),
@@ -1110,23 +1151,16 @@ async function nativeSendTransaction(options, ctx) {
1110
1151
  };
1111
1152
  }
1112
1153
  async function adapterSendTransactionFallback(options) {
1113
- if (options.transactions.length > 1) {
1114
- throw new Error(WAGMI_MULTI_TX_ERROR_MESSAGE);
1115
- }
1116
- const firstTransaction = options.transactions[0];
1117
- if (!firstTransaction) {
1118
- throw new Error("At least one transaction is required");
1119
- }
1120
1154
  const fallbackAdapter = getFallbackAdapter();
1121
1155
  if (!fallbackAdapter?.sendTransaction) {
1122
1156
  throw new Error("Fallback adapter is not registered.");
1123
1157
  }
1124
1158
  const result = await fallbackAdapter.sendTransaction({
1125
- transaction: {
1126
- address: firstTransaction.to,
1127
- data: firstTransaction.data,
1128
- value: firstTransaction.value
1129
- },
1159
+ transactions: options.transactions.map((tx) => ({
1160
+ address: tx.to,
1161
+ data: tx.data,
1162
+ value: tx.value
1163
+ })),
1130
1164
  chainId: options.chainId
1131
1165
  });
1132
1166
  return {
@@ -2294,12 +2328,6 @@ function _clearAddress() {
2294
2328
  function rpcError(code, message) {
2295
2329
  return Object.assign(new Error(message), { code });
2296
2330
  }
2297
- function isHexString(value) {
2298
- return /^0x[0-9a-fA-F]*$/.test(value);
2299
- }
2300
- function isAddressString(value) {
2301
- return /^0x[0-9a-fA-F]{40}$/.test(value);
2302
- }
2303
2331
  function decodeHexToUtf8(hex) {
2304
2332
  const raw = hex.slice(2);
2305
2333
  if (raw.length % 2 !== 0) {
@@ -2331,7 +2359,7 @@ function extractPersonalSignMessage(params) {
2331
2359
  throw new Error("Missing personal_sign params");
2332
2360
  }
2333
2361
  const [first, second] = items;
2334
- const maybeMessage = typeof first === "string" && isAddressString(first) && typeof second === "string" ? second : first;
2362
+ const maybeMessage = typeof first === "string" && isHexAddress(first) && typeof second === "string" ? second : first;
2335
2363
  if (typeof maybeMessage !== "string") {
2336
2364
  throw new Error("Invalid personal_sign message payload");
2337
2365
  }
@@ -2343,7 +2371,7 @@ function extractEthSignMessage(params) {
2343
2371
  throw new Error("Missing eth_sign params");
2344
2372
  }
2345
2373
  const [first, second] = items;
2346
- const maybeMessage = typeof second === "string" ? second : typeof first === "string" && !isAddressString(first) ? first : void 0;
2374
+ const maybeMessage = typeof second === "string" ? second : typeof first === "string" && !isHexAddress(first) ? first : void 0;
2347
2375
  if (typeof maybeMessage !== "string") {
2348
2376
  throw new Error("Invalid eth_sign message payload");
2349
2377
  }
@@ -2380,7 +2408,7 @@ function normalizeRpcValue(value) {
2380
2408
  function extractTransactionParams(params) {
2381
2409
  const items = asArrayParams(params);
2382
2410
  const tx = items[0] ?? {};
2383
- if (typeof tx.to !== "string" || !isAddressString(tx.to)) {
2411
+ if (typeof tx.to !== "string" || !isHexAddress(tx.to)) {
2384
2412
  throw new Error('Invalid transaction "to" address');
2385
2413
  }
2386
2414
  const chainId = typeof tx.chainId === "string" ? Number(tx.chainId) : typeof tx.chainId === "number" ? tx.chainId : void 0;