@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.
@@ -0,0 +1,216 @@
1
+ // src/commands/types.ts
2
+ var Command = /* @__PURE__ */ ((Command2) => {
3
+ Command2["Attestation"] = "attestation";
4
+ Command2["Pay"] = "pay";
5
+ Command2["WalletAuth"] = "wallet-auth";
6
+ Command2["SendTransaction"] = "send-transaction";
7
+ Command2["SignMessage"] = "sign-message";
8
+ Command2["SignTypedData"] = "sign-typed-data";
9
+ Command2["ShareContacts"] = "share-contacts";
10
+ Command2["RequestPermission"] = "request-permission";
11
+ Command2["GetPermissions"] = "get-permissions";
12
+ Command2["SendHapticFeedback"] = "send-haptic-feedback";
13
+ Command2["Share"] = "share";
14
+ Command2["Chat"] = "chat";
15
+ Command2["CloseMiniApp"] = "close-miniapp";
16
+ return Command2;
17
+ })(Command || {});
18
+ var ResponseEvent = /* @__PURE__ */ ((ResponseEvent2) => {
19
+ ResponseEvent2["MiniAppAttestation"] = "miniapp-attestation";
20
+ ResponseEvent2["MiniAppPayment"] = "miniapp-payment";
21
+ ResponseEvent2["MiniAppWalletAuth"] = "miniapp-wallet-auth";
22
+ ResponseEvent2["MiniAppSendTransaction"] = "miniapp-send-transaction";
23
+ ResponseEvent2["MiniAppSignMessage"] = "miniapp-sign-message";
24
+ ResponseEvent2["MiniAppSignTypedData"] = "miniapp-sign-typed-data";
25
+ ResponseEvent2["MiniAppShareContacts"] = "miniapp-share-contacts";
26
+ ResponseEvent2["MiniAppRequestPermission"] = "miniapp-request-permission";
27
+ ResponseEvent2["MiniAppGetPermissions"] = "miniapp-get-permissions";
28
+ ResponseEvent2["MiniAppSendHapticFeedback"] = "miniapp-send-haptic-feedback";
29
+ ResponseEvent2["MiniAppShare"] = "miniapp-share";
30
+ ResponseEvent2["MiniAppMicrophone"] = "miniapp-microphone";
31
+ ResponseEvent2["MiniAppChat"] = "miniapp-chat";
32
+ return ResponseEvent2;
33
+ })(ResponseEvent || {});
34
+ var COMMAND_VERSIONS = {
35
+ ["attestation" /* Attestation */]: 1,
36
+ ["pay" /* Pay */]: 1,
37
+ ["wallet-auth" /* WalletAuth */]: 2,
38
+ ["send-transaction" /* SendTransaction */]: 2,
39
+ ["sign-message" /* SignMessage */]: 1,
40
+ ["sign-typed-data" /* SignTypedData */]: 1,
41
+ ["share-contacts" /* ShareContacts */]: 1,
42
+ ["request-permission" /* RequestPermission */]: 1,
43
+ ["get-permissions" /* GetPermissions */]: 1,
44
+ ["send-haptic-feedback" /* SendHapticFeedback */]: 1,
45
+ ["share" /* Share */]: 1,
46
+ ["chat" /* Chat */]: 1,
47
+ ["close-miniapp" /* CloseMiniApp */]: 1
48
+ };
49
+ var commandAvailability = {
50
+ ["attestation" /* Attestation */]: false,
51
+ ["pay" /* Pay */]: false,
52
+ ["wallet-auth" /* WalletAuth */]: false,
53
+ ["send-transaction" /* SendTransaction */]: false,
54
+ ["sign-message" /* SignMessage */]: false,
55
+ ["sign-typed-data" /* SignTypedData */]: false,
56
+ ["share-contacts" /* ShareContacts */]: false,
57
+ ["request-permission" /* RequestPermission */]: false,
58
+ ["get-permissions" /* GetPermissions */]: false,
59
+ ["send-haptic-feedback" /* SendHapticFeedback */]: false,
60
+ ["share" /* Share */]: false,
61
+ ["chat" /* Chat */]: false,
62
+ ["close-miniapp" /* CloseMiniApp */]: false
63
+ };
64
+ function isCommandAvailable(command) {
65
+ return commandAvailability[command] ?? false;
66
+ }
67
+ function setCommandAvailable(command, available) {
68
+ commandAvailability[command] = available;
69
+ }
70
+ function validateCommands(worldAppSupportedCommands) {
71
+ let allCommandsValid = true;
72
+ Object.entries(COMMAND_VERSIONS).forEach(([commandName, version]) => {
73
+ const commandInput = worldAppSupportedCommands.find(
74
+ (cmd) => cmd.name === commandName
75
+ );
76
+ let isCommandValid = false;
77
+ if (!commandInput) {
78
+ console.warn(
79
+ `Command ${commandName} is not supported by the app. Try updating the app version`
80
+ );
81
+ } else {
82
+ if (commandInput.supported_versions.includes(version)) {
83
+ setCommandAvailable(commandName, true);
84
+ isCommandValid = true;
85
+ } else {
86
+ isCommandValid = true;
87
+ console.warn(
88
+ `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.`
89
+ );
90
+ setCommandAvailable(commandName, true);
91
+ }
92
+ }
93
+ if (!isCommandValid) {
94
+ allCommandsValid = false;
95
+ }
96
+ });
97
+ return allCommandsValid;
98
+ }
99
+ function sendMiniKitEvent(payload) {
100
+ if (window.webkit) {
101
+ window.webkit?.messageHandlers?.minikit?.postMessage?.(payload);
102
+ } else if (window.Android) {
103
+ window.Android?.postMessage?.(JSON.stringify(payload));
104
+ }
105
+ }
106
+ function isInWorldApp() {
107
+ return typeof window !== "undefined" && Boolean(window.WorldApp);
108
+ }
109
+ var FallbackRequiredError = class extends Error {
110
+ constructor(command) {
111
+ super(
112
+ `${command} requires a fallback function when running outside World App. Provide a fallback option: MiniKit.${command}({ ..., fallback: () => yourFallback() })`
113
+ );
114
+ this.name = "FallbackRequiredError";
115
+ }
116
+ };
117
+ var CommandUnavailableError = class extends Error {
118
+ constructor(command, reason) {
119
+ const messages = {
120
+ notInWorldApp: "Not running inside World App",
121
+ commandNotSupported: "Command not supported in this environment",
122
+ oldAppVersion: "World App version does not support this command"
123
+ };
124
+ super(`${command} is unavailable: ${messages[reason]}`);
125
+ this.name = "CommandUnavailableError";
126
+ this.reason = reason;
127
+ }
128
+ };
129
+
130
+ // src/commands/fallback.ts
131
+ var PartialExecutionError = class extends Error {
132
+ constructor(message, submitted, cause) {
133
+ super(message);
134
+ this.name = "PartialExecutionError";
135
+ this.submitted = submitted;
136
+ this.cause = cause;
137
+ }
138
+ };
139
+ async function executeWithFallback(options) {
140
+ const {
141
+ command,
142
+ nativeExecutor,
143
+ wagmiFallback,
144
+ customFallback,
145
+ requiresFallback = false
146
+ } = options;
147
+ const inWorldApp = isInWorldApp();
148
+ const commandAvailable = isCommandAvailable(command);
149
+ let nativeError;
150
+ if (inWorldApp && commandAvailable) {
151
+ try {
152
+ const data = await nativeExecutor();
153
+ return { data, executedWith: "minikit" };
154
+ } catch (error) {
155
+ nativeError = error;
156
+ console.warn(`Native ${command} failed, attempting fallback:`, error);
157
+ }
158
+ }
159
+ if (!inWorldApp && wagmiFallback) {
160
+ try {
161
+ const data = await wagmiFallback();
162
+ return { data, executedWith: "wagmi" };
163
+ } catch (error) {
164
+ if (error instanceof PartialExecutionError || error instanceof Error && error.name === "PartialExecutionError") {
165
+ throw error;
166
+ }
167
+ console.warn(`Wagmi fallback for ${command} failed:`, error);
168
+ }
169
+ }
170
+ if (!inWorldApp && customFallback) {
171
+ const data = await customFallback();
172
+ return { data, executedWith: "fallback" };
173
+ }
174
+ if (nativeError) {
175
+ throw nativeError;
176
+ }
177
+ if (requiresFallback && !inWorldApp) {
178
+ throw new FallbackRequiredError(command);
179
+ }
180
+ throw new CommandUnavailableError(command, determineFallbackReason(command));
181
+ }
182
+ function determineFallbackReason(command) {
183
+ if (!isInWorldApp()) {
184
+ return "notInWorldApp";
185
+ }
186
+ if (!isCommandAvailable(command)) {
187
+ return "oldAppVersion";
188
+ }
189
+ return "commandNotSupported";
190
+ }
191
+
192
+ // src/commands/fallback-adapter-registry.ts
193
+ var FALLBACK_ADAPTER_KEY = "__minikit_fallback_adapter__";
194
+ function setFallbackAdapter(adapter) {
195
+ globalThis[FALLBACK_ADAPTER_KEY] = adapter;
196
+ }
197
+ function getFallbackAdapter() {
198
+ return globalThis[FALLBACK_ADAPTER_KEY];
199
+ }
200
+
201
+ export {
202
+ Command,
203
+ ResponseEvent,
204
+ COMMAND_VERSIONS,
205
+ isCommandAvailable,
206
+ setCommandAvailable,
207
+ validateCommands,
208
+ sendMiniKitEvent,
209
+ isInWorldApp,
210
+ FallbackRequiredError,
211
+ CommandUnavailableError,
212
+ PartialExecutionError,
213
+ executeWithFallback,
214
+ setFallbackAdapter,
215
+ getFallbackAdapter
216
+ };
@@ -1,6 +1,10 @@
1
1
  import {
2
2
  MiniKit
3
- } from "./chunk-363XY57O.js";
3
+ } from "./chunk-7RB4UJBW.js";
4
+ import {
5
+ isHexAddress,
6
+ isHexString
7
+ } from "./chunk-2ADHLH4F.js";
4
8
 
