UNPKG

@airmoney-degn/controller-sdk

Version:

SDK for controlling AirMoney devices, providing button screen management, key event handling, and device communication capabilities

582 lines (581 loc) 20.7 kB
var P = Object.defineProperty; var k = (t, a, e) => a in t ? P(t, a, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[a] = e; var s = (t, a, e) => k(t, typeof a != "symbol" ? a + "" : a, e); var u = /* @__PURE__ */ ((t) => (t.LeftButton = "ArrowLeft", t.RightButton = "ArrowRight", t.CounterClockwiseRotary = "]", t.ClockwiseRotary = "[", t.RotaryButton = "Enter", t.SideButton = "ArrowUp", t.MuteSwitch = "ArrowDown", t))(u || {}); class O { constructor(a) { s(this, "config", { threshold: 300, combinations: void 0, doubleClicks: void 0, debug: !1 }); s(this, "activeKeys", {}); s(this, "timers", {}); s(this, "callbacks", []); s(this, "getCombination", (a) => this.config.combinations && Object.entries(this.config.combinations).find(([, e]) => e.includes(a))); s(this, "getDoubleClick", (a) => this.config.doubleClicks && Object.entries(this.config.doubleClicks).find(([, e]) => e === a)); s(this, "debugLog", (...a) => { this.config.debug && console.log(...a); }); s(this, "onKeyDown", (a) => { if (!Object.values(u).includes(a.key)) return; a.preventDefault(); const e = a.key; switch (this.activeKeys[a.key]) { case "pressed": case "clicked": case "end": return; case "over": { this.notifyCallbacks({ source: "air-money", type: "key-event", subType: "longpressdown", data: { key: e } }), this.debugLog("---> LONG PRESS DOWN", e); return; } case void 0: { const i = this.getCombination(e); if (i && i[1].filter((r) => r !== a.key).every((r) => this.activeKeys[r] === "available")) { i[1].map((r) => { this.activeKeys[r] = "pressed", clearTimeout(this.timers[r]); }), this.notifyCallbacks({ source: "air-money", type: "key-event", subType: "combinationdown", data: { keys: i[1], name: i[0] } }), this.debugLog("---> COMBINATION DOWN", i); return; } this.activeKeys[a.key] = "available", this.timers[a.key] = setTimeout(() => { this.notifyCallbacks({ source: "air-money", type: "key-event", subType: "longpressdown", data: { key: e } }), this.debugLog("---> LONG PRESS DOWN", e), this.activeKeys[a.key] = "over"; }, this.config.threshold); break; } } }); s(this, "onKeyUp", (a) => { if (!Object.values(u).includes(a.key)) return; a.preventDefault(); const e = a.key; switch (this.activeKeys[e]) { case "clicked": { const i = this.getDoubleClick(e); i && (this.notifyCallbacks({ source: "air-money", type: "key-event", subType: "doubleclick", data: { key: e, name: i[0] } }), this.debugLog("---> DOUBLE CLICK", i), clearTimeout(this.timers[e]), delete this.activeKeys[a.key]); break; } case "over": { this.notifyCallbacks({ source: "air-money", type: "key-event", subType: "longpressup", data: { key: e } }), this.debugLog("---> LONG PRESS UP", e), clearTimeout(this.timers[e]), delete this.activeKeys[e]; break; } case "available": { const i = this.getDoubleClick(e), r = this.getCombination(e); if (i) this.activeKeys[e] = "clicked", clearTimeout(this.timers[e]), this.timers[e] = setTimeout(() => { this.notifyCallbacks({ source: "air-money", type: "key-event", subType: "press", data: { key: e } }), this.debugLog("---> PRESS", e), delete this.activeKeys[e]; }, this.config.threshold); else if (r) { if (!r[1].filter((l) => l !== e).every((l) => this.activeKeys[l] === "available")) { this.notifyCallbacks({ source: "air-money", type: "key-event", subType: "press", data: { key: e } }), this.debugLog("---> PRESS (immediate, combination not completed)", e), clearTimeout(this.timers[e]), delete this.activeKeys[e]; break; } } else this.notifyCallbacks({ source: "air-money", type: "key-event", subType: "press", data: { key: e } }), this.debugLog("---> PRESS", e), clearTimeout(this.timers[e]), delete this.activeKeys[e]; break; } case "pressed": { const i = this.getCombination(e); this.notifyCallbacks({ source: "air-money", type: "key-event", subType: "combinationup", data: { keys: i[1], name: i[0] } }), this.debugLog("---> COMBINATION UP", i), i == null || i[1].map((r) => { delete this.activeKeys[r], clearTimeout(this.activeKeys[r]); }); break; } } }); s(this, "onSimulatorMessage", (a) => { a.data.source === "air-money" && a.data.type === "key-event" && this.notifyCallbacks(a.data); }); this.updateConfig(a); } updateConfig(a) { Object.assign(this.config, a); } notifyCallbacks(a) { this.callbacks.forEach((e) => e(a)); } on(a) { this.callbacks.push(a), this.callbacks.length === 1 && (window.addEventListener("keydown", this.onKeyDown), window.addEventListener("keyup", this.onKeyUp), window.addEventListener("message", this.onSimulatorMessage)); } off(a) { a ? this.callbacks = this.callbacks.filter((e) => e !== a) : this.callbacks = [], this.callbacks.length === 0 && (window.removeEventListener("keydown", this.onKeyDown), window.removeEventListener("keyup", this.onKeyUp), window.removeEventListener("message", this.onSimulatorMessage)); } getConfig() { return this.config; } } class g { constructor(a) { s(this, "baseURL"); s(this, "createEndpoint", (a) => [this.baseURL, a].join("/")); s(this, "createPayload", (a, e) => ({ id: (/* @__PURE__ */ new Date()).getTime().toString(), jsonrpc: "2.0", method: a, params: e })); s(this, "request", async (a) => await (await fetch(this.createEndpoint(""), { method: "POST", body: JSON.stringify(a), headers: { Accept: "application/json", "Content-Type": "application/json" } })).json()); this.baseURL = a; } } const o = (t) => { if (typeof t == "bigint" || typeof t == "number") return `0x${t.toString(16)}`; if (typeof t == "string") return t.startsWith("0x") ? t : `0x${t}`; throw new Error("Invalid input"); }, b = (t) => { const a = {}; return t.to && (a.to = o(t.to)), t.value && (a.value = o(t.value)), t.gasLimit && (a.gasLimit = o(t.gasLimit)), t.gasPrice && (a.gasPrice = o(t.gasPrice)), t.maxFeePerGas && (a.maxFeePerGas = o(t.maxFeePerGas)), t.maxPriorityFeePerGas && (a.maxPriorityFeePerGas = o(t.maxPriorityFeePerGas)), t.nonce && (a.nonce = o(t.nonce)), t.chainId && (a.chainId = o(t.chainId)), t.data && (a.data = o(t.data)), t.type && (a.type = o(t.type)), t.gas && (a.gas = o(t.gas)), t.accessList && (a.accessList = t.accessList.map((e) => ({ address: e.address ? o(e.address) : null, storageKeys: e.storageKeys.map((i) => o(i)) }))), a; }; class q extends g { constructor() { super("http://localhost:5050"); // EVM Operations s(this, "generateEvmWallet", async () => { const e = this.createPayload("generateEvmWallet", []); return await this.request(e); }); s(this, "listEvmWallets", async () => { const e = this.createPayload("listEvmWallets", []); return await this.request(e); }); s(this, "signEvmMessage", async (e) => { const i = this.createPayload("signEvmMessage", [e.address, e.message]); return await this.request(i); }); s(this, "signEvmTransaction", async (e) => { const i = this.createPayload("signEvmTransaction", [e.address, e.transaction, e.chainId]); return await this.request(i); }); s(this, "signGeneralEvmTransaction", async (e) => { const i = this.createPayload("signGeneralEvmTransaction", [ e.address, e.transaction, e.chainId ]); return await this.request(i); }); // Solana Operations s(this, "generateSolanaWallet", async () => { const e = this.createPayload("generateSolanaWallet", []); return await this.request(e); }); s(this, "listSolanaWallets", async () => { const e = this.createPayload("listSolanaWallets", []); return await this.request(e); }); s(this, "signSolanaMessage", async (e) => { const i = this.createPayload("signSolanaMessage", [e.address, e.message]); return await this.request(i); }); s(this, "signSolanaTransaction", async (e) => { const i = this.createPayload("signSolanaTransaction", [e]); return await this.request(i); }); s(this, "restoreSvmWallet", async (e) => { const i = this.createPayload("restoreSvmWallet", [e.mnemonic, e.passphrase || ""]); return await this.request(i); }); s(this, "signEVMRawTransaction", async (e) => { const i = b(e.rawTransaction), r = typeof e.chainId == "number" ? o(e.chainId) : e.chainId; return await this.signGeneralEvmTransaction({ address: e.address, transaction: i, chainId: r }); }); } } const h = "app-launcher", U = () => { const t = new URLSearchParams(); t.set("from", window.location.origin); const a = y(h) + "?" + t.toString(); window.location.href = a; }, E = () => window.location.protocol === "file:", W = (t = h) => { window.location.href = y(t); }, S = (t = h, a) => [y(t), a].filter(Boolean).join("/"), y = (t = h) => `http://${t}.internal`, D = (t = h) => S(t, "dapp-logo.png"); let d = null; const A = async () => { if (d) return d; try { const t = await fetch("/metadata.json"); if (!t.ok) throw new Error("Failed to fetch metadata.json"); const a = await t.json(); return d = a, a; } catch (t) { throw new Error(`Failed to load metadata: ${t instanceof Error ? t.message : "Unknown error"}`); } }, C = async () => { try { if (E()) return "file"; try { return (await A()).name; } catch { throw new Error("Could not determine application identifier in unbundled environment"); } } catch { if (window.AIRMONEY_APP_ID === void 0) throw new Error("Neither metadata.json nor AIRMONEY_APP_ID is available"); return window.AIRMONEY_APP_ID; } }, f = { enabled: !1, time: 40 }, I = (t) => t === "setImage" || t === "setAnimate"; class T extends g { constructor(e) { super("http://localhost:4040"); s(this, "appName", ""); s(this, "assetsPath", "assets"); s(this, "isInitialized", !1); s(this, "throttleConfigs", {}); s(this, "createThrottledMethod", (e, i) => async (...r) => { const n = this.throttleConfigs[i]; if (!n || !n.enabled) return e.apply(this, r); const c = r[0].id.toString(); return new Promise((l) => { if (n.lastArgs.set(c, r), !n.timeouts.has(c)) { const w = setTimeout(async () => { try { const p = n.lastArgs.get(c); if (p) { const v = await e.apply(this, p); l(v); } } finally { n.timeouts.delete(c), n.lastArgs.delete(c); } }, n.time); n.timeouts.set(c, w); } }); }); s(this, "initialize", async () => { if (!this.isInitialized && !this.appName) { try { this.appName = await C(); } catch { if (window.AIRMONEY_APP_ID === void 0) throw new Error("Neither identifier from metadata.json nor AIRMONEY_APP_ID is available"); this.appName = window.AIRMONEY_APP_ID; } if (!this.appName) throw new Error("Neither identifier from metadata.json nor AIRMONEY_APP_ID is available"); this.isInitialized = !0; } }); s(this, "ensureInitialized", async () => { this.isInitialized || await this.initialize(); }); s(this, "scanWifi", async () => { const e = this.createPayload("scanWifi", []); return await this.request(e); }); s(this, "connectWifi", async (e) => { const i = this.createPayload("connectWifi", [e.ssid, e.password]); return await this.request(i); }); s(this, "managePairing", async (e) => { const i = this.createPayload("managePairing", [e]); return await this.request(i); }); s(this, "getPairingStatus", async () => { const e = this.createPayload("getPairingStatus", []); return await this.request(e); }); s(this, "getBatteryStatus", async () => { const e = this.createPayload("getBatteryStatus", []); return await this.request(e); }); s(this, "getTemperatureStatus", async () => { const e = this.createPayload("getTemperatureStatus", []); return await this.request(e); }); s(this, "getBrightness", async () => { const e = this.createPayload("getBrightness", []); return await this.request(e); }); s(this, "setBrightness", async (e) => { const i = this.createPayload("setBrightness", [e]); return await this.request(i); }); s(this, "getVolume", async () => { const e = this.createPayload("getVolume", []); return await this.request(e); }); s(this, "setVolume", async (e) => { const i = this.createPayload("setVolume", [e]); return await this.request(i); }); s(this, "getWifiStatus", async () => { const e = this.createPayload("getWifiStatus", []); return await this.request(e); }); s(this, "setImage", this.createThrottledMethod( async (e) => { await this.ensureInitialized(); const i = this.createPayload("setImage", [ this.createImagePathParam(e.imageName), e.id ]); return await this.request(i); }, "setImage" )); s(this, "setAnimate", this.createThrottledMethod( async (e) => { await this.ensureInitialized(); const i = this.createPayload("setAnimate", [ this.createImagePathParam(e.imageName), e.id ]); return await this.request(i); }, "setAnimate" )); /** * @deprecated MPC functionality is deprecated and will be removed in a future version */ s(this, "setMPC", async (e, i) => { const r = this.createPayload("setMpcSession", [e, i]); return await this.request(r); }); /** * @deprecated MPC functionality is deprecated and will be removed in a future version */ s(this, "getMPC", async (e) => { const i = this.createPayload("setMpcSession", [e]); return await this.request(i); }); s(this, "getHapticEffects", async () => { const e = this.createPayload("getHapticEffects", []); return await this.request(e); }); s(this, "getHapticConfig", async () => { const e = this.createPayload("getHapticConfig", []); return await this.request(e); }); s(this, "setHapticEffect", async (e) => { const i = this.createPayload("setHapticEffect", [e.action, e.effectId]); return await this.request(i); }); s(this, "createImagePathParam", (e) => { if (!this.appName) throw new Error("App name is required"); return [this.appName, this.assetsPath, e].filter(Boolean).join("/"); }); e && Object.entries(e).forEach((i) => { const r = i[0], n = i[1]; I(r) && (this.throttleConfigs[r] = { enabled: n.throttleEnabled ?? f.enabled, time: n.throttleTime ?? f.time, timeouts: /* @__PURE__ */ new Map(), lastArgs: /* @__PURE__ */ new Map() }); }); } } const K = new T({ setImage: { throttleEnabled: !0 }, setAnimate: { throttleEnabled: !0 } }); class x { constructor() { s(this, "baseURL", "http://localhost:6060"); s(this, "createEndpoint", (a) => `${this.baseURL}${a}`); s(this, "get", async (a) => { try { const e = await fetch(this.createEndpoint(a), { method: "GET", headers: { Accept: "application/json" } }); if (!e.ok) { const c = await e.text(); throw new Error(`HTTP error ${e.status}: ${c}`); } const i = e.headers.get("content-type"), r = await e.text(); if (!r) return null; let n; if (i != null && i.includes("application/json")) try { n = JSON.parse(r); } catch { throw new Error(`Invalid JSON response: ${r.substring(0, 100)}...`); } else try { n = JSON.parse(r); } catch { return r; } if (n == null) throw new Error("Empty response received"); return n; } catch (e) { throw e instanceof Error ? new Error(`Update service error: ${e.message}`) : new Error("Unknown error occurred while fetching data"); } }); s(this, "appVersions", async () => await this.get("/app/versions")); s(this, "appCheck", async (a) => await this.get(`/app/${a}/version`)); s(this, "appUpdate", async (a) => await this.get(`/app/${a}/update`)); s(this, "serviceVersion", async () => await this.get("/service/version")); s(this, "serviceCheck", async () => await this.get("/service/check")); s(this, "serviceUpdate", async () => await this.get("/service/update")); s(this, "firmwareVersion", async () => await this.get("/firmware/version")); s(this, "internetCheck", async () => await this.get("/internet/check")); s(this, "appList", async () => await this.get("/app/list")); s(this, "appRefresh", async (a) => await this.get(`/app/${a}/refresh`)); s(this, "appRemove", async (a) => await this.get(`/app/${a}/remove`)); } } var _ = /* @__PURE__ */ ((t) => (t.Right = "right", t.Left = "left", t))(_ || {}); const B = { balance_effect: "Balance action", depin_effect: "Depin action", left_effect: "Left button press", right_effect: "Right button press", rotary_click_effect: "Rotary encoder click", rotary_turn_effect: "Rotary encoder turning", shift_effect: "Shift action" }, $ = { balance_effect: "balance", depin_effect: "depin", left_effect: "left", right_effect: "right", rotary_click_effect: "rotary_click", rotary_turn_effect: "rotary_turn", shift_effect: "shift" }, G = (t) => !!(t === "true" || Number(t)), H = (t) => t !== void 0 ? /^[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)$/.test(t) : !1, N = (t) => t.every((a) => a !== void 0), z = (t) => { if (N(t)) return t; }, F = (t) => "result" in t, L = (t) => "error" in t, V = (t) => t.status === !0, M = (t) => t.status === !1, m = (t) => async (...a) => { const e = await t(...a); if (L(e)) throw new Error(e.error.message || "AMService error occurred"); return e; }, Y = (t) => async (...a) => { const e = await t(...a); if (M(e)) throw new Error(e.error || "AMUpdateService error occurred"); return e; }, J = m, Q = m; export { u as AMKey, _ as AMServiceScreen, $ as AM_HAPTIC_ACTION_MAP, B as AM_HAPTIC_ACTION_NAME_MAP, h as APP_LAUNCHER_NAME, q as AirMoneyCryptoService, O as AirMoneyKeyEvent, T as AirMoneyService, x as AirMoneyUpdateService, K as airmoneyService, Q as airmoneyServiceErrorWrapper, U as backToHome, J as cryptoServiceErrorWrapper, S as displayAsset, m as errorWrapper, y as getAppLink, D as getAppLogo, W as goToApp, L as isAMServiceErrorResponse, F as isAMServiceSuccessResponse, M as isAMUpdateServiceErrorResponse, V as isAMUpdateServiceSuccessResponse, E as isFileProtocol, N as isParamsValid, H as isValidNumber, b as normalizeEVMTransaction, z as serializeParams, G as toBoolean, o as toHexString, Y as updateServiceErrorWrapper };