UNPKG

@worldcoin/minikit-js

Version:

minikit-js is our SDK for building mini-apps.

1,512 lines (1,480 loc) 52.7 kB
"use strict"; "use client"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // minikit-provider.tsx var minikit_provider_exports = {}; __export(minikit_provider_exports, { MiniKitProvider: () => MiniKitProvider, useMiniKit: () => useMiniKit }); module.exports = __toCommonJS(minikit_provider_exports); var import_react = require("react"); // helpers/send-webview-event.ts var sendWebviewEvent = (payload) => { if (window.webkit) { window.webkit?.messageHandlers?.minikit?.postMessage?.(payload); } else if (window.Android) { window.Android.postMessage?.(JSON.stringify(payload)); } }; // commands/types.ts var COMMAND_VERSIONS = { ["verify" /* Verify */]: 1, ["pay" /* Pay */]: 1, ["wallet-auth" /* WalletAuth */]: 2, ["send-transaction" /* SendTransaction */]: 1, ["sign-message" /* SignMessage */]: 1, ["sign-typed-data" /* SignTypedData */]: 1, ["share-contacts" /* ShareContacts */]: 1, ["request-permission" /* RequestPermission */]: 1, ["get-permissions" /* GetPermissions */]: 1, ["send-haptic-feedback" /* SendHapticFeedback */]: 1, ["share" /* Share */]: 1, ["chat" /* Chat */]: 1, ["attestation" /* Attestation */]: 1, ["close-miniapp" /* CloseMiniApp */]: 1 }; var commandAvailability = { ["verify" /* Verify */]: false, ["pay" /* Pay */]: false, ["wallet-auth" /* WalletAuth */]: false, ["send-transaction" /* SendTransaction */]: false, ["sign-message" /* SignMessage */]: false, ["sign-typed-data" /* SignTypedData */]: false, ["share-contacts" /* ShareContacts */]: false, ["request-permission" /* RequestPermission */]: false, ["get-permissions" /* GetPermissions */]: false, ["send-haptic-feedback" /* SendHapticFeedback */]: false, ["share" /* Share */]: false, ["chat" /* Chat */]: false, ["attestation" /* Attestation */]: false, ["close-miniapp" /* CloseMiniApp */]: false }; function isCommandAvailable(command) { return commandAvailability[command]; } function setCommandAvailable(command, available) { commandAvailability[command] = available; } function validateCommands(worldAppSupportedCommands) { let allCommandsValid = true; Object.entries(COMMAND_VERSIONS).forEach(([commandName, version]) => { const commandInput = worldAppSupportedCommands.find( (cmd) => cmd.name === commandName ); let isCommandValid = false; if (!commandInput) { console.warn( `Command ${commandName} is not supported by the app. Try updating the app version` ); } else { if (commandInput.supported_versions.includes(version)) { setCommandAvailable(commandName, true); isCommandValid = true; } else { isCommandValid = true; console.warn( `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.` ); setCommandAvailable(commandName, true); } } if (!isCommandValid) { allCommandsValid = false; } }); return allCommandsValid; } function sendMiniKitEvent(payload) { sendWebviewEvent(payload); } // commands/attestation.ts function createAttestationCommand(_ctx) { return (input) => { if (typeof window === "undefined" || !isCommandAvailable("attestation" /* Attestation */)) { console.error( "'attestation' command is unavailable. Check MiniKit.install() or update the app version" ); return null; } if (!input.requestHash || input.requestHash.length === 0) { console.error("'attestation' command requires a non-empty requestHash"); return null; } const payload = { request_hash: input.requestHash }; sendMiniKitEvent({ command: "attestation" /* Attestation */, version: COMMAND_VERSIONS["attestation" /* Attestation */], payload }); return payload; }; } function createAttestationAsyncCommand(ctx, syncCommand) { return async (input) => { return new Promise((resolve, reject) => { try { const handleResponse = (response) => { ctx.events.unsubscribe("miniapp-attestation" /* MiniAppAttestation */); resolve({ commandPayload, finalPayload: response }); }; ctx.events.subscribe( "miniapp-attestation" /* MiniAppAttestation */, handleResponse ); const commandPayload = syncCommand(input); if (!commandPayload) { ctx.events.unsubscribe("miniapp-attestation" /* MiniAppAttestation */); reject( new Error( "'attestation' command failed: command unavailable or invalid input" ) ); } } catch (error) { ctx.events.unsubscribe("miniapp-attestation" /* MiniAppAttestation */); reject(error); } }); }; } // commands/chat.ts function createChatCommand(_ctx) { return (payload) => { if (typeof window === "undefined" || !isCommandAvailable("chat" /* Chat */)) { console.error( "'chat' command is unavailable. Check MiniKit.install() or update the app version" ); return null; } if (payload.message.length === 0) { console.error("'chat' command requires a non-empty message"); return null; } sendMiniKitEvent({ command: "chat" /* Chat */, version: COMMAND_VERSIONS["chat" /* Chat */], payload }); return payload; }; } function createChatAsyncCommand(ctx, syncCommand) { return async (payload) => { return new Promise((resolve, reject) => { try { let commandPayload = null; const handleResponse = (response) => { ctx.events.unsubscribe("miniapp-chat" /* MiniAppChat */); resolve({ commandPayload, finalPayload: response }); }; ctx.events.subscribe("miniapp-chat" /* MiniAppChat */, handleResponse); commandPayload = syncCommand(payload); } catch (error) { reject(error); } }); }; } // commands/close-miniapp.ts function createCloseMiniAppCommand(_ctx) { return () => { if (typeof window === "undefined" || !isCommandAvailable("close-miniapp" /* CloseMiniApp */)) { console.error( "'closeMiniApp' command is unavailable. Check MiniKit.install() or update the app version" ); return false; } sendMiniKitEvent({ command: "close-miniapp" /* CloseMiniApp */, version: COMMAND_VERSIONS["close-miniapp" /* CloseMiniApp */], payload: {} }); return true; }; } // commands/get-permissions.ts function createGetPermissionsCommand(_ctx) { return () => { if (typeof window === "undefined" || !isCommandAvailable("get-permissions" /* GetPermissions */)) { console.error( "'getPermissions' command is unavailable. Check MiniKit.install() or update the app version" ); return null; } sendMiniKitEvent({ command: "get-permissions" /* GetPermissions */, version: COMMAND_VERSIONS["get-permissions" /* GetPermissions */], payload: {} }); return { status: "sent" }; }; } function createGetPermissionsAsyncCommand(ctx, syncCommand) { return async () => { return new Promise((resolve, reject) => { try { let commandPayload = null; const handleResponse = (payload) => { ctx.events.unsubscribe("miniapp-get-permissions" /* MiniAppGetPermissions */); resolve({ commandPayload, finalPayload: payload }); }; ctx.events.subscribe( "miniapp-get-permissions" /* MiniAppGetPermissions */, handleResponse ); commandPayload = syncCommand(); } catch (error) { reject(error); } }); }; } // helpers/payment/client.ts var validatePaymentPayload = (payload) => { if (payload.tokens.some( (token) => token.symbol == "USDCE" /* USDC */ && parseFloat(token.token_amount) < 0.1 )) { console.error("USDC amount should be greater than $0.1"); return false; } if (payload.reference.length > 36) { console.error("Reference must not exceed 36 characters"); return false; } if (typeof payload.reference !== "string") { throw new Error("Reference must be a string"); } return true; }; // commands/pay.ts function createPayCommand(_ctx) { return (payload) => { if (typeof window === "undefined" || !isCommandAvailable("pay" /* Pay */)) { console.error( "'pay' command is unavailable. Check MiniKit.install() or update the app version" ); return null; } if (!validatePaymentPayload(payload)) { return null; } const eventPayload = { ...payload, network: "worldchain" /* WorldChain */ }; sendMiniKitEvent({ command: "pay" /* Pay */, version: COMMAND_VERSIONS["pay" /* Pay */], payload: eventPayload }); return eventPayload; }; } function createPayAsyncCommand(ctx, syncCommand) { return async (payload) => { return new Promise((resolve, reject) => { try { let commandPayload = null; const handleResponse = (response) => { ctx.events.unsubscribe("miniapp-payment" /* MiniAppPayment */); resolve({ commandPayload, finalPayload: response }); }; ctx.events.subscribe( "miniapp-payment" /* MiniAppPayment */, handleResponse ); commandPayload = syncCommand(payload); } catch (error) { reject(error); } }); }; } // commands/request-permission.ts function createRequestPermissionCommand(_ctx) { return (payload) => { if (typeof window === "undefined" || !isCommandAvailable("request-permission" /* RequestPermission */)) { console.error( "'requestPermission' command is unavailable. Check MiniKit.install() or update the app version" ); return null; } sendMiniKitEvent({ command: "request-permission" /* RequestPermission */, version: COMMAND_VERSIONS["request-permission" /* RequestPermission */], payload }); return payload; }; } function createRequestPermissionAsyncCommand(ctx, syncCommand) { return async (payload) => { return new Promise((resolve, reject) => { try { let commandPayload = null; const handleResponse = (response) => { ctx.events.unsubscribe("miniapp-request-permission" /* MiniAppRequestPermission */); resolve({ commandPayload, finalPayload: response }); }; ctx.events.subscribe( "miniapp-request-permission" /* MiniAppRequestPermission */, handleResponse ); commandPayload = syncCommand(payload); } catch (error) { reject(error); } }); }; } // commands/send-haptic-feedback.ts function createSendHapticFeedbackCommand(_ctx) { return (payload) => { if (typeof window === "undefined" || !isCommandAvailable("send-haptic-feedback" /* SendHapticFeedback */)) { console.error( "'sendHapticFeedback' command is unavailable. Check MiniKit.install() or update the app version" ); return null; } sendMiniKitEvent({ command: "send-haptic-feedback" /* SendHapticFeedback */, version: COMMAND_VERSIONS["send-haptic-feedback" /* SendHapticFeedback */], payload }); return payload; }; } function createSendHapticFeedbackAsyncCommand(ctx, syncCommand) { return async (payload) => { return new Promise((resolve, reject) => { try { let commandPayload = null; const handleResponse = (response) => { ctx.events.unsubscribe("miniapp-send-haptic-feedback" /* MiniAppSendHapticFeedback */); resolve({ commandPayload, finalPayload: response }); }; ctx.events.subscribe( "miniapp-send-haptic-feedback" /* MiniAppSendHapticFeedback */, handleResponse ); commandPayload = syncCommand(payload); } catch (error) { reject(error); } }); }; } // helpers/transaction/validate-payload.ts var isValidHex = (str) => { return /^0x[0-9A-Fa-f]+$/.test(str); }; var objectValuesToArrayRecursive = (input) => { if (input === null || typeof input !== "object") { return input; } if (Array.isArray(input)) { return input.map((item) => objectValuesToArrayRecursive(item)); } const values = Object.values(input); return values.map((value) => objectValuesToArrayRecursive(value)); }; var processPayload = (payload) => { if (typeof payload === "boolean" || typeof payload === "string" || payload === null || payload === void 0) { return payload; } if (typeof payload === "number" || typeof payload === "bigint") { return String(payload); } if (Array.isArray(payload)) { return payload.map((value) => processPayload(value)); } if (typeof payload === "object") { const result = { ...payload }; if ("value" in result && result.value !== void 0) { if (typeof result.value !== "string") { result.value = String(result.value); } if (!isValidHex(result.value)) { console.error( "Transaction value must be a valid hex string", result.value ); throw new Error( `Transaction value must be a valid hex string: ${result.value}` ); } } for (const key in result) { if (Object.prototype.hasOwnProperty.call(result, key)) { result[key] = processPayload(result[key]); } } return result; } return payload; }; var validateSendTransactionPayload = (payload) => { if (payload.formatPayload) { const formattedPayload = processPayload(payload); formattedPayload.transaction = formattedPayload.transaction.map((tx) => { const args = objectValuesToArrayRecursive(tx.args); return { ...tx, args }; }); return formattedPayload; } return payload; }; // commands/send-transaction.ts function createSendTransactionCommand(_ctx) { return (payload) => { if (typeof window === "undefined" || !isCommandAvailable("send-transaction" /* SendTransaction */)) { console.error( "'sendTransaction' command is unavailable. Check MiniKit.install() or update the app version" ); return null; } payload.formatPayload = payload.formatPayload !== false; const validatedPayload = validateSendTransactionPayload(payload); sendMiniKitEvent({ command: "send-transaction" /* SendTransaction */, version: COMMAND_VERSIONS["send-transaction" /* SendTransaction */], payload: validatedPayload }); return validatedPayload; }; } function createSendTransactionAsyncCommand(ctx, syncCommand) { return async (payload) => { return new Promise((resolve, reject) => { try { let commandPayload = null; const handleResponse = (response) => { ctx.events.unsubscribe("miniapp-send-transaction" /* MiniAppSendTransaction */); resolve({ commandPayload, finalPayload: response }); }; ctx.events.subscribe( "miniapp-send-transaction" /* MiniAppSendTransaction */, handleResponse ); commandPayload = syncCommand(payload); } catch (error) { reject(error); } }); }; } // helpers/share/index.ts var MAX_FILES = 10; var MAX_TOTAL_SIZE_MB = 50; var MAX_TOTAL_SIZE_BYTES = MAX_TOTAL_SIZE_MB * 1024 * 1024; var processFile = async (file) => { const buffer = await file.arrayBuffer(); const uint8Array = new Uint8Array(buffer); let binaryString = ""; const K_CHUNK_SIZE = 32768; for (let i = 0; i < uint8Array.length; i += K_CHUNK_SIZE) { const chunk = uint8Array.subarray( i, Math.min(i + K_CHUNK_SIZE, uint8Array.length) ); binaryString += String.fromCharCode.apply( null, Array.from(chunk) // Convert Uint8Array chunk to number[] ); } const base64Data = btoa(binaryString); return { name: file.name, type: file.type, data: base64Data }; }; var formatShareInput = async (input) => { if (!input.files) { return { title: input.title, text: input.text, url: input.url }; } if (!Array.isArray(input.files)) { throw new Error('The "files" property must be an array.'); } if (input.files.length === 0) { } else { if (input.files.length > MAX_FILES) { throw new Error(`Cannot share more than ${MAX_FILES} files.`); } let totalSize = 0; for (const file of input.files) { if (!(file instanceof File)) { throw new Error( `Each item in the 'files' array must be a File object. Received: ${typeof file}` ); } totalSize += file.size; } if (totalSize > MAX_TOTAL_SIZE_BYTES) { throw new Error(`Total file size cannot exceed ${MAX_TOTAL_SIZE_MB}MB.`); } } const fileProcessingPromises = input.files.map((file) => processFile(file)); const processedFiles = await Promise.all(fileProcessingPromises); return { files: processedFiles, title: input.title, text: input.text, url: input.url }; }; // commands/share.ts function createShareCommand(ctx) { return (payload) => { if (typeof window === "undefined" || !isCommandAvailable("share" /* Share */)) { console.error( "'share' command is unavailable. Check MiniKit.install() or update the app version" ); return null; } if (ctx.state.deviceProperties.deviceOS === "ios" && typeof navigator !== "undefined") { sendMiniKitEvent({ command: "share" /* Share */, version: COMMAND_VERSIONS["share" /* Share */], payload }); navigator.share(payload); } else { formatShareInput(payload).then((formattedResult) => { sendMiniKitEvent({ command: "share" /* Share */, version: COMMAND_VERSIONS["share" /* Share */], payload: formattedResult }); }).catch((error) => { console.error("Failed to format share input", error); }); ctx.events.subscribe("miniapp-share" /* MiniAppShare */, (response) => { console.log("Share Response", response); }); } return payload; }; } function createShareAsyncCommand(ctx, syncCommand) { return async (payload) => { return new Promise((resolve, reject) => { try { let commandPayload = null; const handleResponse = (response) => { ctx.events.unsubscribe("miniapp-share" /* MiniAppShare */); resolve({ commandPayload, finalPayload: response }); }; ctx.events.subscribe("miniapp-share" /* MiniAppShare */, handleResponse); commandPayload = syncCommand(payload); } catch (error) { reject(error); } }); }; } // commands/share-contacts.ts function createShareContactsCommand(_ctx) { return (payload) => { if (typeof window === "undefined" || !isCommandAvailable("share-contacts" /* ShareContacts */)) { console.error( "'shareContacts' command is unavailable. Check MiniKit.install() or update the app version" ); return null; } sendMiniKitEvent({ command: "share-contacts" /* ShareContacts */, version: COMMAND_VERSIONS["share-contacts" /* ShareContacts */], payload }); return payload; }; } function createShareContactsAsyncCommand(ctx, syncCommand) { return async (payload) => { return new Promise((resolve, reject) => { try { let commandPayload = null; const handleResponse = (response) => { ctx.events.unsubscribe("miniapp-share-contacts" /* MiniAppShareContacts */); resolve({ commandPayload, finalPayload: response }); }; ctx.events.subscribe( "miniapp-share-contacts" /* MiniAppShareContacts */, handleResponse ); commandPayload = syncCommand(payload); } catch (error) { reject(error); } }); }; } // commands/sign-message.ts function createSignMessageCommand(_ctx) { return (payload) => { if (typeof window === "undefined" || !isCommandAvailable("sign-message" /* SignMessage */)) { console.error( "'signMessage' command is unavailable. Check MiniKit.install() or update the app version" ); return null; } sendMiniKitEvent({ command: "sign-message" /* SignMessage */, version: COMMAND_VERSIONS["sign-message" /* SignMessage */], payload }); return payload; }; } function createSignMessageAsyncCommand(ctx, syncCommand) { return async (payload) => { return new Promise((resolve, reject) => { try { let commandPayload = null; const handleResponse = (response) => { ctx.events.unsubscribe("miniapp-sign-message" /* MiniAppSignMessage */); resolve({ commandPayload, finalPayload: response }); }; ctx.events.subscribe( "miniapp-sign-message" /* MiniAppSignMessage */, handleResponse ); commandPayload = syncCommand(payload); } catch (error) { reject(error); } }); }; } // commands/sign-typed-data.ts function createSignTypedDataCommand(_ctx) { return (payload) => { console.warn( "signTypedData is deprecated. Use signMessage or sendTransaction instead." ); if (typeof window === "undefined" || !isCommandAvailable("sign-typed-data" /* SignTypedData */)) { console.error( "'signTypedData' command is unavailable. Check MiniKit.install() or update the app version" ); return null; } if (!payload.chainId) { payload.chainId = 480; } sendMiniKitEvent({ command: "sign-typed-data" /* SignTypedData */, version: COMMAND_VERSIONS["sign-typed-data" /* SignTypedData */], payload }); return payload; }; } function createSignTypedDataAsyncCommand(ctx, syncCommand) { return async (payload) => { return new Promise((resolve, reject) => { try { let commandPayload = null; const handleResponse = (response) => { ctx.events.unsubscribe("miniapp-sign-typed-data" /* MiniAppSignTypedData */); resolve({ commandPayload, finalPayload: response }); }; ctx.events.subscribe( "miniapp-sign-typed-data" /* MiniAppSignTypedData */, handleResponse ); commandPayload = syncCommand(payload); } catch (error) { reject(error); } }); }; } // commands/verify.ts var import_idkit_core = require("@worldcoin/idkit-core"); var import_hashing = require("@worldcoin/idkit-core/hashing"); var import_idkit_core2 = require("@worldcoin/idkit-core"); function createVerifyCommand(ctx) { return (payload) => { if (typeof window === "undefined" || !isCommandAvailable("verify" /* Verify */)) { console.error( "'verify' command is unavailable. Check MiniKit.install() or update the app version" ); return null; } if (Array.isArray(payload.verification_level) && payload.verification_level.length === 0) { console.error("'verification_level' must not be an empty array"); return null; } const timestamp = (/* @__PURE__ */ new Date()).toISOString(); const eventPayload = { action: (0, import_hashing.encodeAction)(payload.action), signal: (0, import_hashing.generateSignal)(payload.signal).digest, verification_level: payload.verification_level || import_idkit_core.VerificationLevel.Orb, timestamp }; ctx.events.setVerifyActionProcessingOptions({ skip_proof_compression: payload.skip_proof_compression }); sendMiniKitEvent({ command: "verify" /* Verify */, version: COMMAND_VERSIONS["verify" /* Verify */], payload: eventPayload }); return eventPayload; }; } function createVerifyAsyncCommand(ctx, syncCommand) { let hasInFlightVerifyRequest = false; return async (payload) => { if (hasInFlightVerifyRequest) { return Promise.reject( new Error( "A verify request is already in flight. Wait for the current request to complete before sending another." ) ); } return new Promise((resolve, reject) => { try { hasInFlightVerifyRequest = true; let commandPayload = null; const handleResponse = (response) => { ctx.events.unsubscribe("miniapp-verify-action" /* MiniAppVerifyAction */); hasInFlightVerifyRequest = false; resolve({ commandPayload, finalPayload: response }); }; ctx.events.subscribe( "miniapp-verify-action" /* MiniAppVerifyAction */, handleResponse ); commandPayload = syncCommand(payload); if (commandPayload === null) { ctx.events.unsubscribe("miniapp-verify-action" /* MiniAppVerifyAction */); hasInFlightVerifyRequest = false; reject( new Error( "Failed to send verify command. Ensure MiniKit is installed and the verify command is available." ) ); } } catch (error) { hasInFlightVerifyRequest = false; reject(error); } }); }; } // helpers/siwe/siwe.ts var import_viem = require("viem"); var import_chains = require("viem/chains"); var generateSiweMessage = (siweMessageData) => { let siweMessage = ""; if (siweMessageData.scheme) { siweMessage += `${siweMessageData.scheme}://${siweMessageData.domain} wants you to sign in with your Ethereum account: `; } else { siweMessage += `${siweMessageData.domain} wants you to sign in with your Ethereum account: `; } if (siweMessageData.address) { siweMessage += `${siweMessageData.address} `; } else { siweMessage += "{address}\n"; } siweMessage += "\n"; if (siweMessageData.statement) { siweMessage += `${siweMessageData.statement} `; } siweMessage += "\n"; siweMessage += `URI: ${siweMessageData.uri} `; siweMessage += `Version: ${siweMessageData.version} `; siweMessage += `Chain ID: ${siweMessageData.chain_id} `; siweMessage += `Nonce: ${siweMessageData.nonce} `; siweMessage += `Issued At: ${siweMessageData.issued_at} `; if (siweMessageData.expiration_time) { siweMessage += `Expiration Time: ${siweMessageData.expiration_time} `; } if (siweMessageData.not_before) { siweMessage += `Not Before: ${siweMessageData.not_before} `; } if (siweMessageData.request_id) { siweMessage += `Request ID: ${siweMessageData.request_id} `; } return siweMessage; }; // helpers/siwe/validate-wallet-auth-command-input.ts var validateWalletAuthCommandInput = (params) => { if (!params.nonce) { return { valid: false, message: "'nonce' is required" }; } if (params.nonce.length < 8) { return { valid: false, message: "'nonce' must be at least 8 characters" }; } if (params.statement && params.statement.includes("\n")) { return { valid: false, message: "'statement' must not contain newlines" }; } if (params.expirationTime && new Date(params.expirationTime) < /* @__PURE__ */ new Date()) { return { valid: false, message: "'expirationTime' must be in the future" }; } if (params.expirationTime && new Date(params.expirationTime) > new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3)) { return { valid: false, message: "'expirationTime' must be within 7 days" }; } if (params.notBefore && new Date(params.notBefore) > new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3)) { return { valid: false, message: "'notBefore' must be within 7 days" }; } return { valid: true }; }; // commands/wallet-auth.ts function createWalletAuthCommand(ctx) { return (payload) => { if (typeof window === "undefined" || !isCommandAvailable("wallet-auth" /* WalletAuth */)) { console.error( "'walletAuth' command is unavailable. Check MiniKit.install() or update the app version" ); return null; } const validationResult = validateWalletAuthCommandInput(payload); if (!validationResult.valid) { console.error( "Failed to validate wallet auth input:\n\n -->", validationResult.message ); return null; } let protocol = null; try { const currentUrl = new URL(window.location.href); protocol = currentUrl.protocol.split(":")[0]; } catch (error) { console.error("Failed to get current URL", error); return null; } const siweMessage = generateSiweMessage({ scheme: protocol, domain: window.location.host, statement: payload.statement ?? void 0, uri: window.location.href, version: "1", chain_id: 480, nonce: payload.nonce, issued_at: (/* @__PURE__ */ new Date()).toISOString(), expiration_time: payload.expirationTime?.toISOString() ?? void 0, not_before: payload.notBefore?.toISOString() ?? void 0, request_id: payload.requestId ?? void 0 }); const walletAuthPayload = { siweMessage }; const walletAuthVersion = ctx.state.user.worldAppVersion && ctx.state.user.worldAppVersion > 2087900 ? COMMAND_VERSIONS["wallet-auth" /* WalletAuth */] : 1; sendMiniKitEvent({ command: "wallet-auth" /* WalletAuth */, version: walletAuthVersion, payload: walletAuthPayload }); return walletAuthPayload; }; } function createWalletAuthAsyncCommand(ctx, syncCommand) { return async (payload) => { return new Promise((resolve, reject) => { try { let commandPayload = null; const handleResponse = async (response) => { ctx.events.unsubscribe("miniapp-wallet-auth" /* MiniAppWalletAuth */); if (response.status === "success") { await ctx.state.updateUserFromWalletAuth(response.address); } resolve({ commandPayload, finalPayload: response }); }; ctx.events.subscribe( "miniapp-wallet-auth" /* MiniAppWalletAuth */, handleResponse ); commandPayload = syncCommand(payload); } catch (error) { reject(error); } }); }; } // commands/index.ts function createCommands(ctx) { return { verify: createVerifyCommand(ctx), pay: createPayCommand(ctx), walletAuth: createWalletAuthCommand(ctx), sendTransaction: createSendTransactionCommand(ctx), signMessage: createSignMessageCommand(ctx), /** @deprecated EIP-712 typed data signing is deprecated. Use signMessage or sendTransaction instead. */ signTypedData: createSignTypedDataCommand(ctx), shareContacts: createShareContactsCommand(ctx), requestPermission: createRequestPermissionCommand(ctx), getPermissions: createGetPermissionsCommand(ctx), sendHapticFeedback: createSendHapticFeedbackCommand(ctx), share: createShareCommand(ctx), chat: createChatCommand(ctx), attestation: createAttestationCommand(ctx), closeMiniApp: createCloseMiniAppCommand(ctx) }; } function createAsyncCommands(ctx, commands) { return { verify: createVerifyAsyncCommand(ctx, commands.verify), pay: createPayAsyncCommand(ctx, commands.pay), walletAuth: createWalletAuthAsyncCommand(ctx, commands.walletAuth), sendTransaction: createSendTransactionAsyncCommand( ctx, commands.sendTransaction ), signMessage: createSignMessageAsyncCommand(ctx, commands.signMessage), /** @deprecated EIP-712 typed data signing is deprecated. Use signMessage or sendTransaction instead. */ signTypedData: createSignTypedDataAsyncCommand(ctx, commands.signTypedData), shareContacts: createShareContactsAsyncCommand(ctx, commands.shareContacts), requestPermission: createRequestPermissionAsyncCommand( ctx, commands.requestPermission ), getPermissions: createGetPermissionsAsyncCommand( ctx, commands.getPermissions ), sendHapticFeedback: createSendHapticFeedbackAsyncCommand( ctx, commands.sendHapticFeedback ), share: createShareAsyncCommand(ctx, commands.share), chat: createChatAsyncCommand(ctx, commands.chat), attestation: createAttestationAsyncCommand(ctx, commands.attestation) }; } // core/events.ts var import_idkit_core3 = require("@worldcoin/idkit-core"); // helpers/proof/index.ts var import_viem2 = require("viem"); var import_chains2 = require("viem/chains"); var semaphoreVerifierAddress = "0x79f46b94d134109EbcbbddBAeD0E88790409A0e4"; var semaphoreVerifierAbi = [ { inputs: [ { internalType: "uint256[8]", name: "proof", type: "uint256[8]" } ], name: "compressProof", outputs: [ { internalType: "uint256[4]", name: "compressed", type: "uint256[4]" } ], stateMutability: "view", type: "function" } ]; var compressAndPadProof = async (proof, rpcUrl) => { try { const publicClient = (0, import_viem2.createPublicClient)({ chain: import_chains2.worldchain, transport: (0, import_viem2.http)( rpcUrl || "https://worldchain-mainnet.g.alchemy.com/public" ) }); const decodedProof = (0, import_viem2.decodeAbiParameters)( [{ type: "uint256[8]" }], proof )[0]; const compressedProof = await publicClient.readContract({ address: semaphoreVerifierAddress, abi: semaphoreVerifierAbi, functionName: "compressProof", args: [decodedProof] }); const paddedProof = [...compressedProof, 0n, 0n, 0n, 0n]; return (0, import_viem2.encodeAbiParameters)([{ type: "uint256[8]" }], [paddedProof]); } catch (e) { return proof; } }; // core/events.ts var EventManager = class { constructor() { this.listeners = { ["miniapp-verify-action" /* MiniAppVerifyAction */]: () => { }, ["miniapp-payment" /* MiniAppPayment */]: () => { }, ["miniapp-wallet-auth" /* MiniAppWalletAuth */]: () => { }, ["miniapp-send-transaction" /* MiniAppSendTransaction */]: () => { }, ["miniapp-sign-message" /* MiniAppSignMessage */]: () => { }, ["miniapp-sign-typed-data" /* MiniAppSignTypedData */]: () => { }, ["miniapp-share-contacts" /* MiniAppShareContacts */]: () => { }, ["miniapp-request-permission" /* MiniAppRequestPermission */]: () => { }, ["miniapp-get-permissions" /* MiniAppGetPermissions */]: () => { }, ["miniapp-send-haptic-feedback" /* MiniAppSendHapticFeedback */]: () => { }, ["miniapp-share" /* MiniAppShare */]: () => { }, ["miniapp-microphone" /* MiniAppMicrophone */]: () => { }, ["miniapp-chat" /* MiniAppChat */]: () => { }, ["miniapp-attestation" /* MiniAppAttestation */]: () => { } }; this.verifyActionProcessingOptionsQueue = []; } subscribe(event, handler) { this.listeners[event] = handler; } unsubscribe(event) { delete this.listeners[event]; } setVerifyActionProcessingOptions(options) { this.verifyActionProcessingOptionsQueue.push({ skip_proof_compression: Boolean(options?.skip_proof_compression ?? false) }); } trigger(event, payload) { if (!this.listeners[event]) { console.error( `No handler for event ${event}, payload: ${JSON.stringify(payload)}` ); return; } if (event === "miniapp-verify-action" /* MiniAppVerifyAction */) { const handler = this.listeners[event]; const processingOptions = this.verifyActionProcessingOptionsQueue.shift() ?? { skip_proof_compression: false }; this.processVerifyActionPayload( payload, handler, processingOptions ); return; } this.listeners[event](payload); } async processVerifyActionPayload(payload, handler, processingOptions) { if (payload.status === "error" && payload.error_code === "user_rejected") { payload.error_code = import_idkit_core3.AppErrorCodes.VerificationRejected; } if (payload.status === "success" && !processingOptions.skip_proof_compression) { if ("verifications" in payload) { const orbVerification = payload.verifications.find( (v) => v.verification_level === import_idkit_core3.VerificationLevel.Orb ); if (orbVerification) { orbVerification.proof = await this.compressProofSafely( orbVerification.proof, { mode: "multi", payloadVersion: payload.version, verificationsCount: payload.verifications.length, verificationLevel: orbVerification.verification_level } ); } } else if (payload.verification_level === import_idkit_core3.VerificationLevel.Orb) { payload.proof = await this.compressProofSafely( payload.proof, { mode: "single", payloadVersion: payload.version, verificationLevel: payload.verification_level } ); } } handler(payload); } async compressProofSafely(proof, context) { try { return await compressAndPadProof(proof); } catch (error) { console.error( "Failed to compress verification proof. Delivering payload with uncompressed proof.", { ...context, error } ); return proof; } } }; // helpers/usernames/index.ts var getUserProfile = async (address) => { const res = await fetch("https://usernames.worldcoin.org/api/v1/query", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ addresses: [address] }) }); const usernames = await res.json(); return usernames?.[0] ?? { username: null, profile_picture_url: null }; }; // types/init.ts var WORLD_APP_LAUNCH_LOCATION_MAP = { "app-store": "app-store" /* AppStore */, carousel: "app-store" /* AppStore */, explore: "app-store" /* AppStore */, app_details: "app-store" /* AppStore */, deeplink: "deep-link" /* DeepLink */, homepage: "home" /* Home */, wallet_tab: "wallet-tab" /* WalletTab */, world_chat: "chat" /* Chat */ }; var mapWorldAppLaunchLocation = (location) => { if (!location || typeof location !== "string") return null; console.log("MiniKit launch location mapped:", location); const normalizedLocation = location.toLowerCase(); return WORLD_APP_LAUNCH_LOCATION_MAP[normalizedLocation] ?? null; }; // core/state.ts var MiniKitState = class { constructor() { this.appId = null; this.user = {}; this.deviceProperties = {}; this.location = null; this.isReady = false; } initFromWorldApp(worldApp) { if (!worldApp) return; this.user.optedIntoOptionalAnalytics = worldApp.is_optional_analytics; this.user.preferredCurrency = worldApp.preferred_currency; this.user.deviceOS = worldApp.device_os; this.user.worldAppVersion = worldApp.world_app_version; this.deviceProperties.safeAreaInsets = worldApp.safe_area_insets; this.deviceProperties.deviceOS = worldApp.device_os; this.deviceProperties.worldAppVersion = worldApp.world_app_version; this.location = mapWorldAppLaunchLocation(worldApp.location); } async updateUserFromWalletAuth(address) { this.user.walletAddress = address; try { const userProfile = await getUserProfile(address); this.user.username = userProfile.username; this.user.profilePictureUrl = userProfile.profile_picture_url; } catch (error) { console.error("Failed to fetch user profile:", error); } } async getUserByAddress(address) { const walletAddress = address ?? this.user.walletAddress; const userProfile = await getUserProfile(walletAddress); return { walletAddress, username: userProfile.username, profilePictureUrl: userProfile.profile_picture_url }; } async getUserByUsername(username) { const res = await fetch( `https://usernames.worldcoin.org/api/v1/${username}`, { method: "GET", headers: { "Content-Type": "application/json" } } ); const user = await res.json(); return { walletAddress: user.address, username: user.username, profilePictureUrl: user.profile_picture_url }; } }; // types/errors.ts var import_idkit_core4 = require("@worldcoin/idkit-core"); var import_idkit_core5 = require("@worldcoin/idkit-core"); var VerificationErrorMessage = { [import_idkit_core4.AppErrorCodes.VerificationRejected]: "You've cancelled the request in World App.", [import_idkit_core4.AppErrorCodes.MaxVerificationsReached]: "You have already verified the maximum number of times for this action.", [import_idkit_core4.AppErrorCodes.CredentialUnavailable]: "It seems you do not have the verification level required by this app.", [import_idkit_core4.AppErrorCodes.MalformedRequest]: "There was a problem with this request. Please try again or contact the app owner.", [import_idkit_core4.AppErrorCodes.InvalidNetwork]: "Invalid network. If you are the app owner, visit docs.worldcoin.org/test for details.", [import_idkit_core4.AppErrorCodes.InclusionProofFailed]: "There was an issue fetching your credential. Please try again.", [import_idkit_core4.AppErrorCodes.InclusionProofPending]: "Your identity is still being registered. Please wait a few minutes and try again.", [import_idkit_core4.AppErrorCodes.UnexpectedResponse]: "Unexpected response from your wallet. Please try again.", [import_idkit_core4.AppErrorCodes.FailedByHostApp]: "Verification failed by the app. Please contact the app owner for details.", [import_idkit_core4.AppErrorCodes.GenericError]: "Something unexpected went wrong. Please try again.", [import_idkit_core4.AppErrorCodes.ConnectionFailed]: "Connection to your wallet failed. Please try again." }; var MiniKitInstallErrorMessage = { ["unknown" /* Unknown */]: "Failed to install MiniKit.", ["already_installed" /* AlreadyInstalled */]: "MiniKit is already installed.", ["outside_of_worldapp" /* OutsideOfWorldApp */]: "MiniApp launched outside of WorldApp.", ["not_on_client" /* NotOnClient */]: "Window object is not available.", ["app_out_of_date" /* AppOutOfDate */]: "WorldApp is out of date. Please update the app." }; // helpers/microphone/index.ts var microphoneSetupDone = false; var setupMicrophone = () => { if (microphoneSetupDone) { return; } if (typeof navigator !== "undefined" && !navigator.mediaDevices?.getUserMedia) return; const originalStop = MediaStreamTrack.prototype.stop; MediaStreamTrack.prototype.stop = function() { originalStop.call(this); if (this.readyState === "ended") { setTimeout(() => this.dispatchEvent(new Event("ended")), 0); } }; const realGUM = navigator.mediaDevices.getUserMedia.bind( navigator.mediaDevices ); const live = /* @__PURE__ */ new Set(); async function wrapped(constraints) { const stream = await realGUM(constraints); const hasAudioTrack = stream.getAudioTracks().length > 0; if (hasAudioTrack) { sendWebviewEvent({ command: "microphone-stream-started", version: 1, payload: { streamId: stream.id } }); live.add(stream); stream.getAudioTracks().forEach((t) => { t.addEventListener("ended", () => { const allAudioTracksEnded = stream.getAudioTracks().every((track) => track.readyState === "ended"); if (allAudioTracksEnded) { sendWebviewEvent({ command: "microphone-stream-ended", version: 1, payload: { streamId: stream.id } }); live.delete(stream); } }); }); } return stream; } Object.defineProperty(navigator.mediaDevices, "getUserMedia", { value: wrapped, writable: false, configurable: false, enumerable: true }); Object.freeze(navigator.mediaDevices); const stopAllMiniAppMicrophoneStreams = () => { live.forEach((s) => { const audioTracks = s.getAudioTracks(); if (audioTracks.length > 0) { audioTracks.forEach((t) => { t.stop(); }); sendWebviewEvent({ command: "microphone-stream-ended", version: 1, payload: { streamId: s.id } }); } }); live.clear(); }; MiniKit.subscribe("miniapp-microphone" /* MiniAppMicrophone */, (payload) => { if (payload.status === "error" && (payload.error_code === "mini_app_permission_not_enabled" /* MiniAppPermissionNotEnabled */ || payload.error_code === "world_app_permission_not_enabled" /* WorldAppPermissionNotEnabled */)) { console.log("stopping all microphone streams", payload); stopAllMiniAppMicrophoneStreams(); } }); window.__stopAllMiniAppMicrophoneStreams = stopAllMiniAppMicrophoneStreams; microphoneSetupDone = true; }; // minikit.ts var MINIKIT_VERSION = 1; var MINIKIT_MINOR_VERSION = 96; var _MiniKit = class _MiniKit { // ============================================================================ // Public State Accessors // ============================================================================ static get appId() { return this.stateManager.appId; } static set appId(value) { this.stateManager.appId = value; } static get user() { return this.stateManager.user; } static set user(value) { this.stateManager.user = value; } static get deviceProperties() { return this.stateManager.deviceProperties; } static get location() { return this.stateManager.location; } // ============================================================================ // Event System // ============================================================================ static subscribe(event, handler) { if (event === "miniapp-wallet-auth" /* MiniAppWalletAuth */) { const originalHandler = handler; const wrappedHandler = async (payload) => { if (payload.status === "success") { await this.stateManager.updateUserFromWalletAuth(payload.address); } originalHandler(payload); }; this.eventManager.subscribe(event, wrappedHandler); } else { this.eventManager.subscribe(event, handler); } } static unsubscribe(event) { this.eventManager.unsubscribe(event); } static trigger(event, payload) { this.eventManager.trigger(event, payload); } // ============================================================================ // Installation // ============================================================================ static sendInit() { sendWebviewEvent({ command: "init", payload: { version: MINIKIT_VERSION, minorVersion: MINIKIT_MINOR_VERSION } }); } static install(appId) { if (typeof window === "undefined" || Boolean(window.MiniKit)) { return { success: false, errorCode: "already_installed" /* AlreadyInstalled */, errorMessage: MiniKitInstallErrorMessage["already_installed" /* AlreadyInstalled */] }; } if (!appId) { console.warn("App ID not provided during install"); } else { this.stateManager.appId = appId; } if (!window.WorldApp) { return { success: false, errorCode: "outside_of_worldapp" /* OutsideOfWorldApp */, errorMessage: MiniKitInstallErrorMessage["outside_of_worldapp" /* OutsideOfWorldApp */] }; } this.stateManager.initFromWorldApp(window.WorldApp); try { window.MiniKit = _MiniKit; this.sendInit(); } catch (error) { console.error( MiniKitInstallErrorMessage["unknown" /* Unknown */], error ); return { success: false, errorCode: "unknown" /* Unknown */, errorMessage: MiniKitInstallErrorMessage["unknown" /* Unknown */] }; } this.stateManager.isReady = true; setupMicrophone(); if (!validateCommands(window.WorldApp.supported_commands)) { return { success: false, errorCode: "app_out_of_date" /* AppOutOfDate */, errorMessage: MiniKitInstallErrorMessage["app_out_of_date" /* AppOutOfDate */] }; } return { success: true }; } static isInstalled(debug) { const isInstalled = this.stateManager.isReady && Boolean(window.MiniKit); if (!isInstalled) { console.error( "MiniKit is not installed. Make sure you're running the application inside of World App" ); } if (debug && isInstalled) { console.log("MiniKit is alive!"); } return isInstalled; } // ============================================================================ // Commands // ============================================================================ static getContext() { return { events: this.eventManager, state: this.stateManager }; } static get commands() { if (!this.commandsInstance) { this.commandsInstance = createCommands(this.getContext()); } return this.commandsInstance; } static get