@worldcoin/minikit-js
Version:
minikit-js is our SDK for building mini-apps.
1,416 lines (1,385 loc) • 61.1 kB
JavaScript
"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