@worldcoin/minikit-js 1.9.10 → 2.0.0-dev.0
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/README.md +104 -0
- package/build/address-book.cjs +81 -0
- package/build/address-book.d.cts +3 -0
- package/build/address-book.d.ts +3 -0
- package/build/address-book.js +54 -0
- package/build/chunk-DIACPBCB.js +1692 -0
- package/build/chunk-LHHKY77D.js +274 -0
- package/build/chunk-OTAA7OOI.js +835 -0
- package/build/command-exports.cjs +1825 -0
- package/build/command-exports.d.cts +102 -0
- package/build/command-exports.d.ts +102 -0
- package/build/command-exports.js +121 -0
- package/build/connector/index.cjs +2388 -0
- package/build/connector/index.d.cts +55 -0
- package/build/connector/index.d.ts +55 -0
- package/build/connector/index.js +86 -0
- package/build/index.cjs +1696 -1480
- package/build/index.d.cts +136 -622
- package/build/index.d.ts +136 -622
- package/build/index.js +5 -196
- package/build/minikit-provider.cjs +1465 -834
- package/build/minikit-provider.d.cts +2 -1
- package/build/minikit-provider.d.ts +2 -1
- package/build/minikit-provider.js +2046 -4
- package/build/provider-DeDUsLbs.d.cts +43 -0
- package/build/provider-DeDUsLbs.d.ts +43 -0
- package/build/siwe-exports.cjs +249 -0
- package/build/siwe-exports.d.cts +10 -0
- package/build/siwe-exports.d.ts +10 -0
- package/build/siwe-exports.js +8 -0
- package/build/types-CGVVuGiN.d.ts +438 -0
- package/build/types-CKn5C-Ro.d.cts +220 -0
- package/build/types-CKn5C-Ro.d.ts +220 -0
- package/build/types-DO2UGrgp.d.cts +438 -0
- package/package.json +81 -18
- package/build/chunk-XFGJKKI2.js +0 -1951
- package/index.ts +0 -29
|
@@ -0,0 +1,835 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EventManager,
|
|
3
|
+
MiniKitInstallErrorMessage,
|
|
4
|
+
chat,
|
|
5
|
+
getPermissions,
|
|
6
|
+
isInWorldApp,
|
|
7
|
+
pay,
|
|
8
|
+
requestPermission,
|
|
9
|
+
sendHapticFeedback,
|
|
10
|
+
sendMiniKitEvent,
|
|
11
|
+
sendTransaction,
|
|
12
|
+
share,
|
|
13
|
+
shareContacts,
|
|
14
|
+
signMessage,
|
|
15
|
+
signTypedData,
|
|
16
|
+
validateCommands,
|
|
17
|
+
walletAuth
|
|
18
|
+
} from "./chunk-DIACPBCB.js";
|
|
19
|
+
|
|
20
|
+
// src/helpers/microphone.ts
|
|
21
|
+
var microphoneSetupDone = false;
|
|
22
|
+
var setupMicrophone = () => {
|
|
23
|
+
if (microphoneSetupDone) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (typeof navigator !== "undefined" && !navigator.mediaDevices?.getUserMedia)
|
|
27
|
+
return;
|
|
28
|
+
const originalStop = MediaStreamTrack.prototype.stop;
|
|
29
|
+
MediaStreamTrack.prototype.stop = function() {
|
|
30
|
+
originalStop.call(this);
|
|
31
|
+
if (this.readyState === "ended") {
|
|
32
|
+
setTimeout(() => this.dispatchEvent(new Event("ended")), 0);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const realGUM = navigator.mediaDevices.getUserMedia.bind(
|
|
36
|
+
navigator.mediaDevices
|
|
37
|
+
);
|
|
38
|
+
const live = /* @__PURE__ */ new Set();
|
|
39
|
+
async function wrapped(constraints) {
|
|
40
|
+
const stream = await realGUM(constraints);
|
|
41
|
+
const hasAudioTrack = stream.getAudioTracks().length > 0;
|
|
42
|
+
if (hasAudioTrack) {
|
|
43
|
+
sendMiniKitEvent({
|
|
44
|
+
command: "microphone-stream-started",
|
|
45
|
+
version: 1,
|
|
46
|
+
payload: {
|
|
47
|
+
streamId: stream.id
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
live.add(stream);
|
|
51
|
+
stream.getAudioTracks().forEach((t) => {
|
|
52
|
+
t.addEventListener("ended", () => {
|
|
53
|
+
const allAudioTracksEnded = stream.getAudioTracks().every((track) => track.readyState === "ended");
|
|
54
|
+
if (allAudioTracksEnded) {
|
|
55
|
+
sendMiniKitEvent({
|
|
56
|
+
command: "microphone-stream-ended",
|
|
57
|
+
version: 1,
|
|
58
|
+
payload: {
|
|
59
|
+
streamId: stream.id
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
live.delete(stream);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return stream;
|
|
68
|
+
}
|
|
69
|
+
Object.defineProperty(navigator.mediaDevices, "getUserMedia", {
|
|
70
|
+
value: wrapped,
|
|
71
|
+
writable: false,
|
|
72
|
+
configurable: false,
|
|
73
|
+
enumerable: true
|
|
74
|
+
});
|
|
75
|
+
Object.freeze(navigator.mediaDevices);
|
|
76
|
+
const stopAllMiniAppMicrophoneStreams = () => {
|
|
77
|
+
live.forEach((s) => {
|
|
78
|
+
const audioTracks = s.getAudioTracks();
|
|
79
|
+
if (audioTracks.length > 0) {
|
|
80
|
+
audioTracks.forEach((t) => {
|
|
81
|
+
t.stop();
|
|
82
|
+
});
|
|
83
|
+
sendMiniKitEvent({
|
|
84
|
+
command: "microphone-stream-ended",
|
|
85
|
+
version: 1,
|
|
86
|
+
payload: {
|
|
87
|
+
streamId: s.id
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
live.clear();
|
|
93
|
+
};
|
|
94
|
+
MiniKit.subscribe("miniapp-microphone" /* MiniAppMicrophone */, (payload) => {
|
|
95
|
+
if (payload.status === "error" && (payload.error_code === "mini_app_permission_not_enabled" /* MiniAppPermissionNotEnabled */ || payload.error_code === "world_app_permission_not_enabled" /* WorldAppPermissionNotEnabled */)) {
|
|
96
|
+
console.log("stopping all microphone streams", payload);
|
|
97
|
+
stopAllMiniAppMicrophoneStreams();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
window.__stopAllMiniAppMicrophoneStreams = stopAllMiniAppMicrophoneStreams;
|
|
101
|
+
microphoneSetupDone = true;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// src/helpers/usernames.ts
|
|
105
|
+
var getUserProfile = async (address) => {
|
|
106
|
+
const res = await fetch("https://usernames.worldcoin.org/api/v1/query", {
|
|
107
|
+
method: "POST",
|
|
108
|
+
headers: {
|
|
109
|
+
"Content-Type": "application/json"
|
|
110
|
+
},
|
|
111
|
+
body: JSON.stringify({
|
|
112
|
+
addresses: [address]
|
|
113
|
+
})
|
|
114
|
+
});
|
|
115
|
+
const usernames = await res.json();
|
|
116
|
+
return usernames?.[0] ?? { username: null, profile_picture_url: null };
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// src/minikit.ts
|
|
120
|
+
var MINIKIT_VERSION = 1;
|
|
121
|
+
var MINIKIT_MINOR_VERSION = 96;
|
|
122
|
+
var WORLD_APP_LAUNCH_LOCATION_MAP = {
|
|
123
|
+
"app-store": "app-store" /* AppStore */,
|
|
124
|
+
carousel: "app-store" /* AppStore */,
|
|
125
|
+
explore: "app-store" /* AppStore */,
|
|
126
|
+
app_details: "app-store" /* AppStore */,
|
|
127
|
+
deeplink: "deep-link" /* DeepLink */,
|
|
128
|
+
homepage: "home" /* Home */,
|
|
129
|
+
wallet_tab: "wallet-tab" /* WalletTab */,
|
|
130
|
+
world_chat: "chat" /* Chat */
|
|
131
|
+
};
|
|
132
|
+
function mapWorldAppLaunchLocation(location) {
|
|
133
|
+
if (!location || typeof location !== "string") return null;
|
|
134
|
+
console.log("MiniKit launch location mapped:", location);
|
|
135
|
+
return WORLD_APP_LAUNCH_LOCATION_MAP[location.toLowerCase()] ?? null;
|
|
136
|
+
}
|
|
137
|
+
var _MiniKit = class _MiniKit {
|
|
138
|
+
static getActiveMiniKit() {
|
|
139
|
+
if (typeof window === "undefined") return this;
|
|
140
|
+
const candidate = window.MiniKit;
|
|
141
|
+
if (candidate && typeof candidate.trigger === "function") {
|
|
142
|
+
return candidate;
|
|
143
|
+
}
|
|
144
|
+
return this;
|
|
145
|
+
}
|
|
146
|
+
// ============================================================================
|
|
147
|
+
// Unified API (auto-detects environment)
|
|
148
|
+
// ============================================================================
|
|
149
|
+
/**
|
|
150
|
+
* Authenticate user via wallet signature (SIWE)
|
|
151
|
+
*
|
|
152
|
+
* Works in World App (native SIWE) and web (Wagmi + SIWE fallback).
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```typescript
|
|
156
|
+
* const result = await MiniKit.walletAuth({ nonce: 'randomnonce123' });
|
|
157
|
+
* console.log(result.data.address);
|
|
158
|
+
* console.log(result.executedWith); // 'minikit' | 'wagmi' | 'fallback'
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
static walletAuth(options) {
|
|
162
|
+
const active = this.getActiveMiniKit();
|
|
163
|
+
if (active !== this) {
|
|
164
|
+
return active.walletAuth(options);
|
|
165
|
+
}
|
|
166
|
+
return walletAuth(options, this.getContext());
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Send one or more transactions
|
|
170
|
+
*
|
|
171
|
+
* World App: batch + permit2 + gas sponsorship
|
|
172
|
+
* Web: sequential execution via Wagmi
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```typescript
|
|
176
|
+
* const result = await MiniKit.sendTransaction({
|
|
177
|
+
* chainId: 480,
|
|
178
|
+
* transaction: [{
|
|
179
|
+
* address: '0x...',
|
|
180
|
+
* abi: ContractABI,
|
|
181
|
+
* functionName: 'mint',
|
|
182
|
+
* args: [],
|
|
183
|
+
* }],
|
|
184
|
+
* });
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
static sendTransaction(options) {
|
|
188
|
+
const active = this.getActiveMiniKit();
|
|
189
|
+
if (active !== this) {
|
|
190
|
+
return active.sendTransaction(options);
|
|
191
|
+
}
|
|
192
|
+
return sendTransaction(options, this.getContext());
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Send a payment (World App only)
|
|
196
|
+
*
|
|
197
|
+
* Requires custom fallback on web.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* const result = await MiniKit.pay({
|
|
202
|
+
* reference: crypto.randomUUID(),
|
|
203
|
+
* to: '0x...',
|
|
204
|
+
* tokens: [{ symbol: Tokens.WLD, token_amount: '1.0' }],
|
|
205
|
+
* description: 'Payment for coffee',
|
|
206
|
+
* fallback: () => showStripeCheckout(),
|
|
207
|
+
* });
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
static pay(options) {
|
|
211
|
+
const active = this.getActiveMiniKit();
|
|
212
|
+
if (active !== this) {
|
|
213
|
+
return active.pay(options);
|
|
214
|
+
}
|
|
215
|
+
return pay(options, this.getContext());
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Open the contact picker (World App only)
|
|
219
|
+
*
|
|
220
|
+
* Requires custom fallback on web.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```typescript
|
|
224
|
+
* const result = await MiniKit.shareContacts({
|
|
225
|
+
* isMultiSelectEnabled: true,
|
|
226
|
+
* fallback: () => showManualAddressInput(),
|
|
227
|
+
* });
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
static shareContacts(options = {}) {
|
|
231
|
+
const active = this.getActiveMiniKit();
|
|
232
|
+
if (active !== this) {
|
|
233
|
+
return active.shareContacts(options);
|
|
234
|
+
}
|
|
235
|
+
return shareContacts(options, this.getContext());
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Sign a message
|
|
239
|
+
*/
|
|
240
|
+
static signMessage(options) {
|
|
241
|
+
const active = this.getActiveMiniKit();
|
|
242
|
+
if (active !== this) {
|
|
243
|
+
return active.signMessage(options);
|
|
244
|
+
}
|
|
245
|
+
return signMessage(options, this.getContext());
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Sign typed data (EIP-712)
|
|
249
|
+
*/
|
|
250
|
+
static signTypedData(options) {
|
|
251
|
+
const active = this.getActiveMiniKit();
|
|
252
|
+
if (active !== this) {
|
|
253
|
+
return active.signTypedData(options);
|
|
254
|
+
}
|
|
255
|
+
return signTypedData(options, this.getContext());
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Send a chat message
|
|
259
|
+
*/
|
|
260
|
+
static chat(options) {
|
|
261
|
+
const active = this.getActiveMiniKit();
|
|
262
|
+
if (active !== this) {
|
|
263
|
+
return active.chat(options);
|
|
264
|
+
}
|
|
265
|
+
return chat(options, this.getContext());
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Share files/text/URL
|
|
269
|
+
*/
|
|
270
|
+
static share(options) {
|
|
271
|
+
const active = this.getActiveMiniKit();
|
|
272
|
+
if (active !== this) {
|
|
273
|
+
return active.share(options);
|
|
274
|
+
}
|
|
275
|
+
return share(options, this.getContext());
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Get current permission settings
|
|
279
|
+
*/
|
|
280
|
+
static getPermissions(options = {}) {
|
|
281
|
+
const active = this.getActiveMiniKit();
|
|
282
|
+
if (active !== this) {
|
|
283
|
+
return active.getPermissions(options);
|
|
284
|
+
}
|
|
285
|
+
return getPermissions(options, this.getContext());
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Request a permission from the user
|
|
289
|
+
*/
|
|
290
|
+
static requestPermission(options) {
|
|
291
|
+
const active = this.getActiveMiniKit();
|
|
292
|
+
if (active !== this) {
|
|
293
|
+
return active.requestPermission(options);
|
|
294
|
+
}
|
|
295
|
+
return requestPermission(options, this.getContext());
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Trigger haptic feedback
|
|
299
|
+
*/
|
|
300
|
+
static sendHapticFeedback(options) {
|
|
301
|
+
const active = this.getActiveMiniKit();
|
|
302
|
+
if (active !== this) {
|
|
303
|
+
return active.sendHapticFeedback(options);
|
|
304
|
+
}
|
|
305
|
+
return sendHapticFeedback(options, this.getContext());
|
|
306
|
+
}
|
|
307
|
+
// ============================================================================
|
|
308
|
+
// Public State Accessors
|
|
309
|
+
// ============================================================================
|
|
310
|
+
static get appId() {
|
|
311
|
+
return this._appId;
|
|
312
|
+
}
|
|
313
|
+
static set appId(value) {
|
|
314
|
+
this._appId = value;
|
|
315
|
+
}
|
|
316
|
+
static get user() {
|
|
317
|
+
return this._user;
|
|
318
|
+
}
|
|
319
|
+
static set user(value) {
|
|
320
|
+
this._user = value;
|
|
321
|
+
}
|
|
322
|
+
static get deviceProperties() {
|
|
323
|
+
return this._deviceProperties;
|
|
324
|
+
}
|
|
325
|
+
static get location() {
|
|
326
|
+
return this._location;
|
|
327
|
+
}
|
|
328
|
+
// ============================================================================
|
|
329
|
+
// Event System
|
|
330
|
+
// ============================================================================
|
|
331
|
+
static subscribe(event, handler) {
|
|
332
|
+
const active = this.getActiveMiniKit();
|
|
333
|
+
if (active !== this) {
|
|
334
|
+
active.subscribe(event, handler);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
if (event === "miniapp-wallet-auth" /* MiniAppWalletAuth */) {
|
|
338
|
+
const originalHandler = handler;
|
|
339
|
+
const wrappedHandler = async (payload) => {
|
|
340
|
+
if (payload.status === "success") {
|
|
341
|
+
await this.updateUserFromWalletAuth(payload.address);
|
|
342
|
+
}
|
|
343
|
+
originalHandler(payload);
|
|
344
|
+
};
|
|
345
|
+
this.eventManager.subscribe(event, wrappedHandler);
|
|
346
|
+
} else {
|
|
347
|
+
this.eventManager.subscribe(event, handler);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
static unsubscribe(event) {
|
|
351
|
+
const active = this.getActiveMiniKit();
|
|
352
|
+
if (active !== this) {
|
|
353
|
+
active.unsubscribe(event);
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
this.eventManager.unsubscribe(event);
|
|
357
|
+
}
|
|
358
|
+
static trigger(event, payload) {
|
|
359
|
+
const active = this.getActiveMiniKit();
|
|
360
|
+
if (active !== this) {
|
|
361
|
+
active.trigger(event, payload);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
this.eventManager.trigger(event, payload);
|
|
365
|
+
}
|
|
366
|
+
// ============================================================================
|
|
367
|
+
// Installation
|
|
368
|
+
// ============================================================================
|
|
369
|
+
static sendInit() {
|
|
370
|
+
sendMiniKitEvent({
|
|
371
|
+
command: "init",
|
|
372
|
+
payload: {
|
|
373
|
+
version: MINIKIT_VERSION,
|
|
374
|
+
minorVersion: MINIKIT_MINOR_VERSION
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
static install(appId) {
|
|
379
|
+
const active = this.getActiveMiniKit();
|
|
380
|
+
if (active !== this) {
|
|
381
|
+
return active.install(appId);
|
|
382
|
+
}
|
|
383
|
+
if (typeof window === "undefined") {
|
|
384
|
+
return {
|
|
385
|
+
success: false,
|
|
386
|
+
errorCode: "already_installed" /* AlreadyInstalled */,
|
|
387
|
+
errorMessage: MiniKitInstallErrorMessage["already_installed" /* AlreadyInstalled */]
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
if (!appId) {
|
|
391
|
+
console.warn("App ID not provided during install");
|
|
392
|
+
} else {
|
|
393
|
+
this._appId = appId;
|
|
394
|
+
}
|
|
395
|
+
if (!window.WorldApp) {
|
|
396
|
+
return {
|
|
397
|
+
success: false,
|
|
398
|
+
errorCode: "outside_of_worldapp" /* OutsideOfWorldApp */,
|
|
399
|
+
errorMessage: MiniKitInstallErrorMessage["outside_of_worldapp" /* OutsideOfWorldApp */]
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
this.initFromWorldApp(window.WorldApp);
|
|
403
|
+
try {
|
|
404
|
+
window.MiniKit = this;
|
|
405
|
+
this.sendInit();
|
|
406
|
+
} catch (error) {
|
|
407
|
+
console.error(
|
|
408
|
+
MiniKitInstallErrorMessage["unknown" /* Unknown */],
|
|
409
|
+
error
|
|
410
|
+
);
|
|
411
|
+
return {
|
|
412
|
+
success: false,
|
|
413
|
+
errorCode: "unknown" /* Unknown */,
|
|
414
|
+
errorMessage: MiniKitInstallErrorMessage["unknown" /* Unknown */]
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
this._isReady = true;
|
|
418
|
+
setupMicrophone();
|
|
419
|
+
if (!validateCommands(window.WorldApp.supported_commands)) {
|
|
420
|
+
return {
|
|
421
|
+
success: false,
|
|
422
|
+
errorCode: "app_out_of_date" /* AppOutOfDate */,
|
|
423
|
+
errorMessage: MiniKitInstallErrorMessage["app_out_of_date" /* AppOutOfDate */]
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
return { success: true };
|
|
427
|
+
}
|
|
428
|
+
static isInstalled(debug) {
|
|
429
|
+
const isInstalled = this._isReady && Boolean(window.MiniKit);
|
|
430
|
+
if (!isInstalled) {
|
|
431
|
+
console.warn(
|
|
432
|
+
"MiniKit is not installed. Make sure you're running the application inside of World App"
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
if (debug && isInstalled) {
|
|
436
|
+
console.log("MiniKit is alive!");
|
|
437
|
+
}
|
|
438
|
+
return isInstalled;
|
|
439
|
+
}
|
|
440
|
+
// ============================================================================
|
|
441
|
+
// Internal
|
|
442
|
+
// ============================================================================
|
|
443
|
+
static initFromWorldApp(worldApp) {
|
|
444
|
+
if (!worldApp) return;
|
|
445
|
+
this._user.optedIntoOptionalAnalytics = worldApp.is_optional_analytics;
|
|
446
|
+
this._deviceProperties.safeAreaInsets = worldApp.safe_area_insets;
|
|
447
|
+
this._deviceProperties.deviceOS = worldApp.device_os;
|
|
448
|
+
this._deviceProperties.worldAppVersion = worldApp.world_app_version;
|
|
449
|
+
this._location = mapWorldAppLaunchLocation(worldApp.location);
|
|
450
|
+
}
|
|
451
|
+
static async updateUserFromWalletAuth(address) {
|
|
452
|
+
this._user.walletAddress = address;
|
|
453
|
+
try {
|
|
454
|
+
const userProfile = await getUserProfile(address);
|
|
455
|
+
this._user.username = userProfile.username;
|
|
456
|
+
this._user.profilePictureUrl = userProfile.profile_picture_url;
|
|
457
|
+
} catch (error) {
|
|
458
|
+
console.error("Failed to fetch user profile:", error);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
static getContext() {
|
|
462
|
+
return {
|
|
463
|
+
events: this.eventManager,
|
|
464
|
+
state: { deviceProperties: this._deviceProperties }
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
// ============================================================================
|
|
468
|
+
// Deprecated — remove in next major
|
|
469
|
+
// ============================================================================
|
|
470
|
+
/**
|
|
471
|
+
* @deprecated Use `MiniKit.pay()`, `MiniKit.walletAuth()`, etc. directly.
|
|
472
|
+
*
|
|
473
|
+
* Migration guide:
|
|
474
|
+
* - `MiniKit.commands.pay(payload)` → `await MiniKit.pay(options)`
|
|
475
|
+
* - `MiniKit.commands.walletAuth(payload)` → `await MiniKit.walletAuth(options)`
|
|
476
|
+
* - `MiniKit.commands.sendTransaction(payload)` → `await MiniKit.sendTransaction(options)`
|
|
477
|
+
* - `MiniKit.commands.signMessage(payload)` → `await MiniKit.signMessage(input)`
|
|
478
|
+
* - `MiniKit.commands.signTypedData(payload)` → `await MiniKit.signTypedData(input)`
|
|
479
|
+
* - `MiniKit.commands.shareContacts(payload)` → `await MiniKit.shareContacts(options)`
|
|
480
|
+
* - `MiniKit.commands.chat(payload)` → `await MiniKit.chat(input)`
|
|
481
|
+
* - `MiniKit.commands.share(payload)` → `await MiniKit.share(input)`
|
|
482
|
+
* - `MiniKit.commands.getPermissions()` → `await MiniKit.getPermissions()`
|
|
483
|
+
* - `MiniKit.commands.requestPermission(payload)` → `await MiniKit.requestPermission(input)`
|
|
484
|
+
* - `MiniKit.commands.sendHapticFeedback(payload)` → `await MiniKit.sendHapticFeedback(input)`
|
|
485
|
+
*/
|
|
486
|
+
static get commands() {
|
|
487
|
+
throw new Error(
|
|
488
|
+
"MiniKit.commands has been removed. Use MiniKit.pay(), MiniKit.walletAuth(), etc. directly."
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* @deprecated Use `MiniKit.pay()`, `MiniKit.walletAuth()`, etc. directly. All commands are now async by default.
|
|
493
|
+
*
|
|
494
|
+
* See `MiniKit.commands` deprecation notice for the full migration guide.
|
|
495
|
+
*/
|
|
496
|
+
static get commandsAsync() {
|
|
497
|
+
throw new Error(
|
|
498
|
+
"MiniKit.commandsAsync has been removed. Use MiniKit.pay(), MiniKit.walletAuth(), etc. directly."
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
_MiniKit.eventManager = new EventManager();
|
|
503
|
+
// State (was MiniKitState)
|
|
504
|
+
_MiniKit._appId = null;
|
|
505
|
+
_MiniKit._user = {};
|
|
506
|
+
_MiniKit._deviceProperties = {};
|
|
507
|
+
_MiniKit._location = null;
|
|
508
|
+
_MiniKit._isReady = false;
|
|
509
|
+
/**
|
|
510
|
+
* Check if running inside World App
|
|
511
|
+
*/
|
|
512
|
+
_MiniKit.isInWorldApp = isInWorldApp;
|
|
513
|
+
// ============================================================================
|
|
514
|
+
// Utility Methods
|
|
515
|
+
// ============================================================================
|
|
516
|
+
_MiniKit.getUserByAddress = async (address) => {
|
|
517
|
+
const walletAddress = address ?? _MiniKit._user.walletAddress;
|
|
518
|
+
const userProfile = await getUserProfile(walletAddress);
|
|
519
|
+
return {
|
|
520
|
+
walletAddress,
|
|
521
|
+
username: userProfile.username,
|
|
522
|
+
profilePictureUrl: userProfile.profile_picture_url
|
|
523
|
+
};
|
|
524
|
+
};
|
|
525
|
+
_MiniKit.getUserByUsername = async (username) => {
|
|
526
|
+
const res = await fetch(
|
|
527
|
+
`https://usernames.worldcoin.org/api/v1/${username}`,
|
|
528
|
+
{
|
|
529
|
+
method: "GET",
|
|
530
|
+
headers: {
|
|
531
|
+
"Content-Type": "application/json"
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
);
|
|
535
|
+
const user = await res.json();
|
|
536
|
+
return {
|
|
537
|
+
walletAddress: user.address,
|
|
538
|
+
username: user.username,
|
|
539
|
+
profilePictureUrl: user.profile_picture_url
|
|
540
|
+
};
|
|
541
|
+
};
|
|
542
|
+
_MiniKit.getUserInfo = _MiniKit.getUserByAddress;
|
|
543
|
+
_MiniKit.getMiniAppUrl = (appId, path) => {
|
|
544
|
+
const baseUrl = new URL("https://world.org/mini-app");
|
|
545
|
+
baseUrl.searchParams.append("app_id", appId);
|
|
546
|
+
if (path) {
|
|
547
|
+
const fullPath = path.startsWith("/") ? path : `/${path}`;
|
|
548
|
+
baseUrl.searchParams.append("path", encodeURIComponent(fullPath));
|
|
549
|
+
}
|
|
550
|
+
return baseUrl.toString();
|
|
551
|
+
};
|
|
552
|
+
_MiniKit.showProfileCard = (username, walletAddress) => {
|
|
553
|
+
if (!username && !walletAddress) {
|
|
554
|
+
console.error(
|
|
555
|
+
"Either username or walletAddress must be provided to show profile card"
|
|
556
|
+
);
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
if (username) {
|
|
560
|
+
window.open(
|
|
561
|
+
`worldapp://profile?username=${encodeURIComponent(username)}`
|
|
562
|
+
);
|
|
563
|
+
} else {
|
|
564
|
+
window.open(
|
|
565
|
+
`worldapp://profile?address=${encodeURIComponent(walletAddress || "")}`
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
var MiniKit = _MiniKit;
|
|
570
|
+
|
|
571
|
+
// src/provider.ts
|
|
572
|
+
function _getAddress() {
|
|
573
|
+
if (typeof window === "undefined") return void 0;
|
|
574
|
+
return window.__worldapp_eip1193_address__;
|
|
575
|
+
}
|
|
576
|
+
function _setAddress(addr) {
|
|
577
|
+
if (typeof window === "undefined") return;
|
|
578
|
+
window.__worldapp_eip1193_address__ = addr;
|
|
579
|
+
}
|
|
580
|
+
function _clearAddress() {
|
|
581
|
+
if (typeof window === "undefined") return;
|
|
582
|
+
window.__worldapp_eip1193_address__ = void 0;
|
|
583
|
+
}
|
|
584
|
+
function rpcError(code, message) {
|
|
585
|
+
return Object.assign(new Error(message), { code });
|
|
586
|
+
}
|
|
587
|
+
function isHexString(value) {
|
|
588
|
+
return /^0x[0-9a-fA-F]*$/.test(value);
|
|
589
|
+
}
|
|
590
|
+
function isAddressString(value) {
|
|
591
|
+
return /^0x[0-9a-fA-F]{40}$/.test(value);
|
|
592
|
+
}
|
|
593
|
+
function decodeHexToUtf8(hex) {
|
|
594
|
+
const raw = hex.slice(2);
|
|
595
|
+
if (raw.length % 2 !== 0) {
|
|
596
|
+
throw new Error("Invalid hex string length");
|
|
597
|
+
}
|
|
598
|
+
const bytes = new Uint8Array(raw.length / 2);
|
|
599
|
+
for (let i = 0; i < raw.length; i += 2) {
|
|
600
|
+
bytes[i / 2] = parseInt(raw.slice(i, i + 2), 16);
|
|
601
|
+
}
|
|
602
|
+
return new TextDecoder().decode(bytes);
|
|
603
|
+
}
|
|
604
|
+
function asArrayParams(params) {
|
|
605
|
+
if (params === void 0) return [];
|
|
606
|
+
return Array.isArray(params) ? params : [params];
|
|
607
|
+
}
|
|
608
|
+
function decodeMaybeHexMessage(value) {
|
|
609
|
+
if (!isHexString(value)) {
|
|
610
|
+
return value;
|
|
611
|
+
}
|
|
612
|
+
try {
|
|
613
|
+
return decodeHexToUtf8(value);
|
|
614
|
+
} catch {
|
|
615
|
+
return value;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
function extractPersonalSignMessage(params) {
|
|
619
|
+
const items = asArrayParams(params);
|
|
620
|
+
if (items.length === 0) {
|
|
621
|
+
throw new Error("Missing personal_sign params");
|
|
622
|
+
}
|
|
623
|
+
const [first, second] = items;
|
|
624
|
+
const maybeMessage = typeof first === "string" && isAddressString(first) && typeof second === "string" ? second : first;
|
|
625
|
+
if (typeof maybeMessage !== "string") {
|
|
626
|
+
throw new Error("Invalid personal_sign message payload");
|
|
627
|
+
}
|
|
628
|
+
return decodeMaybeHexMessage(maybeMessage);
|
|
629
|
+
}
|
|
630
|
+
function extractEthSignMessage(params) {
|
|
631
|
+
const items = asArrayParams(params);
|
|
632
|
+
if (items.length === 0) {
|
|
633
|
+
throw new Error("Missing eth_sign params");
|
|
634
|
+
}
|
|
635
|
+
const [first, second] = items;
|
|
636
|
+
const maybeMessage = typeof second === "string" ? second : typeof first === "string" && !isAddressString(first) ? first : void 0;
|
|
637
|
+
if (typeof maybeMessage !== "string") {
|
|
638
|
+
throw new Error("Invalid eth_sign message payload");
|
|
639
|
+
}
|
|
640
|
+
return decodeMaybeHexMessage(maybeMessage);
|
|
641
|
+
}
|
|
642
|
+
function parseTypedDataInput(params) {
|
|
643
|
+
const items = asArrayParams(params);
|
|
644
|
+
const candidate = items.length > 1 ? items[1] : items[0];
|
|
645
|
+
if (!candidate) {
|
|
646
|
+
throw new Error("Missing typed data payload");
|
|
647
|
+
}
|
|
648
|
+
const parsed = typeof candidate === "string" ? JSON.parse(candidate) : candidate;
|
|
649
|
+
if (!parsed || typeof parsed !== "object" || typeof parsed.primaryType !== "string" || typeof parsed.message !== "object" || !parsed.message || typeof parsed.types !== "object" || !parsed.types) {
|
|
650
|
+
throw new Error("Invalid typed data payload");
|
|
651
|
+
}
|
|
652
|
+
const domainValue = parsed.domain;
|
|
653
|
+
const chainIdValue = domainValue?.chainId ?? parsed.chainId;
|
|
654
|
+
const parsedChainId = typeof chainIdValue === "string" ? Number(chainIdValue) : typeof chainIdValue === "number" ? chainIdValue : void 0;
|
|
655
|
+
return {
|
|
656
|
+
types: parsed.types,
|
|
657
|
+
primaryType: parsed.primaryType,
|
|
658
|
+
domain: domainValue,
|
|
659
|
+
message: parsed.message,
|
|
660
|
+
...Number.isFinite(parsedChainId) ? { chainId: parsedChainId } : {}
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
function normalizeRpcValue(value) {
|
|
664
|
+
if (value === void 0 || value === null) return void 0;
|
|
665
|
+
if (typeof value === "string") return value;
|
|
666
|
+
if (typeof value === "bigint") return `0x${value.toString(16)}`;
|
|
667
|
+
if (typeof value === "number") return `0x${value.toString(16)}`;
|
|
668
|
+
return String(value);
|
|
669
|
+
}
|
|
670
|
+
function extractTransactionParams(params) {
|
|
671
|
+
const items = asArrayParams(params);
|
|
672
|
+
const tx = items[0] ?? {};
|
|
673
|
+
if (typeof tx.to !== "string" || !isAddressString(tx.to)) {
|
|
674
|
+
throw new Error('Invalid transaction "to" address');
|
|
675
|
+
}
|
|
676
|
+
const chainId = typeof tx.chainId === "string" ? Number(tx.chainId) : typeof tx.chainId === "number" ? tx.chainId : void 0;
|
|
677
|
+
const normalizedValue = normalizeRpcValue(tx.value);
|
|
678
|
+
return {
|
|
679
|
+
to: tx.to,
|
|
680
|
+
...typeof tx.data === "string" ? { data: tx.data } : {},
|
|
681
|
+
...normalizedValue !== void 0 ? { value: normalizedValue } : {},
|
|
682
|
+
...Number.isFinite(chainId) ? { chainId } : {}
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
function extractSwitchChainId(params) {
|
|
686
|
+
const items = asArrayParams(params);
|
|
687
|
+
const payload = items[0] ?? {};
|
|
688
|
+
const rawChainId = payload.chainId;
|
|
689
|
+
const chainId = typeof rawChainId === "string" ? Number(rawChainId) : typeof rawChainId === "number" ? rawChainId : NaN;
|
|
690
|
+
if (!Number.isFinite(chainId)) {
|
|
691
|
+
throw new Error("Invalid chainId for wallet_switchEthereumChain");
|
|
692
|
+
}
|
|
693
|
+
return chainId;
|
|
694
|
+
}
|
|
695
|
+
function createProvider() {
|
|
696
|
+
const listeners = {};
|
|
697
|
+
function emit(event, ...args) {
|
|
698
|
+
listeners[event]?.forEach((fn) => fn(...args));
|
|
699
|
+
}
|
|
700
|
+
let authInFlight;
|
|
701
|
+
async function doAuth() {
|
|
702
|
+
if (!MiniKit.isInWorldApp()) {
|
|
703
|
+
throw rpcError(4900, "World App provider only works inside World App");
|
|
704
|
+
}
|
|
705
|
+
try {
|
|
706
|
+
const result = await MiniKit.walletAuth({
|
|
707
|
+
nonce: crypto.randomUUID().replace(/-/g, ""),
|
|
708
|
+
statement: "Sign in with World App"
|
|
709
|
+
});
|
|
710
|
+
const addr = result.data.address;
|
|
711
|
+
_setAddress(addr);
|
|
712
|
+
emit("accountsChanged", [addr]);
|
|
713
|
+
return [addr];
|
|
714
|
+
} catch (e) {
|
|
715
|
+
throw rpcError(4001, `World App wallet auth failed: ${e.message}`);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return {
|
|
719
|
+
async request({ method, params }) {
|
|
720
|
+
switch (method) {
|
|
721
|
+
case "eth_requestAccounts": {
|
|
722
|
+
const existing = _getAddress();
|
|
723
|
+
if (existing) return [existing];
|
|
724
|
+
if (!authInFlight) {
|
|
725
|
+
authInFlight = doAuth().finally(() => {
|
|
726
|
+
authInFlight = void 0;
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
return authInFlight;
|
|
730
|
+
}
|
|
731
|
+
case "eth_accounts": {
|
|
732
|
+
const addr = _getAddress();
|
|
733
|
+
return addr ? [addr] : [];
|
|
734
|
+
}
|
|
735
|
+
case "eth_chainId":
|
|
736
|
+
return "0x1e0";
|
|
737
|
+
// 480 = World Chain
|
|
738
|
+
case "personal_sign": {
|
|
739
|
+
const message = extractPersonalSignMessage(params);
|
|
740
|
+
try {
|
|
741
|
+
const result = await MiniKit.signMessage({ message });
|
|
742
|
+
return result.data.signature;
|
|
743
|
+
} catch (e) {
|
|
744
|
+
throw rpcError(4001, `Sign message failed: ${e.message}`);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
case "eth_sign": {
|
|
748
|
+
const message = extractEthSignMessage(params);
|
|
749
|
+
try {
|
|
750
|
+
const result = await MiniKit.signMessage({ message });
|
|
751
|
+
return result.data.signature;
|
|
752
|
+
} catch (e) {
|
|
753
|
+
throw rpcError(4001, `Sign message failed: ${e.message}`);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
case "eth_signTypedData":
|
|
757
|
+
case "eth_signTypedData_v3":
|
|
758
|
+
case "eth_signTypedData_v4": {
|
|
759
|
+
try {
|
|
760
|
+
const typedData = parseTypedDataInput(params);
|
|
761
|
+
const result = await MiniKit.signTypedData({
|
|
762
|
+
types: typedData.types,
|
|
763
|
+
primaryType: typedData.primaryType,
|
|
764
|
+
domain: typedData.domain,
|
|
765
|
+
message: typedData.message,
|
|
766
|
+
chainId: typedData.chainId
|
|
767
|
+
});
|
|
768
|
+
if (result.data.status === "error") {
|
|
769
|
+
throw rpcError(
|
|
770
|
+
4001,
|
|
771
|
+
`Sign typed data failed: ${result.data.error_code}`
|
|
772
|
+
);
|
|
773
|
+
}
|
|
774
|
+
return result.data.signature;
|
|
775
|
+
} catch (e) {
|
|
776
|
+
throw rpcError(4001, `Sign typed data failed: ${e.message}`);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
case "eth_sendTransaction": {
|
|
780
|
+
const tx = extractTransactionParams(params);
|
|
781
|
+
try {
|
|
782
|
+
const result = await MiniKit.sendTransaction({
|
|
783
|
+
...tx.chainId !== void 0 ? { chainId: tx.chainId } : {},
|
|
784
|
+
transaction: [
|
|
785
|
+
{
|
|
786
|
+
address: tx.to,
|
|
787
|
+
...tx.data && tx.data !== "0x" ? { data: tx.data } : {},
|
|
788
|
+
value: tx.value
|
|
789
|
+
}
|
|
790
|
+
]
|
|
791
|
+
});
|
|
792
|
+
return result.data.transactionId;
|
|
793
|
+
} catch (e) {
|
|
794
|
+
throw rpcError(4001, `Send transaction failed: ${e.message}`);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
case "wallet_switchEthereumChain": {
|
|
798
|
+
const chainId = extractSwitchChainId(params);
|
|
799
|
+
if (chainId !== 480) {
|
|
800
|
+
throw rpcError(4902, "World App only supports World Chain (480)");
|
|
801
|
+
}
|
|
802
|
+
return null;
|
|
803
|
+
}
|
|
804
|
+
case "wallet_addEthereumChain": {
|
|
805
|
+
throw rpcError(4200, "World App only supports World Chain (480)");
|
|
806
|
+
}
|
|
807
|
+
default:
|
|
808
|
+
throw rpcError(4200, `Unsupported method: ${method}`);
|
|
809
|
+
}
|
|
810
|
+
},
|
|
811
|
+
on(event, fn) {
|
|
812
|
+
(listeners[event] ?? (listeners[event] = /* @__PURE__ */ new Set())).add(fn);
|
|
813
|
+
},
|
|
814
|
+
removeListener(event, fn) {
|
|
815
|
+
listeners[event]?.delete(fn);
|
|
816
|
+
}
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
function getWorldAppProvider() {
|
|
820
|
+
if (typeof window === "undefined") {
|
|
821
|
+
return createProvider();
|
|
822
|
+
}
|
|
823
|
+
if (!window.__worldapp_eip1193_provider__) {
|
|
824
|
+
window.__worldapp_eip1193_provider__ = createProvider();
|
|
825
|
+
}
|
|
826
|
+
return window.__worldapp_eip1193_provider__;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
export {
|
|
830
|
+
MiniKit,
|
|
831
|
+
_getAddress,
|
|
832
|
+
_setAddress,
|
|
833
|
+
_clearAddress,
|
|
834
|
+
getWorldAppProvider
|
|
835
|
+
};
|