@airmoney-degn/controller-sdk
Version:
SDK for controlling AirMoney devices, providing button screen management, key event handling, and device communication capabilities
2 lines (1 loc) • 15.1 kB
JavaScript
(function(r,c){typeof exports=="object"&&typeof module<"u"?c(exports):typeof define=="function"&&define.amd?define(["exports"],c):(r=typeof globalThis<"u"?globalThis:r||self,c(r.AirMoneyControllerSDK={}))})(this,function(r){"use strict";var Q=Object.defineProperty;var X=(r,c,h)=>c in r?Q(r,c,{enumerable:!0,configurable:!0,writable:!0,value:h}):r[c]=h;var i=(r,c,h)=>X(r,typeof c!="symbol"?c+"":c,h);var c=(t=>(t.LeftButton="ArrowLeft",t.RightButton="ArrowRight",t.CounterClockwiseRotary="]",t.ClockwiseRotary="[",t.RotaryButton="Enter",t.SideButton="ArrowUp",t.MuteSwitch="ArrowDown",t))(c||{});class h{constructor(a){i(this,"config",{threshold:300,combinations:void 0,doubleClicks:void 0,debug:!1});i(this,"activeKeys",{});i(this,"timers",{});i(this,"callbacks",[]);i(this,"getCombination",a=>this.config.combinations&&Object.entries(this.config.combinations).find(([,e])=>e.includes(a)));i(this,"getDoubleClick",a=>this.config.doubleClicks&&Object.entries(this.config.doubleClicks).find(([,e])=>e===a));i(this,"debugLog",(...a)=>{this.config.debug&&console.log(...a)});i(this,"onKeyDown",a=>{if(!Object.values(c).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 s=this.getCombination(e);if(s&&s[1].filter(n=>n!==a.key).every(n=>this.activeKeys[n]==="available")){s[1].map(n=>{this.activeKeys[n]="pressed",clearTimeout(this.timers[n])}),this.notifyCallbacks({source:"air-money",type:"key-event",subType:"combinationdown",data:{keys:s[1],name:s[0]}}),this.debugLog("---> COMBINATION DOWN",s);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}}});i(this,"onKeyUp",a=>{if(!Object.values(c).includes(a.key))return;a.preventDefault();const e=a.key;switch(this.activeKeys[e]){case"clicked":{const s=this.getDoubleClick(e);s&&(this.notifyCallbacks({source:"air-money",type:"key-event",subType:"doubleclick",data:{key:e,name:s[0]}}),this.debugLog("---> DOUBLE CLICK",s),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 s=this.getDoubleClick(e),n=this.getCombination(e);if(s)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(n){if(!n[1].filter(y=>y!==e).every(y=>this.activeKeys[y]==="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 s=this.getCombination(e);this.notifyCallbacks({source:"air-money",type:"key-event",subType:"combinationup",data:{keys:s[1],name:s[0]}}),this.debugLog("---> COMBINATION UP",s),s==null||s[1].map(n=>{delete this.activeKeys[n],clearTimeout(this.activeKeys[n])});break}}});i(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 m{constructor(a){i(this,"baseURL");i(this,"createEndpoint",a=>[this.baseURL,a].join("/"));i(this,"createPayload",(a,e)=>({id:new Date().getTime().toString(),jsonrpc:"2.0",method:a,params:e}));i(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 l=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")},w=t=>{const a={};return t.to&&(a.to=l(t.to)),t.value&&(a.value=l(t.value)),t.gasLimit&&(a.gasLimit=l(t.gasLimit)),t.gasPrice&&(a.gasPrice=l(t.gasPrice)),t.maxFeePerGas&&(a.maxFeePerGas=l(t.maxFeePerGas)),t.maxPriorityFeePerGas&&(a.maxPriorityFeePerGas=l(t.maxPriorityFeePerGas)),t.nonce&&(a.nonce=l(t.nonce)),t.chainId&&(a.chainId=l(t.chainId)),t.data&&(a.data=l(t.data)),t.type&&(a.type=l(t.type)),t.gas&&(a.gas=l(t.gas)),t.accessList&&(a.accessList=t.accessList.map(e=>({address:e.address?l(e.address):null,storageKeys:e.storageKeys.map(s=>l(s))}))),a};class M extends m{constructor(){super("http://localhost:5050");i(this,"generateEvmWallet",async()=>{const e=this.createPayload("generateEvmWallet",[]);return await this.request(e)});i(this,"listEvmWallets",async()=>{const e=this.createPayload("listEvmWallets",[]);return await this.request(e)});i(this,"signEvmMessage",async e=>{const s=this.createPayload("signEvmMessage",[e.address,e.message]);return await this.request(s)});i(this,"signEvmTransaction",async e=>{const s=this.createPayload("signEvmTransaction",[e.address,e.transaction,e.chainId]);return await this.request(s)});i(this,"signGeneralEvmTransaction",async e=>{const s=this.createPayload("signGeneralEvmTransaction",[e.address,e.transaction,e.chainId]);return await this.request(s)});i(this,"generateSolanaWallet",async()=>{const e=this.createPayload("generateSolanaWallet",[]);return await this.request(e)});i(this,"listSolanaWallets",async()=>{const e=this.createPayload("listSolanaWallets",[]);return await this.request(e)});i(this,"signSolanaMessage",async e=>{const s=this.createPayload("signSolanaMessage",[e.address,e.message]);return await this.request(s)});i(this,"signSolanaTransaction",async e=>{const s=this.createPayload("signSolanaTransaction",[e]);return await this.request(s)});i(this,"restoreSvmWallet",async e=>{const s=this.createPayload("restoreSvmWallet",[e.mnemonic,e.passphrase||""]);return await this.request(s)});i(this,"signEVMRawTransaction",async e=>{const s=w(e.rawTransaction),n=typeof e.chainId=="number"?l(e.chainId):e.chainId;return await this.signGeneralEvmTransaction({address:e.address,transaction:s,chainId:n})})}}const u="app-launcher",I=()=>{const t=new URLSearchParams;t.set("from",window.location.origin);const a=p(u)+"?"+t.toString();window.location.href=a},v=()=>window.location.protocol==="file:",_=(t=u)=>{window.location.href=p(t)},P=(t=u,a)=>[p(t),a].filter(Boolean).join("/"),p=(t=u)=>`http://${t}.internal`,N=(t=u)=>P(t,"dapp-logo.png");let f=null;const L=async()=>{if(f)return f;try{const t=await fetch("/metadata.json");if(!t.ok)throw new Error("Failed to fetch metadata.json");const a=await t.json();return f=a,a}catch(t){throw new Error(`Failed to load metadata: ${t instanceof Error?t.message:"Unknown error"}`)}},R=async()=>{try{if(v())return"file";try{return(await L()).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}},E={enabled:!1,time:40},O=t=>t==="setImage"||t==="setAnimate";class b extends m{constructor(e){super("http://localhost:4040");i(this,"appName","");i(this,"assetsPath","assets");i(this,"isInitialized",!1);i(this,"throttleConfigs",{});i(this,"createThrottledMethod",(e,s)=>async(...n)=>{const o=this.throttleConfigs[s];if(!o||!o.enabled)return e.apply(this,n);const d=n[0].id.toString();return new Promise(y=>{if(o.lastArgs.set(d,n),!o.timeouts.has(d)){const Y=setTimeout(async()=>{try{const C=o.lastArgs.get(d);if(C){const J=await e.apply(this,C);y(J)}}finally{o.timeouts.delete(d),o.lastArgs.delete(d)}},o.time);o.timeouts.set(d,Y)}})});i(this,"initialize",async()=>{if(!this.isInitialized&&!this.appName){try{this.appName=await R()}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}});i(this,"ensureInitialized",async()=>{this.isInitialized||await this.initialize()});i(this,"scanWifi",async()=>{const e=this.createPayload("scanWifi",[]);return await this.request(e)});i(this,"connectWifi",async e=>{const s=this.createPayload("connectWifi",[e.ssid,e.password]);return await this.request(s)});i(this,"managePairing",async e=>{const s=this.createPayload("managePairing",[e]);return await this.request(s)});i(this,"getPairingStatus",async()=>{const e=this.createPayload("getPairingStatus",[]);return await this.request(e)});i(this,"getBatteryStatus",async()=>{const e=this.createPayload("getBatteryStatus",[]);return await this.request(e)});i(this,"getTemperatureStatus",async()=>{const e=this.createPayload("getTemperatureStatus",[]);return await this.request(e)});i(this,"getBrightness",async()=>{const e=this.createPayload("getBrightness",[]);return await this.request(e)});i(this,"setBrightness",async e=>{const s=this.createPayload("setBrightness",[e]);return await this.request(s)});i(this,"getVolume",async()=>{const e=this.createPayload("getVolume",[]);return await this.request(e)});i(this,"setVolume",async e=>{const s=this.createPayload("setVolume",[e]);return await this.request(s)});i(this,"getWifiStatus",async()=>{const e=this.createPayload("getWifiStatus",[]);return await this.request(e)});i(this,"setImage",this.createThrottledMethod(async e=>{await this.ensureInitialized();const s=this.createPayload("setImage",[this.createImagePathParam(e.imageName),e.id]);return await this.request(s)},"setImage"));i(this,"setAnimate",this.createThrottledMethod(async e=>{await this.ensureInitialized();const s=this.createPayload("setAnimate",[this.createImagePathParam(e.imageName),e.id]);return await this.request(s)},"setAnimate"));i(this,"setMPC",async(e,s)=>{const n=this.createPayload("setMpcSession",[e,s]);return await this.request(n)});i(this,"getMPC",async e=>{const s=this.createPayload("setMpcSession",[e]);return await this.request(s)});i(this,"getHapticEffects",async()=>{const e=this.createPayload("getHapticEffects",[]);return await this.request(e)});i(this,"getHapticConfig",async()=>{const e=this.createPayload("getHapticConfig",[]);return await this.request(e)});i(this,"setHapticEffect",async e=>{const s=this.createPayload("setHapticEffect",[e.action,e.effectId]);return await this.request(s)});i(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(s=>{const n=s[0],o=s[1];O(n)&&(this.throttleConfigs[n]={enabled:o.throttleEnabled??E.enabled,time:o.throttleTime??E.time,timeouts:new Map,lastArgs:new Map})})}}const q=new b({setImage:{throttleEnabled:!0},setAnimate:{throttleEnabled:!0}});class U{constructor(){i(this,"baseURL","http://localhost:6060");i(this,"createEndpoint",a=>`${this.baseURL}${a}`);i(this,"get",async a=>{try{const e=await fetch(this.createEndpoint(a),{method:"GET",headers:{Accept:"application/json"}});if(!e.ok){const d=await e.text();throw new Error(`HTTP error ${e.status}: ${d}`)}const s=e.headers.get("content-type"),n=await e.text();if(!n)return null;let o;if(s!=null&&s.includes("application/json"))try{o=JSON.parse(n)}catch{throw new Error(`Invalid JSON response: ${n.substring(0,100)}...`)}else try{o=JSON.parse(n)}catch{return n}if(o==null)throw new Error("Empty response received");return o}catch(e){throw e instanceof Error?new Error(`Update service error: ${e.message}`):new Error("Unknown error occurred while fetching data")}});i(this,"appVersions",async()=>await this.get("/app/versions"));i(this,"appCheck",async a=>await this.get(`/app/${a}/version`));i(this,"appUpdate",async a=>await this.get(`/app/${a}/update`));i(this,"serviceVersion",async()=>await this.get("/service/version"));i(this,"serviceCheck",async()=>await this.get("/service/check"));i(this,"serviceUpdate",async()=>await this.get("/service/update"));i(this,"firmwareVersion",async()=>await this.get("/firmware/version"));i(this,"internetCheck",async()=>await this.get("/internet/check"));i(this,"appList",async()=>await this.get("/app/list"));i(this,"appRefresh",async a=>await this.get(`/app/${a}/refresh`));i(this,"appRemove",async a=>await this.get(`/app/${a}/remove`))}}var S=(t=>(t.Right="right",t.Left="left",t))(S||{});const W={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"},K={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"},D=t=>!!(t==="true"||Number(t)),B=t=>t!==void 0?/^[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)$/.test(t):!1,k=t=>t.every(a=>a!==void 0),H=t=>{if(k(t))return t},$=t=>"result"in t,A=t=>"error"in t,z=t=>t.status===!0,T=t=>t.status===!1,g=t=>async(...a)=>{const e=await t(...a);if(A(e))throw new Error(e.error.message||"AMService error occurred");return e},G=t=>async(...a)=>{const e=await t(...a);if(T(e))throw new Error(e.error||"AMUpdateService error occurred");return e},V=g,F=g;r.AMKey=c,r.AMServiceScreen=S,r.AM_HAPTIC_ACTION_MAP=K,r.AM_HAPTIC_ACTION_NAME_MAP=W,r.APP_LAUNCHER_NAME=u,r.AirMoneyCryptoService=M,r.AirMoneyKeyEvent=h,r.AirMoneyService=b,r.AirMoneyUpdateService=U,r.airmoneyService=q,r.airmoneyServiceErrorWrapper=F,r.backToHome=I,r.cryptoServiceErrorWrapper=V,r.displayAsset=P,r.errorWrapper=g,r.getAppLink=p,r.getAppLogo=N,r.goToApp=_,r.isAMServiceErrorResponse=A,r.isAMServiceSuccessResponse=$,r.isAMUpdateServiceErrorResponse=T,r.isAMUpdateServiceSuccessResponse=z,r.isFileProtocol=v,r.isParamsValid=k,r.isValidNumber=B,r.normalizeEVMTransaction=w,r.serializeParams=H,r.toBoolean=D,r.toHexString=l,r.updateServiceErrorWrapper=G,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})});