@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.
- package/build/chunk-2ADHLH4F.js +14 -0
- package/build/{chunk-OLN2PAHM.js → chunk-5B6BPEWR.js} +105 -73
- package/build/chunk-6E2XIIO6.js +8 -0
- package/build/{chunk-363XY57O.js → chunk-7RB4UJBW.js} +6 -4
- package/build/{chunk-7SC4LSCB.js → chunk-AH3WTRZY.js} +14 -220
- package/build/chunk-DZ2YRSIU.js +216 -0
- package/build/{chunk-XO2TC2R4.js → chunk-MXMNPAOF.js} +8 -10
- package/build/{chunk-4HSRVHAU.js → chunk-YPZEODWL.js} +23 -2
- package/build/command-exports.cjs +16 -19
- package/build/command-exports.js +14 -12
- package/build/connector/index.cjs +273 -245
- package/build/connector/index.js +10 -7
- package/build/index.cjs +31 -28
- package/build/index.js +6 -4
- package/build/minikit-provider.cjs +34 -306
- package/build/minikit-provider.js +15 -8
- package/build/siwe-exports.cjs +21 -1
- package/build/siwe-exports.js +1 -1
- package/build/wagmi-fallback-register.cjs +362 -0
- package/build/wagmi-fallback-register.d.cts +10 -0
- package/build/wagmi-fallback-register.d.ts +10 -0
- package/build/wagmi-fallback-register.js +14 -0
- package/package.json +11 -1
|
@@ -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[
|
|
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[
|
|
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
|
-
|
|
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
|
|
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
|
|
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, {
|
|
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
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
-
|
|
289
|
-
|
|
290
|
-
|
|
470
|
+
const sendWithChainRetry = async (tx) => {
|
|
471
|
+
const send = () => sendTransaction2(config, {
|
|
472
|
+
connector,
|
|
473
|
+
account: address,
|
|
291
474
|
chainId: targetChainId,
|
|
292
|
-
to:
|
|
293
|
-
data:
|
|
294
|
-
value:
|
|
475
|
+
to: tx.to,
|
|
476
|
+
data: tx.data,
|
|
477
|
+
value: tx.value
|
|
295
478
|
});
|
|
296
|
-
|
|
297
|
-
|
|
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
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
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
|
-
|
|
1126
|
-
address:
|
|
1127
|
-
data:
|
|
1128
|
-
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" &&
|
|
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" && !
|
|
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" || !
|
|
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;
|