@enbox/browser 0.3.40 → 0.3.42
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/dist/browser.mjs +110 -47
- package/dist/browser.mjs.map +3 -3
- package/dist/esm/browser-connect-handler.js +15 -5
- package/dist/esm/browser-connect-handler.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/ui/wallet-selector.js +391 -149
- package/dist/esm/ui/wallet-selector.js.map +1 -1
- package/dist/types/browser-connect-handler.d.ts +1 -1
- package/dist/types/browser-connect-handler.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/ui/wallet-selector.d.ts +33 -1
- package/dist/types/ui/wallet-selector.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/browser-connect-handler.ts +16 -6
- package/src/index.ts +2 -1
- package/src/ui/wallet-selector.ts +437 -162
package/dist/browser.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Enbox as
|
|
1
|
+
import{Enbox as et,defineProtocol as tt,repository as nt}from"@enbox/api";import{AuthManager as rt,AuthSession as it,normalizeProtocolRequests as st,WalletConnect as at}from"@enbox/auth/browser";import{CONNECT_DENIED_TOKEN as ct,ConnectProvider as dt}from"@enbox/connect";import{DidDht as V,DidWeb as X,UniversalResolver as H}from"@enbox/dids";function v(n){let e=n.indexOf("://dweb/");if(e===-1)return null;let t=n.slice(0,e);if(t!=="http"&&t!=="https")return null;let o=n.slice(e+8);if(o.length===0)return null;let r=o.indexOf("/");return r===-1?[o,""]:r===0?null:[o.slice(0,r),o.slice(r+1)]}var M=new H({didResolvers:[V,X]}),j=/^http:/,T=/\/$/,B="drl";async function z(n){let{didDocument:e}=await M.resolve(n),t=e?.service?.find(o=>o.type==="DecentralizedWebNode")?.serviceEndpoint;return t?(Array.isArray(t)?t:[t]).filter(o=>typeof o=="string"&&o.startsWith("http")):[]}async function F(){if(!(typeof caches>"u"))return caches.open(B)}async function Z(n,e,t,o){let r=n.request.url.replace(j,"https:").replace(T,""),i=await F(),a=await i?.match(r);if(a){if(!navigator.onLine)return a;let s=await o?.onCacheCheck?.(n,r);if(s){let l=a.headers.get("dwn-cache-time");if(l&&Date.now()<Number(l)+(Number(s.ttl)||0))return a}}try{if(t)return await ee(n,e,r,t,i,o);{let s=await M.resolve(e);return new Response(JSON.stringify(s),{status:200,headers:{"Content-Type":"application/json"}})}}catch(s){return s instanceof Response?s:(console.log(`Error in DID URL fetch: ${s}`),new Response("DID URL fetch error",{status:500}))}}async function ee(n,e,t,o,r,i){let a=await z(e);if(!a?.length)throw new Response("DWeb Node resolution failed: no valid endpoints found.",{status:530});let s;for(let l of a)try{let c=`${l.replace(T,"")}/${e}/${o}`,d=await fetch(c,{headers:n.request.headers});if(d.ok)return await i?.onCacheCheck?.(n,t)&&r&&te(t,c,d,r),d;console.log(`DWN endpoint error: ${d.status}`),s=new Response("DWeb Node request failed",{status:d.status})}catch(c){console.log(`DWN endpoint error: ${c}`),s=new Response("DWeb Node request failed",{status:500})}return s}async function te(n,e,t,o){try{let r=t.clone(),i=new Headers(r.headers);i.append("dwn-cache-time",Date.now().toString()),i.append("dwn-composed-url",e);let a=new Response(r.body,{headers:i});await o.put(n,a)}catch(r){console.log(`Failed to cache DRL response: ${r}`)}}async function ne(n={}){try{if(typeof ServiceWorkerGlobalScope<"u"&&self instanceof ServiceWorkerGlobalScope){let e=self;e.skipWaiting(),e.addEventListener("activate",t=>{t.waitUntil(e.clients.claim())}),e.addEventListener("fetch",t=>{let o=v(t.request.url);o&&t.respondWith(Z(t,o[0],o[1],n))})}else if(globalThis?.navigator?.serviceWorker){if(!await navigator.serviceWorker.getRegistration("/")){let t=n.path||document?.currentScript?.src||import.meta.url;t&&navigator.serviceWorker.register(t,{type:"module"}).catch(o=>{console.error("DWeb networking feature installation failed: ",o)})}}else throw new Error("DWeb networking features are not available for install in this environment")}catch(e){console.error("Error in installing networking features:",e)}}var K=`
|
|
2
2
|
.drl-loading-overlay {
|
|
3
3
|
position: fixed;
|
|
4
4
|
inset: 0;
|
|
@@ -103,7 +103,7 @@ import{Enbox as ot,defineProtocol as rt,repository as it}from"@enbox/api";import
|
|
|
103
103
|
opacity: 0;
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
|
-
`,
|
|
106
|
+
`,oe=`
|
|
107
107
|
<!DOCTYPE html>
|
|
108
108
|
<html lang='en'>
|
|
109
109
|
<head>
|
|
@@ -119,7 +119,7 @@ import{Enbox as ot,defineProtocol as rt,repository as it}from"@enbox/api";import
|
|
|
119
119
|
font-family: Arial, sans-serif;
|
|
120
120
|
text-align: center;
|
|
121
121
|
}
|
|
122
|
-
${
|
|
122
|
+
${K}
|
|
123
123
|
</style>
|
|
124
124
|
</head>
|
|
125
125
|
<body>
|
|
@@ -132,8 +132,8 @@ import{Enbox as ot,defineProtocol as rt,repository as it}from"@enbox/api";import
|
|
|
132
132
|
</div>
|
|
133
133
|
</body>
|
|
134
134
|
</html>
|
|
135
|
-
`,
|
|
136
|
-
${
|
|
135
|
+
`,k=!1,m=null,E=null;function I(){k||(E=document.createElement("style"),E.innerHTML=`
|
|
136
|
+
${K}
|
|
137
137
|
|
|
138
138
|
.drl-loading-overlay {
|
|
139
139
|
opacity: 0;
|
|
@@ -145,13 +145,13 @@ import{Enbox as ot,defineProtocol as rt,repository as it}from"@enbox/api";import
|
|
|
145
145
|
opacity: 1;
|
|
146
146
|
pointer-events: all;
|
|
147
147
|
}
|
|
148
|
-
`,document.head.append(
|
|
148
|
+
`,document.head.append(E),m=document.createElement("div"),m.classList.add("drl-loading-overlay"),m.innerHTML=`
|
|
149
149
|
<div class='drl-loading-spinner'>
|
|
150
150
|
<div></div>
|
|
151
151
|
Loading DRL
|
|
152
152
|
</div>
|
|
153
153
|
<span tabindex='0'></span>
|
|
154
|
-
`,f.lastElementChild.addEventListener("click",H),document.body.prepend(f),M=!0)}function he(){M&&(_?.remove(),_=null,f?.remove(),f=null,M=!1)}function H(){document.documentElement.removeAttribute("drl-link-loading"),D=null}var D=null,S=!1,x=null,C=null;function ge(){S||(x=async n=>{let e=n.target?.closest("a");if(e){let t=e.href,o=b(t);if(o){let r=o[0],i=o[1],a=e.target==="_blank";n.preventDefault();try{let s=null;a?(s=window.open("","_blank"),s&&s.document.write(fe)):(D=i,setTimeout(()=>document.documentElement.setAttribute("drl-link-loading",""),50));let u=await oe(r);if(!u.length)throw new Error("no valid DWN endpoints found");let l=`${u[0].replace(L,"")}/${r}/${i}`;a?s&&!s.closed&&(s.location.href=l):D===i&&(window.location.href=l)}catch{throw D===i&&H(),new Error(`DID endpoint resolution failed for the DRL: ${t}`)}}}},C=async n=>{let e=n.composedPath()[0];if(n.pointerType==="mouse"&&n.button===2||n.pointerType==="touch"&&n.isPrimary){if(E(),e?.src&&b(e.src)){h=e,e.__src__=e.src;let t=e.src.replace(te,"https:").replace(L,""),r=await(await re())?.match(t);if(r){let i=r.headers.get("dwn-composed-url");i&&(e.src=i)}e.addEventListener("pointerup",E,{once:!0})}}else e===h&&E()},document.addEventListener("click",x),document.addEventListener("pointercancel",E),document.addEventListener("pointerdown",C),S=!0)}function we(){S&&(x&&(document.removeEventListener("click",x),x=null),C&&(document.removeEventListener("pointerdown",C),C=null),document.removeEventListener("pointercancel",E),E(),H(),S=!1)}var h=null;async function E(n){n?.type==="pointerup"&&await new Promise(e=>requestAnimationFrame(()=>e())),h&&(h.src=h.__src__,delete h.__src__,h=null)}function Ue(n={}){n.didResolvers&&(j=new ee({didResolvers:n.didResolvers})),n.serviceWorker!==!1&&me(n),typeof window<"u"&&typeof window.document<"u"&&(n.injectStyles!==!1&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",Z,{once:!0}):Z()),n.links!==!1&&ge())}function Ie(){typeof window<"u"&&typeof window.document<"u"&&(we(),he())}async function $e(){return typeof caches>"u"?!1:caches.delete(ne)}import{assertX25519PublicJwk as Ee,CONNECT_DENIED_TOKEN as ve,ConnectClient as ye}from"@enbox/connect";var F="/dweb-connect",R="enbox-connect-loaded",P="enbox-connect-request",T="enbox-connect-response";function A(n,e,t){if(n.origin!==e||n.source!==t)return;let o=n.data;if(!(typeof o!="object"||o===null))return o}var be=3e5,_e=500,xe="enbox-dweb-connect",Ce="width=500,height=700,menubar=no,toolbar=no,location=no,status=no";function Re(){if(typeof window>"u")throw new Error("[@enbox/browser] DWeb Connect is only available in browser environments.")}var k=class extends Error{constructor(){super("[@enbox/browser] Wallet popup was closed before the wallet finished loading."),this.name="PopupWindowClosedError"}},q=class{constructor(e){this.requiresPin=!1;this._settled=!1;this._walletEpkReceived=!1;Re(),this._walletOrigin=new URL(e.walletUrl).origin,this._timeoutMs=e.timeoutMs??be;let t=new URL(F,e.walletUrl).toString(),o=window.open(t,xe,Ce);if(!o)throw new Error("[@enbox/browser] Popup blocked. Allow popups for this site to connect to a wallet.");this._popup=o,this._walletEpkPromise=new Promise((r,i)=>{this._resolveWalletEpk=r,this._rejectWalletEpk=i}),this._responsePromise=new Promise((r,i)=>{this._resolveResponse=r,this._rejectResponse=i}),this._responsePromise.catch(()=>{}),this._messageListener=r=>{this.onMessage(r)},window.addEventListener("message",this._messageListener),this._timeoutId=setTimeout(()=>{this.fail(new Error("[@enbox/browser] DWeb Connect timed out waiting for wallet response."))},this._timeoutMs),this._closedPollId=setInterval(()=>{this.onClosedPoll()},_e)}async requestProfile(e){return{encryption:{mode:"ecdh-es",walletEpk:await this._walletEpkPromise,walletOrigin:this._walletOrigin},reply:{mode:"post_message"},state:e}}async deliverRequest(e){this._popup.postMessage({type:P,jwe:e},this._walletOrigin)}async awaitResponse(){return await this._responsePromise}onMessage(e){let t=A(e,this._walletOrigin,this._popup);if(t!==void 0){if(t.type===R){this.onLoadedBeacon(t);return}t.type===T&&this.onResponseMessage(t)}}onLoadedBeacon(e){if(this._settled||this._walletEpkReceived)return;let t;try{Ee(e.walletEpk),t=e.walletEpk}catch{this.fail(new Error("[@enbox/browser] Wallet loaded beacon did not carry a valid X25519 public key."));return}if(e.walletOrigin!==this._walletOrigin){this.fail(new Error("[@enbox/browser] Wallet loaded beacon origin does not match the configured wallet origin."));return}this._walletEpkReceived=!0,this._resolveWalletEpk?.(t)}onResponseMessage(e){if(!this._settled){if(typeof e.payload!="string"){this.fail(new Error("[@enbox/browser] Wallet response message did not carry a ciphertext payload."));return}this._settled=!0,this.cleanup(),this._rejectWalletEpk?.(new Error("[@enbox/browser] Wallet responded before the handshake was established.")),this._resolveResponse?.(e.payload)}}onClosedPoll(){if(!(this._settled||this._popup.closed!==!0)){if(!this._walletEpkReceived){this.fail(new k);return}this._settled=!0,this.cleanup(),this._resolveResponse?.(ve)}}fail(e){if(!this._settled){this._settled=!0,this.cleanup();try{this._popup.close()}catch{}this._rejectWalletEpk?.(e),this._rejectResponse?.(e)}}cleanup(){clearTimeout(this._timeoutId),clearInterval(this._closedPollId),this._messageListener!==void 0&&(window.removeEventListener("message",this._messageListener),this._messageListener=void 0)}};function Pe(){let n=Intl.DateTimeFormat().resolvedOptions(),e=Array.isArray(globalThis.navigator.languages)?globalThis.navigator.languages.filter(t=>typeof t=="string"&&t.length>0):void 0;return{origin:globalThis.location.origin,userAgent:globalThis.navigator.userAgent,platform:globalThis.navigator.platform,language:globalThis.navigator.language,...e&&e.length>0?{languages:e}:{},...n.timeZone?{timezone:n.timeZone}:{}}}async function Y(n){let e=new q({walletUrl:n.walletUrl,timeoutMs:n.timeout}),t=new ye({transport:e});try{return await t.connect({appName:n.appName??globalThis.location.host,appIcon:n.appIcon,clientMetadata:Pe(),permissionRequests:n.permissionRequests})}catch(o){if(o instanceof k)return;throw o}}function G(n){if(typeof window>"u"||typeof document>"u")throw new Error("[@enbox/browser] Wallet selector is only available in browser environments.");return new Promise((e,t)=>{let o=document.createElement("div");o.id="enbox-wallet-selector";let r=o.attachShadow({mode:"open"}),i,a=()=>{i!==void 0&&(document.removeEventListener("keydown",i),i=void 0);try{document.body.removeChild(o)}catch{}},s=window.matchMedia?.("(prefers-color-scheme: dark)").matches,u=document.createElement("style");u.textContent=ke(s),r.appendChild(u);let l=document.createElement("div");l.className="overlay";let c=document.createElement("div");c.className="modal";let v=document.createElement("div");v.className="header";let J=document.createElement("h2");J.textContent="Connect Wallet";let O=document.createElement("button");O.className="close-btn",O.innerHTML="×",O.addEventListener("click",()=>{a(),t(new Error("[@enbox/browser] Wallet selection cancelled."))}),v.appendChild(J),v.appendChild(O),c.appendChild(v);let U=document.createElement("div");U.className="wallet-list";for(let d of n){let w=document.createElement("button");w.className="wallet-item";let m=document.createElement("img");m.src=d.icon??Te(d.url),m.alt=d.name,m.width=32,m.height=32,m.onerror=()=>{m.style.display="none"};let N=document.createElement("div");N.className="wallet-text";let I=document.createElement("span");if(I.className="wallet-name",I.textContent=d.name,N.appendChild(I),d.description){let B=document.createElement("span");B.className="wallet-description",B.textContent=d.description,N.appendChild(B)}let $=document.createElement("span");$.className="arrow",$.textContent="\u203A",w.appendChild(m),w.appendChild(N),w.appendChild($),w.addEventListener("click",()=>{a(),e(d.url)}),U.appendChild(w)}c.appendChild(U);let y=document.createElement("div");y.className="separator";let V=document.createElement("div");V.className="sep-line";let Q=document.createElement("span");Q.textContent="or";let X=document.createElement("div");X.className="sep-line",y.appendChild(V),y.appendChild(Q),y.appendChild(X),c.appendChild(y);let W=document.createElement("div");W.className="input-group";let p=document.createElement("input");p.type="url",p.placeholder="Enter wallet URL...",p.className="url-input";let g=document.createElement("button");g.className="go-btn",g.textContent="Connect",g.disabled=!0,p.addEventListener("input",()=>{g.disabled=!z(p.value)}),p.addEventListener("keydown",d=>{d.key==="Enter"&&z(p.value)&&(a(),e(se(p.value)))}),g.addEventListener("click",()=>{z(p.value)&&(a(),e(se(p.value)))}),W.appendChild(p),W.appendChild(g),c.appendChild(W),l.addEventListener("click",d=>{d.target===l&&(a(),t(new Error("[@enbox/browser] Wallet selection cancelled.")))}),i=d=>{d.key==="Escape"&&(a(),t(new Error("[@enbox/browser] Wallet selection cancelled.")))},document.addEventListener("keydown",i),l.appendChild(c),r.appendChild(l),document.body.appendChild(o),p.focus()})}function Te(n){return`https://t3.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=${n}&size=128`}function z(n){try{let e=new URL(n.includes("://")?n:`https://${n}`);return e.protocol==="https:"||e.protocol==="http:"}catch{return!1}}function se(n){return n.includes("://")||(n=`https://${n}`),new URL(n).origin}function ke(n){let e=n?"#1a1a2e":"#ffffff",t=n?"#e0e0e0":"#1a1a2e",o=n?"#888":"#666",r=n?"#333":"#e0e0e0",i=n?"#16213e":"#f8f9fa",a=n?"#0f3460":"#e9ecef",s=n?"#4a9eff":"#0066cc";return`
|
|
154
|
+
`,m.lastElementChild.addEventListener("click",S),document.body.prepend(m),k=!0)}function re(){k&&(E?.remove(),E=null,m?.remove(),m=null,k=!1)}function S(){document.documentElement.removeAttribute("drl-link-loading"),P=null}var P=null,W=!1,b=null,y=null;function ie(){W||(b=async n=>{let e=n.target?.closest("a");if(e){let t=e.href,o=v(t);if(o){let r=o[0],i=o[1],a=e.target==="_blank";n.preventDefault();try{let s=null;a?(s=window.open("","_blank"),s&&s.document.write(oe)):(P=i,setTimeout(()=>document.documentElement.setAttribute("drl-link-loading",""),50));let l=await z(r);if(!l.length)throw new Error("no valid DWN endpoints found");let c=`${l[0].replace(T,"")}/${r}/${i}`;a?s&&!s.closed&&(s.location.href=c):P===i&&(window.location.href=c)}catch{throw P===i&&S(),new Error(`DID endpoint resolution failed for the DRL: ${t}`)}}}},y=async n=>{let e=n.composedPath()[0];if(n.pointerType==="mouse"&&n.button===2||n.pointerType==="touch"&&n.isPrimary){if(g(),e?.src&&v(e.src)){f=e,e.__src__=e.src;let t=e.src.replace(j,"https:").replace(T,""),r=await(await F())?.match(t);if(r){let i=r.headers.get("dwn-composed-url");i&&(e.src=i)}e.addEventListener("pointerup",g,{once:!0})}}else e===f&&g()},document.addEventListener("click",b),document.addEventListener("pointercancel",g),document.addEventListener("pointerdown",y),W=!0)}function se(){W&&(b&&(document.removeEventListener("click",b),b=null),y&&(document.removeEventListener("pointerdown",y),y=null),document.removeEventListener("pointercancel",g),g(),S(),W=!1)}var f=null;async function g(n){n?.type==="pointerup"&&await new Promise(e=>requestAnimationFrame(()=>e())),f&&(f.src=f.__src__,delete f.__src__,f=null)}function De(n={}){n.didResolvers&&(M=new H({didResolvers:n.didResolvers})),n.serviceWorker!==!1&&ne(n),typeof window<"u"&&typeof window.document<"u"&&(n.injectStyles!==!1&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",I,{once:!0}):I()),n.links!==!1&&ie())}function qe(){typeof window<"u"&&typeof window.document<"u"&&(se(),re())}async function Ae(){return typeof caches>"u"?!1:caches.delete(B)}import{assertX25519PublicJwk as ae,CONNECT_DENIED_TOKEN as le,ConnectClient as ce}from"@enbox/connect";var D="/dweb-connect",x="enbox-connect-loaded",_="enbox-connect-request",C="enbox-connect-response";function O(n,e,t){if(n.origin!==e||n.source!==t)return;let o=n.data;if(!(typeof o!="object"||o===null))return o}var de=3e5,pe=500,ue="enbox-dweb-connect",me="width=500,height=700,menubar=no,toolbar=no,location=no,status=no";function fe(){if(typeof window>"u")throw new Error("[@enbox/browser] DWeb Connect is only available in browser environments.")}var R=class extends Error{constructor(){super("[@enbox/browser] Wallet popup was closed before the wallet finished loading."),this.name="PopupWindowClosedError"}},L=class{constructor(e){this.requiresPin=!1;this._settled=!1;this._walletEpkReceived=!1;fe(),this._walletOrigin=new URL(e.walletUrl).origin,this._timeoutMs=e.timeoutMs??de;let t=new URL(D,e.walletUrl).toString(),o=window.open(t,ue,me);if(!o)throw new Error("[@enbox/browser] Popup blocked. Allow popups for this site to connect to a wallet.");this._popup=o,this._walletEpkPromise=new Promise((r,i)=>{this._resolveWalletEpk=r,this._rejectWalletEpk=i}),this._responsePromise=new Promise((r,i)=>{this._resolveResponse=r,this._rejectResponse=i}),this._responsePromise.catch(()=>{}),this._messageListener=r=>{this.onMessage(r)},window.addEventListener("message",this._messageListener),this._timeoutId=setTimeout(()=>{this.fail(new Error("[@enbox/browser] DWeb Connect timed out waiting for wallet response."))},this._timeoutMs),this._closedPollId=setInterval(()=>{this.onClosedPoll()},pe)}async requestProfile(e){return{encryption:{mode:"ecdh-es",walletEpk:await this._walletEpkPromise,walletOrigin:this._walletOrigin},reply:{mode:"post_message"},state:e}}async deliverRequest(e){this._popup.postMessage({type:_,jwe:e},this._walletOrigin)}async awaitResponse(){return await this._responsePromise}onMessage(e){let t=O(e,this._walletOrigin,this._popup);if(t!==void 0){if(t.type===x){this.onLoadedBeacon(t);return}t.type===C&&this.onResponseMessage(t)}}onLoadedBeacon(e){if(this._settled||this._walletEpkReceived)return;let t;try{ae(e.walletEpk),t=e.walletEpk}catch{this.fail(new Error("[@enbox/browser] Wallet loaded beacon did not carry a valid X25519 public key."));return}if(e.walletOrigin!==this._walletOrigin){this.fail(new Error("[@enbox/browser] Wallet loaded beacon origin does not match the configured wallet origin."));return}this._walletEpkReceived=!0,this._resolveWalletEpk?.(t)}onResponseMessage(e){if(!this._settled){if(typeof e.payload!="string"){this.fail(new Error("[@enbox/browser] Wallet response message did not carry a ciphertext payload."));return}this._settled=!0,this.cleanup(),this._rejectWalletEpk?.(new Error("[@enbox/browser] Wallet responded before the handshake was established.")),this._resolveResponse?.(e.payload)}}onClosedPoll(){if(!(this._settled||this._popup.closed!==!0)){if(!this._walletEpkReceived){this.fail(new R);return}this._settled=!0,this.cleanup(),this._resolveResponse?.(le)}}fail(e){if(!this._settled){this._settled=!0,this.cleanup();try{this._popup.close()}catch{}this._rejectWalletEpk?.(e),this._rejectResponse?.(e)}}cleanup(){clearTimeout(this._timeoutId),clearInterval(this._closedPollId),this._messageListener!==void 0&&(window.removeEventListener("message",this._messageListener),this._messageListener=void 0)}};function ge(){let n=Intl.DateTimeFormat().resolvedOptions(),e=Array.isArray(globalThis.navigator.languages)?globalThis.navigator.languages.filter(t=>typeof t=="string"&&t.length>0):void 0;return{origin:globalThis.location.origin,userAgent:globalThis.navigator.userAgent,platform:globalThis.navigator.platform,language:globalThis.navigator.language,...e&&e.length>0?{languages:e}:{},...n.timeZone?{timezone:n.timeZone}:{}}}async function q(n){let e=new L({walletUrl:n.walletUrl,timeoutMs:n.timeout}),t=new ce({transport:e});try{return await t.connect({appName:n.appName??globalThis.location.host,appIcon:n.appIcon,clientMetadata:ge(),permissionRequests:n.permissionRequests})}catch(o){if(o instanceof R)return;throw o}}var Y="/.well-known/enbox-connect";async function J(n){try{let e=new URL(Y,n).toString(),t=await fetch(e,{signal:AbortSignal.timeout(6e3)});return t.ok?typeof(await t.json())?.connectServerUrl=="string":!1}catch{return!1}}function A(n,e={}){if(typeof window>"u"||typeof document>"u")throw new Error("[@enbox/browser] Wallet selector is only available in browser environments.");let t=e.validateWalletUrl??J;return new Promise((o,r)=>{let i=document.createElement("div");i.id="enbox-wallet-selector";let a=i.attachShadow({mode:"open"}),s,l=()=>{s!==void 0&&(document.removeEventListener("keydown",s),s=void 0);try{document.body.removeChild(i)}catch{}},c=w=>{l(),o(w)},d=()=>{l(),r(new Error("[@enbox/browser] Wallet selection cancelled."))},p=window.matchMedia?.("(prefers-color-scheme: dark)").matches??!1,N=document.createElement("style");N.textContent=Re(p),a.appendChild(N);let h=document.createElement("div");h.className="overlay";let u=document.createElement("div");u.className="modal",u.appendChild(he(d));let $=n[0];$!==void 0&&u.appendChild(we($,c)),u.appendChild(ve(n,c)),u.appendChild(xe()),u.appendChild(_e(t,c)),h.addEventListener("click",w=>{w.target===h&&d()}),s=w=>{w.key==="Escape"&&d()},document.addEventListener("keydown",s),h.appendChild(u),a.appendChild(h),document.body.appendChild(i),a.querySelector(".wallet-search")?.focus()})}function he(n){let e=document.createElement("div");e.className="header";let t=document.createElement("h2");t.textContent="Connect a wallet";let o=document.createElement("button");return o.className="close-btn",o.setAttribute("aria-label","Close"),o.innerHTML="×",o.addEventListener("click",n),e.appendChild(t),e.appendChild(o),e}function we(n,e){let t=document.createElement("button");t.className="quick-connect";let o=document.createElement("span");o.className="quick-bolt",o.textContent="\u26A1";let r=document.createElement("span");r.className="quick-text";let i=document.createElement("span");i.className="quick-label",i.textContent="Quick connect";let a=document.createElement("span");return a.className="quick-sub",a.textContent=`Connect with ${n.name}`,r.appendChild(i),r.appendChild(a),t.appendChild(o),t.appendChild(r),t.addEventListener("click",()=>e(n.url)),t}function ve(n,e){let t=document.createElement("div");t.className="grid-section";let o=document.createElement("input");o.type="search",o.className="wallet-search",o.placeholder="Search wallets\u2026";let r=document.createElement("div");r.className="wallet-grid";let i=document.createElement("div");i.className="grid-empty",i.textContent="No wallets match your search.",i.style.display="none";let a=n.map(s=>{let l=Ee(s,e);return r.appendChild(l),{name:s.name.toLowerCase(),tile:l}});return o.addEventListener("input",()=>{let s=o.value.trim().toLowerCase(),l=0;for(let{name:c,tile:d}of a){let p=c.includes(s);d.style.display=p?"":"none",p&&(l+=1)}i.style.display=l===0?"":"none"}),t.appendChild(o),t.appendChild(r),t.appendChild(i),t}function Ee(n,e){let t=document.createElement("button");t.className="wallet-item",t.title=n.description??n.name,t.appendChild(be(n));let o=document.createElement("span");return o.className="wallet-name",o.textContent=n.name,t.appendChild(o),t.addEventListener("click",()=>e(n.url)),t}function be(n){let e=document.createElement("span");e.className="wallet-icon";let t=document.createElement("span");t.className="wallet-badge",t.textContent=n.name.charAt(0).toUpperCase(),e.appendChild(t);let o=ye(n);if(o.length===0)return e;let r=document.createElement("img");r.className="wallet-img",r.alt="",r.width=40,r.height=40;let i=0;return r.addEventListener("error",()=>{i+=1,i<o.length?r.src=o[i]:r.remove()}),r.src=o[i],e.appendChild(r),e}function ye(n){if(n.icon!==void 0)return[n.icon];let e;try{e=new URL(n.url).origin}catch{return[]}return[`${e}/favicon.svg`,`${e}/favicon.ico`,`${e}/favicon.png`]}function xe(){let n=document.createElement("div");n.className="separator";let e=document.createElement("div");e.className="sep-line";let t=document.createElement("span");t.textContent="or";let o=document.createElement("div");return o.className="sep-line",n.appendChild(e),n.appendChild(t),n.appendChild(o),n}function _e(n,e){let t=document.createElement("div");t.className="custom-section";let o=document.createElement("label");o.className="custom-label",o.textContent="Have a wallet URL?";let r=document.createElement("div");r.className="input-group";let i=document.createElement("input");i.type="url",i.placeholder="https://your-wallet.example",i.className="url-input";let a=document.createElement("button");a.className="go-btn",a.textContent="Connect",a.disabled=!0;let s=document.createElement("div");s.className="url-error",s.style.display="none";let l=!1,c=()=>{l=!1,a.textContent="Connect",s.style.display="none",a.disabled=!G(i.value)},d=async()=>{if(!G(i.value))return;let p=Ce(i.value);if(l){e(p);return}if(a.disabled=!0,a.textContent="Verifying\u2026",s.style.display="none",await n(p)){e(p);return}l=!0,a.disabled=!1,a.textContent="Connect anyway",s.textContent=`Couldn't verify an Enbox wallet at ${p}.`,s.style.display=""};return i.addEventListener("input",c),i.addEventListener("keydown",p=>{p.key==="Enter"&&d()}),a.addEventListener("click",()=>void d()),r.appendChild(i),r.appendChild(a),t.appendChild(o),t.appendChild(r),t.appendChild(s),t}function G(n){try{let e=new URL(n.includes("://")?n:`https://${n}`);return e.protocol==="https:"||e.protocol==="http:"}catch{return!1}}function Ce(n){let e=n.includes("://")?n:`https://${n}`;return new URL(e).origin}function Re(n){let e=n?"#1a1a2e":"#ffffff",t=n?"#e0e0e0":"#1a1a2e",o=n?"#888":"#666",r=n?"#333":"#e0e0e0",i=n?"#16213e":"#f8f9fa",a=n?"#0f3460":"#e9ecef",s=n?"#4a9eff":"#0066cc";return`
|
|
155
155
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
156
156
|
|
|
157
157
|
.overlay {
|
|
@@ -180,9 +180,9 @@ import{Enbox as ot,defineProtocol as rt,repository as it}from"@enbox/api";import
|
|
|
180
180
|
background: ${e};
|
|
181
181
|
color: ${t};
|
|
182
182
|
border-radius: 16px;
|
|
183
|
-
width:
|
|
184
|
-
max-width:
|
|
185
|
-
max-height:
|
|
183
|
+
width: 420px;
|
|
184
|
+
max-width: 92vw;
|
|
185
|
+
max-height: 86vh;
|
|
186
186
|
overflow-y: auto;
|
|
187
187
|
padding: 24px;
|
|
188
188
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
@@ -193,13 +193,10 @@ import{Enbox as ot,defineProtocol as rt,repository as it}from"@enbox/api";import
|
|
|
193
193
|
display: flex;
|
|
194
194
|
justify-content: space-between;
|
|
195
195
|
align-items: center;
|
|
196
|
-
margin-bottom:
|
|
196
|
+
margin-bottom: 18px;
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
h2 {
|
|
200
|
-
font-size: 18px;
|
|
201
|
-
font-weight: 600;
|
|
202
|
-
}
|
|
199
|
+
h2 { font-size: 18px; font-weight: 600; }
|
|
203
200
|
|
|
204
201
|
.close-btn {
|
|
205
202
|
background: none;
|
|
@@ -213,51 +210,110 @@ import{Enbox as ot,defineProtocol as rt,repository as it}from"@enbox/api";import
|
|
|
213
210
|
}
|
|
214
211
|
.close-btn:hover { color: ${t}; background: ${i}; }
|
|
215
212
|
|
|
216
|
-
.
|
|
213
|
+
.quick-connect {
|
|
217
214
|
display: flex;
|
|
218
|
-
|
|
219
|
-
gap:
|
|
215
|
+
align-items: center;
|
|
216
|
+
gap: 12px;
|
|
217
|
+
width: 100%;
|
|
218
|
+
text-align: left;
|
|
219
|
+
padding: 14px 16px;
|
|
220
|
+
margin-bottom: 18px;
|
|
221
|
+
border: none;
|
|
222
|
+
border-radius: 12px;
|
|
223
|
+
cursor: pointer;
|
|
224
|
+
color: #fff;
|
|
225
|
+
background: linear-gradient(135deg, ${s}, ${n?"#7b5cff":"#5b8def"});
|
|
226
|
+
transition: filter 0.15s;
|
|
227
|
+
}
|
|
228
|
+
.quick-connect:hover { filter: brightness(1.08); }
|
|
229
|
+
.quick-bolt { font-size: 22px; line-height: 1; }
|
|
230
|
+
.quick-text { display: flex; flex-direction: column; gap: 2px; }
|
|
231
|
+
.quick-label { font-weight: 600; font-size: 15px; }
|
|
232
|
+
.quick-sub { font-size: 12px; opacity: 0.85; }
|
|
233
|
+
|
|
234
|
+
.wallet-search {
|
|
235
|
+
width: 100%;
|
|
236
|
+
padding: 10px 14px;
|
|
237
|
+
margin-bottom: 12px;
|
|
238
|
+
border: 1px solid ${r};
|
|
239
|
+
border-radius: 10px;
|
|
240
|
+
font-size: 14px;
|
|
241
|
+
background: ${i};
|
|
242
|
+
color: ${t};
|
|
243
|
+
outline: none;
|
|
244
|
+
}
|
|
245
|
+
.wallet-search:focus { border-color: ${s}; }
|
|
246
|
+
.wallet-search::placeholder { color: ${o}; }
|
|
247
|
+
|
|
248
|
+
.wallet-grid {
|
|
249
|
+
display: grid;
|
|
250
|
+
grid-template-columns: repeat(3, 1fr);
|
|
251
|
+
gap: 10px;
|
|
252
|
+
max-height: 216px;
|
|
253
|
+
overflow-y: auto;
|
|
254
|
+
padding: 2px;
|
|
220
255
|
}
|
|
221
256
|
|
|
222
257
|
.wallet-item {
|
|
223
258
|
display: flex;
|
|
259
|
+
flex-direction: column;
|
|
224
260
|
align-items: center;
|
|
225
|
-
|
|
226
|
-
|
|
261
|
+
justify-content: center;
|
|
262
|
+
gap: 8px;
|
|
263
|
+
padding: 14px 8px;
|
|
227
264
|
background: ${i};
|
|
228
265
|
border: 1px solid ${r};
|
|
229
266
|
border-radius: 12px;
|
|
230
267
|
cursor: pointer;
|
|
231
|
-
font-size: 15px;
|
|
232
268
|
color: ${t};
|
|
233
|
-
transition: background 0.15s;
|
|
234
|
-
width: 100%;
|
|
235
|
-
text-align: left;
|
|
269
|
+
transition: background 0.15s, border-color 0.15s;
|
|
236
270
|
}
|
|
237
|
-
.wallet-item:hover { background: ${a}; }
|
|
271
|
+
.wallet-item:hover { background: ${a}; border-color: ${s}; }
|
|
238
272
|
|
|
239
|
-
.wallet-
|
|
240
|
-
|
|
273
|
+
.wallet-icon {
|
|
274
|
+
position: relative;
|
|
275
|
+
width: 40px;
|
|
276
|
+
height: 40px;
|
|
241
277
|
display: flex;
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
278
|
+
align-items: center;
|
|
279
|
+
justify-content: center;
|
|
280
|
+
}
|
|
281
|
+
.wallet-badge {
|
|
282
|
+
position: absolute;
|
|
283
|
+
inset: 0;
|
|
284
|
+
display: flex;
|
|
285
|
+
align-items: center;
|
|
286
|
+
justify-content: center;
|
|
287
|
+
border-radius: 10px;
|
|
288
|
+
background: ${a};
|
|
289
|
+
color: ${t};
|
|
290
|
+
font-size: 18px;
|
|
291
|
+
font-weight: 600;
|
|
292
|
+
}
|
|
293
|
+
.wallet-img {
|
|
294
|
+
position: relative;
|
|
295
|
+
width: 40px;
|
|
296
|
+
height: 40px;
|
|
297
|
+
border-radius: 10px;
|
|
298
|
+
object-fit: cover;
|
|
299
|
+
background: ${e};
|
|
245
300
|
}
|
|
246
301
|
|
|
247
|
-
.wallet-name {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
color: ${o};
|
|
252
|
-
white-space: nowrap;
|
|
302
|
+
.wallet-name {
|
|
303
|
+
font-size: 13px;
|
|
304
|
+
font-weight: 500;
|
|
305
|
+
max-width: 100%;
|
|
253
306
|
overflow: hidden;
|
|
254
307
|
text-overflow: ellipsis;
|
|
308
|
+
white-space: nowrap;
|
|
255
309
|
}
|
|
256
310
|
|
|
257
|
-
.
|
|
258
|
-
|
|
311
|
+
.grid-empty {
|
|
312
|
+
grid-column: 1 / -1;
|
|
313
|
+
padding: 16px;
|
|
314
|
+
text-align: center;
|
|
259
315
|
color: ${o};
|
|
260
|
-
|
|
316
|
+
font-size: 13px;
|
|
261
317
|
}
|
|
262
318
|
|
|
263
319
|
.separator {
|
|
@@ -270,11 +326,15 @@ import{Enbox as ot,defineProtocol as rt,repository as it}from"@enbox/api";import
|
|
|
270
326
|
}
|
|
271
327
|
.sep-line { flex: 1; height: 1px; background: ${r}; }
|
|
272
328
|
|
|
273
|
-
.
|
|
274
|
-
display:
|
|
275
|
-
|
|
329
|
+
.custom-label {
|
|
330
|
+
display: block;
|
|
331
|
+
font-size: 13px;
|
|
332
|
+
color: ${o};
|
|
333
|
+
margin-bottom: 8px;
|
|
276
334
|
}
|
|
277
335
|
|
|
336
|
+
.input-group { display: flex; gap: 8px; }
|
|
337
|
+
|
|
278
338
|
.url-input {
|
|
279
339
|
flex: 1;
|
|
280
340
|
padding: 10px 14px;
|
|
@@ -299,10 +359,13 @@ import{Enbox as ot,defineProtocol as rt,repository as it}from"@enbox/api";import
|
|
|
299
359
|
cursor: pointer;
|
|
300
360
|
white-space: nowrap;
|
|
301
361
|
}
|
|
302
|
-
.go-btn:disabled {
|
|
303
|
-
opacity: 0.4;
|
|
304
|
-
cursor: not-allowed;
|
|
305
|
-
}
|
|
362
|
+
.go-btn:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
306
363
|
.go-btn:not(:disabled):hover { filter: brightness(1.1); }
|
|
307
|
-
|
|
364
|
+
|
|
365
|
+
.url-error {
|
|
366
|
+
margin-top: 8px;
|
|
367
|
+
font-size: 12px;
|
|
368
|
+
color: ${n?"#ff6b6b":"#c0392b"};
|
|
369
|
+
}
|
|
370
|
+
`}var Q=[{name:"Enbox",url:"https://enbox-wallet.pages.dev",description:"Manage your digital identity and data"},{name:"Prism",url:"https://prism-wallet.pages.dev",description:"A clear view into your digital identity"},{name:"Matcha",url:"https://matcha-wallet.pages.dev",description:"A fresh approach to digital identity"},{name:"Onyx",url:"https://onyx-wallet.pages.dev",description:"A refined home for your digital identity"}];function Pe(n={}){let{wallets:e=Q,walletUrl:t,timeout:o,appName:r,appIcon:i}=n;return{async requestAccess(a){let s=t;return s||(s=await A(e)),q({walletUrl:s,permissionRequests:a.permissionRequests,timeout:o,appName:r,appIcon:i})}}}import{X25519 as Te}from"@enbox/crypto";import{CONNECT_DENIED_TOKEN as ke,ConnectProvider as We}from"@enbox/connect";var Oe=3e5,U=class n{constructor(e){this._requestReceived=!1;this._dappOrigin=e.dappOrigin,this._dappWindow=e.dappWindow,this._recipientPrivateKey=e.recipientPrivateKey,this._requestPromise=new Promise((t,o)=>{this._resolveRequest=t,this._rejectRequest=o}),this._requestPromise.catch(()=>{}),this._messageListener=t=>{this.onMessage(t)},window.addEventListener("message",this._messageListener),this._timeoutId=setTimeout(()=>{this.close(),this._rejectRequest?.(new Error("[@enbox/browser] Timed out waiting for the connect request from the dapp."))},e.timeoutMs)}static async create(e={}){if(typeof window>"u")throw new Error("[@enbox/browser] WalletPostMessageTransport is only available in browser environments.");let t=e.dappWindow??window.opener;if(!t)throw new Error("[@enbox/browser] No opener window: the DWeb Connect page must be opened as a popup by the dapp.");let o=Le(e.dappOrigin),r=await Te.generateKey(),i={kty:"OKP",crv:"X25519",x:r.x},a=new n({dappOrigin:o,dappWindow:t,recipientPrivateKey:r,timeoutMs:e.timeoutMs??Oe});return t.postMessage({type:x,walletEpk:i,walletOrigin:globalThis.location.origin},o),a}get dappOrigin(){return this._dappOrigin}async awaitRequest(){return await this._requestPromise}sendResponse(e){this._dappWindow.postMessage({type:C,payload:e},this._dappOrigin),this.close()}deny(){this.sendResponse(ke)}close(){clearTimeout(this._timeoutId),this._messageListener!==void 0&&(window.removeEventListener("message",this._messageListener),this._messageListener=void 0)}onMessage(e){let t=O(e,this._dappOrigin,this._dappWindow);if(t!==void 0&&!(t.type!==_||this._requestReceived)){if(this._requestReceived=!0,typeof t.jwe!="string"){this.settleRequest(new Error("[@enbox/browser] Connect request message did not carry a ciphertext payload."));return}this.openRequest(t.jwe)}}async openRequest(e){try{let t=await We.openRequest({jwe:e,decryption:{mode:"ecdh-es",recipientPrivateKey:this._recipientPrivateKey,walletOrigin:globalThis.location.origin}});if(t.reply.mode!=="post_message"){this.settleRequest(new Error("[@enbox/browser] Connect request over the popup channel must use the `post_message` reply mode."));return}this.settleRequest(t)}catch(t){this.settleRequest(t instanceof Error?t:new Error(String(t)))}}settleRequest(e){if(clearTimeout(this._timeoutId),e instanceof Error){this.close(),this._rejectRequest?.(e);return}this._resolveRequest?.(e)}};function Le(n){if(n!==void 0)return new URL(n).origin;if(document.referrer)return new URL(document.referrer).origin;throw new Error("[@enbox/browser] Unable to determine the dapp origin: no `dappOrigin` option was provided and `document.referrer` is empty.")}export{rt as AuthManager,it as AuthSession,Pe as BrowserConnectHandler,ct as CONNECT_DENIED_TOKEN,dt as ConnectProvider,Q as DEFAULT_WALLETS,x as DWEB_CONNECT_LOADED_MESSAGE_TYPE,D as DWEB_CONNECT_PATH,_ as DWEB_CONNECT_REQUEST_MESSAGE_TYPE,C as DWEB_CONNECT_RESPONSE_MESSAGE_TYPE,et as Enbox,L as PopupClientTransport,R as PopupWindowClosedError,Y as WALLET_WELL_KNOWN_PATH,at as WalletConnect,U as WalletPostMessageTransport,De as activatePolyfills,te as cacheResponse,Ae as clearDrlCache,q as connectViaPopup,qe as deactivatePolyfills,tt as defineProtocol,ee as fetchResource,z as getDwnEndpoints,Z as handleEvent,st as normalizeProtocolRequests,v as parseDrlUrl,J as probeWalletWellKnown,nt as repository,A as showWalletSelector};
|
|
308
371
|
//# sourceMappingURL=browser.mjs.map
|