5
9
  // src/provider.ts
6
10
  import { getAddress } from "viem";
@@ -23,12 +27,6 @@ function _clearAddress() {
23
27
  function rpcError(code, message) {
24
28
  return Object.assign(new Error(message), { code });
25
29
  }
26
- function isHexString(value) {
27
- return /^0x[0-9a-fA-F]*$/.test(value);
28
- }
29
- function isAddressString(value) {
30
- return /^0x[0-9a-fA-F]{40}$/.test(value);
31
- }
32
30
  function decodeHexToUtf8(hex) {
33
31
  const raw = hex.slice(2);
34
32
  if (raw.length % 2 !== 0) {
@@ -60,7 +58,7 @@ function extractPersonalSignMessage(params) {
60
58
  throw new Error("Missing personal_sign params");
61
59
  }
62
60
  const [first, second] = items;
63
- const maybeMessage = typeof first === "string" && isAddressString(first) && typeof second === "string" ? second : first;
61
+ const maybeMessage = typeof first === "string" && isHexAddress(first) && typeof second === "string" ? second : first;
64
62
  if (typeof maybeMessage !== "string") {
65
63
  throw new Error("Invalid personal_sign message payload");
66
64
  }
@@ -72,7 +70,7 @@ function extractEthSignMessage(params) {
72
70
  throw new Error("Missing eth_sign params");
73
71
  }
74
72
  const [first, second] = items;
75
- const maybeMessage = typeof second === "string" ? second : typeof first === "string" && !isAddressString(first) ? first : void 0;
73
+ const maybeMessage = typeof second === "string" ? second : typeof first === "string" && !isHexAddress(first) ? first : void 0;
76
74
  if (typeof maybeMessage !== "string") {
77
75
  throw new Error("Invalid eth_sign message payload");
78
76
  }
@@ -109,7 +107,7 @@ function normalizeRpcValue(value) {
109
107
  function extractTransactionParams(params) {
110
108
  const items = asArrayParams(params);
111
109
  const tx = items[0] ?? {};
112
- if (typeof tx.to !== "string" || !isAddressString(tx.to)) {
110
+ if (typeof tx.to !== "string" || !isHexAddress(tx.to)) {
113
111
  throw new Error('Invalid transaction "to" address');
114
112
  }
115
113
  const chainId = typeof tx.chainId === "string" ? Number(tx.chainId) : typeof tx.chainId === "number" ? tx.chainId : void 0;
@@ -3,7 +3,8 @@ import {
3
3
  createPublicClient,
4
4
  getContract,
5
5
  hashMessage,
6
- http
6
+ http,
7
+ recoverMessageAddress
7
8
  } from "viem";
8
9
  import { worldchain } from "viem/chains";
9
10
  var PREAMBLE = " wants you to sign in with your Ethereum account:";
@@ -209,11 +210,31 @@ var verifySiweMessageV2 = async (payload, nonce, statement, requestId, userProvi
209
210
  if (!validateMessage(siweMessageData, nonce, statement, requestId)) {
210
211
  throw new Error("Validation failed");
211
212
  }
213
+ if (siweMessageData.address && siweMessageData.address.toLowerCase() !== address.toLowerCase()) {
214
+ throw new Error(
215
+ "Address mismatch: payload address does not match SIWE message address"
216
+ );
217
+ }
218
+ const expectedAddress = (siweMessageData.address ?? address).toLowerCase();
219
+ try {
220
+ const recoveredAddress = await recoverMessageAddress({
221
+ message,
222
+ signature
223
+ });
224
+ if (recoveredAddress.toLowerCase() === expectedAddress) {
225
+ return {
226
+ isValid: true,
227
+ siweMessageData
228
+ };
229
+ }
230
+ } catch {
231
+ }
212
232
  try {
233
+ const client = userProvider || createPublicClient({ chain: worldchain, transport: http() });
213
234
  const walletContract = getContract({
214
235
  address,
215
236
  abi: SAFE_CONTRACT_ABI,
216
- client: userProvider || createPublicClient({ chain: worldchain, transport: http() })
237
+ client
217
238
  });
218
239
  const hashedMessage = hashMessage(message);
219
240
  const res = await walletContract.read.isValidSignature([
@@ -264,6 +264,14 @@ var EventManager = class {
264
264
  };
265
265
 
266
266
  // src/commands/fallback.ts
267
+ var PartialExecutionError = class extends Error {
268
+ constructor(message, submitted, cause) {
269
+ super(message);
270
+ this.name = "PartialExecutionError";
271
+ this.submitted = submitted;
272
+ this.cause = cause;
273
+ }
274
+ };
267
275
  async function executeWithFallback(options) {
268
276
  const {
269
277
  command,
@@ -289,6 +297,9 @@ async function executeWithFallback(options) {
289
297
  const data = await wagmiFallback();
290
298
  return { data, executedWith: "wagmi" };
291
299
  } catch (error) {
300
+ if (error instanceof PartialExecutionError || error instanceof Error && error.name === "PartialExecutionError") {
301
+ throw error;
302
+ }
292
303
  console.warn(`Wagmi fallback for ${command} failed:`, error);
293
304
  }
294
305
  }
@@ -951,7 +962,6 @@ var validateSendTransactionPayload = (payload) => {
951
962
 
952
963
  // src/commands/send-transaction/index.ts
953
964
  var WORLD_CHAIN_ID = 480;
954
- 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.";
955
965
  function resolveChainId(options) {
956
966
  return options.chainId;
957
967
  }
@@ -978,12 +988,6 @@ function normalizeSendTransactionOptions(options) {
978
988
  async function sendTransaction(options, ctx) {
979
989
  const normalizedOptions = normalizeSendTransactionOptions(options);
980
990
  const fallbackAdapter = getFallbackAdapter();
981
- const isWagmiFallbackPath = !isInWorldApp() && Boolean(fallbackAdapter?.sendTransaction);
982
- if (isWagmiFallbackPath && normalizedOptions.transactions.length > 1 && !options.fallback) {
983
- throw new SendTransactionError("invalid_operation" /* InvalidOperation */, {
984
- reason: WAGMI_MULTI_TX_ERROR_MESSAGE
985
- });
986
- }
987
991
  const result = await executeWithFallback({
988
992
  command: "send-transaction" /* SendTransaction */,
989
993
  nativeExecutor: () => nativeSendTransaction(normalizedOptions, ctx),
@@ -1064,23 +1068,16 @@ async function nativeSendTransaction(options, ctx) {
1064
1068
  };
1065
1069
  }
1066
1070
  async function adapterSendTransactionFallback(options) {
1067
- if (options.transactions.length > 1) {
1068
- throw new Error(WAGMI_MULTI_TX_ERROR_MESSAGE);
1069
- }
1070
- const firstTransaction = options.transactions[0];
1071
- if (!firstTransaction) {
1072
- throw new Error("At least one transaction is required");
1073
- }
1074
1071
  const fallbackAdapter = getFallbackAdapter();
1075
1072
  if (!fallbackAdapter?.sendTransaction) {
1076
1073
  throw new Error("Fallback adapter is not registered.");
1077
1074
  }
1078
1075
  const result = await fallbackAdapter.sendTransaction({
1079
- transaction: {
1080
- address: firstTransaction.to,
1081
- data: firstTransaction.data,
1082
- value: firstTransaction.value
1083
- },
1076
+ transactions: options.transactions.map((tx) => ({
1077
+ address: tx.to,
1078
+ data: tx.data,
1079
+ value: tx.value
1080
+ })),
1084
1081
  chainId: options.chainId
1085
1082
  });
1086
1083
  return {
@@ -1,12 +1,8 @@
1
1
  import {
2
2
  AttestationError,
3
3
  AttestationErrorCodes,
4
- COMMAND_VERSIONS,
5
4
  ChatError,
6
5
  ChatErrorCodes,
7
- Command,
8
- CommandUnavailableError,
9
- FallbackRequiredError,
10
6
  GetPermissionsError,
11
7
  GetPermissionsErrorCodes,
12
8
  MiniAppLaunchLocation,
@@ -19,7 +15,6 @@ import {
19
15
  Permission,
20
16
  RequestPermissionError,
21
17
  RequestPermissionErrorCodes,
22
- ResponseEvent,
23
18
  SendHapticFeedbackError,
24
19
  SendHapticFeedbackErrorCodes,
25
20
  SendTransactionError,
@@ -46,23 +41,30 @@ import {
46
41
  closeMiniApp,
47
42
  getContacts,
48
43
  getPermissions,
49
- isCommandAvailable,
50
- isInWorldApp,
51
44
  pay,
52
45
  requestPermission,
53
46
  sendHapticFeedback,
54
- sendMiniKitEvent,
55
47
  sendTransaction,
56
- setCommandAvailable,
57
48
  share,
58
49
  shareContacts,
59
50
  signMessage,
60
51
  signTypedData,
61
52
  tokenToDecimals,
62
- validateCommands,
63
53
  walletAuth
64
- } from "./chunk-7SC4LSCB.js";
65
- import "./chunk-4HSRVHAU.js";
54
+ } from "./chunk-AH3WTRZY.js";
55
+ import "./chunk-YPZEODWL.js";
56
+ import {
57
+ COMMAND_VERSIONS,
58
+ Command,
59
+ CommandUnavailableError,
60
+ FallbackRequiredError,
61
+ ResponseEvent,
62
+ isCommandAvailable,
63
+ isInWorldApp,
64
+ sendMiniKitEvent,
65
+ setCommandAvailable,
66
+ validateCommands
67
+ } from "./chunk-DZ2YRSIU.js";
66
68
  export {
67
69
  AttestationError,
68
70
  AttestationErrorCodes,