@ada-anvil/weld-plugin-hodei 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cdn.min.js +2 -2
- package/package.json +2 -2
package/cdn.min.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var HodeiPlugin=function(b,p){"use strict";var ce=Object.defineProperty;var de=(b,p,w)=>p in b?ce(b,p,{enumerable:!0,configurable:!0,writable:!0,value:w}):b[p]=w;var g=(b,p,w)=>de(b,typeof p!="symbol"?p+"":p,w);async function w(e){const{baseUrl:t,apiKey:n}=e.config.anvil[e.network],o=new URL(`${t}/wallets/utxos`);return o.searchParams.set("address",e.address),o.searchParams.set("includeMempool","true"),(await fetch(o,{headers:{"x-api-key":n}})).json()}async function H(e){const{baseUrl:t,apiKey:n}=e.config.anvil[e.network],o=new URL(`${t}/wallets/balance`);return o.searchParams.set("address",e.address),(await fetch(o,{headers:{"x-api-key":n}})).json()}async function j(e){const{baseUrl:t,apiKey:n}=e.config.anvil[e.network];return(await fetch(`${t}/transactions/submit`,{method:"POST",headers:{"x-api-key":n,"content-type":"application/json"},body:JSON.stringify({transaction:e.transaction,signatures:e.signature?[e.signature]:[]})})).json()}const C="hodei-token";function x(){return localStorage.getItem(C)??void 0}function q(e){localStorage.setItem(C,e)}function U(){localStorage.removeItem(C)}function E(){let e="pending",t=()=>{},n=()=>{};const o=new Promise((i,d)=>{t=l=>{e="resolved",i(l)},n=l=>{e="rejected",d(l)}});return{status:e,promise:o,resolve:t,reject:n}}function f(e){if(e){if((e instanceof Error||L(e,"message"))&&typeof e.message=="string"&&e.message.length>0)return e.message;if(L(e,"data")&&L(e.data,"message")&&typeof e.data.message=="string"&&e.data.message.length>0)return e.data.message;if(typeof e=="string"&&e.length>0)return e}}function L(e,t){return typeof e=="object"&&e!==null&&t in e}class D{constructor(t){g(this,"_config");g(this,"_onStateChange");g(this,"_debug");g(this,"_connectPromise");g(this,"_connection");g(this,"_attempts",0);g(this,"_reconnectTimer");var n;this._config=t.config,this._onStateChange=t.onStateChange,this._debug=((n=t.config)==null?void 0:n.debug)??!1}setDebug(t){this._debug=t}debugLog(...t){if(!this._debug)return;let n="[HODEI]";this.connection&&(n+=` (${this.connection.id})`),console.log(n,...t)}get connection(){return this._connection}isConnected(){var t,n;return((t=this.connection)==null?void 0:t.state.status)==="paired"||((n=this.connection)==null?void 0:n.state.status)==="pairing"}async connect(){if(this._connectPromise)return this._connectPromise;if(this.isConnected())return this.connection.state;this._connectPromise=this._connect();try{return await this._connectPromise}finally{this._connectPromise=void 0}}disconnect(){var t;(t=this._connection)==null||t.ws.close(1e3,"disconnected"),this._connection=void 0}unlink(){this.send({type:"client.session_unlinked",payload:{}})}getState(){var t;return(t=this.connection)==null?void 0:t.state}async _connect(){var k,a,r,u;(k=this._connection)==null||k.ws.close(1e3,"disconnected");const t=this._config.bridge.baseUrl.replace("http","ws"),n=new URL(`${t}/client/ws`),o=await this._getToken();o&&n.searchParams.set("token",o);const i=(((a=this.connection)==null?void 0:a.id)??0)+1,d=new WebSocket(n),l=new AbortController,m=E();this.debugLog("connecting"),d.addEventListener("message",c=>{try{const s=JSON.parse(c.data);z(s),this.debugLog("received connection message"),m.resolve(s.payload)}catch(s){m.reject(`Error parsing connection message ${c.data}: ${f(s)}`)}finally{l.abort()}},{signal:l.signal}),d.addEventListener("error",c=>{this.debugLog("received connection error"),m.reject(`Error connecting: ${f(c)}`),l.abort()},{signal:l.signal});try{const c=await m.promise;this.debugLog("connected"),q(c.token);const s={id:i,ws:d,state:c,controller:((r=this._connection)==null?void 0:r.controller)??new AbortController,events:((u=this._connection)==null?void 0:u.events)??new EventTarget};return this._connection=s,this._onStateChange(s.state),d.addEventListener("message",h=>{var $;try{if(s.state.status==="error")throw new Error("Received message after error");if(s.state.status==="closed")throw new Error("Received message after closed");const y=JSON.parse(h.data);P(y),($=this._connection)==null||$.events.dispatchEvent(new CustomEvent("message",{detail:y})),y.type==="client.wallet_updated"&&(this.debugLog("received wallet_updated message"),s.state={...y.payload,status:"paired",sessionId:s.state.sessionId,token:s.state.token},this._onStateChange(s.state))}catch(y){this.debugLog(`error parsing message ${h.data}: ${f(y)}`)}},{signal:s.controller.signal}),d.addEventListener("error",h=>{if(this._scheduleReconnect()){this.debugLog("scheduled reconnect after error");return}this.debugLog(`received error: ${f(h)}`),s.state={status:"error",error:f(h)},this._onStateChange(s.state),s.controller.abort()},{signal:s.controller.signal}),d.addEventListener("close",async h=>{if(h.code===4001&&(this.debugLog("session deleted"),U()),h.code!==1e3&&this._scheduleReconnect()){this.debugLog("scheduled reconnect after close");return}this.debugLog(`received close: ${h.code} ${h.reason}`),s.state={status:"closed",reason:h.reason,code:h.code},this._onStateChange(s.state),s.controller.abort()},{signal:s.controller.signal}),this._attempts=0,c}catch(c){throw d.close(void 0,`failed to connect: ${f(c)}`),c}}send(t){var n;(n=this.connection)==null||n.ws.send(JSON.stringify(t))}_scheduleReconnect(){this._reconnectTimer&&(this.debugLog("clearing reconnect timer"),clearTimeout(this._reconnectTimer)),this._attempts=Math.min(this._attempts+1,5);const t=2**this._attempts*1e3;this.debugLog(`reconnecting in ${t/1e3}s`);const n=setTimeout(()=>{if(this._reconnectTimer!==n){this.debugLog("reconnect timer cleared. ignoring");return}this.debugLog("reconnecting"),this._reconnectTimer=void 0,this._connect().catch(()=>this._scheduleReconnect())},t);return this._reconnectTimer=n,!0}async _getToken(){const t=x();if(!t)return;const n=await A({config:this._config,token:t});if(this.debugLog(`checked token: ${n.valid?"valid":`invalid: ${n.reason}`}`),n.valid)return t;if(n.reason==="tooManyConnections")throw new Error("Too many connections");n.reason==="notFound"&&U()}}async function A(e){const t=new URL(`${e.config.bridge.baseUrl}/client/check`),n=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${e.token}`}});return n.status===404?{valid:!1,reason:"notFound"}:n.status===409?{valid:!1,reason:"tooManyConnections"}:{valid:!0,token:e.token}}function _(e){return typeof e=="object"&&e!==null}function O(e){return _(e)&&(e.status==="pairing"||e.status==="paired")}function z(e){if(!_(e)||e.type!=="client.connected"||!O(e.payload))throw new Error("Invalid connected message")}const R=new Set(["client.wallet_updated","client.sig_req_accepted","client.sig_req_rejected"]);function P(e){if(!_(e)||typeof e.type!="string"||!R.has(e.type))throw new Error("Invalid incoming message")}function W(e){if(!_(e)||e.type!=="client.sig_req_accepted"&&e.type!=="client.sig_req_rejected")throw new Error("Invalid sig req response")}const M=new Set(["pairing","paired","closed","error"]);function N(e){return _(e)&&typeof e.status=="string"&&M.has(e.status)}function S(e,t){e.dispatchEvent(new CustomEvent("command",{detail:t}))}function I(e,t,n){const o=i=>{const d=J(i);d&&t(d)};return e.addEventListener("command",o,n),()=>{e.removeEventListener("command",o,n)}}function J(e){if(e instanceof CustomEvent)return K(e.detail)?e.detail:void 0}const F=new Set(["disconnecting","disconnected","unlinked","dialog_closed"]);function K(e){if(typeof e!="object"||e===null)return!1;const t=e;return typeof t.type!="string"?!1:F.has(t.type)?!0:t.type==="state_changed"&&N(t.payload)}const G={bridge:{baseUrl:"https://bridge.hodei.io/api/dev"},anvil:{mainnet:{baseUrl:"https://prod.api.ada-anvil.app/v2/services",apiKey:"mainnet_IIrhwohjiEAJ2LFOgI8p5F735xz4C6XsgH6KfzpC"},preprod:{baseUrl:"https://preprod.api.ada-anvil.app/v2/services",apiKey:"testnet_C301LOscFsUccwR4zCqEtTJvizEAUc3AaVhRDdcY"}},debug:!1,waitForPairing:!0,onError:({error:e})=>console.error("[HODEI] unhandled error:",e??"unknown"),onClose:({code:e,reason:t})=>console.error("[HODEI] unhandled closure:",e,t)},V={refused:1,failure:2};function B(e,t){return{code:V[e],info:f(t)??"unknown"}}const X={invalidRequest:-1,internalError:-2,refused:-3,accountChange:-4};function v(e,t){return{code:X[e],info:f(t)??"unknown"}}const Y={proofGeneration:1,userDeclined:2};function Q(e,t){let n=f(t)??"unknown";for(const o of["ProofGeneration: ","UserDeclined: "])if(n.startsWith(o)){n=n.slice(o.length);break}return n==="UserDeclined"&&(n="User declined"),n==="ProofGeneration"&&(n="Unable to sign the transaction"),{code:Y[e],info:n}}function Z(e){if(!(typeof window>"u"))return window.cardano||(window.cardano={}),"hodei"in window.cardano||(window.cardano.hodei=ee(e)),window.cardano.hodei}function ee(e={}){const t={config:{...G,...e}},n=async o=>{var i,d,l,m;await((i=t.promise)==null?void 0:i.catch(()=>{})),o.status==="error"&&t.config.onError(o),o.status==="closed"&&t.config.onClose(o),o.status==="paired"&&((l=(d=t.config).onWalletUpdate)==null||l.call(d,{baseAddress:o.baseAddress,stakeAddress:o.stakeAddress,network:o.network})),t.resolved?(m=t.resolved)==null||m.client.sendCommand({sender:"wallet",type:"state_changed",payload:o}):console.error("[HODEI] (state_changed)",o)};return{name:"hodei",icon:"https://raw.githubusercontent.com/cardano-forge/weld/main/images/wallets/hodei.png",apiVersion:"1",async enable(){var o;if((o=t.resolved)!=null&&o.bridge.isConnected())return t.resolved.api;t.promise||(t.promise=te({config:t.config,onStateChange:n}));try{const i=await t.promise;return t.resolved=i,t.config.waitForPairing?await i.pairingPromise:i.pairingPromise.catch(()=>{}),i.api}finally{t.promise=void 0}},async isEnabled(){if(t.promise)try{return await t.promise,!0}catch{return!1}if(t.resolved)return t.resolved.bridge.isConnected();const o=x();if(!o)return!1;try{return(await A({config:t.config,token:o})).valid}catch{return!1}}}}async function te(e){var m,k;const t=await ne(),n=new D(e);await n.connect(),I(t.element,a=>{var r;if(a.sender==="client")switch(a.type){case"dialog_closed":{((r=n.getState())==null?void 0:r.status)==="pairing"&&n.disconnect();break}case"disconnected":{n.disconnect();break}case"unlinked":{n.unlink();break}default:{n.debugLog(`unhandled command received from client: ${JSON.stringify(a)}`);break}}},{signal:(m=n.connection)==null?void 0:m.controller.signal});const o=()=>{const a=n.getState();if((a==null?void 0:a.status)!=="paired")throw v("refused",new Error("Wallet is not connected"));return a},i=async a=>{if(o(),!n.isConnected())throw v("refused",new Error("Wallet is not connected"));const r=new AbortController;n.connection.controller.signal.addEventListener("abort",()=>r.abort(),{signal:r.signal});const u=E();return r.signal.addEventListener("abort",()=>{u.reject("aborted")}),n.connection.events.addEventListener("message",c=>{if(c instanceof CustomEvent)try{const s=c.detail;if(W(s),s.payload.requestId!==a.requestId)return;n.send({type:"client.sig_req_ack",payload:{requestId:s.payload.requestId}}),s.type==="client.sig_req_accepted"?u.resolve(s.payload.signature):u.reject(s.payload.reason),r.abort()}catch(s){n.debugLog(`error parsing message ${c.detail}: ${f(s)}`)}},{signal:r.signal}),n.send({type:"client.sig_req_created",payload:a}),u.promise},d={getNetworkId:async()=>o().network==="mainnet"?1:0,getUtxos:async()=>{const a=o();try{return await w({config:e.config,network:a.network,address:a.baseAddress})}catch(r){throw v("internalError",r)}},getBalance:async()=>{const a=o();try{return await H({config:e.config,network:a.network,address:a.baseAddress})}catch(r){throw v("internalError",r)}},getUsedAddresses:async()=>[o().baseAddress],getUnusedAddresses:async()=>[],getChangeAddress:async()=>o().baseAddress,getRewardAddresses:async()=>[o().stakeAddress],signTx:async(a,r=!1)=>{try{return await i({requestId:crypto.randomUUID(),tx:a,partialSign:r,capabilities:["ack"]})}catch(u){const c=f(u),s=c!=null&&c.startsWith("ProofGeneration")?"proofGeneration":"userDeclined";throw Q(s,c)}},signData:async(a,r)=>{const u=await i({requestId:crypto.randomUUID(),address:a,data:r,capabilities:["ack"]}),[c,s]=u.split("::");if(!c||!s)throw v("internalError",new Error("Invalid signature"));return{signature:c,key:s}},submitTx:async a=>{const r=o();try{return(await j({config:e.config,network:r.network,transaction:a})).txHash}catch(u){throw B("failure",u)}},disconnect:async()=>{t.sendCommand({sender:"wallet",type:"disconnecting"})}},l=E();if(n.connection&&((k=n.getState())==null?void 0:k.status)==="pairing"){const a=new AbortController;n.connection.controller.signal.addEventListener("abort",()=>{a.abort(),l.reject(new Error("Aborted"))},{signal:a.signal}),n.connection.events.addEventListener("message",r=>{if(r instanceof CustomEvent)try{const u=r.detail;P(u),u.type==="client.wallet_updated"&&(l.resolve(),a.abort())}catch{}},{signal:a.signal})}else l.resolve();return{api:d,bridge:n,client:t,pairingPromise:l.promise}}async function ne(){if(!customElements.get("hodei-client")){const t=await Promise.resolve().then(()=>re);customElements.define("hodei-client",t.HodeiClient)}let e=document.querySelector("hodei-client")??void 0;if(!e){e=document.createElement("hodei-client");const t=E();e.addEventListener("mounted",()=>t.resolve(),{once:!0}),document.body.appendChild(e),await t.promise}return{element:e,sendCommand:t=>S(e,t)}}class T extends p.DefaultWalletHandler{async disconnect(){var t;if("disconnect"in this.enabledApi&&typeof this.enabledApi.disconnect=="function")return(t=this.enabledApi)==null?void 0:t.disconnect()}}function oe(e){return{key:"hodei",connector:p.getDefaultWalletConnector(T),initialize:p.runOnce(t=>Z({debug:t.config.debug,...e,onError:o=>{var i;t.config.debug&&console.error("[WELD] Hodei socket error, disconnecting.",o),(i=e==null?void 0:e.onError)==null||i.call(e,o,t),t.wallet.disconnect()},onClose:o=>{var i;t.config.debug&&console.error("[WELD] Hodei socket closed, disconnecting.",o),(i=e==null?void 0:e.onClose)==null||i.call(e,o,t),t.wallet.disconnect()},onWalletUpdate:o=>{var i;t.config.debug&&console.log("[WELD] Hodei wallet updated, updating state.",o),(i=e==null?void 0:e.onWalletUpdate)==null||i.call(e,o,t),t.wallet.updateState()}})?(t.extensions.registerWallets([{supported:!0,key:"hodei",displayName:"Hodei",icon:"https://raw.githubusercontent.com/cardano-forge/weld/main/images/wallets/hodei.png",website:"https://github.com/cardano-forge/hodei-client",supportsTxChaining:!1}]),!0):!1)}}const se="*{box-sizing:border-box}:host{font-family:Roboto,Arial,Helvetica,sans-serif;pointer-events:auto}dialog{width:100%;max-width:300px;outline:none;border:none;padding:24px;background:transparent}dialog::backdrop{background:#00000052}article{padding:24px;border-radius:22px;display:flex;flex-direction:column;align-items:center;justify-content:center;flex:1;overflow:hidden;text-align:center;background:linear-gradient(to bottom right,#ebdee8,#fff7fa);color:#1e191e}h1{margin:12px 0 16px;font-size:20px;font-weight:400}p{margin:0;font-size:14px}h2{margin:0 0 24px;font-size:24px;font-weight:600;letter-spacing:.2em}img{width:75px;height:75px}button{--bg: #69548e;--fg: #ffffff;background:var(--bg);color:var(--fg);outline:none;border:none;height:32px;padding:0 12px;border-radius:24px;position:relative;overflow:hidden;transition:all .2s ease-in-out}button:hover{cursor:pointer;--bg: #746197;--fg: #ffffff}button.tonal{--bg: #e8dff8;--fg: #1e182b}button.tonal:hover{--bg: #d9cfe7;--fg: #1f182b}footer{margin-top:24px}@media(prefers-color-scheme:dark){article{background:linear-gradient(to bottom right,#362a36,#181215);color:#eadfe6}button{--bg: #d3bcfd;--fg: #37265c}button:hover{--bg: #c6b0f0;--fg: #37265c}button.tonal{--bg: #4b4358;--fg: #e8dff8}button.tonal:hover{--bg: #574f63;--fg: #e9def8}}",ie=`<dialog></dialog>
|
|
1
|
+
var HodeiPlugin=function(b,p){"use strict";var le=Object.defineProperty;var ue=(b,p,w)=>p in b?le(b,p,{enumerable:!0,configurable:!0,writable:!0,value:w}):b[p]=w;var g=(b,p,w)=>ue(b,typeof p!="symbol"?p+"":p,w);async function w(e){const{baseUrl:t,apiKey:n}=e.config.anvil[e.network],o=new URL(`${t}/wallets/utxos`);return o.searchParams.set("address",e.address),o.searchParams.set("includeMempool","true"),(await fetch(o,{headers:{"x-api-key":n}})).json()}async function D(e){const{baseUrl:t,apiKey:n}=e.config.anvil[e.network],o=new URL(`${t}/wallets/balance`);return o.searchParams.set("address",e.address),(await fetch(o,{headers:{"x-api-key":n}})).json()}async function j(e){const{baseUrl:t,apiKey:n}=e.config.anvil[e.network];return(await fetch(`${t}/transactions/submit`,{method:"POST",headers:{"x-api-key":n,"content-type":"application/json"},body:JSON.stringify({transaction:e.transaction,signatures:e.signature?[e.signature]:[]})})).json()}const L="hodei-token";function x(){return localStorage.getItem(L)??void 0}function q(e){localStorage.setItem(L,e)}function U(){localStorage.removeItem(L)}function E(){let e="pending",t=()=>{},n=()=>{};const o=new Promise((i,d)=>{t=u=>{e="resolved",i(u)},n=u=>{e="rejected",d(u)}});return{status:e,promise:o,resolve:t,reject:n}}function f(e){if(e){if((e instanceof Error||C(e,"message"))&&typeof e.message=="string"&&e.message.length>0)return e.message;if(C(e,"data")&&C(e.data,"message")&&typeof e.data.message=="string"&&e.data.message.length>0)return e.data.message;if(typeof e=="string"&&e.length>0)return e}}function C(e,t){return typeof e=="object"&&e!==null&&t in e}function O(e,t){let n;return()=>{n||(n=setTimeout(()=>{e(),n=void 0},t))}}class R{constructor(t){g(this,"_config");g(this,"_onStateChange");g(this,"_debug");g(this,"_connectPromise");g(this,"_connection");g(this,"_attempts",0);g(this,"_reconnectTimer");var n;this._config=t.config,this._onStateChange=t.onStateChange,this._debug=((n=t.config)==null?void 0:n.debug)??!1}setDebug(t){this._debug=t}debugLog(...t){if(!this._debug)return;let n="[HODEI]";this.connection&&(n+=` (${this.connection.id})`),console.log(n,...t)}get connection(){return this._connection}isConnected(){var t,n;return((t=this.connection)==null?void 0:t.state.status)==="paired"||((n=this.connection)==null?void 0:n.state.status)==="pairing"}async connect(){if(this._connectPromise)return this._connectPromise;if(this.isConnected())return this.connection.state;this._connectPromise=this._connect();try{return await this._connectPromise}finally{this._connectPromise=void 0}}_shutdown(t){t.ws.close(1e3,"disconnected");for(const n of t.subscriptions)n.unsubscribe()}disconnect(){this._connection&&(this._shutdown(this._connection),this._connection=void 0)}unlink(){this.send({type:"client.session_unlinked",payload:{}})}getState(){var t;return(t=this.connection)==null?void 0:t.state}async _connect(){var k,r,c;this._connection&&this._shutdown(this._connection);const t=this._config.bridge.baseUrl.replace("http","ws"),n=new URL(`${t}/client/ws`),o=await this._getToken();o&&n.searchParams.set("token",o);const i=(((k=this.connection)==null?void 0:k.id)??0)+1,d=new WebSocket(n),u=new AbortController,m=E();this.debugLog("connecting"),d.addEventListener("message",a=>{try{const s=JSON.parse(a.data);z(s),this.debugLog("received connection message"),m.resolve(s.payload)}catch(s){m.reject(`Error parsing connection message ${a.data}: ${f(s)}`)}finally{u.abort()}},{signal:u.signal}),d.addEventListener("error",a=>{this.debugLog("received connection error"),m.reject(`Error connecting: ${f(a)}`),u.abort()},{signal:u.signal});try{const a=await m.promise;this.debugLog("connected"),q(a.token);const s={id:i,ws:d,state:a,controller:((r=this._connection)==null?void 0:r.controller)??new AbortController,events:((c=this._connection)==null?void 0:c.events)??new EventTarget,subscriptions:[]},l=O(()=>{this.debugLog("reconnecting"),this._reconnectNow()},500),$=()=>{document.visibilityState==="visible"&&l()};return document.addEventListener("visibilitychange",$),window.addEventListener("focus",l),s.subscriptions.push({unsubscribe:()=>{window.removeEventListener("visibilityChange",$),window.removeEventListener("focus",l)}}),this._connection=s,this._onStateChange(s.state),d.addEventListener("message",h=>{var H;try{if(s.state.status==="error")throw new Error("Received message after error");if(s.state.status==="closed")throw new Error("Received message after closed");const _=JSON.parse(h.data);T(_),(H=this._connection)==null||H.events.dispatchEvent(new CustomEvent("message",{detail:_})),_.type==="client.wallet_updated"&&(this.debugLog("received wallet_updated message"),s.state={..._.payload,status:"paired",sessionId:s.state.sessionId,token:s.state.token},this._onStateChange(s.state))}catch(_){this.debugLog(`error parsing message ${h.data}: ${f(_)}`)}},{signal:s.controller.signal}),d.addEventListener("error",h=>{if(this._scheduleReconnect()){this.debugLog("scheduled reconnect after error");return}this.debugLog(`received error: ${f(h)}`),s.state={status:"error",error:f(h)},this._onStateChange(s.state),s.controller.abort()},{signal:s.controller.signal}),d.addEventListener("close",async h=>{if(h.code===4001&&(this.debugLog("session deleted"),U()),h.code!==1e3&&this._scheduleReconnect()){this.debugLog("scheduled reconnect after close");return}this.debugLog(`received close: ${h.code} ${h.reason}`),s.state={status:"closed",reason:h.reason,code:h.code},this._onStateChange(s.state),s.controller.abort()},{signal:s.controller.signal}),this._attempts=0,a}catch(a){throw d.close(void 0,`failed to connect: ${f(a)}`),a}}send(t){var n;(n=this.connection)==null||n.ws.send(JSON.stringify(t))}_scheduleReconnect(){this._reconnectTimer&&(this.debugLog("clearing reconnect timer"),clearTimeout(this._reconnectTimer)),this._attempts=Math.min(this._attempts+1,5);const t=2**this._attempts*1e3;this.debugLog(`reconnecting in ${t/1e3}s`);const n=setTimeout(()=>{var o;if(this._reconnectTimer!==n){this.debugLog("reconnect timer cleared. ignoring");return}if(((o=this.connection)==null?void 0:o.ws.readyState)===WebSocket.OPEN){this.debugLog("skipping reconnect, socket is connected");return}this.debugLog("reconnecting"),this._reconnectTimer=void 0,this._connect().catch(()=>this._scheduleReconnect())},t);return this._reconnectTimer=n,!0}_reconnectNow(){var t;if(((t=this.connection)==null?void 0:t.ws.readyState)===WebSocket.OPEN){this.debugLog("skipping reconnect, socket is connected");return}return this._reconnectTimer&&(this.debugLog("clearing reconnect timer"),clearTimeout(this._reconnectTimer)),this.debugLog("reconnecting now"),this._reconnectTimer=void 0,this._connect().catch(()=>this._scheduleReconnect()),!0}async _getToken(){const t=x();if(!t)return;const n=await P({config:this._config,token:t});if(this.debugLog(`checked token: ${n.valid?"valid":`invalid: ${n.reason}`}`),n.valid)return t;if(n.reason==="tooManyConnections")throw new Error("Too many connections");n.reason==="notFound"&&U()}}async function P(e){const t=new URL(`${e.config.bridge.baseUrl}/client/check`),n=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${e.token}`}});return n.status===404?{valid:!1,reason:"notFound"}:n.status===409?{valid:!1,reason:"tooManyConnections"}:{valid:!0,token:e.token}}function y(e){return typeof e=="object"&&e!==null}function W(e){return y(e)&&(e.status==="pairing"||e.status==="paired")}function z(e){if(!y(e)||e.type!=="client.connected"||!W(e.payload))throw new Error("Invalid connected message")}const N=new Set(["client.wallet_updated","client.sig_req_accepted","client.sig_req_rejected"]);function T(e){if(!y(e)||typeof e.type!="string"||!N.has(e.type))throw new Error("Invalid incoming message")}function M(e){if(!y(e)||e.type!=="client.sig_req_accepted"&&e.type!=="client.sig_req_rejected")throw new Error("Invalid sig req response")}const F=new Set(["pairing","paired","closed","error"]);function J(e){return y(e)&&typeof e.status=="string"&&F.has(e.status)}function S(e,t){e.dispatchEvent(new CustomEvent("command",{detail:t}))}function A(e,t,n){const o=i=>{const d=K(i);d&&t(d)};return e.addEventListener("command",o,n),()=>{e.removeEventListener("command",o,n)}}function K(e){if(e instanceof CustomEvent)return V(e.detail)?e.detail:void 0}const G=new Set(["disconnecting","disconnected","unlinked","dialog_closed"]);function V(e){if(typeof e!="object"||e===null)return!1;const t=e;return typeof t.type!="string"?!1:G.has(t.type)?!0:t.type==="state_changed"&&J(t.payload)}const B={bridge:{baseUrl:"https://bridge.hodei.io/api/dev"},anvil:{mainnet:{baseUrl:"https://prod.api.ada-anvil.app/v2/services",apiKey:"mainnet_IIrhwohjiEAJ2LFOgI8p5F735xz4C6XsgH6KfzpC"},preprod:{baseUrl:"https://preprod.api.ada-anvil.app/v2/services",apiKey:"testnet_C301LOscFsUccwR4zCqEtTJvizEAUc3AaVhRDdcY"}},debug:!1,waitForPairing:!0,onError:({error:e})=>console.error("[HODEI] unhandled error:",e??"unknown"),onClose:({code:e,reason:t})=>console.error("[HODEI] unhandled closure:",e,t)},X={refused:1,failure:2};function Y(e,t){return{code:X[e],info:f(t)??"unknown"}}const Q={invalidRequest:-1,internalError:-2,refused:-3,accountChange:-4};function v(e,t){return{code:Q[e],info:f(t)??"unknown"}}const Z={proofGeneration:1,userDeclined:2};function ee(e,t){let n=f(t)??"unknown";for(const o of["ProofGeneration: ","UserDeclined: "])if(n.startsWith(o)){n=n.slice(o.length);break}return n==="UserDeclined"&&(n="User declined"),n==="ProofGeneration"&&(n="Unable to sign the transaction"),{code:Z[e],info:n}}function te(e){if(!(typeof window>"u"))return window.cardano||(window.cardano={}),"hodei"in window.cardano||(window.cardano.hodei=ne(e)),window.cardano.hodei}function ne(e={}){const t={config:{...B,...e}},n=async o=>{var i,d,u,m;await((i=t.promise)==null?void 0:i.catch(()=>{})),o.status==="error"&&t.config.onError(o),o.status==="closed"&&t.config.onClose(o),o.status==="paired"&&((u=(d=t.config).onWalletUpdate)==null||u.call(d,{baseAddress:o.baseAddress,stakeAddress:o.stakeAddress,network:o.network})),t.resolved?(m=t.resolved)==null||m.client.sendCommand({sender:"wallet",type:"state_changed",payload:o}):console.error("[HODEI] (state_changed)",o)};return{name:"hodei",icon:"https://raw.githubusercontent.com/cardano-forge/weld/main/images/wallets/hodei.png",apiVersion:"1",async enable(){var o;if((o=t.resolved)!=null&&o.bridge.isConnected())return t.resolved.api;t.promise||(t.promise=oe({config:t.config,onStateChange:n}));try{const i=await t.promise;return t.resolved=i,t.config.waitForPairing?await i.pairingPromise:i.pairingPromise.catch(()=>{}),i.api}finally{t.promise=void 0}},async isEnabled(){if(t.promise)try{return await t.promise,!0}catch{return!1}if(t.resolved)return t.resolved.bridge.isConnected();const o=x();if(!o)return!1;try{return(await P({config:t.config,token:o})).valid}catch{return!1}}}}async function oe(e){var m,k;const t=await se(),n=new R(e);await n.connect(),A(t.element,r=>{var c;if(r.sender==="client")switch(r.type){case"dialog_closed":{((c=n.getState())==null?void 0:c.status)==="pairing"&&n.disconnect();break}case"disconnected":{n.disconnect();break}case"unlinked":{n.unlink();break}default:{n.debugLog(`unhandled command received from client: ${JSON.stringify(r)}`);break}}},{signal:(m=n.connection)==null?void 0:m.controller.signal});const o=()=>{const r=n.getState();if((r==null?void 0:r.status)!=="paired")throw v("refused",new Error("Wallet is not connected"));return r},i=async r=>{if(o(),!n.isConnected())throw v("refused",new Error("Wallet is not connected"));const c=new AbortController;n.connection.controller.signal.addEventListener("abort",()=>c.abort(),{signal:c.signal});const a=E();return c.signal.addEventListener("abort",()=>{a.reject("aborted")}),n.connection.events.addEventListener("message",s=>{if(s instanceof CustomEvent)try{const l=s.detail;if(M(l),l.payload.requestId!==r.requestId)return;n.send({type:"client.sig_req_ack",payload:{requestId:l.payload.requestId}}),l.type==="client.sig_req_accepted"?a.resolve(l.payload.signature):a.reject(l.payload.reason),c.abort()}catch(l){n.debugLog(`error parsing message ${s.detail}: ${f(l)}`)}},{signal:c.signal}),n.send({type:"client.sig_req_created",payload:r}),a.promise},d={getNetworkId:async()=>o().network==="mainnet"?1:0,getUtxos:async()=>{const r=o();try{return await w({config:e.config,network:r.network,address:r.baseAddress})}catch(c){throw v("internalError",c)}},getBalance:async()=>{const r=o();try{return await D({config:e.config,network:r.network,address:r.baseAddress})}catch(c){throw v("internalError",c)}},getUsedAddresses:async()=>[o().baseAddress],getUnusedAddresses:async()=>[],getChangeAddress:async()=>o().baseAddress,getRewardAddresses:async()=>[o().stakeAddress],signTx:async(r,c=!1)=>{try{return await i({requestId:crypto.randomUUID(),tx:r,partialSign:c,capabilities:["ack"]})}catch(a){const s=f(a),l=s!=null&&s.startsWith("ProofGeneration")?"proofGeneration":"userDeclined";throw ee(l,s)}},signData:async(r,c)=>{const a=await i({requestId:crypto.randomUUID(),address:r,data:c,capabilities:["ack"]}),[s,l]=a.split("::");if(!s||!l)throw v("internalError",new Error("Invalid signature"));return{signature:s,key:l}},submitTx:async r=>{const c=o();try{return(await j({config:e.config,network:c.network,transaction:r})).txHash}catch(a){throw Y("failure",a)}},disconnect:async()=>{t.sendCommand({sender:"wallet",type:"disconnecting"})}},u=E();if(n.connection&&((k=n.getState())==null?void 0:k.status)==="pairing"){const r=new AbortController;n.connection.controller.signal.addEventListener("abort",()=>{r.abort(),u.reject(new Error("Aborted"))},{signal:r.signal}),n.connection.events.addEventListener("message",c=>{if(c instanceof CustomEvent)try{const a=c.detail;T(a),a.type==="client.wallet_updated"&&(u.resolve(),r.abort())}catch{}},{signal:r.signal})}else u.resolve();return{api:d,bridge:n,client:t,pairingPromise:u.promise}}async function se(){if(!customElements.get("hodei-client")){const t=await Promise.resolve().then(()=>de);customElements.define("hodei-client",t.HodeiClient)}let e=document.querySelector("hodei-client")??void 0;if(!e){e=document.createElement("hodei-client");const t=E();e.addEventListener("mounted",()=>t.resolve(),{once:!0}),document.body.appendChild(e),await t.promise}return{element:e,sendCommand:t=>S(e,t)}}class I extends p.DefaultWalletHandler{async disconnect(){var t;if("disconnect"in this.enabledApi&&typeof this.enabledApi.disconnect=="function")return(t=this.enabledApi)==null?void 0:t.disconnect()}}function ie(e){return{key:"hodei",connector:p.getDefaultWalletConnector(I),initialize:p.runOnce(t=>te({debug:t.config.debug,...e,onError:o=>{var i;t.config.debug&&console.error("[WELD] Hodei socket error, disconnecting.",o),(i=e==null?void 0:e.onError)==null||i.call(e,o,t),t.wallet.disconnect()},onClose:o=>{var i;t.config.debug&&console.error("[WELD] Hodei socket closed, disconnecting.",o),(i=e==null?void 0:e.onClose)==null||i.call(e,o,t),t.wallet.disconnect()},onWalletUpdate:o=>{var i;t.config.debug&&console.log("[WELD] Hodei wallet updated, updating state.",o),(i=e==null?void 0:e.onWalletUpdate)==null||i.call(e,o,t),t.wallet.updateState()}})?(t.extensions.registerWallets([{supported:!0,key:"hodei",displayName:"Hodei",icon:"https://raw.githubusercontent.com/cardano-forge/weld/main/images/wallets/hodei.png",website:"https://github.com/cardano-forge/hodei-client",supportsTxChaining:!1}]),!0):!1)}}const re="*{box-sizing:border-box}:host{font-family:Roboto,Arial,Helvetica,sans-serif;pointer-events:auto}dialog{width:100%;max-width:300px;outline:none;border:none;padding:24px;background:transparent}dialog::backdrop{background:#00000052}article{padding:24px;border-radius:22px;display:flex;flex-direction:column;align-items:center;justify-content:center;flex:1;overflow:hidden;text-align:center;background:linear-gradient(to bottom right,#ebdee8,#fff7fa);color:#1e191e}h1{margin:12px 0 16px;font-size:20px;font-weight:400}p{margin:0;font-size:14px}h2{margin:0 0 24px;font-size:24px;font-weight:600;letter-spacing:.2em}img{width:75px;height:75px}button{--bg: #69548e;--fg: #ffffff;background:var(--bg);color:var(--fg);outline:none;border:none;height:32px;padding:0 12px;border-radius:24px;position:relative;overflow:hidden;transition:all .2s ease-in-out}button:hover{cursor:pointer;--bg: #746197;--fg: #ffffff}button.tonal{--bg: #e8dff8;--fg: #1e182b}button.tonal:hover{--bg: #d9cfe7;--fg: #1f182b}footer{margin-top:24px}@media(prefers-color-scheme:dark){article{background:linear-gradient(to bottom right,#362a36,#181215);color:#eadfe6}button{--bg: #d3bcfd;--fg: #37265c}button:hover{--bg: #c6b0f0;--fg: #37265c}button.tonal{--bg: #4b4358;--fg: #e8dff8}button.tonal:hover{--bg: #574f63;--fg: #e9def8}}",ae=`<dialog></dialog>
|
|
2
2
|
|
|
3
3
|
<template id="pairing">
|
|
4
4
|
<article>
|
|
@@ -20,4 +20,4 @@ var HodeiPlugin=function(b,p){"use strict";var ce=Object.defineProperty;var de=(
|
|
|
20
20
|
</footer>
|
|
21
21
|
</article>
|
|
22
22
|
</template>
|
|
23
|
-
`;class
|
|
23
|
+
`;class ce extends HTMLElement{constructor(){super();g(this,"_state",{status:"disconnected"});g(this,"_shadow");g(this,"_dialog");g(this,"_unsub");g(this,"_observer");this._shadow=this.attachShadow({mode:"open"}),this._shadow.innerHTML=`<style>${re}</style>${ae}`;const n=this._shadow.querySelector("dialog");if(n)this._dialog=n;else throw new Error("dialog not found");for(const o of["pointerdown","pointerup","click","mousedown","mouseup"])this.addEventListener(o,i=>i.stopPropagation());this._dialog.addEventListener("click",o=>{o.target===this._dialog&&this._dialog.close("backdrop")}),this._dialog.addEventListener("close",()=>{switch(this._state.status){case"pairing":S(this,{sender:"client",type:"dialog_closed"});break;case"disconnecting":this._dialog.returnValue==="backdrop"?this._state={status:"connected"}:S(this,{sender:"client",type:this._state.shouldUnlink?"unlinked":"disconnected"});break}})}connectedCallback(){this._unsub=A(this,o=>{if(o.sender==="wallet"&&!(o.type==="state_changed"&&o.payload.status==="paired"&&this._state.status==="disconnecting"))switch(o.type){case"state_changed":switch(o.payload.status){case"paired":this._state={status:"connected"};break;case"pairing":this._state={status:"pairing",pin:o.payload.pin};break;default:this._state={status:"disconnected"};break}this._update();break;case"disconnecting":this._state.status==="connected"&&(this._state={status:"disconnecting",shouldUnlink:!1},this._update());break}});const n=this.parentElement;n&&(this._observer=new MutationObserver(()=>{n.lastElementChild!==this&&(n.removeChild(this),n.appendChild(this))}),this._observer.observe(n,{childList:!0})),this.dispatchEvent(new CustomEvent("mounted"))}disconnectedCallback(){var n,o;(n=this._unsub)==null||n.call(this),(o=this._observer)==null||o.disconnect(),this.dispatchEvent(new CustomEvent("unmounted"))}_cloneTemplate(n){var o;return(o=this._shadow.querySelector(`#${n}`))==null?void 0:o.content.cloneNode(!0)}_update(){const n=this._state;switch(n.status){case"pairing":{const o=this._cloneTemplate(n.status),i=o.querySelector(".pin");i&&(i.textContent=n.pin),this._dialog.replaceChildren(o),this._dialog.open||this._dialog.showModal();break}case"disconnecting":{const o=this._cloneTemplate(n.status);this._dialog.replaceChildren(o);for(const i of this._dialog.querySelectorAll("button"))i.addEventListener("click",()=>{n.shouldUnlink=i.dataset.action==="unlink",this._dialog.close("disconnect")});this._dialog.open||this._dialog.showModal();break}default:{this._dialog.open&&this._dialog.close("no-content");break}}}}const de=Object.freeze(Object.defineProperty({__proto__:null,HodeiClient:ce},Symbol.toStringTag,{value:"Module"}));return b.HodeiHandler=I,b.hodeiPlugin=ie,Object.defineProperty(b,Symbol.toStringTag,{value:"Module"}),b}({},WeldCore);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ada-anvil/weld-plugin-hodei",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"files": [
|
|
5
5
|
"**"
|
|
6
6
|
],
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"@ada-anvil/weld": ">=0.7.0"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@ada-anvil/hodei-client": "^0.0.
|
|
22
|
+
"@ada-anvil/hodei-client": "^0.0.7"
|
|
23
23
|
},
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"publishConfig": {
|