UNPKG

@worldcoin/minikit-js

Version:

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

1,416 lines (1,385 loc) 61.1 kB
"use strict"; 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); // src/command-exports.ts var command_exports_exports = {}; __export(command_exports_exports, { AttestationError: () => AttestationError, AttestationErrorCodes: () => AttestationErrorCodes, COMMAND_VERSIONS: () => COMMAND_VERSIONS, ChatError: () => ChatError, ChatErrorCodes: () => ChatErrorCodes, Command: () => Command, CommandUnavailableError: () => CommandUnavailableError, FallbackRequiredError: () => FallbackRequiredError, GetPermissionsError: () => GetPermissionsError, GetPermissionsErrorCodes: () => GetPermissionsErrorCodes, MiniAppLaunchLocation: () => MiniAppLaunchLocation, MiniKitInstallErrorCodes: () => MiniKitInstallErrorCodes, MiniKitInstallErrorMessage: () => MiniKitInstallErrorMessage, Network: () => Network, PayError: () => PayError, PaymentErrorCodes: () => PaymentErrorCodes, PaymentErrorMessage: () => PaymentErrorMessage, Permission: () => Permission, RequestPermissionError: () => RequestPermissionError, RequestPermissionErrorCodes: () => RequestPermissionErrorCodes, ResponseEvent: () => ResponseEvent, SendHapticFeedbackError: () => SendHapticFeedbackError, SendHapticFeedbackErrorCodes: () => SendHapticFeedbackErrorCodes, SendTransactionError: () => SendTransactionError, SendTransactionErrorCodes: () => SendTransactionErrorCodes, SendTransactionErrorMessage: () => SendTransactionErrorMessage, ShareContactsError: () => ShareContactsError, ShareContactsErrorCodes: () => ShareContactsErrorCodes, ShareContactsErrorMessage: () => ShareContactsErrorMessage, ShareError: () => ShareError, ShareFilesErrorCodes: () => ShareFilesErrorCodes, SignMessageError: () => SignMessageError, SignMessageErrorCodes: () => SignMessageErrorCodes, SignTypedDataError: () => SignTypedDataError, SignTypedDataErrorCodes: () => SignTypedDataErrorCodes, TokenDecimals: () => TokenDecimals, Tokens: () => Tokens, WEB_FEATURES: () => WEB_FEATURES, WORLD_APP_FEATURES: () => WORLD_APP_FEATURES, WalletAuthError: () => WalletAuthError, WalletAuthErrorCodes: () => WalletAuthErrorCodes, WalletAuthErrorMessage: () => WalletAuthErrorMessage, attestation: () => attestation, chat: () => chat, closeMiniApp: () => closeMiniApp, getContacts: () => getContacts, getPermissions: () => getPermissions, isCommandAvailable: () => isCommandAvailable, isInWorldApp: () => isInWorldApp, pay: () => pay, requestPermission: () => requestPermission, sendHapticFeedback: () => sendHapticFeedback, sendMiniKitEvent: () => sendMiniKitEvent, sendTransaction: () => sendTransaction, setCommandAvailable: () => setCommandAvailable, share: () => share, shareContacts: () => shareContacts, signMessage: () => signMessage, signTypedData: () => signTypedData, tokenToDecimals: () => tokenToDecimals, validateCommands: () => validateCommands, walletAuth: () => walletAuth }); module.exports = __toCommonJS(command_exports_exports); // src/commands/types.ts var Command = /* @__PURE__ */ ((Command2) => { Command2["Attestation"] = "attestation"; Command2["Pay"] = "pay"; Command2["WalletAuth"] = "wallet-auth"; Command2["SendTransaction"] = "send-transaction"; Command2["SignMessage"] = "sign-message"; Command2["SignTypedData"] = "sign-typed-data"; Command2["ShareContacts"] = "share-contacts"; Command2["RequestPermission"] = "request-permission"; Command2["GetPermissions"] = "get-permissions"; Command2["SendHapticFeedback"] = "send-haptic-feedback"; Command2["Share"] = "share"; Command2["Chat"] = "chat"; Command2["CloseMiniApp"] = "close-miniapp"; return Command2; })(Command || {}); var ResponseEvent = /* @__PURE__ */ ((ResponseEvent2) => { ResponseEvent2["MiniAppAttestation"] = "miniapp-attestation"; ResponseEvent2["MiniAppPayment"] = "miniapp-payment"; ResponseEvent2["MiniAppWalletAuth"] = "miniapp-wallet-auth"; ResponseEvent2["MiniAppSendTransaction"] = "miniapp-send-transaction"; ResponseEvent2["MiniAppSignMessage"] = "miniapp-sign-message"; ResponseEvent2["MiniAppSignTypedData"] = "miniapp-sign-typed-data"; ResponseEvent2["MiniAppShareContacts"] = "miniapp-share-contacts"; ResponseEvent2["MiniAppRequestPermission"] = "miniapp-request-permission"; ResponseEvent2["MiniAppGetPermissions"] = "miniapp-get-permissions"; ResponseEvent2["MiniAppSendHapticFeedback"] = "miniapp-send-haptic-feedback"; ResponseEvent2["MiniAppShare"] = "miniapp-share"; ResponseEvent2["MiniAppMicrophone"] = "miniapp-microphone"; ResponseEvent2["MiniAppChat"] = "miniapp-chat"; return ResponseEvent2; })(ResponseEvent || {}); var COMMAND_VERSIONS = { ["attestation" /* Attestation */]: 1, ["pay" /* Pay */]: 1, ["wallet-auth" /* WalletAuth */]: 2, ["send-transaction" /* SendTransaction */]: 2, ["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, ["close-miniapp" /* CloseMiniApp */]: 1 }; var commandAvailability = { ["attestation" /* Attestation */]: 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, ["close-miniapp" /* CloseMiniApp */]: false }; function isCommandAvailable(command) { return commandAvailability[command] ?? false; } 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) { if (window.webkit) { window.webkit?.messageHandlers?.minikit?.postMessage?.(payload); } else if (window.Android) { window.Android?.postMessage?.(JSON.stringify(payload)); } } function isInWorldApp() { return typeof window !== "undefined" && Boolean(window.WorldApp); } var FallbackRequiredError = class extends Error { constructor(command) { super( `${command} requires a fallback function when running outside World App. Provide a fallback option: MiniKit.${command}({ ..., fallback: () => yourFallback() })` ); this.name = "FallbackRequiredError"; } }; var CommandUnavailableError = class extends Error { constructor(command, reason) { const messages = { notInWorldApp: "Not running inside World App", commandNotSupported: "Command not supported in this environment", oldAppVersion: "World App version does not support this command" }; super(`${command} is unavailable: ${messages[reason]}`); this.name = "CommandUnavailableError"; this.reason = reason; } }; // src/events.ts var EventManager = class { constructor() { this.listeners = { ["miniapp-attestation" /* MiniAppAttestation */]: () => { }, ["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 */]: () => { } }; } subscribe(event, handler) { this.listeners[event] = handler; } unsubscribe(event) { delete this.listeners[event]; } trigger(event, payload) { if (!this.listeners[event]) { console.error( `No handler for event ${event}, payload: ${JSON.stringify(payload)}` ); return; } this.listeners[event](payload); } }; // src/commands/fallback.ts var PartialExecutionError = class extends Error { constructor(message, submitted, cause) { super(message); this.name = "PartialExecutionError"; this.submitted = submitted; this.cause = cause; } }; async function executeWithFallback(options) { const { command, nativeExecutor, wagmiFallback, customFallback, requiresFallback = false } = options; const inWorldApp = isInWorldApp(); const commandAvailable = isCommandAvailable(command); let nativeError; if (inWorldApp && commandAvailable) { try { const data = await nativeExecutor(); return { data, executedWith: "minikit" }; } catch (error) { nativeError = error; console.warn(`Native ${command} failed, attempting fallback:`, error); } } if (!inWorldApp && wagmiFallback) { try { const data = await wagmiFallback(); return { data, executedWith: "wagmi" }; } catch (error) { if (error instanceof PartialExecutionError || error instanceof Error && error.name === "PartialExecutionError") { throw error; } console.warn(`Wagmi fallback for ${command} failed:`, error); } } if (!inWorldApp && customFallback) { const data = await customFallback(); return { data, executedWith: "fallback" }; } if (nativeError) { throw nativeError; } if (requiresFallback && !inWorldApp) { throw new FallbackRequiredError(command); } throw new CommandUnavailableError(command, determineFallbackReason(command)); } function determineFallbackReason(command) { if (!isInWorldApp()) { return "notInWorldApp"; } if (!isCommandAvailable(command)) { return "oldAppVersion"; } return "commandNotSupported"; } // src/commands/attestation/types.ts var AttestationErrorCodes = /* @__PURE__ */ ((AttestationErrorCodes2) => { AttestationErrorCodes2["Unauthorized"] = "unauthorized"; AttestationErrorCodes2["AttestationFailed"] = "attestation_failed"; AttestationErrorCodes2["IntegrityFailed"] = "integrity_failed"; AttestationErrorCodes2["InvalidInput"] = "invalid_input"; AttestationErrorCodes2["UnsupportedVersion"] = "unsupported_version"; return AttestationErrorCodes2; })(AttestationErrorCodes || {}); var AttestationError = class extends Error { constructor(error_code) { super(`Attestation failed: ${error_code}`); this.error_code = error_code; this.name = "AttestationError"; } }; // src/commands/attestation/index.ts async function attestation(options, ctx) { const result = await executeWithFallback({ command: "attestation" /* Attestation */, nativeExecutor: () => nativeAttestation(options, ctx), customFallback: options.fallback }); if (result.executedWith === "fallback") { return { executedWith: "fallback", data: result.data }; } return { executedWith: "minikit", data: result.data }; } async function nativeAttestation(options, ctx) { if (!ctx) { ctx = { events: new EventManager(), state: { deviceProperties: {} } }; } if (typeof window === "undefined" || !isCommandAvailable("attestation" /* Attestation */)) { throw new Error( "'attestation' command is unavailable. Check MiniKit.install() or update the app version" ); } if (!options.requestHash || options.requestHash.length === 0) { throw new Error("'attestation' command requires a non-empty requestHash"); } const payload = await new Promise( (resolve, reject) => { try { ctx.events.subscribe("miniapp-attestation" /* MiniAppAttestation */, (response) => { ctx.events.unsubscribe("miniapp-attestation" /* MiniAppAttestation */); resolve(response); }); sendMiniKitEvent({ command: "attestation" /* Attestation */, version: COMMAND_VERSIONS["attestation" /* Attestation */], payload: { request_hash: options.requestHash } }); } catch (error) { reject(error); } } ); if (payload.status === "error") { throw new AttestationError(payload.error_code); } return payload; } // src/commands/chat/types.ts var ChatErrorCodes = /* @__PURE__ */ ((ChatErrorCodes2) => { ChatErrorCodes2["UserRejected"] = "user_rejected"; ChatErrorCodes2["SendFailed"] = "send_failed"; ChatErrorCodes2["GenericError"] = "generic_error"; return ChatErrorCodes2; })(ChatErrorCodes || {}); var ChatError = class extends Error { constructor(error_code) { super(`Chat failed: ${error_code}`); this.error_code = error_code; this.name = "ChatError"; } }; // src/commands/chat/index.ts async function chat(options, ctx) { const result = await executeWithFallback({ command: "chat" /* Chat */, nativeExecutor: () => nativeChat(options, ctx), customFallback: options.fallback }); if (result.executedWith === "fallback") { return { executedWith: "fallback", data: result.data }; } return { executedWith: "minikit", data: result.data }; } async function nativeChat(options, ctx) { if (!ctx) { ctx = { events: new EventManager(), state: { deviceProperties: {} } }; } if (typeof window === "undefined" || !isCommandAvailable("chat" /* Chat */)) { throw new Error( "'chat' command is unavailable. Check MiniKit.install() or update the app version" ); } const payloadInput = { message: options.message, to: options.to }; if (payloadInput.message.length === 0) { throw new Error("'chat' command requires a non-empty message"); } const payload = await new Promise((resolve, reject) => { try { ctx.events.subscribe("miniapp-chat" /* MiniAppChat */, (response) => { ctx.events.unsubscribe("miniapp-chat" /* MiniAppChat */); resolve(response); }); sendMiniKitEvent({ command: "chat" /* Chat */, version: COMMAND_VERSIONS["chat" /* Chat */], payload: payloadInput }); } catch (error) { reject(error); } }); if (payload.status === "error") { throw new ChatError(payload.error_code); } return payload; } // src/commands/close-miniapp/index.ts async function closeMiniApp(options = {}, _ctx) { const result = await executeWithFallback({ command: "close-miniapp" /* CloseMiniApp */, nativeExecutor: () => nativeCloseMiniApp(), customFallback: options.fallback }); if (result.executedWith === "fallback") { return { executedWith: "fallback", data: result.data }; } return { executedWith: "minikit", data: result.data }; } async function nativeCloseMiniApp() { if (typeof window === "undefined" || !isCommandAvailable("close-miniapp" /* CloseMiniApp */)) { throw new Error( "'closeMiniApp' command is unavailable. Check MiniKit.install() or update the app version" ); } sendMiniKitEvent({ command: "close-miniapp" /* CloseMiniApp */, version: COMMAND_VERSIONS["close-miniapp" /* CloseMiniApp */], payload: {} }); return { status: "success", version: COMMAND_VERSIONS["close-miniapp" /* CloseMiniApp */] }; } // src/commands/get-permissions/types.ts var GetPermissionsErrorCodes = /* @__PURE__ */ ((GetPermissionsErrorCodes2) => { GetPermissionsErrorCodes2["GenericError"] = "generic_error"; return GetPermissionsErrorCodes2; })(GetPermissionsErrorCodes || {}); var Permission = /* @__PURE__ */ ((Permission2) => { Permission2["Notifications"] = "notifications"; Permission2["Contacts"] = "contacts"; Permission2["Microphone"] = "microphone"; return Permission2; })(Permission || {}); var GetPermissionsError = class extends Error { constructor(error_code) { super(`Get permissions failed: ${error_code}`); this.error_code = error_code; this.name = "GetPermissionsError"; } }; // src/commands/get-permissions/index.ts async function getPermissions(options, ctx) { const resolvedOptions = options ?? {}; const result = await executeWithFallback({ command: "get-permissions" /* GetPermissions */, nativeExecutor: () => nativeGetPermissions(ctx), customFallback: resolvedOptions.fallback }); if (result.executedWith === "fallback") { return { executedWith: "fallback", data: result.data }; } return { executedWith: "minikit", data: result.data }; } async function nativeGetPermissions(ctx) { if (!ctx) { ctx = { events: new EventManager(), state: { deviceProperties: {} } }; } if (typeof window === "undefined" || !isCommandAvailable("get-permissions" /* GetPermissions */)) { throw new Error( "'getPermissions' command is unavailable. Check MiniKit.install() or update the app version" ); } const payload = await new Promise( (resolve, reject) => { try { ctx.events.subscribe("miniapp-get-permissions" /* MiniAppGetPermissions */, (response) => { ctx.events.unsubscribe("miniapp-get-permissions" /* MiniAppGetPermissions */); resolve(response); }); sendMiniKitEvent({ command: "get-permissions" /* GetPermissions */, version: COMMAND_VERSIONS["get-permissions" /* GetPermissions */], payload: {} }); } catch (error) { reject(error); } } ); if (payload.status === "error") { throw new GetPermissionsError(payload.error_code); } return payload; } // src/commands/pay/types.ts var Tokens = /* @__PURE__ */ ((Tokens2) => { Tokens2["USDC"] = "USDCE"; Tokens2["WLD"] = "WLD"; Tokens2["WARS"] = "WARS"; Tokens2["WCOP"] = "WCOP"; Tokens2["WMXN"] = "WMXN"; Tokens2["WBRL"] = "WBRL"; Tokens2["WPEN"] = "WPEN"; Tokens2["WCLP"] = "WCLP"; Tokens2["EURC"] = "EURC"; return Tokens2; })(Tokens || {}); var TokenDecimals = { ["USDCE" /* USDC */]: 6, ["WLD" /* WLD */]: 18, ["WARS" /* WARS */]: 18, ["WCOP" /* WCOP */]: 18, ["WMXN" /* WMXN */]: 18, ["WBRL" /* WBRL */]: 18, ["WPEN" /* WPEN */]: 18, ["WCLP" /* WCLP */]: 18, ["EURC" /* EURC */]: 6 }; var Network = /* @__PURE__ */ ((Network2) => { Network2["WorldChain"] = "worldchain"; return Network2; })(Network || {}); var PaymentErrorCodes = /* @__PURE__ */ ((PaymentErrorCodes2) => { PaymentErrorCodes2["InputError"] = "input_error"; PaymentErrorCodes2["UserRejected"] = "user_rejected"; PaymentErrorCodes2["PaymentRejected"] = "payment_rejected"; PaymentErrorCodes2["InvalidReceiver"] = "invalid_receiver"; PaymentErrorCodes2["InsufficientBalance"] = "insufficient_balance"; PaymentErrorCodes2["TransactionFailed"] = "transaction_failed"; PaymentErrorCodes2["GenericError"] = "generic_error"; PaymentErrorCodes2["UserBlocked"] = "user_blocked"; return PaymentErrorCodes2; })(PaymentErrorCodes || {}); var PaymentErrorMessage = { ["input_error" /* InputError */]: "There was a problem with this request. Please try again or contact the app owner.", ["user_rejected" /* UserRejected */]: "You have cancelled the payment in World App.", ["payment_rejected" /* PaymentRejected */]: "You've cancelled the payment in World App.", ["invalid_receiver" /* InvalidReceiver */]: "The receiver address is invalid. Please contact the app owner.", ["insufficient_balance" /* InsufficientBalance */]: "You do not have enough balance to complete this transaction.", ["transaction_failed" /* TransactionFailed */]: "The transaction failed. Please try again.", ["generic_error" /* GenericError */]: "Something unexpected went wrong. Please try again.", ["user_blocked" /* UserBlocked */]: "User's region is blocked from making payments." }; var PayError = class extends Error { constructor(code) { super(`Payment failed: ${code}`); this.name = "PayError"; this.code = code; } }; // src/commands/pay/validate.ts var tokenToDecimals = (amount, token) => { const decimals = TokenDecimals[token]; if (decimals === void 0) { throw new Error(`Invalid token: ${token}`); } const factor = 10 ** decimals; const result = amount * factor; if (!Number.isInteger(result)) { throw new Error(`The resulting amount is not a whole number: ${result}`); } return result; }; 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; }; // src/commands/pay/index.ts async function pay(options, ctx) { const result = await executeWithFallback({ command: "pay" /* Pay */, nativeExecutor: () => nativePay(options, ctx), // No Wagmi fallback - pay is native only customFallback: options.fallback }); if (result.executedWith === "fallback") { return { executedWith: "fallback", data: result.data }; } return { executedWith: "minikit", data: result.data }; } async function nativePay(options, ctx) { if (!ctx) { ctx = { events: new EventManager(), state: { deviceProperties: {} } }; } if (typeof window === "undefined" || !isCommandAvailable("pay" /* Pay */)) { throw new Error( "'pay' command is unavailable. Check MiniKit.install() or update the app version" ); } const input = { reference: options.reference, to: options.to, tokens: options.tokens, description: options.description, network: options.network }; if (!validatePaymentPayload(input)) { throw new Error("Invalid payment payload"); } const eventPayload = { ...input, network: "worldchain" /* WorldChain */ }; const finalPayload = await new Promise( (resolve, reject) => { try { ctx.events.subscribe("miniapp-payment" /* MiniAppPayment */, (response) => { ctx.events.unsubscribe("miniapp-payment" /* MiniAppPayment */); resolve(response); }); sendMiniKitEvent({ command: "pay" /* Pay */, version: COMMAND_VERSIONS["pay" /* Pay */], payload: eventPayload }); } catch (error) { reject(error); } } ); if (finalPayload.status === "error") { throw new PayError(finalPayload.error_code); } return { transactionId: finalPayload.transaction_id, reference: finalPayload.reference, from: finalPayload.from, chain: finalPayload.chain, timestamp: finalPayload.timestamp }; } // src/commands/request-permission/types.ts var RequestPermissionErrorCodes = /* @__PURE__ */ ((RequestPermissionErrorCodes2) => { RequestPermissionErrorCodes2["UserRejected"] = "user_rejected"; RequestPermissionErrorCodes2["GenericError"] = "generic_error"; RequestPermissionErrorCodes2["AlreadyRequested"] = "already_requested"; RequestPermissionErrorCodes2["PermissionDisabled"] = "permission_disabled"; RequestPermissionErrorCodes2["AlreadyGranted"] = "already_granted"; RequestPermissionErrorCodes2["UnsupportedPermission"] = "unsupported_permission"; return RequestPermissionErrorCodes2; })(RequestPermissionErrorCodes || {}); var RequestPermissionError = class extends Error { constructor(error_code) { super(`Request permission failed: ${error_code}`); this.error_code = error_code; this.name = "RequestPermissionError"; } }; // src/commands/request-permission/index.ts async function requestPermission(options, ctx) { const result = await executeWithFallback({ command: "request-permission" /* RequestPermission */, nativeExecutor: () => nativeRequestPermission(options, ctx), customFallback: options.fallback }); if (result.executedWith === "fallback") { return { executedWith: "fallback", data: result.data }; } return { executedWith: "minikit", data: result.data }; } async function nativeRequestPermission(options, ctx) { if (!ctx) { ctx = { events: new EventManager(), state: { deviceProperties: {} } }; } if (typeof window === "undefined" || !isCommandAvailable("request-permission" /* RequestPermission */)) { throw new Error( "'requestPermission' command is unavailable. Check MiniKit.install() or update the app version" ); } const payload = await new Promise( (resolve, reject) => { try { ctx.events.subscribe("miniapp-request-permission" /* MiniAppRequestPermission */, (response) => { ctx.events.unsubscribe("miniapp-request-permission" /* MiniAppRequestPermission */); resolve(response); }); sendMiniKitEvent({ command: "request-permission" /* RequestPermission */, version: COMMAND_VERSIONS["request-permission" /* RequestPermission */], payload: { permission: options.permission } }); } catch (error) { reject(error); } } ); if (payload.status === "error") { throw new RequestPermissionError(payload.error_code); } return payload; } // src/commands/send-haptic-feedback/types.ts var SendHapticFeedbackErrorCodes = /* @__PURE__ */ ((SendHapticFeedbackErrorCodes2) => { SendHapticFeedbackErrorCodes2["GenericError"] = "generic_error"; SendHapticFeedbackErrorCodes2["UserRejected"] = "user_rejected"; return SendHapticFeedbackErrorCodes2; })(SendHapticFeedbackErrorCodes || {}); var SendHapticFeedbackError = class extends Error { constructor(error_code) { super(`Send haptic feedback failed: ${error_code}`); this.error_code = error_code; this.name = "SendHapticFeedbackError"; } }; // src/commands/send-haptic-feedback/index.ts async function sendHapticFeedback(options, ctx) { const result = await executeWithFallback({ command: "send-haptic-feedback" /* SendHapticFeedback */, nativeExecutor: () => nativeSendHapticFeedback(options, ctx), customFallback: options.fallback }); if (result.executedWith === "fallback") { return { executedWith: "fallback", data: result.data }; } return { executedWith: "minikit", data: result.data }; } async function nativeSendHapticFeedback(options, ctx) { if (!ctx) { ctx = { events: new EventManager(), state: { deviceProperties: {} } }; } if (typeof window === "undefined" || !isCommandAvailable("send-haptic-feedback" /* SendHapticFeedback */)) { throw new Error( "'sendHapticFeedback' command is unavailable. Check MiniKit.install() or update the app version" ); } const payloadInput = options.hapticsType === "selection-changed" ? { hapticsType: "selection-changed" } : options.hapticsType === "impact" ? { hapticsType: "impact", style: options.style } : { hapticsType: "notification", style: options.style }; const payload = await new Promise( (resolve, reject) => { try { ctx.events.subscribe("miniapp-send-haptic-feedback" /* MiniAppSendHapticFeedback */, (response) => { ctx.events.unsubscribe("miniapp-send-haptic-feedback" /* MiniAppSendHapticFeedback */); resolve(response); }); sendMiniKitEvent({ command: "send-haptic-feedback" /* SendHapticFeedback */, version: COMMAND_VERSIONS["send-haptic-feedback" /* SendHapticFeedback */], payload: payloadInput }); } catch (error) { reject(error); } } ); if (payload.status === "error") { throw new SendHapticFeedbackError(payload.error_code); } return payload; } // src/commands/fallback-adapter-registry.ts var FALLBACK_ADAPTER_KEY = "__minikit_fallback_adapter__"; function getFallbackAdapter() { return globalThis[FALLBACK_ADAPTER_KEY]; } // src/commands/send-transaction/types.ts var SendTransactionErrorCodes = /* @__PURE__ */ ((SendTransactionErrorCodes2) => { SendTransactionErrorCodes2["InvalidOperation"] = "invalid_operation"; SendTransactionErrorCodes2["UserRejected"] = "user_rejected"; SendTransactionErrorCodes2["InputError"] = "input_error"; SendTransactionErrorCodes2["SimulationFailed"] = "simulation_failed"; SendTransactionErrorCodes2["TransactionFailed"] = "transaction_failed"; SendTransactionErrorCodes2["GenericError"] = "generic_error"; SendTransactionErrorCodes2["DisallowedOperation"] = "disallowed_operation"; SendTransactionErrorCodes2["ValidationError"] = "validation_error"; SendTransactionErrorCodes2["InvalidContract"] = "invalid_contract"; SendTransactionErrorCodes2["MaliciousOperation"] = "malicious_operation"; SendTransactionErrorCodes2["DailyTxLimitReached"] = "daily_tx_limit_reached"; SendTransactionErrorCodes2["PermittedAmountExceedsSlippage"] = "permitted_amount_exceeds_slippage"; SendTransactionErrorCodes2["PermittedAmountNotFound"] = "permitted_amount_not_found"; return SendTransactionErrorCodes2; })(SendTransactionErrorCodes || {}); var SendTransactionErrorMessage = { ["invalid_operation" /* InvalidOperation */]: "Transaction included an operation that was invalid", ["user_rejected" /* UserRejected */]: "User rejected the request.", ["input_error" /* InputError */]: "Invalid payload.", ["simulation_failed" /* SimulationFailed */]: "The transaction simulation failed.", ["validation_error" /* ValidationError */]: "The transaction validation failed. Please try again.", ["transaction_failed" /* TransactionFailed */]: "The transaction failed. Please try again later.", ["generic_error" /* GenericError */]: "Something unexpected went wrong. Please try again.", ["disallowed_operation" /* DisallowedOperation */]: "The operation requested is not allowed. Please refer to the docs.", ["invalid_contract" /* InvalidContract */]: "The contract address is not allowed for your application. Please check your developer portal configurations", ["malicious_operation" /* MaliciousOperation */]: "The operation requested is considered malicious.", ["daily_tx_limit_reached" /* DailyTxLimitReached */]: "Daily transaction limit reached. Max 100 transactions per day. Wait until the next day.", ["permitted_amount_exceeds_slippage" /* PermittedAmountExceedsSlippage */]: "Permitted amount exceeds slippage. You must spend at least 90% of the permitted amount.", ["permitted_amount_not_found" /* PermittedAmountNotFound */]: "Permitted amount not found in permit2 payload." }; var WORLD_APP_FEATURES = { batch: true, permit2: true, gasSponsorship: true }; var WEB_FEATURES = { batch: false, permit2: false, gasSponsorship: false }; var SendTransactionError = class extends Error { constructor(code, details) { super(`Transaction failed: ${code}`); this.name = "SendTransactionError"; this.code = code; this.details = details; } }; // src/commands/send-transaction/validate.ts var isValidHex = (str) => { return /^0x[0-9A-Fa-f]+$/.test(str); }; 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 ("chainId" in result && result.chainId !== void 0) { if (typeof result.chainId === "string") { const parsed = Number(result.chainId); if (Number.isFinite(parsed)) { result.chainId = parsed; } } else if (typeof result.chainId === "bigint") { const parsed = Number(result.chainId); if (!Number.isSafeInteger(parsed)) { throw new Error(`Invalid chainId: ${String(result.chainId)}`); } result.chainId = parsed; } } 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)) { if (key === "chainId") continue; result[key] = processPayload(result[key]); } } return result; } return payload; }; var validateSendTransactionPayload = (payload) => { return processPayload(payload); }; // src/commands/send-transaction/index.ts var WORLD_CHAIN_ID = 480; function resolveChainId(options) { return options.chainId; } function resolveTransactions(options) { if (options.transactions.length === 0) { throw new SendTransactionError("input_error" /* InputError */, { reason: "At least one transaction is required. Use `transactions: [{ to, data, value }]`." }); } return options.transactions; } function normalizeSendTransactionOptions(options) { const chainId = resolveChainId(options); if (chainId !== WORLD_CHAIN_ID) { throw new SendTransactionError("invalid_operation" /* InvalidOperation */, { reason: `World App only supports World Chain (chainId: ${WORLD_CHAIN_ID})` }); } return { transactions: resolveTransactions(options), chainId }; } async function sendTransaction(options, ctx) { const normalizedOptions = normalizeSendTransactionOptions(options); const fallbackAdapter = getFallbackAdapter(); const result = await executeWithFallback({ command: "send-transaction" /* SendTransaction */, nativeExecutor: () => nativeSendTransaction(normalizedOptions, ctx), wagmiFallback: fallbackAdapter?.sendTransaction ? () => adapterSendTransactionFallback(normalizedOptions) : void 0, customFallback: options.fallback }); if (result.executedWith === "fallback") { return { executedWith: "fallback", data: result.data }; } if (result.executedWith === "wagmi") { return { executedWith: "wagmi", data: result.data }; } return { executedWith: "minikit", data: result.data }; } async function nativeSendTransaction(options, ctx) { if (!ctx) { ctx = { events: new EventManager(), state: { deviceProperties: {} } }; } if (typeof window === "undefined" || !isCommandAvailable("send-transaction" /* SendTransaction */)) { throw new Error( "'sendTransaction' command is unavailable. Check MiniKit.install() or update the app version" ); } if (options.chainId !== WORLD_CHAIN_ID) { throw new Error( `World App only supports World Chain (chainId: ${WORLD_CHAIN_ID})` ); } const commandInput = window.WorldApp?.supported_commands.find( (command) => command.name === "send-transaction" /* SendTransaction */ ); if (commandInput && !commandInput.supported_versions.includes( COMMAND_VERSIONS["send-transaction" /* SendTransaction */] )) { throw new CommandUnavailableError("send-transaction" /* SendTransaction */, "oldAppVersion"); } const input = { transactions: options.transactions, chainId: options.chainId }; const validatedPayload = validateSendTransactionPayload(input); const finalPayload = await new Promise( (resolve, reject) => { try { ctx.events.subscribe("miniapp-send-transaction" /* MiniAppSendTransaction */, (response) => { ctx.events.unsubscribe("miniapp-send-transaction" /* MiniAppSendTransaction */); resolve(response); }); sendMiniKitEvent({ command: "send-transaction" /* SendTransaction */, version: COMMAND_VERSIONS["send-transaction" /* SendTransaction */], payload: validatedPayload }); } catch (error) { reject(error); } } ); if (finalPayload.status === "error") { throw new SendTransactionError( finalPayload.error_code, finalPayload.details ); } const successPayload = finalPayload; return { userOpHash: String(successPayload.userOpHash ?? ""), status: finalPayload.status, version: finalPayload.version, from: String(successPayload.from ?? ""), timestamp: String(successPayload.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()) }; } async function adapterSendTransactionFallback(options) { const fallbackAdapter = getFallbackAdapter(); if (!fallbackAdapter?.sendTransaction) { throw new Error("Fallback adapter is not registered."); } const result = await fallbackAdapter.sendTransaction({ transactions: options.transactions.map((tx) => ({ address: tx.to, data: tx.data, value: tx.value })), chainId: options.chainId }); return { userOpHash: result.transactionHash, status: "success", version: COMMAND_VERSIONS["send-transaction" /* SendTransaction */], from: "", timestamp: (/* @__PURE__ */ new Date()).toISOString() }; } // src/commands/share/format.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 }; }; // src/commands/share/types.ts var ShareFilesErrorCodes = /* @__PURE__ */ ((ShareFilesErrorCodes2) => { ShareFilesErrorCodes2["UserRejected"] = "user_rejected"; ShareFilesErrorCodes2["GenericError"] = "generic_error"; ShareFilesErrorCodes2["InvalidFileName"] = "invalid_file_name"; return ShareFilesErrorCodes2; })(ShareFilesErrorCodes || {}); var ShareError = class extends Error { constructor(error_code) { super(`Share failed: ${error_code}`); this.error_code = error_code; this.name = "ShareError"; } }; // src/commands/share/index.ts async function share(options, ctx) { const result = await executeWithFallback({ command: "share" /* Share */, nativeExecutor: () => nativeShare(options, ctx), customFallback: options.fallback }); if (result.executedWith === "fallback") { return { executedWith: "fallback", data: result.data }; } return { executedWith: "minikit", data: result.data }; } async function nativeShare(options, ctx) { if (!ctx) { ctx = { events: new EventManager(), state: { deviceProperties: {} } }; } if (typeof window === "undefined" || !isCommandAvailable("share" /* Share */)) { throw new Error( "'share' command is unavailable. Check MiniKit.install() or update the app version" ); } const payloadInput = { files: options.files, title: options.title, text: options.text, url: options.url }; if (ctx.state.deviceProperties.deviceOS === "ios" && typeof navigator !== "undefined") { sendMiniKitEvent({ command: "share" /* Share */, version: COMMAND_VERSIONS["share" /* Share */], payload: payloadInput }); await navigator.share(payloadInput); return { status: "success", version: COMMAND_VERSIONS["share" /* Share */], shared_files_count: payloadInput.files?.length ?? 0, timestamp: (/* @__PURE__ */ new Date()).toISOString() }; } const formattedPayload = await formatShareInput(payloadInput); const payload = await new Promise((resolve, reject) => { try { ctx.events.subscribe("miniapp-share" /* MiniAppShare */, (response) => { ctx.events.unsubscribe("miniapp-share" /* MiniAppShare */); resolve(response); }); sendMiniKitEvent({ command: "share" /* Share */, version: COMMAND_VERSIONS["share" /* Share */], payload: formattedPayload }); } catch (error) { reject(error); } }); if (payload.status === "error") { throw new ShareError(payload.error_code); } return payload; } // src/commands/share-contacts/types.ts var ShareContactsErrorCodes = /* @__PURE__ */ ((ShareContactsErrorCodes2) => { ShareContactsErrorCodes2["UserRejected"] = "user_rejected"; ShareContactsErrorCodes2["GenericError"] = "generic_error"; return ShareContactsErrorCodes2; })(ShareContactsErrorCodes || {}); var ShareContactsErrorMessage = { ["user_rejected" /* UserRejected */]: "User rejected the request.", ["generic_error" /* GenericError */]: "Something unexpected went wrong." }; var ShareContactsError = class extends Error { constructor(code) { super(`Share contacts failed: ${code}`); this.name = "ShareContactsError"; this.code = code; } }; // src/commands/share-contacts/index.ts async function shareContacts(options, ctx) { const resolvedOptions = options ?? {}; const result = await executeWithFallback({ command: "share-contacts" /* ShareContacts */, nativeExecutor: () => nativeShareContacts(resolvedOptions, ctx), // No Wagmi fallback - contacts is native only customFallback: resolvedOptions.fallback }); if (result.executedWith === "fallback") { return { executedWith: "fallback", data: result.data }; } return { executedWith: "minikit", data: result.data }; } var getContacts = shareContacts; async function nativeShareContacts(options, ctx) { if (!ctx) { ctx = { events: new EventManager(), state: { deviceProperties: {} } }; } if (typeof window === "undefined" || !isCommandAvailable("share-contacts" /* ShareContacts */)) { throw new Error( "'shareContacts' command is unavailable. Check MiniKit.install() or update the app version" ); } const payload = { isMultiSelectEnabled: options.isMultiSelectEnabled ?? false, inviteMessage: options.inviteMessage }; const finalPayload = await new Promise( (resolve, reject) => { try { ctx.events.subscribe("miniapp-share-contacts" /* MiniAppShareContacts */, (response) => { ctx.events.unsubscribe("miniapp-share-contacts" /* MiniAppShareContacts */); resolve(response); }); sendMiniKitEvent({ command: "share-contacts" /* ShareContacts */, version: COMMAND_VERSIONS["share-contacts" /* ShareContacts */], payload }); } catch (error) { reject(error); } } ); if (finalPayload.status === "error") { throw new ShareContactsError(finalPayload.error_code); } return { contacts: finalPayload.contacts, timestamp: finalPayload.timestamp }; } // src/commands/sign-message/types.ts var SignMessageErrorCodes = /* @__PURE__ */ ((SignMessageErrorCodes2) => { SignMessageErrorCodes2["InvalidMessage"] = "invalid_message"; SignMessageErrorCodes2["UserRejected"] = "user_rejected"; SignMessageErrorCodes2["GenericError"] = "generic_error"; return SignMessageErrorCodes2; })(SignMessageErrorCodes || {}); var SignMessageError = class extends Error { constructor(error_code) { super(`Sign message failed: ${error_code}`); this.error_code = error_code; this.name = "SignMessageError"; } }; // src/commands/sign-message/index.ts async function signMessage(options, ctx) { const fallbackAdapter = getFallbackAdapter(); const result = await executeWithFallback({ command: "sign-message" /* SignMessage */, nativeExecutor: () => nativeSignMessage(options, ctx), wagmiFallback: fallbackAdapter?.signMessage ? () => fallbackAdapter.signMessage({ message: options.message }) : void 0, customFallback: options.fallback }); if (result.executedWith === "fallback") { return { executedWith: "fallback", data: result.data }; } if (result.executedWith === "wagmi") { return { executedWith: "wagmi", data: result.data }; } return { executedWith: "minikit", data: result.data }; } async function nativeSignMessage(options, ctx) { if (!ctx) { ctx = { events: new EventManager(), state: { deviceProperties: {} } }; } if (typeof window === "undefined" || !isCommandAvailable("sign-message" /* SignMessage */)) { throw new Error( "'signMessage' command is unavailable. Check MiniKit.install() or update the app version" ); } const payload = await new Promise( (resolve, reject) => { try { ctx.events.subscribe("miniapp-sign-message" /* MiniAppSignMessage */, (response) => { ctx.events.unsubscribe("miniapp-sign-message" /* MiniAppSignMessage */); resolve(response); }); sendMiniKitEvent({ command: "sign-message" /* SignMessage */, version: COMMAND_VERSIONS["sign-message" /* SignMessage */], payload: { message: options.message } }); } catch (error) { reject(error); } } ); if (payload.status === "error") { throw new SignMessageError(payload.error_code); } return payload; } // src/commands/sign-typed-data/types.ts var SignTypedDataErrorCodes = /* @__PURE__ */ ((SignTypedDataErrorCodes2) => { SignTypedDataErrorCodes2["InvalidOperation"] = "invalid_operation"; SignTypedDataErrorCodes2["UserRejected"] = "user_rejected"; SignTypedDataErrorCodes2["InputError"] = "input_error"; SignTypedDataErrorCodes2["SimulationFailed"] = "simulation_failed"; SignTypedDataErrorCodes2["GenericError"] = "generic_error"; SignTypedDataErrorCodes2["DisallowedOperation"] = "disallowed_operation"; SignTypedDataErrorCodes2["InvalidContract"] = "invalid_contract"; SignTypedDataErrorCodes2["MaliciousOperation"] = "malicious_operation"; return SignTypedDataErrorCodes2; })(SignTypedDataErrorCodes || {}); var SignTypedDataError = class extends Error { constructor(error_code) { super(`Sign typed data failed: ${error_code}`); this.error_code = error_code; this.name = "SignTypedDataError"; } }; // src/commands/sign-typed-data/index.ts async function signTypedData(options, ctx) { const fallbackAdapter = getFallbackAdapter(); const result = await executeWithFallback({ command: "sign-typed-data" /* SignTypedData */, nativeExecutor: () => nativeSignTypedData(options, ctx), wagmiFallback: fallbackAdapter?.signTypedData ? () => fallbackAdapter.signTypedData({ types: options.types, primaryType: options.primaryType, message: options.message, domain: options.do