@qinzhehan/rainbow-wallet-kit 0.1.1 → 0.1.2
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/README.md +1 -0
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +283 -262
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,6 +5,7 @@ RainbowKit-style React wallet component packaged as ESM, CJS, UMD and TypeScript
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- MetaMask, OKX Wallet and Phantom adapters
|
|
8
|
+
- OKX Wallet detection supports both `window.okxwallet` and EIP-1193 provider arrays
|
|
8
9
|
- EventEmitter-driven wallet state with BroadcastChannel/localStorage multi-tab sync
|
|
9
10
|
- Nonce signature verification hooks
|
|
10
11
|
- JWT auto-renewal helper
|
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)}async function R(t){var s;if(!((s=t.auth)!=null&&s.enabled))return;if(!t.auth.getNonce||!t.auth.verifySignature)throw new h("AUTH_FAILED","Wallet auth requires getNonce and verifySignature callbacks.");const e=await t.auth.getNonce({wallet:t.wallet,address:t.account.address,chainType:t.account.chainType,audience:t.auth.audience}),n=I({nonce:e,address:t.account.address,wallet:t.wallet,chainType:t.account.chainType,audience:t.auth.audience}),a=await t.signMessage(n).catch(m=>{throw new h("SIGNATURE_REJECTED","Wallet signature was rejected or failed.",m)});return t.auth.verifySignature({wallet:t.wallet,address:t.account.address,chainType:t.account.chainType,audience:t.auth.audience,nonce:e,message:n,signature:a})}async function P(t){var e;if(!((e=t.auth)!=null&&e.enabled)||!t.auth.refreshJwt||!t.session||!t.wallet||!t.account)return t.session;try{return await t.auth.refreshJwt({token:t.session.token,refreshToken:t.session.refreshToken,wallet:t.wallet,address:t.account.address})}catch(n){throw new h("JWT_REFRESH_FAILED","JWT refresh failed.",n)}}function H(t,e=6e4){return Math.max(0,t.expiresAt-Date.now()-e)}const k={metamask:"https://metamask.app.link/dapp/",okx:"okx://wallet/dapp/url?dappUrl=",phantom:"https://phantom.app/ul/browse/"};function G(){return typeof navigator>"u"?!1:/Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent)}function W(t){return t!=null&&t.dappUrl?t.dappUrl:typeof window>"u"?"":window.location.href}function U(t,e,n){const a=encodeURIComponent(e);return t==="metamask"?`${(n==null?void 0:n.metamask)??k.metamask}${e.replace(/^https?:\/\//,"")}`:t==="okx"?`${(n==null?void 0:n.okx)??k.okx}${a}`:`${(n==null?void 0:n.phantom)??k.phantom}${a}?ref=${a}`}class ${constructor(){E(this,"listeners",new Map)}on(e,n){const a=this.listeners.get(e)??new Set;return a.add(n),this.listeners.set(e,a),()=>this.off(e,n)}off(e,n){var a;(a=this.listeners.get(e))==null||a.delete(n)}emit(e,n){var a;(a=this.listeners.get(e))==null||a.forEach(s=>s(n))}removeAllListeners(){this.listeners.clear()}}function O(t){var n;if(t instanceof h)return t;const e=t;return(e==null?void 0:e.code)===4001||(e==null?void 0:e.code)==="ACTION_REJECTED"?new h("USER_REJECTED",e.message??"User rejected wallet request.",t):(n=e==null?void 0:e.message)!=null&&n.toLowerCase().includes("timeout")?new h("CONNECT_TIMEOUT",e.message,t):new h("UNKNOWN",(e==null?void 0:e.message)??"Unexpected wallet error.",t)}function j(t,e,n){let a;const s=new Promise((m,y)=>{a=setTimeout(()=>y(new h("CONNECT_TIMEOUT",n)),e)});return Promise.race([t,s]).finally(()=>{a&&clearTimeout(a)})}const Y="rainbow-wallet-kit:state";class F{constructor(e,n){E(this,"channel");E(this,"tabId",Math.random().toString(36).slice(2));E(this,"handleStorage",e=>{if(!(e.key!==this.storageKey||!e.newValue))try{const n=JSON.parse(e.newValue);n.tabId!==this.tabId&&this.emitter.emit("state",n.state)}catch{}});this.emitter=e,this.storageKey=n,!(typeof window>"u")&&("BroadcastChannel"in window&&(this.channel=new BroadcastChannel(Y),this.channel.onmessage=a=>{var s;((s=a.data)==null?void 0:s.tabId)!==this.tabId&&this.emitter.emit("state",a.data.state)}),window.addEventListener("storage",this.handleStorage))}publish(e){var a;if(typeof window>"u")return;const n={tabId:this.tabId,state:e};localStorage.setItem(this.storageKey,JSON.stringify(n)),(a=this.channel)==null||a.postMessage(n)}read(){if(typeof window>"u")return;const e=localStorage.getItem(this.storageKey);if(e)try{return JSON.parse(e).state}catch{return}}destroy(){var e;(e=this.channel)==null||e.close(),typeof window<"u"&&window.removeEventListener("storage",this.handleStorage)}}function D(t){var a,s,m;if(typeof window>"u")return;const e=t==="okx"?(a=window.okxwallet)==null?void 0:a.ethereum:window.ethereum,n=(e==null?void 0:e.providers)??((s=window.ethereum)==null?void 0:s.providers);if(n!=null&&n.length){const y=n.find(f=>t==="metamask"?f.isMetaMask&&!f.isOkxWallet:f.isOkxWallet);if(y)return y}if(t==="metamask"&&(e!=null&&e.isMetaMask)&&!e.isOkxWallet||t==="okx"&&(e!=null&&e.isOkxWallet||(m=window.okxwallet)!=null&&m.ethereum))return e}function X(t){if(t)return Number.parseInt(t,16)}function _(t){return{id:t.id,name:t.name,chainType:"evm",icon:t.icon,installed:()=>!!D(t.id),connect:async()=>{const e=D(t.id);if(!e)throw new h("PROVIDER_NOT_FOUND",`${t.name} provider was not found.`);const n=await e.request({method:"eth_requestAccounts"}),a=await e.request({method:"eth_chainId"}).catch(()=>{}),s=n[0];if(!s)throw new h("PROVIDER_NOT_FOUND",`${t.name} did not return an address.`);return{address:s,chainType:"evm",chainId:X(a)}},signMessage:async(e,n)=>{const a=D(t.id);if(!a)throw new h("PROVIDER_NOT_FOUND",`${t.name} provider was not found.`);return a.request({method:"personal_sign",params:[e,n.address]})},getDeepLink:e=>U(t.id,e,t.deepLinks)}}function b(){var t,e;if(!(typeof window>"u"))return(e=(t=window.phantom)==null?void 0:t.solana)!=null&&e.isPhantom?window.phantom.solana:void 0}function Q(t){let e="";return t.forEach(n=>{e+=String.fromCharCode(n)}),btoa(e)}function Z(t){return{id:"phantom",name:"Phantom",chainType:"solana",icon:"P",installed:()=>!!b(),connect:async()=>{const e=b();if(!e)throw new h("PROVIDER_NOT_FOUND","Phantom provider was not found.");const a=(await e.connect()).publicKey.toString();return{address:a,publicKey:a,chainType:"solana",chainId:"solana:mainnet"}},disconnect:async()=>{var e,n;await((n=(e=b())==null?void 0:e.disconnect)==null?void 0:n.call(e))},signMessage:async e=>{const n=b();if(!n)throw new h("PROVIDER_NOT_FOUND","Phantom provider was not found.");const a=new TextEncoder().encode(e),{signature:s}=await n.signMessage(a,"utf8");return Q(s)},getDeepLink:e=>U("phantom",e,t)}}function J(t){return[_({id:"metamask",name:"MetaMask",icon:"M",deepLinks:t}),_({id:"okx",name:"OKX Wallet",icon:"O",deepLinks:t}),Z(t)]}const L=3e4,ee="rainbow-wallet-kit:wallet-state",te={status:"idle",updatedAt:Date.now()},S=u.createContext(void 0);function ne({children:t,auth:e,deepLinks:n,connectTimeoutMs:a=L,storageKey:s=ee,initialWallet:m,autoConnect:y}){const f=u.useRef(new $),T=u.useRef(null),[o,v]=u.useState(te),i=u.useMemo(()=>J(n),[n]),w=u.useCallback(r=>{var c;v(r),f.current.emit("state",r),(c=T.current)==null||c.publish(r)},[]),N=u.useCallback(async r=>{const c=i.find(l=>l.id===r);if(!c)return;if(!c.installed()&&(n==null?void 0:n.enabled)!==!1&&(n!=null&&n.openOnConnect)&&G()){window.location.href=c.getDeepLink(W(n));return}if(!c.installed()){const l=new h("PROVIDER_NOT_FOUND",`${c.name} extension was not found.`);throw w({status:"error",wallet:r,error:l,updatedAt:Date.now()}),f.current.emit("error",l),l}const g={...o,status:"connecting",wallet:r,error:void 0,updatedAt:Date.now()};w(g);try{const l=await j(c.connect(),a,`${c.name} connection timed out.`),p=await R({auth:e,wallet:r,account:l,signMessage:q=>c.signMessage(q,l)});w({status:"connected",wallet:r,account:l,auth:p,updatedAt:Date.now()}),f.current.emit("accountChanged",l)}catch(l){const p=O(l);throw w({status:"error",wallet:r,error:p,updatedAt:Date.now()}),f.current.emit("error",p),p}},[e,a,n,w,o,i]),C=u.useCallback(r=>{const c=i.find(g=>g.id===r);!c||(n==null?void 0:n.enabled)===!1||typeof window>"u"||(window.location.href=c.getDeepLink(W(n)))},[n,i]),A=u.useCallback(async()=>{var g;const r=i.find(l=>l.id===o.wallet);await((g=r==null?void 0:r.disconnect)==null?void 0:g.call(r));const c={status:"disconnected",updatedAt:Date.now()};w(c),f.current.emit("disconnect",void 0)},[w,o.wallet,i]),x=u.useCallback(async()=>{const r=await P({auth:e,session:o.auth,wallet:o.wallet,account:o.account});r&&o.status==="connected"&&w({...o,auth:r,updatedAt:Date.now()})},[e,w,o]);u.useEffect(()=>{const r=new F(f.current,s);T.current=r;const c=r.read();c&&v(c);const g=f.current.on("state",l=>{v(p=>l.updatedAt>=p.updatedAt?l:p)});return()=>{g(),r.destroy()}},[s]),u.useEffect(()=>{y&&m&&N(m).catch(()=>{})},[y,N,m]),u.useEffect(()=>{if(!o.auth||o.status!=="connected")return;const r=H(o.auth,e==null?void 0:e.renewalWindowMs),c=window.setTimeout(()=>{x().catch(g=>{const l=O(g);w({...o,status:"error",error:l,updatedAt:Date.now()})})},r);return()=>window.clearTimeout(c)},[e==null?void 0:e.renewalWindowMs,w,x,o]);const V=u.useMemo(()=>({state:o,wallets:i,connect:N,disconnect:A,openWalletApp:C,refreshAuth:x}),[N,A,C,x,o,i]);return d.jsx(S.Provider,{value:V,children:t})}function K(){const t=u.useContext(S);if(!t)throw new Error("useWallet must be used inside WalletProvider.");return t}function ae({label:t="Connect Wallet",className:e="",preferredWallets:n,onError:a}){const{state:s,wallets:m,connect:y,disconnect:f}=K(),[T,o]=u.useState(!1),v=n!=null&&n.length?n.flatMap(i=>m.filter(w=>w.id===i)):m;return s.status==="connected"&&s.account?d.jsxs("div",{className:`rwk-root ${e}`,children:[d.jsxs("button",{className:"rwk-account",type:"button",onClick:()=>o(i=>!i),children:[d.jsx("span",{className:"rwk-status-dot"}),d.jsx("span",{children:M(s.account.address)})]}),T?d.jsxs("div",{className:"rwk-panel",role:"dialog","aria-label":"Wallet account",children:[d.jsxs("div",{className:"rwk-account-row",children:[d.jsx("span",{children:s.wallet}),d.jsx("strong",{children:M(s.account.address)})]}),d.jsx("button",{className:"rwk-disconnect",type:"button",onClick:()=>void f(),children:"Disconnect"})]}):null]}):d.jsxs("div",{className:`rwk-root ${e}`,children:[d.jsx("button",{className:"rwk-connect",type:"button",disabled:s.status==="connecting",onClick:()=>o(i=>!i),children:s.status==="connecting"?"Connecting...":t}),T?d.jsxs("div",{className:"rwk-panel",role:"dialog","aria-label":"Connect wallet",children:[v.map(i=>d.jsxs("button",{className:"rwk-wallet",type:"button",onClick:()=>{y(i.id).then(()=>o(!1)).catch(w=>a==null?void 0:a(w))},children:[d.jsx("span",{className:"rwk-wallet-icon",children:i.icon}),d.jsx("span",{children:i.name}),d.jsx("small",{children:i.installed()?"Detected":"Not installed"})]},i.id)),s.error?d.jsx("p",{className:"rwk-error",children:s.error.message}):null]}):null]})}function M(t){return t.length<=12?t:`${t.slice(0,6)}...${t.slice(-4)}`}exports.ConnectWalletButton=ae;exports.EventEmitter=$;exports.WalletContext=S;exports.WalletKitError=h;exports.WalletProvider=ne;exports.WalletStateSync=F;exports.authenticateWallet=R;exports.createNonceMessage=I;exports.createWalletAdapters=J;exports.normalizeWalletError=O;exports.refreshJwtSession=P;exports.useWallet=K;exports.withTimeout=j;
|
|
1
|
+
"use strict";var H=Object.defineProperty;var G=(e,t,n)=>t in e?H(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var N=(e,t,n)=>G(e,typeof t!="symbol"?t+"":t,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("react/jsx-runtime"),w=require("react");class f extends Error{constructor(n,a,s){super(a);N(this,"code");N(this,"cause");this.name="WalletKitError",this.code=n,this.cause=s}}function R(e){return[e.audience??"Wallet Login","",`Wallet: ${e.wallet}`,`Address: ${e.address}`,`Chain: ${e.chainType}`,`Nonce: ${e.nonce}`,`Issued At: ${new Date().toISOString()}`].join(`
|
|
2
|
+
`)}async function j(e){var s;if(!((s=e.auth)!=null&&s.enabled))return;if(!e.auth.getNonce||!e.auth.verifySignature)throw new f("AUTH_FAILED","Wallet auth requires getNonce and verifySignature callbacks.");const t=await e.auth.getNonce({wallet:e.wallet,address:e.account.address,chainType:e.account.chainType,audience:e.auth.audience}),n=R({nonce:t,address:e.account.address,wallet:e.wallet,chainType:e.account.chainType,audience:e.auth.audience}),a=await e.signMessage(n).catch(m=>{throw new f("SIGNATURE_REJECTED","Wallet signature was rejected or failed.",m)});return e.auth.verifySignature({wallet:e.wallet,address:e.account.address,chainType:e.account.chainType,audience:e.auth.audience,nonce:t,message:n,signature:a})}async function U(e){var t;if(!((t=e.auth)!=null&&t.enabled)||!e.auth.refreshJwt||!e.session||!e.wallet||!e.account)return e.session;try{return await e.auth.refreshJwt({token:e.session.token,refreshToken:e.session.refreshToken,wallet:e.wallet,address:e.account.address})}catch(n){throw new f("JWT_REFRESH_FAILED","JWT refresh failed.",n)}}function X(e,t=6e4){return Math.max(0,e.expiresAt-Date.now()-t)}const S={metamask:"https://metamask.app.link/dapp/",okx:"okx://wallet/dapp/url?dappUrl=",phantom:"https://phantom.app/ul/browse/"};function Y(){return typeof navigator>"u"?!1:/Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent)}function _(e){return e!=null&&e.dappUrl?e.dappUrl:typeof window>"u"?"":window.location.href}function $(e,t,n){const a=encodeURIComponent(t);return e==="metamask"?`${(n==null?void 0:n.metamask)??S.metamask}${t.replace(/^https?:\/\//,"")}`:e==="okx"?`${(n==null?void 0:n.okx)??S.okx}${a}`:`${(n==null?void 0:n.phantom)??S.phantom}${a}?ref=${a}`}class K{constructor(){N(this,"listeners",new Map)}on(t,n){const a=this.listeners.get(t)??new Set;return a.add(n),this.listeners.set(t,a),()=>this.off(t,n)}off(t,n){var a;(a=this.listeners.get(t))==null||a.delete(n)}emit(t,n){var a;(a=this.listeners.get(t))==null||a.forEach(s=>s(n))}removeAllListeners(){this.listeners.clear()}}function p(e){var n;if(e instanceof f)return e;const t=e;return(t==null?void 0:t.code)===4001||(t==null?void 0:t.code)==="ACTION_REJECTED"?new f("USER_REJECTED",t.message??"User rejected wallet request.",e):(n=t==null?void 0:t.message)!=null&&n.toLowerCase().includes("timeout")?new f("CONNECT_TIMEOUT",t.message,e):new f("UNKNOWN",(t==null?void 0:t.message)??"Unexpected wallet error.",e)}function F(e,t,n){let a;const s=new Promise((m,y)=>{a=setTimeout(()=>y(new f("CONNECT_TIMEOUT",n)),t)});return Promise.race([e,s]).finally(()=>{a&&clearTimeout(a)})}const Q="rainbow-wallet-kit:state";class J{constructor(t,n){N(this,"channel");N(this,"tabId",Math.random().toString(36).slice(2));N(this,"handleStorage",t=>{if(!(t.key!==this.storageKey||!t.newValue))try{const n=JSON.parse(t.newValue);n.tabId!==this.tabId&&this.emitter.emit("state",n.state)}catch{}});this.emitter=t,this.storageKey=n,!(typeof window>"u")&&("BroadcastChannel"in window&&(this.channel=new BroadcastChannel(Q),this.channel.onmessage=a=>{var s;((s=a.data)==null?void 0:s.tabId)!==this.tabId&&this.emitter.emit("state",a.data.state)}),window.addEventListener("storage",this.handleStorage))}publish(t){var a;if(typeof window>"u")return;const n={tabId:this.tabId,state:t};localStorage.setItem(this.storageKey,JSON.stringify(n)),(a=this.channel)==null||a.postMessage(n)}read(){if(typeof window>"u")return;const t=localStorage.getItem(this.storageKey);if(t)try{return JSON.parse(t).state}catch{return}}destroy(){var t;(t=this.channel)==null||t.close(),typeof window<"u"&&window.removeEventListener("storage",this.handleStorage)}}function C(e){var m,y;if(typeof window>"u")return;const t=Z(e),n=t.flatMap(u=>u.providers??[]),a=v([...t,...n]);if(e==="okx"){const u=a.find(O);if(u)return u;if((m=window.okxwallet)!=null&&m.request)return window.okxwallet}if(n!=null&&n.length){const u=n.find(E=>e==="metamask"?E.isMetaMask&&!E.isOkxWallet:O(E));if(u)return u}const s=e==="metamask"?window.ethereum:((y=window.okxwallet)==null?void 0:y.ethereum)??window.ethereum;if(e==="metamask"&&(s!=null&&s.isMetaMask)&&!O(s)||e==="okx"&&s&&O(s))return s}function Z(e){var n,a;const t=[window.ethereum,window.okxwallet,(n=window.okxwallet)==null?void 0:n.ethereum];return v(e==="metamask"?[window.ethereum,...((a=window.ethereum)==null?void 0:a.providers)??[]]:t)}function v(e){return e.filter((t,n,a)=>!!(t!=null&&t.request)&&a.indexOf(t)===n)}function O(e){return!!(e!=null&&e.isOkxWallet||e!=null&&e.isOKExWallet||e!=null&&e.isOKXWallet)}function L(e){if(e)return Number.parseInt(e,16)}function P(e){return{id:e.id,name:e.name,chainType:"evm",icon:e.icon,installed:()=>!!C(e.id),connect:async()=>{const t=C(e.id);if(!t)throw new f("PROVIDER_NOT_FOUND",`${e.name} provider was not found.`);const n=await t.request({method:"eth_requestAccounts"}),a=await t.request({method:"eth_chainId"}).catch(()=>{}),s=n[0];if(!s)throw new f("PROVIDER_NOT_FOUND",`${e.name} did not return an address.`);return{address:s,chainType:"evm",chainId:L(a)}},signMessage:async(t,n)=>{const a=C(e.id);if(!a)throw new f("PROVIDER_NOT_FOUND",`${e.name} provider was not found.`);return a.request({method:"personal_sign",params:[t,n.address]})},getDeepLink:t=>$(e.id,t,e.deepLinks)}}function D(){var e,t;if(!(typeof window>"u"))return(t=(e=window.phantom)==null?void 0:e.solana)!=null&&t.isPhantom?window.phantom.solana:void 0}function ee(e){let t="";return e.forEach(n=>{t+=String.fromCharCode(n)}),btoa(t)}function te(e){return{id:"phantom",name:"Phantom",chainType:"solana",icon:"P",installed:()=>!!D(),connect:async()=>{const t=D();if(!t)throw new f("PROVIDER_NOT_FOUND","Phantom provider was not found.");const a=(await t.connect()).publicKey.toString();return{address:a,publicKey:a,chainType:"solana",chainId:"solana:mainnet"}},disconnect:async()=>{var t,n;await((n=(t=D())==null?void 0:t.disconnect)==null?void 0:n.call(t))},signMessage:async t=>{const n=D();if(!n)throw new f("PROVIDER_NOT_FOUND","Phantom provider was not found.");const a=new TextEncoder().encode(t),{signature:s}=await n.signMessage(a,"utf8");return ee(s)},getDeepLink:t=>$("phantom",t,e)}}function q(e){return[P({id:"metamask",name:"MetaMask",icon:"M",deepLinks:e}),P({id:"okx",name:"OKX Wallet",icon:"O",deepLinks:e}),te(e)]}const ne=3e4,ae="rainbow-wallet-kit:wallet-state",se={status:"idle",updatedAt:Date.now()},A=w.createContext(void 0);function oe({children:e,auth:t,deepLinks:n,connectTimeoutMs:a=ne,storageKey:s=ae,initialWallet:m,autoConnect:y}){const u=w.useRef(new K),E=w.useRef(null),[r,x]=w.useState(se),i=w.useMemo(()=>q(n),[n]),h=w.useCallback(o=>{var c;x(o),u.current.emit("state",o),(c=E.current)==null||c.publish(o)},[]),k=w.useCallback(async o=>{const c=i.find(l=>l.id===o);if(!c)return;if(!c.installed()&&(n==null?void 0:n.enabled)!==!1&&(n!=null&&n.openOnConnect)&&Y()){window.location.href=c.getDeepLink(_(n));return}if(!c.installed()){const l=new f("PROVIDER_NOT_FOUND",`${c.name} extension was not found.`);throw h({status:"error",wallet:o,error:l,updatedAt:Date.now()}),u.current.emit("error",l),l}const g={...r,status:"connecting",wallet:o,error:void 0,updatedAt:Date.now()};h(g);try{const l=await F(c.connect(),a,`${c.name} connection timed out.`),T=await j({auth:t,wallet:o,account:l,signMessage:z=>c.signMessage(z,l)});h({status:"connected",wallet:o,account:l,auth:T,updatedAt:Date.now()}),u.current.emit("accountChanged",l)}catch(l){const T=p(l);throw h({status:"error",wallet:o,error:T,updatedAt:Date.now()}),u.current.emit("error",T),T}},[t,a,n,h,r,i]),W=w.useCallback(o=>{const c=i.find(g=>g.id===o);!c||(n==null?void 0:n.enabled)===!1||typeof window>"u"||(window.location.href=c.getDeepLink(_(n)))},[n,i]),M=w.useCallback(async()=>{var g;const o=i.find(l=>l.id===r.wallet);await((g=o==null?void 0:o.disconnect)==null?void 0:g.call(o));const c={status:"disconnected",updatedAt:Date.now()};h(c),u.current.emit("disconnect",void 0)},[h,r.wallet,i]),b=w.useCallback(async()=>{const o=await U({auth:t,session:r.auth,wallet:r.wallet,account:r.account});o&&r.status==="connected"&&h({...r,auth:o,updatedAt:Date.now()})},[t,h,r]);w.useEffect(()=>{const o=new J(u.current,s);E.current=o;const c=o.read();c&&x(c);const g=u.current.on("state",l=>{x(T=>l.updatedAt>=T.updatedAt?l:T)});return()=>{g(),o.destroy()}},[s]),w.useEffect(()=>{y&&m&&k(m).catch(()=>{})},[y,k,m]),w.useEffect(()=>{if(!r.auth||r.status!=="connected")return;const o=X(r.auth,t==null?void 0:t.renewalWindowMs),c=window.setTimeout(()=>{b().catch(g=>{const l=p(g);h({...r,status:"error",error:l,updatedAt:Date.now()})})},o);return()=>window.clearTimeout(c)},[t==null?void 0:t.renewalWindowMs,h,b,r]);const V=w.useMemo(()=>({state:r,wallets:i,connect:k,disconnect:M,openWalletApp:W,refreshAuth:b}),[k,M,W,b,r,i]);return d.jsx(A.Provider,{value:V,children:e})}function B(){const e=w.useContext(A);if(!e)throw new Error("useWallet must be used inside WalletProvider.");return e}function re({label:e="Connect Wallet",className:t="",preferredWallets:n,onError:a}){const{state:s,wallets:m,connect:y,disconnect:u}=B(),[E,r]=w.useState(!1),x=n!=null&&n.length?n.flatMap(i=>m.filter(h=>h.id===i)):m;return s.status==="connected"&&s.account?d.jsxs("div",{className:`rwk-root ${t}`,children:[d.jsxs("button",{className:"rwk-account",type:"button",onClick:()=>r(i=>!i),children:[d.jsx("span",{className:"rwk-status-dot"}),d.jsx("span",{children:I(s.account.address)})]}),E?d.jsxs("div",{className:"rwk-panel",role:"dialog","aria-label":"Wallet account",children:[d.jsxs("div",{className:"rwk-account-row",children:[d.jsx("span",{children:s.wallet}),d.jsx("strong",{children:I(s.account.address)})]}),d.jsx("button",{className:"rwk-disconnect",type:"button",onClick:()=>void u(),children:"Disconnect"})]}):null]}):d.jsxs("div",{className:`rwk-root ${t}`,children:[d.jsx("button",{className:"rwk-connect",type:"button",disabled:s.status==="connecting",onClick:()=>r(i=>!i),children:s.status==="connecting"?"Connecting...":e}),E?d.jsxs("div",{className:"rwk-panel",role:"dialog","aria-label":"Connect wallet",children:[x.map(i=>d.jsxs("button",{className:"rwk-wallet",type:"button",onClick:()=>{y(i.id).then(()=>r(!1)).catch(h=>a==null?void 0:a(h))},children:[d.jsx("span",{className:"rwk-wallet-icon",children:i.icon}),d.jsx("span",{children:i.name}),d.jsx("small",{children:i.installed()?"Detected":"Not installed"})]},i.id)),s.error?d.jsx("p",{className:"rwk-error",children:s.error.message}):null]}):null]})}function I(e){return e.length<=12?e:`${e.slice(0,6)}...${e.slice(-4)}`}exports.ConnectWalletButton=re;exports.EventEmitter=K;exports.WalletContext=A;exports.WalletKitError=f;exports.WalletProvider=oe;exports.WalletStateSync=J;exports.authenticateWallet=j;exports.createNonceMessage=R;exports.createWalletAdapters=q;exports.normalizeWalletError=p;exports.refreshJwtSession=U;exports.useWallet=B;exports.withTimeout=F;
|
|
3
3
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/types.ts","../src/core/auth.ts","../src/core/deepLinks.ts","../src/core/eventEmitter.ts","../src/core/errors.ts","../src/core/storageSync.ts","../src/wallets/eip1193.ts","../src/wallets/phantom.ts","../src/wallets/index.ts","../src/react/WalletProvider.tsx","../src/react/useWallet.ts","../src/react/ConnectWalletButton.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nexport type ChainType = 'evm' | 'solana';\nexport type WalletId = 'metamask' | 'okx' | 'phantom';\nexport type WalletStatus = 'idle' | 'connecting' | 'connected' | 'disconnected' | 'error';\n\nexport interface WalletAccount {\n address: string;\n chainType: ChainType;\n chainId?: string | number;\n publicKey?: string;\n}\n\nexport interface WalletState {\n status: WalletStatus;\n wallet?: WalletId;\n account?: WalletAccount;\n auth?: AuthSession;\n error?: WalletKitError;\n updatedAt: number;\n}\n\nexport interface AuthSession {\n token: string;\n expiresAt: number;\n refreshToken?: string;\n}\n\nexport interface NonceRequest {\n wallet: WalletId;\n address: string;\n chainType: ChainType;\n audience?: string;\n}\n\nexport interface VerifySignaturePayload extends NonceRequest {\n nonce: string;\n message: string;\n signature: string;\n}\n\nexport interface JwtRefreshRequest {\n token: string;\n refreshToken?: string;\n wallet: WalletId;\n address: string;\n}\n\nexport interface WalletAuthConfig {\n enabled?: boolean;\n audience?: string;\n renewalWindowMs?: number;\n getNonce?: (request: NonceRequest) => Promise<string>;\n verifySignature?: (payload: VerifySignaturePayload) => Promise<AuthSession>;\n refreshJwt?: (request: JwtRefreshRequest) => Promise<AuthSession>;\n}\n\nexport interface DeepLinkConfig {\n enabled?: boolean;\n openOnConnect?: boolean;\n dappUrl?: string;\n metamask?: string;\n okx?: string;\n phantom?: string;\n}\n\nexport interface WalletKitOptions {\n auth?: WalletAuthConfig;\n deepLinks?: DeepLinkConfig;\n connectTimeoutMs?: number;\n storageKey?: string;\n}\n\nexport interface WalletProviderProps extends WalletKitOptions {\n children: ReactNode;\n initialWallet?: WalletId;\n autoConnect?: boolean;\n}\n\nexport type WalletKitErrorCode =\n | 'PROVIDER_NOT_FOUND'\n | 'USER_REJECTED'\n | 'CONNECT_TIMEOUT'\n | 'SIGNATURE_REJECTED'\n | 'AUTH_FAILED'\n | 'JWT_REFRESH_FAILED'\n | 'UNSUPPORTED_CHAIN'\n | 'UNKNOWN';\n\nexport class WalletKitError extends Error {\n code: WalletKitErrorCode;\n cause?: unknown;\n\n constructor(code: WalletKitErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = 'WalletKitError';\n this.code = code;\n this.cause = cause;\n }\n}\n\nexport interface WalletAdapter {\n id: WalletId;\n name: string;\n chainType: ChainType;\n icon: string;\n installed: () => boolean;\n connect: () => Promise<WalletAccount>;\n disconnect?: () => Promise<void>;\n signMessage: (message: string, account: WalletAccount) => Promise<string>;\n getDeepLink: (targetUrl: string) => string;\n}\n\nexport type WalletEventMap = {\n state: WalletState;\n accountChanged: WalletAccount | undefined;\n disconnect: undefined;\n error: WalletKitError;\n};\n\nexport interface WalletContextValue {\n state: WalletState;\n wallets: WalletAdapter[];\n connect: (wallet: WalletId) => Promise<void>;\n disconnect: () => Promise<void>;\n openWalletApp: (wallet: WalletId) => void;\n refreshAuth: () => Promise<void>;\n}\n","import { WalletKitError } from '../types';\nimport type { AuthSession, WalletAccount, WalletAuthConfig, WalletId } from '../types';\n\nexport function createNonceMessage(input: {\n nonce: string;\n address: string;\n wallet: WalletId;\n chainType: string;\n audience?: string;\n}): string {\n return [\n input.audience ?? 'Wallet Login',\n '',\n `Wallet: ${input.wallet}`,\n `Address: ${input.address}`,\n `Chain: ${input.chainType}`,\n `Nonce: ${input.nonce}`,\n `Issued At: ${new Date().toISOString()}`,\n ].join('\\n');\n}\n\nexport async function authenticateWallet(input: {\n auth?: WalletAuthConfig;\n wallet: WalletId;\n account: WalletAccount;\n signMessage: (message: string) => Promise<string>;\n}): Promise<AuthSession | undefined> {\n if (!input.auth?.enabled) return undefined;\n if (!input.auth.getNonce || !input.auth.verifySignature) {\n throw new WalletKitError('AUTH_FAILED', 'Wallet auth requires getNonce and verifySignature callbacks.');\n }\n\n const nonce = await input.auth.getNonce({\n wallet: input.wallet,\n address: input.account.address,\n chainType: input.account.chainType,\n audience: input.auth.audience,\n });\n const message = createNonceMessage({\n nonce,\n address: input.account.address,\n wallet: input.wallet,\n chainType: input.account.chainType,\n audience: input.auth.audience,\n });\n const signature = await input.signMessage(message).catch((error) => {\n throw new WalletKitError('SIGNATURE_REJECTED', 'Wallet signature was rejected or failed.', error);\n });\n\n return input.auth.verifySignature({\n wallet: input.wallet,\n address: input.account.address,\n chainType: input.account.chainType,\n audience: input.auth.audience,\n nonce,\n message,\n signature,\n });\n}\n\nexport async function refreshJwtSession(input: {\n auth?: WalletAuthConfig;\n session?: AuthSession;\n wallet?: WalletId;\n account?: WalletAccount;\n}): Promise<AuthSession | undefined> {\n if (!input.auth?.enabled || !input.auth.refreshJwt || !input.session || !input.wallet || !input.account) {\n return input.session;\n }\n\n try {\n return await input.auth.refreshJwt({\n token: input.session.token,\n refreshToken: input.session.refreshToken,\n wallet: input.wallet,\n address: input.account.address,\n });\n } catch (error) {\n throw new WalletKitError('JWT_REFRESH_FAILED', 'JWT refresh failed.', error);\n }\n}\n\nexport function getRenewalDelay(session: AuthSession, windowMs = 60_000): number {\n return Math.max(0, session.expiresAt - Date.now() - windowMs);\n}\n","import type { DeepLinkConfig, WalletId } from '../types';\n\nconst DEFAULT_DEEP_LINKS: Required<Pick<DeepLinkConfig, 'metamask' | 'okx' | 'phantom'>> = {\n metamask: 'https://metamask.app.link/dapp/',\n okx: 'okx://wallet/dapp/url?dappUrl=',\n phantom: 'https://phantom.app/ul/browse/',\n};\n\nexport function isMobileH5(): boolean {\n if (typeof navigator === 'undefined') return false;\n return /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent);\n}\n\nexport function resolveDappUrl(config?: DeepLinkConfig): string {\n if (config?.dappUrl) return config.dappUrl;\n if (typeof window === 'undefined') return '';\n return window.location.href;\n}\n\nexport function getWalletDeepLink(wallet: WalletId, targetUrl: string, config?: DeepLinkConfig): string {\n const encoded = encodeURIComponent(targetUrl);\n if (wallet === 'metamask') return `${config?.metamask ?? DEFAULT_DEEP_LINKS.metamask}${targetUrl.replace(/^https?:\\/\\//, '')}`;\n if (wallet === 'okx') return `${config?.okx ?? DEFAULT_DEEP_LINKS.okx}${encoded}`;\n return `${config?.phantom ?? DEFAULT_DEEP_LINKS.phantom}${encoded}?ref=${encoded}`;\n}\n","type Listener<T> = (payload: T) => void;\n\nexport class EventEmitter<Events extends Record<string, unknown>> {\n private listeners = new Map<keyof Events, Set<Listener<Events[keyof Events]>>>();\n\n on<Key extends keyof Events>(event: Key, listener: Listener<Events[Key]>): () => void {\n const listeners = this.listeners.get(event) ?? new Set();\n listeners.add(listener as Listener<Events[keyof Events]>);\n this.listeners.set(event, listeners);\n return () => this.off(event, listener);\n }\n\n off<Key extends keyof Events>(event: Key, listener: Listener<Events[Key]>): void {\n this.listeners.get(event)?.delete(listener as Listener<Events[keyof Events]>);\n }\n\n emit<Key extends keyof Events>(event: Key, payload: Events[Key]): void {\n this.listeners.get(event)?.forEach((listener) => listener(payload));\n }\n\n removeAllListeners(): void {\n this.listeners.clear();\n }\n}\n","import { WalletKitError } from '../types';\n\nexport function normalizeWalletError(error: unknown): WalletKitError {\n if (error instanceof WalletKitError) return error;\n\n const maybe = error as { code?: number | string; message?: string } | undefined;\n if (maybe?.code === 4001 || maybe?.code === 'ACTION_REJECTED') {\n return new WalletKitError('USER_REJECTED', maybe.message ?? 'User rejected wallet request.', error);\n }\n\n if (maybe?.message?.toLowerCase().includes('timeout')) {\n return new WalletKitError('CONNECT_TIMEOUT', maybe.message, error);\n }\n\n return new WalletKitError('UNKNOWN', maybe?.message ?? 'Unexpected wallet error.', error);\n}\n\nexport function withTimeout<T>(promise: Promise<T>, timeoutMs: number, message: string): Promise<T> {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<T>((_, reject) => {\n timeout = setTimeout(() => reject(new WalletKitError('CONNECT_TIMEOUT', message)), timeoutMs);\n });\n\n return Promise.race([promise, timeoutPromise]).finally(() => {\n if (timeout) clearTimeout(timeout);\n });\n}\n","import { EventEmitter } from './eventEmitter';\nimport type { WalletEventMap, WalletState } from '../types';\n\nconst SYNC_EVENT = 'rainbow-wallet-kit:state';\n\nexport class WalletStateSync {\n private channel?: BroadcastChannel;\n private tabId = Math.random().toString(36).slice(2);\n\n constructor(\n private emitter: EventEmitter<WalletEventMap>,\n private storageKey: string,\n ) {\n if (typeof window === 'undefined') return;\n\n if ('BroadcastChannel' in window) {\n this.channel = new BroadcastChannel(SYNC_EVENT);\n this.channel.onmessage = (event: MessageEvent<{ tabId: string; state: WalletState }>) => {\n if (event.data?.tabId !== this.tabId) {\n this.emitter.emit('state', event.data.state);\n }\n };\n }\n\n window.addEventListener('storage', this.handleStorage);\n }\n\n publish(state: WalletState): void {\n if (typeof window === 'undefined') return;\n const payload = { tabId: this.tabId, state };\n localStorage.setItem(this.storageKey, JSON.stringify(payload));\n this.channel?.postMessage(payload);\n }\n\n read(): WalletState | undefined {\n if (typeof window === 'undefined') return undefined;\n const raw = localStorage.getItem(this.storageKey);\n if (!raw) return undefined;\n\n try {\n const parsed = JSON.parse(raw) as { state?: WalletState };\n return parsed.state;\n } catch {\n return undefined;\n }\n }\n\n destroy(): void {\n this.channel?.close();\n if (typeof window !== 'undefined') {\n window.removeEventListener('storage', this.handleStorage);\n }\n }\n\n private handleStorage = (event: StorageEvent) => {\n if (event.key !== this.storageKey || !event.newValue) return;\n try {\n const payload = JSON.parse(event.newValue) as { tabId: string; state: WalletState };\n if (payload.tabId !== this.tabId) {\n this.emitter.emit('state', payload.state);\n }\n } catch {\n // Ignore malformed cross-tab payloads from older package versions.\n }\n };\n}\n","import { getWalletDeepLink } from '../core/deepLinks';\nimport { WalletKitError } from '../types';\nimport type { DeepLinkConfig, WalletAccount, WalletAdapter, WalletId } from '../types';\nimport type { Eip1193Provider } from './providerTypes';\n\nfunction pickInjectedProvider(wallet: WalletId): Eip1193Provider | undefined {\n if (typeof window === 'undefined') return undefined;\n\n const injected = wallet === 'okx' ? window.okxwallet?.ethereum : window.ethereum;\n const providers = injected?.providers ?? window.ethereum?.providers;\n if (providers?.length) {\n const matched = providers.find((provider) => {\n if (wallet === 'metamask') return provider.isMetaMask && !provider.isOkxWallet;\n return provider.isOkxWallet;\n });\n if (matched) return matched;\n }\n\n if (wallet === 'metamask' && injected?.isMetaMask && !injected.isOkxWallet) return injected;\n if (wallet === 'okx' && (injected?.isOkxWallet || window.okxwallet?.ethereum)) return injected;\n return undefined;\n}\n\nfunction hexToNumber(hex?: string): number | undefined {\n if (!hex) return undefined;\n return Number.parseInt(hex, 16);\n}\n\nexport function createEvmAdapter(options: {\n id: Extract<WalletId, 'metamask' | 'okx'>;\n name: string;\n icon: string;\n deepLinks?: DeepLinkConfig;\n}): WalletAdapter {\n return {\n id: options.id,\n name: options.name,\n chainType: 'evm',\n icon: options.icon,\n installed: () => Boolean(pickInjectedProvider(options.id)),\n connect: async (): Promise<WalletAccount> => {\n const provider = pickInjectedProvider(options.id);\n if (!provider) {\n throw new WalletKitError('PROVIDER_NOT_FOUND', `${options.name} provider was not found.`);\n }\n\n const accounts = await provider.request<string[]>({ method: 'eth_requestAccounts' });\n const chainId = await provider.request<string>({ method: 'eth_chainId' }).catch(() => undefined);\n const address = accounts[0];\n if (!address) throw new WalletKitError('PROVIDER_NOT_FOUND', `${options.name} did not return an address.`);\n\n return {\n address,\n chainType: 'evm',\n chainId: hexToNumber(chainId),\n };\n },\n signMessage: async (message: string, account: WalletAccount): Promise<string> => {\n const provider = pickInjectedProvider(options.id);\n if (!provider) throw new WalletKitError('PROVIDER_NOT_FOUND', `${options.name} provider was not found.`);\n return provider.request<string>({\n method: 'personal_sign',\n params: [message, account.address],\n });\n },\n getDeepLink: (targetUrl: string) => getWalletDeepLink(options.id, targetUrl, options.deepLinks),\n };\n}\n","import { getWalletDeepLink } from '../core/deepLinks';\nimport { WalletKitError } from '../types';\nimport type { DeepLinkConfig, WalletAccount, WalletAdapter } from '../types';\nimport type { PhantomSolanaProvider } from './providerTypes';\n\nfunction getProvider(): PhantomSolanaProvider | undefined {\n if (typeof window === 'undefined') return undefined;\n return window.phantom?.solana?.isPhantom ? window.phantom.solana : undefined;\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n let binary = '';\n bytes.forEach((byte) => {\n binary += String.fromCharCode(byte);\n });\n return btoa(binary);\n}\n\nexport function createPhantomAdapter(deepLinks?: DeepLinkConfig): WalletAdapter {\n return {\n id: 'phantom',\n name: 'Phantom',\n chainType: 'solana',\n icon: 'P',\n installed: () => Boolean(getProvider()),\n connect: async (): Promise<WalletAccount> => {\n const provider = getProvider();\n if (!provider) throw new WalletKitError('PROVIDER_NOT_FOUND', 'Phantom provider was not found.');\n const response = await provider.connect();\n const address = response.publicKey.toString();\n return {\n address,\n publicKey: address,\n chainType: 'solana',\n chainId: 'solana:mainnet',\n };\n },\n disconnect: async () => {\n await getProvider()?.disconnect?.();\n },\n signMessage: async (message: string): Promise<string> => {\n const provider = getProvider();\n if (!provider) throw new WalletKitError('PROVIDER_NOT_FOUND', 'Phantom provider was not found.');\n const encoded = new TextEncoder().encode(message);\n const { signature } = await provider.signMessage(encoded, 'utf8');\n return bytesToBase64(signature);\n },\n getDeepLink: (targetUrl: string) => getWalletDeepLink('phantom', targetUrl, deepLinks),\n };\n}\n","import type { DeepLinkConfig, WalletAdapter } from '../types';\nimport { createEvmAdapter } from './eip1193';\nimport { createPhantomAdapter } from './phantom';\n\nexport function createWalletAdapters(deepLinks?: DeepLinkConfig): WalletAdapter[] {\n return [\n createEvmAdapter({ id: 'metamask', name: 'MetaMask', icon: 'M', deepLinks }),\n createEvmAdapter({ id: 'okx', name: 'OKX Wallet', icon: 'O', deepLinks }),\n createPhantomAdapter(deepLinks),\n ];\n}\n","import { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { authenticateWallet, getRenewalDelay, refreshJwtSession } from '../core/auth';\nimport { isMobileH5, resolveDappUrl } from '../core/deepLinks';\nimport { EventEmitter } from '../core/eventEmitter';\nimport { normalizeWalletError, withTimeout } from '../core/errors';\nimport { WalletStateSync } from '../core/storageSync';\nimport { WalletKitError } from '../types';\nimport { createWalletAdapters } from '../wallets';\nimport type { WalletContextValue, WalletEventMap, WalletId, WalletProviderProps, WalletState } from '../types';\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_STORAGE_KEY = 'rainbow-wallet-kit:wallet-state';\n\nconst initialState: WalletState = {\n status: 'idle',\n updatedAt: Date.now(),\n};\n\nexport const WalletContext = createContext<WalletContextValue | undefined>(undefined);\n\nexport function WalletProvider({\n children,\n auth,\n deepLinks,\n connectTimeoutMs = DEFAULT_TIMEOUT_MS,\n storageKey = DEFAULT_STORAGE_KEY,\n initialWallet,\n autoConnect,\n}: WalletProviderProps) {\n const emitterRef = useRef(new EventEmitter<WalletEventMap>());\n const syncRef = useRef<WalletStateSync | null>(null);\n const [state, setState] = useState<WalletState>(initialState);\n const wallets = useMemo(() => createWalletAdapters(deepLinks), [deepLinks]);\n\n const publishState = useCallback((nextState: WalletState) => {\n setState(nextState);\n emitterRef.current.emit('state', nextState);\n syncRef.current?.publish(nextState);\n }, []);\n\n const connect = useCallback(\n async (walletId: WalletId) => {\n const wallet = wallets.find((item) => item.id === walletId);\n if (!wallet) return;\n\n if (!wallet.installed() && deepLinks?.enabled !== false && deepLinks?.openOnConnect && isMobileH5()) {\n window.location.href = wallet.getDeepLink(resolveDappUrl(deepLinks));\n return;\n }\n\n if (!wallet.installed()) {\n const error = new WalletKitError('PROVIDER_NOT_FOUND', `${wallet.name} extension was not found.`);\n publishState({\n status: 'error',\n wallet: walletId,\n error,\n updatedAt: Date.now(),\n });\n emitterRef.current.emit('error', error);\n throw error;\n }\n\n const connectingState: WalletState = {\n ...state,\n status: 'connecting',\n wallet: walletId,\n error: undefined,\n updatedAt: Date.now(),\n };\n publishState(connectingState);\n\n try {\n const account = await withTimeout(\n wallet.connect(),\n connectTimeoutMs,\n `${wallet.name} connection timed out.`,\n );\n const session = await authenticateWallet({\n auth,\n wallet: walletId,\n account,\n signMessage: (message) => wallet.signMessage(message, account),\n });\n publishState({\n status: 'connected',\n wallet: walletId,\n account,\n auth: session,\n updatedAt: Date.now(),\n });\n emitterRef.current.emit('accountChanged', account);\n } catch (error) {\n const normalized = normalizeWalletError(error);\n publishState({\n status: 'error',\n wallet: walletId,\n error: normalized,\n updatedAt: Date.now(),\n });\n emitterRef.current.emit('error', normalized);\n throw normalized;\n }\n },\n [auth, connectTimeoutMs, deepLinks, publishState, state, wallets],\n );\n\n const openWalletApp = useCallback(\n (walletId: WalletId) => {\n const wallet = wallets.find((item) => item.id === walletId);\n if (!wallet || deepLinks?.enabled === false || typeof window === 'undefined') return;\n window.location.href = wallet.getDeepLink(resolveDappUrl(deepLinks));\n },\n [deepLinks, wallets],\n );\n\n const disconnect = useCallback(async () => {\n const wallet = wallets.find((item) => item.id === state.wallet);\n await wallet?.disconnect?.();\n const nextState: WalletState = {\n status: 'disconnected',\n updatedAt: Date.now(),\n };\n publishState(nextState);\n emitterRef.current.emit('disconnect', undefined);\n }, [publishState, state.wallet, wallets]);\n\n const refreshAuth = useCallback(async () => {\n const session = await refreshJwtSession({\n auth,\n session: state.auth,\n wallet: state.wallet,\n account: state.account,\n });\n if (session && state.status === 'connected') {\n publishState({\n ...state,\n auth: session,\n updatedAt: Date.now(),\n });\n }\n }, [auth, publishState, state]);\n\n useEffect(() => {\n const sync = new WalletStateSync(emitterRef.current, storageKey);\n syncRef.current = sync;\n const stored = sync.read();\n if (stored) setState(stored);\n\n const unsubscribe = emitterRef.current.on('state', (nextState) => {\n setState((current) => (nextState.updatedAt >= current.updatedAt ? nextState : current));\n });\n\n return () => {\n unsubscribe();\n sync.destroy();\n };\n }, [storageKey]);\n\n useEffect(() => {\n if (autoConnect && initialWallet) {\n void connect(initialWallet).catch(() => undefined);\n }\n }, [autoConnect, connect, initialWallet]);\n\n useEffect(() => {\n if (!state.auth || state.status !== 'connected') return;\n const delay = getRenewalDelay(state.auth, auth?.renewalWindowMs);\n const timer = window.setTimeout(() => {\n void refreshAuth().catch((error) => {\n const normalized = normalizeWalletError(error);\n publishState({ ...state, status: 'error', error: normalized, updatedAt: Date.now() });\n });\n }, delay);\n return () => window.clearTimeout(timer);\n }, [auth?.renewalWindowMs, publishState, refreshAuth, state]);\n\n const value = useMemo<WalletContextValue>(\n () => ({\n state,\n wallets,\n connect,\n disconnect,\n openWalletApp,\n refreshAuth,\n }),\n [connect, disconnect, openWalletApp, refreshAuth, state, wallets],\n );\n\n return <WalletContext.Provider value={value}>{children}</WalletContext.Provider>;\n}\n","import { useContext } from 'react';\nimport { WalletContext } from './WalletProvider';\n\nexport function useWallet() {\n const context = useContext(WalletContext);\n if (!context) {\n throw new Error('useWallet must be used inside WalletProvider.');\n }\n return context;\n}\n","import { useState } from 'react';\nimport type { WalletId } from '../types';\nimport { useWallet } from './useWallet';\n\nexport interface ConnectWalletButtonProps {\n label?: string;\n className?: string;\n preferredWallets?: WalletId[];\n onError?: (error: unknown) => void;\n}\n\nexport function ConnectWalletButton({\n label = 'Connect Wallet',\n className = '',\n preferredWallets,\n onError,\n}: ConnectWalletButtonProps) {\n const { state, wallets, connect, disconnect } = useWallet();\n const [open, setOpen] = useState(false);\n const orderedWallets = preferredWallets?.length\n ? preferredWallets.flatMap((id) => wallets.filter((wallet) => wallet.id === id))\n : wallets;\n\n if (state.status === 'connected' && state.account) {\n return (\n <div className={`rwk-root ${className}`}>\n <button className=\"rwk-account\" type=\"button\" onClick={() => setOpen((value) => !value)}>\n <span className=\"rwk-status-dot\" />\n <span>{shortenAddress(state.account.address)}</span>\n </button>\n {open ? (\n <div className=\"rwk-panel\" role=\"dialog\" aria-label=\"Wallet account\">\n <div className=\"rwk-account-row\">\n <span>{state.wallet}</span>\n <strong>{shortenAddress(state.account.address)}</strong>\n </div>\n <button className=\"rwk-disconnect\" type=\"button\" onClick={() => void disconnect()}>\n Disconnect\n </button>\n </div>\n ) : null}\n </div>\n );\n }\n\n return (\n <div className={`rwk-root ${className}`}>\n <button\n className=\"rwk-connect\"\n type=\"button\"\n disabled={state.status === 'connecting'}\n onClick={() => setOpen((value) => !value)}\n >\n {state.status === 'connecting' ? 'Connecting...' : label}\n </button>\n {open ? (\n <div className=\"rwk-panel\" role=\"dialog\" aria-label=\"Connect wallet\">\n {orderedWallets.map((wallet) => (\n <button\n className=\"rwk-wallet\"\n key={wallet.id}\n type=\"button\"\n onClick={() => {\n void connect(wallet.id)\n .then(() => setOpen(false))\n .catch((error) => onError?.(error));\n }}\n >\n <span className=\"rwk-wallet-icon\">{wallet.icon}</span>\n <span>{wallet.name}</span>\n <small>{wallet.installed() ? 'Detected' : 'Not installed'}</small>\n </button>\n ))}\n {state.error ? <p className=\"rwk-error\">{state.error.message}</p> : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction shortenAddress(address: string): string {\n if (address.length <= 12) return address;\n return `${address.slice(0, 6)}...${address.slice(-4)}`;\n}\n"],"names":["WalletKitError","code","message","cause","__publicField","createNonceMessage","input","authenticateWallet","_a","nonce","signature","error","refreshJwtSession","getRenewalDelay","session","windowMs","DEFAULT_DEEP_LINKS","isMobileH5","resolveDappUrl","config","getWalletDeepLink","wallet","targetUrl","encoded","EventEmitter","event","listener","listeners","payload","normalizeWalletError","maybe","withTimeout","promise","timeoutMs","timeout","timeoutPromise","_","reject","SYNC_EVENT","WalletStateSync","emitter","storageKey","state","raw","pickInjectedProvider","injected","providers","_b","matched","provider","_c","hexToNumber","hex","createEvmAdapter","options","accounts","chainId","address","account","getProvider","bytesToBase64","bytes","binary","byte","createPhantomAdapter","deepLinks","createWalletAdapters","DEFAULT_TIMEOUT_MS","DEFAULT_STORAGE_KEY","initialState","WalletContext","createContext","WalletProvider","children","auth","connectTimeoutMs","initialWallet","autoConnect","emitterRef","useRef","syncRef","setState","useState","wallets","useMemo","publishState","useCallback","nextState","connect","walletId","item","connectingState","normalized","openWalletApp","disconnect","refreshAuth","useEffect","sync","stored","unsubscribe","current","delay","timer","value","jsx","useWallet","context","useContext","ConnectWalletButton","label","className","preferredWallets","onError","open","setOpen","orderedWallets","id","jsxs","shortenAddress"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/types.ts","../src/core/auth.ts","../src/core/deepLinks.ts","../src/core/eventEmitter.ts","../src/core/errors.ts","../src/core/storageSync.ts","../src/wallets/eip1193.ts","../src/wallets/phantom.ts","../src/wallets/index.ts","../src/react/WalletProvider.tsx","../src/react/useWallet.ts","../src/react/ConnectWalletButton.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nexport type ChainType = 'evm' | 'solana';\nexport type WalletId = 'metamask' | 'okx' | 'phantom';\nexport type WalletStatus = 'idle' | 'connecting' | 'connected' | 'disconnected' | 'error';\n\nexport interface WalletAccount {\n address: string;\n chainType: ChainType;\n chainId?: string | number;\n publicKey?: string;\n}\n\nexport interface WalletState {\n status: WalletStatus;\n wallet?: WalletId;\n account?: WalletAccount;\n auth?: AuthSession;\n error?: WalletKitError;\n updatedAt: number;\n}\n\nexport interface AuthSession {\n token: string;\n expiresAt: number;\n refreshToken?: string;\n}\n\nexport interface NonceRequest {\n wallet: WalletId;\n address: string;\n chainType: ChainType;\n audience?: string;\n}\n\nexport interface VerifySignaturePayload extends NonceRequest {\n nonce: string;\n message: string;\n signature: string;\n}\n\nexport interface JwtRefreshRequest {\n token: string;\n refreshToken?: string;\n wallet: WalletId;\n address: string;\n}\n\nexport interface WalletAuthConfig {\n enabled?: boolean;\n audience?: string;\n renewalWindowMs?: number;\n getNonce?: (request: NonceRequest) => Promise<string>;\n verifySignature?: (payload: VerifySignaturePayload) => Promise<AuthSession>;\n refreshJwt?: (request: JwtRefreshRequest) => Promise<AuthSession>;\n}\n\nexport interface DeepLinkConfig {\n enabled?: boolean;\n openOnConnect?: boolean;\n dappUrl?: string;\n metamask?: string;\n okx?: string;\n phantom?: string;\n}\n\nexport interface WalletKitOptions {\n auth?: WalletAuthConfig;\n deepLinks?: DeepLinkConfig;\n connectTimeoutMs?: number;\n storageKey?: string;\n}\n\nexport interface WalletProviderProps extends WalletKitOptions {\n children: ReactNode;\n initialWallet?: WalletId;\n autoConnect?: boolean;\n}\n\nexport type WalletKitErrorCode =\n | 'PROVIDER_NOT_FOUND'\n | 'USER_REJECTED'\n | 'CONNECT_TIMEOUT'\n | 'SIGNATURE_REJECTED'\n | 'AUTH_FAILED'\n | 'JWT_REFRESH_FAILED'\n | 'UNSUPPORTED_CHAIN'\n | 'UNKNOWN';\n\nexport class WalletKitError extends Error {\n code: WalletKitErrorCode;\n cause?: unknown;\n\n constructor(code: WalletKitErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = 'WalletKitError';\n this.code = code;\n this.cause = cause;\n }\n}\n\nexport interface WalletAdapter {\n id: WalletId;\n name: string;\n chainType: ChainType;\n icon: string;\n installed: () => boolean;\n connect: () => Promise<WalletAccount>;\n disconnect?: () => Promise<void>;\n signMessage: (message: string, account: WalletAccount) => Promise<string>;\n getDeepLink: (targetUrl: string) => string;\n}\n\nexport type WalletEventMap = {\n state: WalletState;\n accountChanged: WalletAccount | undefined;\n disconnect: undefined;\n error: WalletKitError;\n};\n\nexport interface WalletContextValue {\n state: WalletState;\n wallets: WalletAdapter[];\n connect: (wallet: WalletId) => Promise<void>;\n disconnect: () => Promise<void>;\n openWalletApp: (wallet: WalletId) => void;\n refreshAuth: () => Promise<void>;\n}\n","import { WalletKitError } from '../types';\nimport type { AuthSession, WalletAccount, WalletAuthConfig, WalletId } from '../types';\n\nexport function createNonceMessage(input: {\n nonce: string;\n address: string;\n wallet: WalletId;\n chainType: string;\n audience?: string;\n}): string {\n return [\n input.audience ?? 'Wallet Login',\n '',\n `Wallet: ${input.wallet}`,\n `Address: ${input.address}`,\n `Chain: ${input.chainType}`,\n `Nonce: ${input.nonce}`,\n `Issued At: ${new Date().toISOString()}`,\n ].join('\\n');\n}\n\nexport async function authenticateWallet(input: {\n auth?: WalletAuthConfig;\n wallet: WalletId;\n account: WalletAccount;\n signMessage: (message: string) => Promise<string>;\n}): Promise<AuthSession | undefined> {\n if (!input.auth?.enabled) return undefined;\n if (!input.auth.getNonce || !input.auth.verifySignature) {\n throw new WalletKitError('AUTH_FAILED', 'Wallet auth requires getNonce and verifySignature callbacks.');\n }\n\n const nonce = await input.auth.getNonce({\n wallet: input.wallet,\n address: input.account.address,\n chainType: input.account.chainType,\n audience: input.auth.audience,\n });\n const message = createNonceMessage({\n nonce,\n address: input.account.address,\n wallet: input.wallet,\n chainType: input.account.chainType,\n audience: input.auth.audience,\n });\n const signature = await input.signMessage(message).catch((error) => {\n throw new WalletKitError('SIGNATURE_REJECTED', 'Wallet signature was rejected or failed.', error);\n });\n\n return input.auth.verifySignature({\n wallet: input.wallet,\n address: input.account.address,\n chainType: input.account.chainType,\n audience: input.auth.audience,\n nonce,\n message,\n signature,\n });\n}\n\nexport async function refreshJwtSession(input: {\n auth?: WalletAuthConfig;\n session?: AuthSession;\n wallet?: WalletId;\n account?: WalletAccount;\n}): Promise<AuthSession | undefined> {\n if (!input.auth?.enabled || !input.auth.refreshJwt || !input.session || !input.wallet || !input.account) {\n return input.session;\n }\n\n try {\n return await input.auth.refreshJwt({\n token: input.session.token,\n refreshToken: input.session.refreshToken,\n wallet: input.wallet,\n address: input.account.address,\n });\n } catch (error) {\n throw new WalletKitError('JWT_REFRESH_FAILED', 'JWT refresh failed.', error);\n }\n}\n\nexport function getRenewalDelay(session: AuthSession, windowMs = 60_000): number {\n return Math.max(0, session.expiresAt - Date.now() - windowMs);\n}\n","import type { DeepLinkConfig, WalletId } from '../types';\n\nconst DEFAULT_DEEP_LINKS: Required<Pick<DeepLinkConfig, 'metamask' | 'okx' | 'phantom'>> = {\n metamask: 'https://metamask.app.link/dapp/',\n okx: 'okx://wallet/dapp/url?dappUrl=',\n phantom: 'https://phantom.app/ul/browse/',\n};\n\nexport function isMobileH5(): boolean {\n if (typeof navigator === 'undefined') return false;\n return /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent);\n}\n\nexport function resolveDappUrl(config?: DeepLinkConfig): string {\n if (config?.dappUrl) return config.dappUrl;\n if (typeof window === 'undefined') return '';\n return window.location.href;\n}\n\nexport function getWalletDeepLink(wallet: WalletId, targetUrl: string, config?: DeepLinkConfig): string {\n const encoded = encodeURIComponent(targetUrl);\n if (wallet === 'metamask') return `${config?.metamask ?? DEFAULT_DEEP_LINKS.metamask}${targetUrl.replace(/^https?:\\/\\//, '')}`;\n if (wallet === 'okx') return `${config?.okx ?? DEFAULT_DEEP_LINKS.okx}${encoded}`;\n return `${config?.phantom ?? DEFAULT_DEEP_LINKS.phantom}${encoded}?ref=${encoded}`;\n}\n","type Listener<T> = (payload: T) => void;\n\nexport class EventEmitter<Events extends Record<string, unknown>> {\n private listeners = new Map<keyof Events, Set<Listener<Events[keyof Events]>>>();\n\n on<Key extends keyof Events>(event: Key, listener: Listener<Events[Key]>): () => void {\n const listeners = this.listeners.get(event) ?? new Set();\n listeners.add(listener as Listener<Events[keyof Events]>);\n this.listeners.set(event, listeners);\n return () => this.off(event, listener);\n }\n\n off<Key extends keyof Events>(event: Key, listener: Listener<Events[Key]>): void {\n this.listeners.get(event)?.delete(listener as Listener<Events[keyof Events]>);\n }\n\n emit<Key extends keyof Events>(event: Key, payload: Events[Key]): void {\n this.listeners.get(event)?.forEach((listener) => listener(payload));\n }\n\n removeAllListeners(): void {\n this.listeners.clear();\n }\n}\n","import { WalletKitError } from '../types';\n\nexport function normalizeWalletError(error: unknown): WalletKitError {\n if (error instanceof WalletKitError) return error;\n\n const maybe = error as { code?: number | string; message?: string } | undefined;\n if (maybe?.code === 4001 || maybe?.code === 'ACTION_REJECTED') {\n return new WalletKitError('USER_REJECTED', maybe.message ?? 'User rejected wallet request.', error);\n }\n\n if (maybe?.message?.toLowerCase().includes('timeout')) {\n return new WalletKitError('CONNECT_TIMEOUT', maybe.message, error);\n }\n\n return new WalletKitError('UNKNOWN', maybe?.message ?? 'Unexpected wallet error.', error);\n}\n\nexport function withTimeout<T>(promise: Promise<T>, timeoutMs: number, message: string): Promise<T> {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<T>((_, reject) => {\n timeout = setTimeout(() => reject(new WalletKitError('CONNECT_TIMEOUT', message)), timeoutMs);\n });\n\n return Promise.race([promise, timeoutPromise]).finally(() => {\n if (timeout) clearTimeout(timeout);\n });\n}\n","import { EventEmitter } from './eventEmitter';\nimport type { WalletEventMap, WalletState } from '../types';\n\nconst SYNC_EVENT = 'rainbow-wallet-kit:state';\n\nexport class WalletStateSync {\n private channel?: BroadcastChannel;\n private tabId = Math.random().toString(36).slice(2);\n\n constructor(\n private emitter: EventEmitter<WalletEventMap>,\n private storageKey: string,\n ) {\n if (typeof window === 'undefined') return;\n\n if ('BroadcastChannel' in window) {\n this.channel = new BroadcastChannel(SYNC_EVENT);\n this.channel.onmessage = (event: MessageEvent<{ tabId: string; state: WalletState }>) => {\n if (event.data?.tabId !== this.tabId) {\n this.emitter.emit('state', event.data.state);\n }\n };\n }\n\n window.addEventListener('storage', this.handleStorage);\n }\n\n publish(state: WalletState): void {\n if (typeof window === 'undefined') return;\n const payload = { tabId: this.tabId, state };\n localStorage.setItem(this.storageKey, JSON.stringify(payload));\n this.channel?.postMessage(payload);\n }\n\n read(): WalletState | undefined {\n if (typeof window === 'undefined') return undefined;\n const raw = localStorage.getItem(this.storageKey);\n if (!raw) return undefined;\n\n try {\n const parsed = JSON.parse(raw) as { state?: WalletState };\n return parsed.state;\n } catch {\n return undefined;\n }\n }\n\n destroy(): void {\n this.channel?.close();\n if (typeof window !== 'undefined') {\n window.removeEventListener('storage', this.handleStorage);\n }\n }\n\n private handleStorage = (event: StorageEvent) => {\n if (event.key !== this.storageKey || !event.newValue) return;\n try {\n const payload = JSON.parse(event.newValue) as { tabId: string; state: WalletState };\n if (payload.tabId !== this.tabId) {\n this.emitter.emit('state', payload.state);\n }\n } catch {\n // Ignore malformed cross-tab payloads from older package versions.\n }\n };\n}\n","import { getWalletDeepLink } from '../core/deepLinks';\nimport { WalletKitError } from '../types';\nimport type { DeepLinkConfig, WalletAccount, WalletAdapter, WalletId } from '../types';\nimport type { Eip1193Provider } from './providerTypes';\n\nfunction pickInjectedProvider(wallet: WalletId): Eip1193Provider | undefined {\n if (typeof window === 'undefined') return undefined;\n\n const candidates = collectInjectedProviders(wallet);\n const providers = candidates.flatMap((provider) => provider.providers ?? []);\n const allProviders = uniqueProviders([...candidates, ...providers]);\n\n if (wallet === 'okx') {\n const matched = allProviders.find(isOkxProvider);\n if (matched) return matched;\n\n if (window.okxwallet?.request) return window.okxwallet;\n }\n\n if (providers?.length) {\n const matched = providers.find((provider) => {\n if (wallet === 'metamask') return provider.isMetaMask && !provider.isOkxWallet;\n return isOkxProvider(provider);\n });\n if (matched) return matched;\n }\n\n const injected = wallet === 'metamask' ? window.ethereum : window.okxwallet?.ethereum ?? window.ethereum;\n if (wallet === 'metamask' && injected?.isMetaMask && !isOkxProvider(injected)) return injected;\n if (wallet === 'okx' && injected && isOkxProvider(injected)) return injected;\n return undefined;\n}\n\nfunction collectInjectedProviders(wallet: WalletId): Eip1193Provider[] {\n const providers: Array<Eip1193Provider | undefined> = [\n window.ethereum,\n window.okxwallet,\n window.okxwallet?.ethereum,\n ];\n\n if (wallet === 'metamask') {\n return uniqueProviders([window.ethereum, ...(window.ethereum?.providers ?? [])]);\n }\n\n return uniqueProviders(providers);\n}\n\nfunction uniqueProviders(providers: Array<Eip1193Provider | undefined>): Eip1193Provider[] {\n return providers.filter((provider, index, list): provider is Eip1193Provider => {\n return Boolean(provider?.request) && list.indexOf(provider) === index;\n });\n}\n\nfunction isOkxProvider(provider?: Eip1193Provider): boolean {\n return Boolean(provider?.isOkxWallet || provider?.isOKExWallet || provider?.isOKXWallet);\n}\n\nfunction hexToNumber(hex?: string): number | undefined {\n if (!hex) return undefined;\n return Number.parseInt(hex, 16);\n}\n\nexport function createEvmAdapter(options: {\n id: Extract<WalletId, 'metamask' | 'okx'>;\n name: string;\n icon: string;\n deepLinks?: DeepLinkConfig;\n}): WalletAdapter {\n return {\n id: options.id,\n name: options.name,\n chainType: 'evm',\n icon: options.icon,\n installed: () => Boolean(pickInjectedProvider(options.id)),\n connect: async (): Promise<WalletAccount> => {\n const provider = pickInjectedProvider(options.id);\n if (!provider) {\n throw new WalletKitError('PROVIDER_NOT_FOUND', `${options.name} provider was not found.`);\n }\n\n const accounts = await provider.request<string[]>({ method: 'eth_requestAccounts' });\n const chainId = await provider.request<string>({ method: 'eth_chainId' }).catch(() => undefined);\n const address = accounts[0];\n if (!address) throw new WalletKitError('PROVIDER_NOT_FOUND', `${options.name} did not return an address.`);\n\n return {\n address,\n chainType: 'evm',\n chainId: hexToNumber(chainId),\n };\n },\n signMessage: async (message: string, account: WalletAccount): Promise<string> => {\n const provider = pickInjectedProvider(options.id);\n if (!provider) throw new WalletKitError('PROVIDER_NOT_FOUND', `${options.name} provider was not found.`);\n return provider.request<string>({\n method: 'personal_sign',\n params: [message, account.address],\n });\n },\n getDeepLink: (targetUrl: string) => getWalletDeepLink(options.id, targetUrl, options.deepLinks),\n };\n}\n","import { getWalletDeepLink } from '../core/deepLinks';\nimport { WalletKitError } from '../types';\nimport type { DeepLinkConfig, WalletAccount, WalletAdapter } from '../types';\nimport type { PhantomSolanaProvider } from './providerTypes';\n\nfunction getProvider(): PhantomSolanaProvider | undefined {\n if (typeof window === 'undefined') return undefined;\n return window.phantom?.solana?.isPhantom ? window.phantom.solana : undefined;\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n let binary = '';\n bytes.forEach((byte) => {\n binary += String.fromCharCode(byte);\n });\n return btoa(binary);\n}\n\nexport function createPhantomAdapter(deepLinks?: DeepLinkConfig): WalletAdapter {\n return {\n id: 'phantom',\n name: 'Phantom',\n chainType: 'solana',\n icon: 'P',\n installed: () => Boolean(getProvider()),\n connect: async (): Promise<WalletAccount> => {\n const provider = getProvider();\n if (!provider) throw new WalletKitError('PROVIDER_NOT_FOUND', 'Phantom provider was not found.');\n const response = await provider.connect();\n const address = response.publicKey.toString();\n return {\n address,\n publicKey: address,\n chainType: 'solana',\n chainId: 'solana:mainnet',\n };\n },\n disconnect: async () => {\n await getProvider()?.disconnect?.();\n },\n signMessage: async (message: string): Promise<string> => {\n const provider = getProvider();\n if (!provider) throw new WalletKitError('PROVIDER_NOT_FOUND', 'Phantom provider was not found.');\n const encoded = new TextEncoder().encode(message);\n const { signature } = await provider.signMessage(encoded, 'utf8');\n return bytesToBase64(signature);\n },\n getDeepLink: (targetUrl: string) => getWalletDeepLink('phantom', targetUrl, deepLinks),\n };\n}\n","import type { DeepLinkConfig, WalletAdapter } from '../types';\nimport { createEvmAdapter } from './eip1193';\nimport { createPhantomAdapter } from './phantom';\n\nexport function createWalletAdapters(deepLinks?: DeepLinkConfig): WalletAdapter[] {\n return [\n createEvmAdapter({ id: 'metamask', name: 'MetaMask', icon: 'M', deepLinks }),\n createEvmAdapter({ id: 'okx', name: 'OKX Wallet', icon: 'O', deepLinks }),\n createPhantomAdapter(deepLinks),\n ];\n}\n","import { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { authenticateWallet, getRenewalDelay, refreshJwtSession } from '../core/auth';\nimport { isMobileH5, resolveDappUrl } from '../core/deepLinks';\nimport { EventEmitter } from '../core/eventEmitter';\nimport { normalizeWalletError, withTimeout } from '../core/errors';\nimport { WalletStateSync } from '../core/storageSync';\nimport { WalletKitError } from '../types';\nimport { createWalletAdapters } from '../wallets';\nimport type { WalletContextValue, WalletEventMap, WalletId, WalletProviderProps, WalletState } from '../types';\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_STORAGE_KEY = 'rainbow-wallet-kit:wallet-state';\n\nconst initialState: WalletState = {\n status: 'idle',\n updatedAt: Date.now(),\n};\n\nexport const WalletContext = createContext<WalletContextValue | undefined>(undefined);\n\nexport function WalletProvider({\n children,\n auth,\n deepLinks,\n connectTimeoutMs = DEFAULT_TIMEOUT_MS,\n storageKey = DEFAULT_STORAGE_KEY,\n initialWallet,\n autoConnect,\n}: WalletProviderProps) {\n const emitterRef = useRef(new EventEmitter<WalletEventMap>());\n const syncRef = useRef<WalletStateSync | null>(null);\n const [state, setState] = useState<WalletState>(initialState);\n const wallets = useMemo(() => createWalletAdapters(deepLinks), [deepLinks]);\n\n const publishState = useCallback((nextState: WalletState) => {\n setState(nextState);\n emitterRef.current.emit('state', nextState);\n syncRef.current?.publish(nextState);\n }, []);\n\n const connect = useCallback(\n async (walletId: WalletId) => {\n const wallet = wallets.find((item) => item.id === walletId);\n if (!wallet) return;\n\n if (!wallet.installed() && deepLinks?.enabled !== false && deepLinks?.openOnConnect && isMobileH5()) {\n window.location.href = wallet.getDeepLink(resolveDappUrl(deepLinks));\n return;\n }\n\n if (!wallet.installed()) {\n const error = new WalletKitError('PROVIDER_NOT_FOUND', `${wallet.name} extension was not found.`);\n publishState({\n status: 'error',\n wallet: walletId,\n error,\n updatedAt: Date.now(),\n });\n emitterRef.current.emit('error', error);\n throw error;\n }\n\n const connectingState: WalletState = {\n ...state,\n status: 'connecting',\n wallet: walletId,\n error: undefined,\n updatedAt: Date.now(),\n };\n publishState(connectingState);\n\n try {\n const account = await withTimeout(\n wallet.connect(),\n connectTimeoutMs,\n `${wallet.name} connection timed out.`,\n );\n const session = await authenticateWallet({\n auth,\n wallet: walletId,\n account,\n signMessage: (message) => wallet.signMessage(message, account),\n });\n publishState({\n status: 'connected',\n wallet: walletId,\n account,\n auth: session,\n updatedAt: Date.now(),\n });\n emitterRef.current.emit('accountChanged', account);\n } catch (error) {\n const normalized = normalizeWalletError(error);\n publishState({\n status: 'error',\n wallet: walletId,\n error: normalized,\n updatedAt: Date.now(),\n });\n emitterRef.current.emit('error', normalized);\n throw normalized;\n }\n },\n [auth, connectTimeoutMs, deepLinks, publishState, state, wallets],\n );\n\n const openWalletApp = useCallback(\n (walletId: WalletId) => {\n const wallet = wallets.find((item) => item.id === walletId);\n if (!wallet || deepLinks?.enabled === false || typeof window === 'undefined') return;\n window.location.href = wallet.getDeepLink(resolveDappUrl(deepLinks));\n },\n [deepLinks, wallets],\n );\n\n const disconnect = useCallback(async () => {\n const wallet = wallets.find((item) => item.id === state.wallet);\n await wallet?.disconnect?.();\n const nextState: WalletState = {\n status: 'disconnected',\n updatedAt: Date.now(),\n };\n publishState(nextState);\n emitterRef.current.emit('disconnect', undefined);\n }, [publishState, state.wallet, wallets]);\n\n const refreshAuth = useCallback(async () => {\n const session = await refreshJwtSession({\n auth,\n session: state.auth,\n wallet: state.wallet,\n account: state.account,\n });\n if (session && state.status === 'connected') {\n publishState({\n ...state,\n auth: session,\n updatedAt: Date.now(),\n });\n }\n }, [auth, publishState, state]);\n\n useEffect(() => {\n const sync = new WalletStateSync(emitterRef.current, storageKey);\n syncRef.current = sync;\n const stored = sync.read();\n if (stored) setState(stored);\n\n const unsubscribe = emitterRef.current.on('state', (nextState) => {\n setState((current) => (nextState.updatedAt >= current.updatedAt ? nextState : current));\n });\n\n return () => {\n unsubscribe();\n sync.destroy();\n };\n }, [storageKey]);\n\n useEffect(() => {\n if (autoConnect && initialWallet) {\n void connect(initialWallet).catch(() => undefined);\n }\n }, [autoConnect, connect, initialWallet]);\n\n useEffect(() => {\n if (!state.auth || state.status !== 'connected') return;\n const delay = getRenewalDelay(state.auth, auth?.renewalWindowMs);\n const timer = window.setTimeout(() => {\n void refreshAuth().catch((error) => {\n const normalized = normalizeWalletError(error);\n publishState({ ...state, status: 'error', error: normalized, updatedAt: Date.now() });\n });\n }, delay);\n return () => window.clearTimeout(timer);\n }, [auth?.renewalWindowMs, publishState, refreshAuth, state]);\n\n const value = useMemo<WalletContextValue>(\n () => ({\n state,\n wallets,\n connect,\n disconnect,\n openWalletApp,\n refreshAuth,\n }),\n [connect, disconnect, openWalletApp, refreshAuth, state, wallets],\n );\n\n return <WalletContext.Provider value={value}>{children}</WalletContext.Provider>;\n}\n","import { useContext } from 'react';\nimport { WalletContext } from './WalletProvider';\n\nexport function useWallet() {\n const context = useContext(WalletContext);\n if (!context) {\n throw new Error('useWallet must be used inside WalletProvider.');\n }\n return context;\n}\n","import { useState } from 'react';\nimport type { WalletId } from '../types';\nimport { useWallet } from './useWallet';\n\nexport interface ConnectWalletButtonProps {\n label?: string;\n className?: string;\n preferredWallets?: WalletId[];\n onError?: (error: unknown) => void;\n}\n\nexport function ConnectWalletButton({\n label = 'Connect Wallet',\n className = '',\n preferredWallets,\n onError,\n}: ConnectWalletButtonProps) {\n const { state, wallets, connect, disconnect } = useWallet();\n const [open, setOpen] = useState(false);\n const orderedWallets = preferredWallets?.length\n ? preferredWallets.flatMap((id) => wallets.filter((wallet) => wallet.id === id))\n : wallets;\n\n if (state.status === 'connected' && state.account) {\n return (\n <div className={`rwk-root ${className}`}>\n <button className=\"rwk-account\" type=\"button\" onClick={() => setOpen((value) => !value)}>\n <span className=\"rwk-status-dot\" />\n <span>{shortenAddress(state.account.address)}</span>\n </button>\n {open ? (\n <div className=\"rwk-panel\" role=\"dialog\" aria-label=\"Wallet account\">\n <div className=\"rwk-account-row\">\n <span>{state.wallet}</span>\n <strong>{shortenAddress(state.account.address)}</strong>\n </div>\n <button className=\"rwk-disconnect\" type=\"button\" onClick={() => void disconnect()}>\n Disconnect\n </button>\n </div>\n ) : null}\n </div>\n );\n }\n\n return (\n <div className={`rwk-root ${className}`}>\n <button\n className=\"rwk-connect\"\n type=\"button\"\n disabled={state.status === 'connecting'}\n onClick={() => setOpen((value) => !value)}\n >\n {state.status === 'connecting' ? 'Connecting...' : label}\n </button>\n {open ? (\n <div className=\"rwk-panel\" role=\"dialog\" aria-label=\"Connect wallet\">\n {orderedWallets.map((wallet) => (\n <button\n className=\"rwk-wallet\"\n key={wallet.id}\n type=\"button\"\n onClick={() => {\n void connect(wallet.id)\n .then(() => setOpen(false))\n .catch((error) => onError?.(error));\n }}\n >\n <span className=\"rwk-wallet-icon\">{wallet.icon}</span>\n <span>{wallet.name}</span>\n <small>{wallet.installed() ? 'Detected' : 'Not installed'}</small>\n </button>\n ))}\n {state.error ? <p className=\"rwk-error\">{state.error.message}</p> : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction shortenAddress(address: string): string {\n if (address.length <= 12) return address;\n return `${address.slice(0, 6)}...${address.slice(-4)}`;\n}\n"],"names":["WalletKitError","code","message","cause","__publicField","createNonceMessage","input","authenticateWallet","_a","nonce","signature","error","refreshJwtSession","getRenewalDelay","session","windowMs","DEFAULT_DEEP_LINKS","isMobileH5","resolveDappUrl","config","getWalletDeepLink","wallet","targetUrl","encoded","EventEmitter","event","listener","listeners","payload","normalizeWalletError","maybe","withTimeout","promise","timeoutMs","timeout","timeoutPromise","_","reject","SYNC_EVENT","WalletStateSync","emitter","storageKey","state","raw","pickInjectedProvider","candidates","collectInjectedProviders","providers","provider","allProviders","uniqueProviders","matched","isOkxProvider","injected","_b","index","list","hexToNumber","hex","createEvmAdapter","options","accounts","chainId","address","account","getProvider","bytesToBase64","bytes","binary","byte","createPhantomAdapter","deepLinks","createWalletAdapters","DEFAULT_TIMEOUT_MS","DEFAULT_STORAGE_KEY","initialState","WalletContext","createContext","WalletProvider","children","auth","connectTimeoutMs","initialWallet","autoConnect","emitterRef","useRef","syncRef","setState","useState","wallets","useMemo","publishState","useCallback","nextState","connect","walletId","item","connectingState","normalized","openWalletApp","disconnect","refreshAuth","useEffect","sync","stored","unsubscribe","current","delay","timer","value","jsx","useWallet","context","useContext","ConnectWalletButton","label","className","preferredWallets","onError","open","setOpen","orderedWallets","id","jsxs","shortenAddress"],"mappings":"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"}
|