@rango-dev/wallets-react 0.0.0-experimental-767249ce-20261007 → 0.0.0-experimental-2938686c-20261012
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/hub/autoConnect.d.ts.map +1 -1
- package/dist/hub/autoConnect.test.d.ts +2 -0
- package/dist/hub/autoConnect.test.d.ts.map +1 -0
- package/dist/hub/errors.d.ts +9 -0
- package/dist/hub/errors.d.ts.map +1 -0
- package/dist/hub/errors.test.d.ts +2 -0
- package/dist/hub/errors.test.d.ts.map +1 -0
- package/dist/hub/useHubAdapter.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +4 -4
- package/package.json +13 -13
- package/src/hub/autoConnect.test.ts +172 -0
- package/src/hub/autoConnect.ts +6 -0
- package/src/hub/errors.test.ts +91 -0
- package/src/hub/errors.ts +45 -0
- package/src/hub/useHubAdapter.ts +15 -10
- package/src/walletEvents.test.tsx +2 -2
- package/dist/helpers.d.ts +0 -3
- package/dist/helpers.d.ts.map +0 -1
- package/src/helpers.ts +0 -43
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autoConnect.d.ts","sourceRoot":"","sources":["../../src/hub/autoConnect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM9D,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"autoConnect.d.ts","sourceRoot":"","sources":["../../src/hub/autoConnect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM9D,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,cAAc,CAAC;AAgNtB,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,MAAM,EAAE,MAAM,GAAG,CAAC;IAClB,cAAc,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE,CAAC,UAAU,GAAG,QAAQ,CAAC,EAAE,CAAC;IACpC,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B,GAAG,OAAO,CAAC,IAAI,CAAC,CA8EhB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autoConnect.test.d.ts","sourceRoot":"","sources":["../../src/hub/autoConnect.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WalletConnectOrigin } from '../events.js';
|
|
2
|
+
import type { WalletType } from '@hub3js/core';
|
|
3
|
+
import type { Namespace } from '@hub3js/namespaces';
|
|
4
|
+
export declare function reportConnectionFailure(error: unknown, options: {
|
|
5
|
+
walletType: WalletType;
|
|
6
|
+
namespace: Namespace;
|
|
7
|
+
origin: WalletConnectOrigin;
|
|
8
|
+
}): void;
|
|
9
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/hub/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAsBpD,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE;IACP,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,mBAAmB,CAAC;CAC7B,GACA,IAAI,CAaN"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.test.d.ts","sourceRoot":"","sources":["../../src/hub/errors.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHubAdapter.d.ts","sourceRoot":"","sources":["../../src/hub/useHubAdapter.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"useHubAdapter.d.ts","sourceRoot":"","sources":["../../src/hub/useHubAdapter.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,cAAc,CAAC;AAqCzD,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,GAAG;IAChE,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,eAAe,CAghBvE"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var Ce=Object.defineProperty;var o=(e,t)=>Ce(e,"name",{value:t,configurable:!0});import Ze from"react";import{createContext as he}from"react";var A="Context hasn't been initialized yet.",Ee={async connect(){throw new Error(A)},async disconnect(){throw new Error(A)},async disconnectAll(){throw new Error(A)},async suggestAndConnect(){throw new Error(A)},state(){throw new Error(A)},canSwitchNetworkTo(){throw new Error(A)},getWalletInfo(){throw new Error(A)},getSigners(){throw new Error(A)},hubProvider(){throw new Error(A)}},O=he(Ee);import{convertEvmBlockchainMetaToEvmChainInfo as Ie,formatAddressWithNetwork as xe,getBlockChainNameFromId as be,getSupportedChainsFromProvider as Se}from"@rango-dev/internal-blockchains";import{AccountId as Le}from"caip";import{isEvmBlockchain as De}from"rango-types";var B=(m=>(m.CONNECTED="connected",m.CONNECTING="connecting",m.REACHABLE="reachable",m.INSTALLED="installed",m.ACCOUNTS="accounts",m.NETWORK="network",m.NAMESPACE_DISCONNECTED="namespace_disconnected",m.PROVIDER_DISCONNECTED="provider_disconnected",m))(B||{});import{WalletTypes as b}from"@rango-dev/provider-all";var P="hub-v1-last-connected-wallets",z=[b.LEDGER,b.TREZOR,b.LEDGER_WALLET,b.WALLET_CONNECT_2,b.TON_CONNECT,b.DEFAULT];import{CAIP_BITCOIN_CHAIN_ID as ye,CAIP_BITCOINCASH_CHAIN_ID as ve,CAIP_DOGECOIN_CHAIN_ID as we,CAIP_LITECOIN_CHAIN_ID as Ne,CAIP_ZCASH_CHAIN_ID as ge}from"@hub3js/bip122";import{CAIP_TRON_CHAIN_ID as Pe}from"@hub3js/tron";import{CAIP_NAMESPACE as Te}from"@hub3js/tvm";import{formatAddressWithNetwork as ke}from"@rango-dev/internal-blockchains";import{AccountId as Ae}from"caip";import{Err as U,Ok as X}from"ts-results";function We(e){return typeof e=="string"?e:["solana","xrpl","stellar"].includes(e.namespace.toLowerCase())?e.namespace.toUpperCase():e.namespace.toLowerCase()==="eip155"?"ETH":e.reference===ye?"BTC":e.reference===ge?"ZCASH":e.reference===Ne?"LTC":e.reference===we?"DOGE":e.reference===ve?"BCH":e.namespace.toLowerCase()===Te?"TON":e.namespace==="sui"||e.reference===Pe?e.reference.toUpperCase():e.namespace==="starknet"?e.namespace.toUpperCase():e.reference}o(We,"mapCaipNamespaceToLegacyNetworkName");function L(e){let{chainId:t,address:n}=Ae.parse(e),l=We(t);return ke(n,l)}o(L,"fromAccountIdToLegacyAddressFormat");async function q(e){return e.reduce(async(t,n)=>{let l=await t;try{let r=await n();return[...l,new X(r)]}catch(r){return[...l,new U(r)]}},Promise.resolve([]))}o(q,"runSequentiallyWithoutFailure");function Z(e){return typeof e=="object"&&!Array.isArray(e)}o(Z,"isConnectResultEvm");function J(e){return Array.isArray(e)}o(J,"isConnectResultSolana");function ee(e){let t=new Set,n=[],l=o((u,d)=>{n=n.filter(m=>m.key!==u?!0:(m.resolve(d),!1))},"removeKeyFromQueue"),r=o(async()=>{let u=n.find(f=>!t.has(f.key));if(!u)return;let{task:d,resolve:m,key:w}=u;t.add(w);try{let f=await d();m(new X(f))}catch(f){e?.onError&&e.onError(f,{removeCurrentKeyFromQueue:()=>l(w,new U(f))}),m(new U(f))}finally{let f=n.findIndex(s=>s.key===w);f>=0&&n.splice(f,1),t.delete(w),r()}},"processQueue");return o(async(u,d)=>new Promise(m=>{n.push({task:u,resolve:m,key:d}),r()}),"queueTask")}o(ee,"createQueue");function te(e){return!!e.allBlockChains?.length&&!!e.autoConnect}o(te,"shouldTryAutoConnect");var I=class{static{o(this,"Persistor")}getItem(t){let n=localStorage.getItem(t);return n?JSON.parse(n):null}setItem(t,n){localStorage.setItem(t,JSON.stringify(n))}removeItem(t){localStorage.removeItem(t)}};var W=class{static{o(this,"LastConnectedWalletsFromStorage")}#e;constructor(t){this.#e=t}addWallet(t,n){if(this.#e===P)return this.#t(t,n);throw new Error("Not implemented")}removeWallets(t){if(this.#e===P)return this.#n(t);throw new Error("Not implemented")}list(){if(this.#e===P)return this.#o();throw new Error("Not implemented")}removeNamespacesFromWallet(t,n){if(this.#e===P)return this.#r(t,n);throw new Error("Not implemented")}#o(){return new I().getItem(P)||{}}#t(t,n){let l=new I,r=l.getItem(this.#e)||{},C=n;if(r[t]){let u=r[t];C=u.concat(n.filter(d=>!u.some(m=>m.namespace===d.namespace)))}l.setItem(this.#e,{...r,[t]:C})}#n(t){let n=new I,l=n.getItem(this.#e)||{};if(!t){n.setItem(this.#e,{});return}t.forEach(r=>{l[r]&&delete l[r]}),n.setItem(this.#e,l)}#r(t,n){let u=(new I().getItem(this.#e)||{})[t]?.filter(d=>!n.includes(d.namespace));this.#n([t]),u?.length>0&&this.#t(t,u)}};var _e=new W(P);function ne(e,t,n,l){let r=e.get(t.provider);if(!r)throw new Error("Currently all the events have assigned to a provider. The event doesn't include one.",{cause:t});let C=t.namespace,u=C?r.findByNamespace(C):void 0,d=null,m=null,w;if(u){let[i]=u.state();d=i().accounts,m=i().network,l.lastConnectAttemptParams[t.provider]&&(w=l.lastConnectAttemptParams[t.provider].find(p=>p.namespace===C)?.derivationPath)}let[f]=r.state(),s={connected:f().connected,connecting:f().connecting,installed:f().installed,accounts:d,network:m,reachable:!0,derivationPath:w},a=r.info()?.metadata.properties?.find(i=>i.name==="details"),c={supportedBlockchains:Se(r,l.allBlockChains),isContractWallet:a?.value?.isContractWallet??!1,isHub:!0,namespace:C};switch(t.type){case"provider_detected":n(t.provider,"installed",!0,s,c);break;case"provider_connecting":n(t.provider,"connecting",t.value,s,c);break;case"provider_connected":n(t.provider,"connected",!0,s,c);break;case"provider_disconnected":n(t.provider,"provider_disconnected",t.provider,s,c),n(t.provider,"connected",!1,s,c),n(t.provider,"accounts",null,s,c);break;case"namespace_disconnected":_e.removeNamespacesFromWallet(t.provider,[t.namespace]),n(t.provider,"namespace_disconnected",t.namespace,s,{...c,namespace:t.namespace});break;case"namespace_connected":case"namespace_account_switched":{t.type==="namespace_account_switched"&&n(t.provider,"namespace_disconnected",t.namespace,s,c);let i=[];c.isContractWallet?i=t.accounts.map(p=>{let{chainId:E,address:N}=Le.parse(p);if(typeof E=="string")throw new Error("Should be in CAIP format");let y=be(E.reference,c.supportedBlockchains);return y?xe(N,y):L(p)}):i=t.accounts.map(p=>L(p)),n(t.provider,"accounts",i,s,{...c,namespace:t.namespace})}break;case"namespace_network_switched":n(t.provider,"network",t.network,s,{...c,namespace:t.namespace});break}}o(ne,"mapHubEventsToLegacy");function K(e,t){if(!e.network)return;let n=t.filter(De);return Ie(n)[e.network]}o(K,"convertNamespaceNetworkToEvmChainId");function oe(e,t){return K(e,t)||e.network}o(oe,"tryConvertNamespaceNetworkToChainInfo");function R(e){return Z(e)?{accounts:e.accounts,network:e.network}:J(e)?{accounts:e,network:null}:{accounts:[e],network:null}}o(R,"transformHubResultToLegacyResult");function re(e,t){let n=e.getAll();t.filter(r=>!n.get(r.id)).forEach(r=>{e.add(r.id,r),r.init()}),n.forEach(r=>{t.some(u=>u.id===r.id)||e.remove(r.id)})}o(re,"synchronizeHubWithConfigProviders");function ae(e){return e.namespaceId==="Solana"}o(ae,"isSolanaNamespace");function F(e){return e.namespaceId==="EVM"}o(F,"isEvmNamespace");function se(e){return e.namespaceId==="UTXO"}o(se,"isUtxoNamespace");import{utils as Ge}from"@hub3js/evm";import{getSupportedChainsFromNamespace as Ye,getSupportedChainsFromProvider as Qe}from"@rango-dev/internal-blockchains";import{useEffect as G,useRef as Y,useState as Ve}from"react";import{Ok as ze,Result as Xe}from"ts-results";import{getBlockChainNameFromId as Oe}from"@rango-dev/internal-blockchains";var T="walletEvent",H=(C=>(C.WALLET_DETECTED="walletDetected",C.WALLET_CONNECT_INITIATED="walletConnectInitiated",C.WALLET_CONNECTED="walletConnected",C.WALLET_CONNECT_FAILED="walletConnectFailed",C.WALLET_DISCONNECTED="walletDisconnected",C))(H||{}),ce=new Set;function ie(e,t){ce.has(e)||z.includes(e)||(ce.add(e),t?.emit(T,{type:"walletDetected",payload:{walletName:e}}))}o(ie,"emitWalletDetectedOnce");function j(e,t){return e?Oe(e,t||[]):null}o(j,"toBlockchainName");import{debug as Be}from"@rango-dev/logging-core";function le(e,t,n){let l=n instanceof Error?n:new Error(String(n));Be(l,{context:{method:e,args:t},tags:{type:"wallet-error"}})}o(le,"logError");function Re(e,t){return(...n)=>{try{let l=t(...n);return l instanceof Promise?l.catch(r=>{throw le(e,n,r),r}):l}catch(l){throw le(e,n,l),l}}}o(Re,"withErrorLogging");function pe(e){let t=Object.entries(e).map(([n,l])=>[n,Re(n,l.bind(e))]);return Object.fromEntries(t)}o(pe,"withErrorLoggingApi");import{Result as Fe}from"ts-results";function $(e,t){return{walletName:e,namespace:t.namespace,chain:t.network||null,origin:"auto"}}o($,"createAutoConnectEventPayload");function He(e){return e.namespace==="EVM"}o(He,"isEvmNamespaceInput");var M=new W(P);async function je(e,t,n){let{getHub:l,allBlockChains:r,emitter:C}=n,u=l().get(e);if(!u)throw new Error(`You should add ${e} to provider first then call 'connect'.`);if(!t)throw new Error("Passing namespace to `connect` is required. ");let d=[];t.forEach(a=>{let c=a.namespace,i=u.findByNamespace(c);if(!i)throw new Error(`We couldn't find any provider matched with your request namespace. (requested namespace: ${a.namespace})`);d.push([a,i])});let m=d.map(([a,c])=>{let p=(He(a)?K(a,r||[]):void 0)||a.network;return async()=>{let E;F(c)?E=o(async()=>c.connect(p),"connectNamespacePromise"):E=o(async()=>c.connect(),"connectNamespacePromise");let N=$(e,a);try{let y=await E();C?.emit(T,{type:"walletConnected",payload:{...N,chain:j(R(y).network,r)}})}catch(y){throw C?.emit(T,{type:"walletConnectFailed",payload:N}),y instanceof Error?y:new Error(y)}}}),w=await q(m),f=d.filter((a,c)=>w[c].err).map(a=>a[0]);if(f.length>0&&M.removeNamespacesFromWallet(e,f.map(a=>a.namespace)),!w.some(a=>a.ok))throw new Error(`No namespace connected for ${e}`);return Fe.all(...w.filter(a=>a.ok)).unwrap()}o(je,"eagerConnect");async function Me(e,t){let n=[],l=[],r=[],C=[];e.forEach(d=>{let m=t.findByNamespace(d.namespace);m?(n.push(d),C.push(async()=>await m.canEagerConnect())):r.push(d)});let u=await q(C);return n.forEach((d,m)=>{u[m].ok&&u[m].val?l.push(d):r.push(d)}),{successNamespaces:l,failedNamespaces:r}}o(Me,"tryRunCanEagerConnect");async function ue(e){let{getHub:t,allBlockChains:n,wallets:l,emitter:r}=e,C=M.list(),u=Object.keys(C),d=[];if(u.length){let m=[],w=l?.map(f=>typeof f=="string"?f:f.id);u.forEach(async f=>{if(w&&!w.includes(f)){console.warn("Trying to run auto connect for a wallet which is not included in config. Desired wallet:",f),d.push(f);return}let s=t().get(f),a=C[f].map(p=>({namespace:p.namespace,network:p.network}));if(!a.length||!s){d.push(f);return}a.forEach(p=>{r?.emit(T,{type:"walletConnectInitiated",payload:$(f,p)})});let{successNamespaces:c,failedNamespaces:i}=await Me(a,s);if(i.forEach(p=>{r?.emit(T,{type:"walletConnectFailed",payload:$(f,p)})}),c.length)i.length&&M.removeNamespacesFromWallet(s.id,i.map(p=>p.namespace));else{d.push(f);return}m.push(je(f,c,{allBlockChains:n,getHub:t,emitter:r}).catch(p=>console.warn(p)))}),M.removeWallets(d),await Promise.all(m)}}o(ue,"autoConnect");import{useEffect as Ue,useRef as qe}from"react";function me(e){let t=qe(!1);Ue(()=>{te(e)&&!t.current&&(t.current=!0,e.autoConnectHandler())},[e.autoConnect,e.allBlockChains])}o(me,"useAutoConnect");import{createStore as Ke,Hub as $e}from"@hub3js/core";import{useRef as de}from"react";function fe(e){let t=de(null),n=de(null);function l(){let u=new $e({store:r()});return e.forEach(d=>{u.add(d.id,d)}),n.current=u,u}o(l,"createHub");function r(){if(t.current!==null)return t.current;let u=Ke();return t.current=u,u}o(r,"getStore");function C(){let u=n.current?.getAll();return!n.current||!u?l():(re(n.current,e),n.current)}return o(C,"getHub"),{getStore:r,getHub:C}}o(fe,"useHubRefs");function Q(e){let{getStore:t,getHub:n}=fe(e.providers),[,l]=Ve(0),r=Y({onUpdateState:e.onUpdateState,allBlockChains:e.allBlockChains,emitter:e.emitter}),C=Y(!1),u=Y({}),d=o((s,a)=>{u.current[s]=a||[]},"updateLastConnectAttemptParams"),m=ee({onError:(s,a)=>{Ge.isUserRejectionError(s)&&a.removeCurrentKeyFromQueue()}});G(()=>{r.current={onUpdateState:e.onUpdateState,allBlockChains:e.allBlockChains,emitter:e.emitter}},[e]),G(()=>{let s=o((c,i,p,E,N)=>{i==="installed"&&E.installed&&ie(c,r.current.emitter),r.current.onUpdateState?.(c,i,p,E,N)},"onUpdateState"),a=o(c=>{try{ne(n(),c,s,{allBlockChains:r.current.allBlockChains,lastConnectAttemptParams:u.current})}catch(i){console.error(i)}l(i=>i+1)},"onStoreEvent");t().subscribe(a).flushEvents()},[]),G(()=>{C.current||!e.allBlockChains?.length||(n().init(e.configs?.walletOptions),l(s=>s+1),C.current=!0)},[e.allBlockChains,e.configs?.walletOptions]),me({autoConnect:e.autoConnect,allBlockChains:e.allBlockChains,autoConnectHandler:()=>{ue({allBlockChains:e.allBlockChains,getHub:n,wallets:e.configs?.wallets,emitter:r.current.emitter})}});let w=new W(P);return pe({canSwitchNetworkTo(s,a,c){let i=n().get(s);if(!i)return!1;if(!c)throw new Error("Passing namespace to `canSwitchNetworkTo` is required.");let p=i.findByNamespace(c.namespace);if(!p)throw new Error(`We couldn't find any matched namespace on your request provider. (requested namespace: ${c.namespace})`);if(!("canSwitchNetwork"in p))return!1;let E=i.info()?.metadata?.properties?.find(g=>g.name==="namespaces");if(!r.current.allBlockChains)throw new Error("Blockchains are not available");let N=E?.value.data.find(g=>g.value===c.namespace);if(!N)throw new Error(`NamespaceMeta is not defined for requested namespace: ${c.namespace}`);let y=Ye(N,r.current.allBlockChains);return p.canSwitchNetwork({network:a,supportedChains:y})},async connect(s,a){let c=n().get(s);if(!c)throw new Error(`You should add ${s} to provider first then call 'connect'.`);if(!a)throw new Error("Passing namespace to `connect` is required.");d(s,a);let i=[];a.forEach(h=>{let v=h.namespace,k=c.findByNamespace(v);if(!k)throw new Error(`We couldn't find any provider matched with your request namespace. (requested namespace: ${h.namespace})`);i.push([h,k])});let p=i.map(async([h,v])=>{let k=oe(h,e.allBlockChains||[]),x;ae(v)?x=o(async()=>v.connect({derivationPath:h.derivationPath}),"connectNamespacePromise"):F(v)?x=o(async()=>v.connect(k,{derivationPath:h.derivationPath}),"connectNamespacePromise"):se(v)?x=o(async()=>v.connect({derivationPath:h.derivationPath}),"connectNamespacePromise"):x=o(async()=>v.connect(),"connectNamespacePromise");let D=o(async()=>x().then(R).then(S=>({response:S,input:{namespace:h.namespace,network:h.network,supportsEagerConnect:"canEagerConnect"in v}})),"connectNamespaceProcess");return m(o(async()=>{if(v.state()[0]().connected)return D();let S={walletName:s,namespace:h.namespace,origin:"manual"},V=h.network||null;r.current.emitter?.emit(T,{type:"walletConnectInitiated",payload:{...S,chain:V}});try{let _=await D();return r.current.emitter?.emit(T,{type:"walletConnected",payload:{...S,chain:j(_.response.network,e.allBlockChains)}}),_}catch(_){throw r.current.emitter?.emit(T,{type:"walletConnectFailed",payload:{...S,chain:V}}),_}},"connectNamespaceProcessWithEvents"),s)}),E=await Promise.all(p),N=E.filter(h=>h.ok).filter(h=>h.val.input.supportsEagerConnect).map(h=>({namespace:h.val.input.namespace,network:h.val.input.network}));N.length>0&&w.addWallet(s,N);let y=E.map(h=>h.andThen(v=>new ze(v.response))),g=Xe.all(...y);if(g.err)throw g.val;return g.unwrap()},async disconnect(s,a){let c=n().get(s);if(!c)throw new Error(`You should add ${s} to provider first then call 'disconnect'.`);c.getAll().forEach(i=>{let p=!a||a.includes(i.namespaceId),E=i.state()[0]().connected;if(p&&E)return r.current.emitter?.emit(T,{type:"walletDisconnected",payload:{walletName:s,namespace:i.namespaceId}}),i.disconnect()}),e.autoConnect&&(a?w.removeNamespacesFromWallet(s,a):w.removeWallets([s]))},async disconnectAll(){let s=Array.from(n().getAll().values()).map(async a=>this.disconnect(a.id));return await Promise.allSettled(s)},async getSigners(s){let a=n().get(s);if(!a)throw new Error(`You should add ${s} to provider first.`);let c=a.info();if(!c)throw new Error("Your provider should have required `info`.");let p=c.metadata.properties?.find(E=>E.name==="signers");if(!p)throw new Error("Your provider should contain signers property.");return p.value.getSigners()},getWalletInfo(s){let a=n().get(s);if(!a)throw new Error(`You should add ${s} to provider first.`);let c=a.info();if(!c)throw new Error("Your provider should have required `info`.");let i={DEFAULT:""},{metadata:p}=c,{extensions:E}=p;Object.keys(E).forEach(v=>{let k=v;if(k==="homepage"&&(i.DEFAULT=E[k]||""),["firefox","chrome","brave","edge"].includes(k)){let D=k.toUpperCase();i[D]=E[k]||""}});let N=p.properties,y=N?.find(v=>v.name==="namespaces"),g=N?.find(v=>v.name==="derivationPath"),h=N?.find(v=>v.name==="details");return{name:p.name,img:p.icon,installLink:i,color:"red",supportedChains:Qe(a,r.current.allBlockChains),isContractWallet:h?.value?.isContractWallet,mobileWallet:h?.value?.mobileWallet,showOnMobile:h?.value?.showOnMobile,needsNamespace:y?.value,needsDerivationPath:g?.value,isHub:!0,properties:p.properties}},state(s){let a=n().state(),c=n().get(s),i=a[s];if(!i||!c)return{connected:!1,connecting:!1,installed:!1,reachable:!1,accounts:null,network:null,namespaces:new Map};let p=i.namespaces.filter(y=>y.connected).flatMap(y=>y.accounts?.map(g=>L(g))).filter(y=>!!y),E=new Map(Array.from(c.getAll(),([y,g])=>[g.namespaceId,g.state()[0]()]));return{connected:i.connected,connecting:i.connecting,installed:i.installed,reachable:!0,accounts:p,network:null,namespaces:E}},async suggestAndConnect(s,a){let c=n().get(s);if(!c)throw new Error(`You should add ${s} to provider first then call 'suggestAndConnect'.`);let i=c.findByNamespace(a.namespace);throw i?"suggest"in i?a.network?new Error(`Suggest has not been implemented for given chain: ${a.network}`):new Error("You should pass network to the suggest and connect"):new Error("Suggest is not implemented on the provider"):new Error(`We couldn't find any matched namespace on your request provider. (requested namespace: ${a.namespace})`)},hubProvider(s){let a=n().get(s);if(!a)throw new Error(`You're trying to access ${s} provider which is not found in hub providers. it may not be registered yet.`);return a}})}o(Q,"useHubAdapter");function Je(e){let t=Q(e);return Ze.createElement(O.Provider,{value:t},e.children)}o(Je,"Provider");var et=Je;import{useContext as tt}from"react";function nt(){let e=tt(O);if(!e)throw Error("useWallet can only be used within the Provider component");return e}o(nt,"useWallets");export{B as Events,et as Provider,T as WalletEventChannel,H as WalletEventTypes,nt as useWallets};
|
|
1
|
+
var Ee=Object.defineProperty;var o=(e,t)=>Ee(e,"name",{value:t,configurable:!0});import nt from"react";import{createContext as he}from"react";var W="Context hasn't been initialized yet.",ye={async connect(){throw new Error(W)},async disconnect(){throw new Error(W)},async disconnectAll(){throw new Error(W)},async suggestAndConnect(){throw new Error(W)},state(){throw new Error(W)},canSwitchNetworkTo(){throw new Error(W)},getWalletInfo(){throw new Error(W)},getSigners(){throw new Error(W)},hubProvider(){throw new Error(W)}},O=he(ye);import{convertEvmBlockchainMetaToEvmChainInfo as be,formatAddressWithNetwork as Se,getBlockChainNameFromId as xe,getSupportedChainsFromProvider as Le}from"@rango-dev/internal-blockchains";import{AccountId as De}from"caip";import{isEvmBlockchain as _e}from"rango-types";var R=(u=>(u.CONNECTED="connected",u.CONNECTING="connecting",u.REACHABLE="reachable",u.INSTALLED="installed",u.ACCOUNTS="accounts",u.NETWORK="network",u.NAMESPACE_DISCONNECTED="namespace_disconnected",u.PROVIDER_DISCONNECTED="provider_disconnected",u))(R||{});import{WalletTypes as x}from"@rango-dev/provider-all";var P="hub-v1-last-connected-wallets",Z=[x.LEDGER,x.TREZOR,x.LEDGER_WALLET,x.WALLET_CONNECT_2,x.TON_CONNECT,x.DEFAULT];import{CAIP_BITCOIN_CHAIN_ID as Ne,CAIP_BITCOINCASH_CHAIN_ID as ve,CAIP_DOGECOIN_CHAIN_ID as we,CAIP_LITECOIN_CHAIN_ID as ge,CAIP_ZCASH_CHAIN_ID as Pe}from"@hub3js/bip122";import{CAIP_TRON_CHAIN_ID as Te}from"@hub3js/tron";import{CAIP_NAMESPACE as ke}from"@hub3js/tvm";import{formatAddressWithNetwork as We}from"@rango-dev/internal-blockchains";import{AccountId as Ae}from"caip";import{Err as q,Ok as J}from"ts-results";function Ie(e){return typeof e=="string"?e:["solana","xrpl","stellar"].includes(e.namespace.toLowerCase())?e.namespace.toUpperCase():e.namespace.toLowerCase()==="eip155"?"ETH":e.reference===Ne?"BTC":e.reference===Pe?"ZCASH":e.reference===ge?"LTC":e.reference===we?"DOGE":e.reference===ve?"BCH":e.namespace.toLowerCase()===ke?"TON":e.namespace==="sui"||e.reference===Te?e.reference.toUpperCase():e.namespace==="starknet"?e.namespace.toUpperCase():e.reference}o(Ie,"mapCaipNamespaceToLegacyNetworkName");function L(e){let{chainId:t,address:n}=Ae.parse(e),m=Ie(t);return We(n,m)}o(L,"fromAccountIdToLegacyAddressFormat");async function K(e){return e.reduce(async(t,n)=>{let m=await t;try{let s=await n();return[...m,new J(s)]}catch(s){return[...m,new q(s)]}},Promise.resolve([]))}o(K,"runSequentiallyWithoutFailure");function ee(e){return typeof e=="object"&&!Array.isArray(e)}o(ee,"isConnectResultEvm");function te(e){return Array.isArray(e)}o(te,"isConnectResultSolana");function ne(e){let t=new Set,n=[],m=o((p,d)=>{n=n.filter(u=>u.key!==p?!0:(u.resolve(d),!1))},"removeKeyFromQueue"),s=o(async()=>{let p=n.find(f=>!t.has(f.key));if(!p)return;let{task:d,resolve:u,key:v}=p;t.add(v);try{let f=await d();u(new J(f))}catch(f){e?.onError&&e.onError(f,{removeCurrentKeyFromQueue:()=>m(v,new q(f))}),u(new q(f))}finally{let f=n.findIndex(a=>a.key===v);f>=0&&n.splice(f,1),t.delete(v),s()}},"processQueue");return o(async(p,d)=>new Promise(u=>{n.push({task:p,resolve:u,key:d}),s()}),"queueTask")}o(ne,"createQueue");function oe(e){return!!e.allBlockChains?.length&&!!e.autoConnect}o(oe,"shouldTryAutoConnect");var b=class{static{o(this,"Persistor")}getItem(t){let n=localStorage.getItem(t);return n?JSON.parse(n):null}setItem(t,n){localStorage.setItem(t,JSON.stringify(n))}removeItem(t){localStorage.removeItem(t)}};var I=class{static{o(this,"LastConnectedWalletsFromStorage")}#e;constructor(t){this.#e=t}addWallet(t,n){if(this.#e===P)return this.#t(t,n);throw new Error("Not implemented")}removeWallets(t){if(this.#e===P)return this.#n(t);throw new Error("Not implemented")}list(){if(this.#e===P)return this.#o();throw new Error("Not implemented")}removeNamespacesFromWallet(t,n){if(this.#e===P)return this.#r(t,n);throw new Error("Not implemented")}#o(){return new b().getItem(P)||{}}#t(t,n){let m=new b,s=m.getItem(this.#e)||{},C=n;if(s[t]){let p=s[t];C=p.concat(n.filter(d=>!p.some(u=>u.namespace===d.namespace)))}m.setItem(this.#e,{...s,[t]:C})}#n(t){let n=new b,m=n.getItem(this.#e)||{};if(!t){n.setItem(this.#e,{});return}t.forEach(s=>{m[s]&&delete m[s]}),n.setItem(this.#e,m)}#r(t,n){let p=(new b().getItem(this.#e)||{})[t]?.filter(d=>!n.includes(d.namespace));this.#n([t]),p?.length>0&&this.#t(t,p)}};function $(e,t){return e.find(n=>n.id===t)}o($,"findProviderByType");var Oe=new I(P);function re(e,t,n,m){let s=e.get(t.provider);if(!s)throw new Error("Currently all the events have assigned to a provider. The event doesn't include one.",{cause:t});let C=t.namespace,p=C?s.findByNamespace(C):void 0,d=null,u=null,v;if(p){let[i]=p.state();d=i().accounts,u=i().network,m.lastConnectAttemptParams[t.provider]&&(v=m.lastConnectAttemptParams[t.provider].find(l=>l.namespace===C)?.derivationPath)}let[f]=s.state(),a={connected:f().connected,connecting:f().connecting,installed:f().installed,accounts:d,network:u,reachable:!0,derivationPath:v},r=s.info()?.metadata.properties?.find(i=>i.name==="details"),c={supportedBlockchains:Le(s,m.allBlockChains),isContractWallet:r?.value?.isContractWallet??!1,isHub:!0,namespace:C};switch(t.type){case"provider_detected":n(t.provider,"installed",!0,a,c);break;case"provider_connecting":n(t.provider,"connecting",t.value,a,c);break;case"provider_connected":n(t.provider,"connected",!0,a,c);break;case"provider_disconnected":n(t.provider,"provider_disconnected",t.provider,a,c),n(t.provider,"connected",!1,a,c),n(t.provider,"accounts",null,a,c);break;case"namespace_disconnected":Oe.removeNamespacesFromWallet(t.provider,[t.namespace]),n(t.provider,"namespace_disconnected",t.namespace,a,{...c,namespace:t.namespace});break;case"namespace_connected":case"namespace_account_switched":{t.type==="namespace_account_switched"&&n(t.provider,"namespace_disconnected",t.namespace,a,c);let i=[];c.isContractWallet?i=t.accounts.map(l=>{let{chainId:h,address:w}=De.parse(l);if(typeof h=="string")throw new Error("Should be in CAIP format");let y=xe(h.reference,c.supportedBlockchains);return y?Se(w,y):L(l)}):i=t.accounts.map(l=>L(l)),n(t.provider,"accounts",i,a,{...c,namespace:t.namespace})}break;case"namespace_network_switched":n(t.provider,"network",t.network,a,{...c,namespace:t.namespace});break}}o(re,"mapHubEventsToLegacy");function G(e,t){if(!e.network)return;let n=t.filter(_e);return be(n)[e.network]}o(G,"convertNamespaceNetworkToEvmChainId");function ae(e,t){return G(e,t)||e.network}o(ae,"tryConvertNamespaceNetworkToChainInfo");function B(e){return ee(e)?{accounts:e.accounts,network:e.network}:te(e)?{accounts:e,network:null}:{accounts:[e],network:null}}o(B,"transformHubResultToLegacyResult");function se(e,t){let n=e.getAll();t.filter(s=>!n.get(s.id)).forEach(s=>{e.add(s.id,s),s.init()}),n.forEach(s=>{t.some(p=>p.id===s.id)||e.remove(s.id)})}o(se,"synchronizeHubWithConfigProviders");function ce(e){return e.namespaceId==="Solana"}o(ce,"isSolanaNamespace");function F(e){return e.namespaceId==="EVM"}o(F,"isEvmNamespace");function ie(e){return e.namespaceId==="UTXO"}o(ie,"isUtxoNamespace");import{Hub3Error as Xe}from"@hub3js/core";import{getSupportedChainsFromNamespace as ze,getSupportedChainsFromProvider as Ze}from"@rango-dev/internal-blockchains";import{useEffect as Q,useRef as V,useState as Je}from"react";import{Ok as et,Result as tt}from"ts-results";import{getBlockChainNameFromId as Re}from"@rango-dev/internal-blockchains";var T="walletEvent",H=(C=>(C.WALLET_DETECTED="walletDetected",C.WALLET_CONNECT_INITIATED="walletConnectInitiated",C.WALLET_CONNECTED="walletConnected",C.WALLET_CONNECT_FAILED="walletConnectFailed",C.WALLET_DISCONNECTED="walletDisconnected",C))(H||{}),le=new Set;function pe(e,t){le.has(e)||Z.includes(e)||(le.add(e),t?.emit(T,{type:"walletDetected",payload:{walletName:e}}))}o(pe,"emitWalletDetectedOnce");function j(e,t){return e?Re(e,t||[]):null}o(j,"toBlockchainName");import{Result as Ue}from"ts-results";import{getErrorMessage as Be,Hub3Error as Fe}from"@hub3js/core";import{error as me}from"@rango-dev/logging-core";var He="NonErrorThrown",je="Non-Error value thrown during connect.";function Me(e){let t=typeof e=="string"?e:Be(e)??je,n=new Error(t,{cause:e});return n.name=He,n}o(Me,"wrapNonError");function M(e,t){if(e instanceof Fe){if(e.type!=="PROVIDER_UNEXPECTED")return;me(e,{tags:{name:e.name,type:e.type,...t}});return}let n=e instanceof Error?e:Me(e);me(n,{tags:{name:n.name,...t}})}o(M,"reportConnectionFailure");function Y(e,t){return{walletName:e,namespace:t.namespace,chain:t.network||null,origin:"auto"}}o(Y,"createAutoConnectEventPayload");function qe(e){return e.namespace==="EVM"}o(qe,"isEvmNamespaceInput");var U=new I(P);async function Ke(e,t,n){let{getHub:m,allBlockChains:s,emitter:C}=n,p=m().get(e);if(!p)throw new Error(`You should add ${e} to provider first then call 'connect'.`);if(!t)throw new Error("Passing namespace to `connect` is required. ");let d=[];t.forEach(r=>{let c=r.namespace,i=p.findByNamespace(c);if(!i)throw new Error(`We couldn't find any provider matched with your request namespace. (requested namespace: ${r.namespace})`);d.push([r,i])});let u=d.map(([r,c])=>{let l=(qe(r)?G(r,s||[]):void 0)||r.network;return async()=>{let h;F(c)?h=o(async()=>c.connect(l),"connectNamespacePromise"):h=o(async()=>c.connect(),"connectNamespacePromise");let w=Y(e,r);try{let y=await h();C?.emit(T,{type:"walletConnected",payload:{...w,chain:j(B(y).network,s)}})}catch(y){throw M(y,{walletType:e,namespace:r.namespace,origin:"auto"}),C?.emit(T,{type:"walletConnectFailed",payload:w}),y instanceof Error?y:new Error(y)}}}),v=await K(u),f=d.filter((r,c)=>v[c].err).map(r=>r[0]);if(f.length>0&&U.removeNamespacesFromWallet(e,f.map(r=>r.namespace)),!v.some(r=>r.ok))throw new Error(`No namespace connected for ${e}`);return Ue.all(...v.filter(r=>r.ok)).unwrap()}o(Ke,"eagerConnect");async function $e(e,t){let n=[],m=[],s=[],C=[];e.forEach(d=>{let u=t.findByNamespace(d.namespace);u?(n.push(d),C.push(async()=>await u.canEagerConnect())):s.push(d)});let p=await K(C);return n.forEach((d,u)=>{p[u].ok&&p[u].val?m.push(d):s.push(d)}),{successNamespaces:m,failedNamespaces:s}}o($e,"tryRunCanEagerConnect");async function ue(e){let{getHub:t,allBlockChains:n,wallets:m,emitter:s}=e,C=U.list(),p=Object.keys(C),d=[];if(p.length){let u=[],v=m?.map(f=>typeof f=="string"?f:f.id);p.forEach(async f=>{if(v&&!v.includes(f)){console.warn("Trying to run auto connect for a wallet which is not included in config. Desired wallet:",f),d.push(f);return}let a=t().get(f),r=C[f].map(l=>({namespace:l.namespace,network:l.network}));if(!r.length||!a){d.push(f);return}r.forEach(l=>{s?.emit(T,{type:"walletConnectInitiated",payload:Y(f,l)})});let{successNamespaces:c,failedNamespaces:i}=await $e(r,a);if(i.forEach(l=>{s?.emit(T,{type:"walletConnectFailed",payload:Y(f,l)})}),c.length)i.length&&U.removeNamespacesFromWallet(a.id,i.map(l=>l.namespace));else{d.push(f);return}u.push(Ke(f,c,{allBlockChains:n,getHub:t,emitter:s}).catch(l=>console.warn(l)))}),U.removeWallets(d),await Promise.all(u)}}o(ue,"autoConnect");import{useEffect as Ge,useRef as Ye}from"react";function de(e){let t=Ye(!1);Ge(()=>{oe(e)&&!t.current&&(t.current=!0,e.autoConnectHandler())},[e.autoConnect,e.allBlockChains])}o(de,"useAutoConnect");import{createStore as Qe,Hub as Ve}from"@hub3js/core";import{useRef as fe}from"react";function Ce(e){let t=fe(null),n=fe(null);function m(){let p=new Ve({store:s()});return e.forEach(d=>{p.add(d.id,d)}),n.current=p,p}o(m,"createHub");function s(){if(t.current!==null)return t.current;let p=Qe();return t.current=p,p}o(s,"getStore");function C(){let p=n.current?.getAll();return!n.current||!p?m():(se(n.current,e),n.current)}return o(C,"getHub"),{getStore:s,getHub:C}}o(Ce,"useHubRefs");function X(e){let{getStore:t,getHub:n}=Ce(e.providers),[,m]=Je(0),s=V({onUpdateState:e.onUpdateState,allBlockChains:e.allBlockChains,emitter:e.emitter}),C=V(!1),p=V({}),d=o((a,r)=>{p.current[a]=r||[]},"updateLastConnectAttemptParams"),u=ne({onError:(a,r)=>{a instanceof Xe&&a.type!=="PROVIDER_UNEXPECTED"&&r.removeCurrentKeyFromQueue()}});Q(()=>{s.current={onUpdateState:e.onUpdateState,allBlockChains:e.allBlockChains,emitter:e.emitter}},[e]),Q(()=>{let a=o((c,i,l,h,w)=>{i==="installed"&&h.installed&&pe(c,s.current.emitter),s.current.onUpdateState?.(c,i,l,h,w)},"onUpdateState"),r=o(c=>{try{re(n(),c,a,{allBlockChains:s.current.allBlockChains,lastConnectAttemptParams:p.current})}catch(i){console.error(i)}m(i=>i+1)},"onStoreEvent");t().subscribe(r).flushEvents()},[]),Q(()=>{C.current||!e.allBlockChains?.length||(n().init(e.configs?.walletOptions),m(a=>a+1),C.current=!0)},[e.allBlockChains,e.configs?.walletOptions]),de({autoConnect:e.autoConnect,allBlockChains:e.allBlockChains,autoConnectHandler:()=>{ue({allBlockChains:e.allBlockChains,getHub:n,wallets:e.configs?.wallets,emitter:s.current.emitter})}});let v=new I(P);return{canSwitchNetworkTo(a,r,c){let i=n().get(a);if(!i)return!1;if(!c)throw new Error("Passing namespace to `canSwitchNetworkTo` is required.");let l=i.findByNamespace(c.namespace);if(!l)throw new Error(`We couldn't find any matched namespace on your request provider. (requested namespace: ${c.namespace})`);if(!("canSwitchNetwork"in l))return!1;let h=i.info()?.metadata?.properties?.find(g=>g.name==="namespaces");if(!s.current.allBlockChains)throw new Error("Blockchains are not available");let w=h?.value.data.find(g=>g.value===c.namespace);if(!w)throw new Error(`NamespaceMeta is not defined for requested namespace: ${c.namespace}`);let y=ze(w,s.current.allBlockChains);return l.canSwitchNetwork({network:r,supportedChains:y})},async connect(a,r){let c=n().get(a);if(!c)throw new Error(`You should add ${a} to provider first then call 'connect'.`);if(!r)throw new Error("Passing namespace to `connect` is required.");d(a,r);let i=[];r.forEach(E=>{let N=E.namespace,k=c.findByNamespace(N);if(!k)throw new Error(`We couldn't find any provider matched with your request namespace. (requested namespace: ${E.namespace})`);i.push([E,k])});let l=i.map(async([E,N])=>{let k=ae(E,e.allBlockChains||[]),S;ce(N)?S=o(async()=>N.connect({derivationPath:E.derivationPath}),"connectNamespacePromise"):F(N)?S=o(async()=>N.connect(k,{derivationPath:E.derivationPath}),"connectNamespacePromise"):ie(N)?S=o(async()=>N.connect({derivationPath:E.derivationPath}),"connectNamespacePromise"):S=o(async()=>N.connect(),"connectNamespacePromise");let D=o(async()=>S().catch(A=>{throw M(A,{walletType:a,namespace:E.namespace,origin:"manual"}),A}).then(B).then(A=>({response:A,input:{namespace:E.namespace,network:E.network,supportsEagerConnect:"canEagerConnect"in N}})),"connectNamespaceProcess");return u(o(async()=>{if(N.state()[0]().connected)return D();let A={walletName:a,namespace:E.namespace,origin:"manual"},z=E.network||null;s.current.emitter?.emit(T,{type:"walletConnectInitiated",payload:{...A,chain:z}});try{let _=await D();return s.current.emitter?.emit(T,{type:"walletConnected",payload:{...A,chain:j(_.response.network,e.allBlockChains)}}),_}catch(_){throw s.current.emitter?.emit(T,{type:"walletConnectFailed",payload:{...A,chain:z}}),_}},"connectNamespaceProcessWithEvents"),a)}),h=await Promise.all(l),w=h.filter(E=>E.ok).filter(E=>E.val.input.supportsEagerConnect).map(E=>({namespace:E.val.input.namespace,network:E.val.input.network}));w.length>0&&v.addWallet(a,w);let y=h.map(E=>E.andThen(N=>new et(N.response))),g=tt.all(...y);if(g.err)throw g.val;return g.unwrap()},async disconnect(a,r){let c=n().get(a);if(!c)throw new Error(`You should add ${a} to provider first then call 'disconnect'.`);c.getAll().forEach(i=>{let l=!r||r.includes(i.namespaceId),h=i.state()[0]().connected;if(l&&h)return s.current.emitter?.emit(T,{type:"walletDisconnected",payload:{walletName:a,namespace:i.namespaceId}}),i.disconnect()}),e.autoConnect&&(r?v.removeNamespacesFromWallet(a,r):v.removeWallets([a]))},async disconnectAll(){let a=Array.from(n().getAll().values()).map(async r=>this.disconnect(r.id));return await Promise.allSettled(a)},async getSigners(a){let r=n().get(a);if(!r)throw new Error(`You should add ${a} to provider first.`);let c=r.info();if(!c)throw new Error("Your provider should have required `info`.");let l=c.metadata.properties?.find(h=>h.name==="signers");if(!l)throw new Error("Your provider should contain signers property.");return l.value.getSigners()},getWalletInfo(a){let r=n().get(a);if(!r)throw new Error(`You should add ${a} to provider first.`);let c=r.info();if(!c)throw new Error("Your provider should have required `info`.");let i={DEFAULT:""},{metadata:l}=c,{extensions:h}=l;Object.keys(h).forEach(N=>{let k=N;if(k==="homepage"&&(i.DEFAULT=h[k]||""),["firefox","chrome","brave","edge"].includes(k)){let D=k.toUpperCase();i[D]=h[k]||""}});let w=l.properties,y=w?.find(N=>N.name==="namespaces"),g=w?.find(N=>N.name==="derivationPath"),E=w?.find(N=>N.name==="details");return{name:l.name,img:l.icon,installLink:i,color:"red",supportedChains:Ze(r,s.current.allBlockChains),isContractWallet:E?.value?.isContractWallet,mobileWallet:E?.value?.mobileWallet,showOnMobile:E?.value?.showOnMobile,needsNamespace:y?.value,needsDerivationPath:g?.value,isHub:!0,properties:l.properties}},state(a){let r=n().state(),c=n().get(a),i=r[a];if(!i||!c)return{connected:!1,connecting:!1,installed:!1,reachable:!1,accounts:null,network:null,namespaces:new Map};let l=i.namespaces.filter(y=>y.connected).flatMap(y=>y.accounts?.map(g=>L(g))).filter(y=>!!y),h=new Map(Array.from(c.getAll(),([y,g])=>[g.namespaceId,g.state()[0]()]));return{connected:i.connected,connecting:i.connecting,installed:i.installed,reachable:!0,accounts:l,network:null,namespaces:h}},async suggestAndConnect(a,r){let c=n().get(a);if(!c)throw new Error(`You should add ${a} to provider first then call 'suggestAndConnect'.`);let i=c.findByNamespace(r.namespace);throw i?"suggest"in i?r.network?new Error(`Suggest has not been implemented for given chain: ${r.network}`):new Error("You should pass network to the suggest and connect"):new Error("Suggest is not implemented on the provider"):new Error(`We couldn't find any matched namespace on your request provider. (requested namespace: ${r.namespace})`)},hubProvider(a){let r=$(e.providers,a);if(!r)throw new Error(`You're trying to access ${a} provider which is not found in hub providers. it may not be registered yet.`);return r}}}o(X,"useHubAdapter");function ot(e){let t=X(e);return nt.createElement(O.Provider,{value:t},e.children)}o(ot,"Provider");var rt=ot;import{useContext as at}from"react";function st(){let e=at(O);if(!e)throw Error("useWallet can only be used within the Provider component");return e}o(st,"useWallets");export{R as Events,rt as Provider,T as WalletEventChannel,H as WalletEventTypes,st as useWallets};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/provider.tsx", "../src/context.ts", "../src/hub/utils.ts", "../src/legacy/types.ts", "../src/hub/constants.ts", "../src/hub/helpers.ts", "../src/hub/persistor.ts", "../src/hub/lastConnectedWallets.ts", "../src/hub/useHubAdapter.ts", "../src/events.ts", "../src/
|
|
4
|
-
"sourcesContent": ["import type { ProviderProps } from './types.js';\n\nimport React from 'react';\n\nimport { WalletContext } from './context.js';\nimport { useHubAdapter } from './hub/mod.js';\n\nfunction Provider(props: ProviderProps) {\n const api = useHubAdapter(props);\n\n return (\n <WalletContext.Provider value={api}>\n {props.children}\n </WalletContext.Provider>\n );\n}\n\nexport default Provider;\n", "import type { ProviderContext } from './types.js';\n\nimport { createContext } from 'react';\n\nconst defaultErrorMessage = \"Context hasn't been initialized yet.\";\nconst defaultContext: ProviderContext = {\n async connect() {\n throw new Error(defaultErrorMessage);\n },\n async disconnect() {\n throw new Error(defaultErrorMessage);\n },\n async disconnectAll() {\n throw new Error(defaultErrorMessage);\n },\n async suggestAndConnect() {\n throw new Error(defaultErrorMessage);\n },\n state() {\n throw new Error(defaultErrorMessage);\n },\n canSwitchNetworkTo() {\n throw new Error(defaultErrorMessage);\n },\n getWalletInfo() {\n throw new Error(defaultErrorMessage);\n },\n getSigners() {\n throw new Error(defaultErrorMessage);\n },\n hubProvider() {\n throw new Error(defaultErrorMessage);\n },\n};\n\nexport const WalletContext = createContext<ProviderContext>(defaultContext);\n", "import type { AllProxiedNamespaces } from './types.js';\nimport type {\n ConnectResult,\n NamespaceInputForConnect,\n EventHandler as WalletEventHandler,\n} from '../legacy/mod.js';\nimport type { ProviderProps } from '../types.js';\nimport type { UtxoActions } from '@hub3js/bip122';\nimport type { Hub, Provider, ProxiedNamespace, WalletType } from '@hub3js/core';\nimport type { Event } from '@hub3js/core/store';\nimport type {\n Chain as AddEthereumChainParameter,\n EvmActions,\n} from '@hub3js/evm';\nimport type { SolanaActions } from '@hub3js/solana';\n\nimport {\n convertEvmBlockchainMetaToEvmChainInfo,\n formatAddressWithNetwork,\n getBlockChainNameFromId,\n getSupportedChainsFromProvider,\n} from '@rango-dev/internal-blockchains';\nimport { AccountId } from 'caip';\nimport { type BlockchainMeta, isEvmBlockchain } from 'rango-types';\n\nimport { Events } from '../legacy/mod.js';\n\nimport { HUB_LAST_CONNECTED_WALLETS } from './constants.js';\nimport {\n fromAccountIdToLegacyAddressFormat,\n isConnectResultEvm,\n isConnectResultSolana,\n} from './helpers.js';\nimport { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';\n\nexport function findProviderByType(\n providers: Provider[],\n type: string\n): Provider | undefined {\n return providers.find((provider) => provider.id === type);\n}\n\n/**\n * We will call this function on hub's `subscribe`.\n * it will check states and will emit legacy events for backward compatibility.\n */\n\nconst lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n HUB_LAST_CONNECTED_WALLETS\n);\n\nexport function mapHubEventsToLegacy(\n hub: Hub,\n event: Event,\n onUpdateState: WalletEventHandler,\n metadata: {\n allBlockChains: ProviderProps['allBlockChains'];\n lastConnectAttemptParams: {\n [type: WalletType]: NamespaceInputForConnect[];\n };\n }\n): void {\n const provider = hub.get(event.provider);\n if (!provider) {\n throw new Error(\n \"Currently all the events have assigned to a provider. The event doesn't include one.\",\n {\n cause: event,\n }\n );\n }\n\n // @ts-expect-error for those events that doesn't have namespace, it will be undefinded\n const namespaceId: string | undefined = event.namespace;\n\n const namespace = namespaceId\n ? provider.findByNamespace(namespaceId)\n : undefined;\n let accounts: string[] | null = null;\n let network: string | null = null;\n let derivationPath: string | undefined;\n\n if (namespace) {\n const [getNamespaceState] = namespace.state();\n accounts = getNamespaceState().accounts;\n network = getNamespaceState().network;\n\n if (metadata.lastConnectAttemptParams[event.provider]) {\n derivationPath = metadata.lastConnectAttemptParams[event.provider].find(\n (namespace) => namespace.namespace === namespaceId\n )?.derivationPath;\n }\n }\n\n const [getProviderState] = provider.state();\n const coreState = {\n connected: getProviderState().connected,\n connecting: getProviderState().connecting,\n installed: getProviderState().installed,\n accounts,\n network,\n reachable: true,\n derivationPath,\n };\n\n const detailsProperty = provider\n .info()\n ?.metadata.properties?.find((property) => property.name === 'details');\n\n const eventInfo = {\n supportedBlockchains: getSupportedChainsFromProvider(\n provider,\n metadata.allBlockChains\n ),\n isContractWallet: detailsProperty?.value?.isContractWallet ?? false,\n isHub: true,\n namespace: namespaceId,\n };\n\n switch (event.type) {\n case 'provider_detected':\n onUpdateState(\n event.provider,\n Events.INSTALLED,\n true,\n coreState,\n eventInfo\n );\n break;\n case 'provider_connecting':\n onUpdateState(\n event.provider,\n Events.CONNECTING,\n event.value,\n coreState,\n eventInfo\n );\n break;\n case 'provider_connected':\n onUpdateState(\n event.provider,\n Events.CONNECTED,\n true,\n coreState,\n eventInfo\n );\n break;\n case 'provider_disconnected':\n onUpdateState(\n event.provider,\n Events.PROVIDER_DISCONNECTED,\n event.provider,\n coreState,\n eventInfo\n );\n onUpdateState(\n event.provider,\n Events.CONNECTED,\n false,\n coreState,\n eventInfo\n );\n onUpdateState(\n event.provider,\n Events.ACCOUNTS,\n null,\n coreState,\n eventInfo\n );\n break;\n case 'namespace_disconnected':\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n event.provider,\n [event.namespace]\n );\n\n onUpdateState(\n event.provider,\n Events.NAMESPACE_DISCONNECTED,\n event.namespace,\n coreState,\n {\n ...eventInfo,\n namespace: event.namespace,\n }\n );\n // onUpdateState(event.provider, Events.ACCOUNTS, null, coreState, eventInfo);\n break;\n case 'namespace_connected':\n case 'namespace_account_switched':\n {\n if (event.type === 'namespace_account_switched') {\n onUpdateState(\n event.provider,\n Events.NAMESPACE_DISCONNECTED,\n event.namespace,\n coreState,\n eventInfo\n );\n }\n\n let formattedAddresses: string[] = [];\n if (eventInfo.isContractWallet) {\n formattedAddresses = event.accounts.map((account) => {\n const { chainId, address } = AccountId.parse(account);\n if (typeof chainId === 'string') {\n throw new Error('Should be in CAIP format');\n }\n const blockchainName = getBlockChainNameFromId(\n chainId.reference,\n eventInfo.supportedBlockchains\n );\n\n return blockchainName\n ? formatAddressWithNetwork(address, blockchainName)\n : fromAccountIdToLegacyAddressFormat(account);\n });\n } else {\n formattedAddresses = event.accounts.map((accounts) =>\n fromAccountIdToLegacyAddressFormat(accounts)\n );\n }\n\n onUpdateState(\n event.provider,\n Events.ACCOUNTS,\n formattedAddresses,\n coreState,\n {\n ...eventInfo,\n namespace: event.namespace,\n }\n );\n }\n break;\n case 'namespace_network_switched':\n onUpdateState(event.provider, Events.NETWORK, event.network, coreState, {\n ...eventInfo,\n namespace: event.namespace,\n });\n break;\n }\n}\n\n/**\n * In legacy mode, for those who have switch network functionality (like evm), we are using an enum for network names\n * this enum only has meaning for us, and when we are going to connect an instance (e.g. window.ethereum) we should pass chain id.\n */\nexport function convertNamespaceNetworkToEvmChainId(\n namespace: NamespaceInputForConnect,\n meta: BlockchainMeta[]\n): AddEthereumChainParameter | undefined {\n if (!namespace.network) {\n return undefined;\n }\n\n const evmBlockchainsList = meta.filter(isEvmBlockchain);\n const evmChains = convertEvmBlockchainMetaToEvmChainInfo(evmBlockchainsList);\n\n return evmChains[namespace.network];\n}\n\n/**\n * We are passing an string for chain id (e.g. ETH, POLYGON), but wallet's instances (e.g. window.ethereum) needs chainId (e.g. 0x1).\n * This function will help us to map these strings to proper hex ids.\n */\nexport function tryConvertNamespaceNetworkToChainInfo(\n namespace: NamespaceInputForConnect,\n meta: BlockchainMeta[]\n): string | AddEthereumChainParameter | undefined {\n // `undefined` means it's not evm or we couldn't find it in meta.\n const evmChain = convertNamespaceNetworkToEvmChainId(namespace, meta);\n const network = evmChain || namespace.network;\n\n return network;\n}\n\nexport function transformHubResultToLegacyResult(\n res: Awaited<ReturnType<AllProxiedNamespaces['connect']>>\n): ConnectResult {\n if (isConnectResultEvm(res)) {\n return {\n accounts: res.accounts,\n network: res.network,\n };\n } else if (isConnectResultSolana(res)) {\n return {\n accounts: res,\n network: null,\n };\n }\n\n return {\n accounts: [res],\n network: null,\n };\n}\n\n/**\n * Synchronizes providers in the hub with the configuration providers.\n * - Registers and initializes any configuration providers not yet in the hub\n * - Removes providers from the hub that aren't in the configuration\n */\nexport function synchronizeHubWithConfigProviders(\n hub: Hub,\n configurationProviders: Provider[]\n) {\n const registeredProviders = hub.getAll();\n\n // Register and initialize providers that exist in config but not in hub\n const providersToRegister = configurationProviders.filter(\n (configProvider) => !registeredProviders.get(configProvider.id)\n );\n\n providersToRegister.forEach((providerToRegister) => {\n hub.add(providerToRegister.id, providerToRegister);\n providerToRegister.init();\n });\n\n // Remove providers that exist in hub but not in config\n registeredProviders.forEach((registeredProvider) => {\n const isProviderInConfig = configurationProviders.some(\n (configProvider) => configProvider.id === registeredProvider.id\n );\n\n if (!isProviderInConfig) {\n hub.remove(registeredProvider.id);\n }\n });\n}\n\nexport function isSolanaNamespace(\n ns: AllProxiedNamespaces\n): ns is AllProxiedNamespaces &\n ProxiedNamespace<SolanaActions> & { namespaceId: 'Solana' } {\n return ns.namespaceId === 'Solana';\n}\nexport function isEvmNamespace(\n ns: AllProxiedNamespaces\n): ns is AllProxiedNamespaces &\n ProxiedNamespace<EvmActions> & { namespaceId: 'EVM' } {\n return ns.namespaceId === 'EVM';\n}\nexport function isUtxoNamespace(\n ns: AllProxiedNamespaces\n): ns is AllProxiedNamespaces &\n ProxiedNamespace<UtxoActions> & { namespaceId: 'UTXO' } {\n return ns.namespaceId === 'UTXO';\n}\n", "import type {\n DerivationPathProperty,\n NamespacesProperty,\n ProviderMetadata,\n WalletType,\n} from '@hub3js/core';\nimport type { Namespace } from '@hub3js/namespaces';\nimport type { Network } from '@rango-dev/internal-blockchains';\nimport type { BlockchainMeta, SignerFactory } from 'rango-types';\n\nexport type NamespaceMeta = NamespacesProperty['value']['data'][number];\nexport type NeedsNamespace = NamespacesProperty['value'];\nexport type NeedsDerivationPath = DerivationPathProperty['value'];\n\nexport type InstallObjects = {\n CHROME?: string;\n FIREFOX?: string;\n EDGE?: string;\n BRAVE?: string;\n DEFAULT: string;\n};\n\nexport type WalletInfo = {\n name: string;\n img: string;\n installLink: InstallObjects | string;\n /**\n * @deprecated we don't use this value anymore.\n */\n color: string;\n supportedChains: BlockchainMeta[];\n showOnMobile?: boolean;\n isContractWallet?: boolean;\n mobileWallet?: boolean;\n\n needsDerivationPath?: NeedsDerivationPath;\n needsNamespace?: NeedsNamespace;\n};\n\nexport type WalletState = {\n connected: boolean;\n connecting: boolean;\n /**\n * @deprecated it always returns `false`. don't use it.\n */\n reachable: boolean;\n installed: boolean;\n accounts: string[] | null;\n network: Network | null;\n derivationPath?: string;\n};\n\ntype NamespaceData = {\n namespace: Namespace;\n derivationPath?: string;\n};\n\nexport type NamespaceInputForConnect<T extends Namespace = Namespace> = {\n /**\n * By default, you should specify namespace (e.g. evm).\n */\n namespace: T;\n /**\n * In some cases, we need to connect a specific network on a namespace. e.g. Polygon on EVM.\n */\n network: Network | undefined;\n derivationPath?: string;\n};\n\nexport enum Events {\n CONNECTED = 'connected',\n CONNECTING = 'connecting',\n REACHABLE = 'reachable',\n INSTALLED = 'installed',\n ACCOUNTS = 'accounts',\n NETWORK = 'network',\n // Hub only events\n NAMESPACE_DISCONNECTED = 'namespace_disconnected',\n\n PROVIDER_DISCONNECTED = 'provider_disconnected',\n}\n\nexport type EventInfo = {\n supportedBlockchains: BlockchainMeta[];\n isContractWallet: boolean;\n isHub: boolean;\n // will be set alongside ACCOUNT event\n namespace?: Namespace;\n derivationPath?: string;\n};\n\nexport type EventHandler = (\n type: WalletType,\n event: Events,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n value: any,\n coreState: WalletState,\n info: EventInfo\n) => void;\n\nexport type ConnectResult = {\n accounts: string[] | null;\n network: Network | null;\n};\n\nexport type ExtendedWalletInfo = WalletInfo & {\n properties?: ProviderMetadata['properties'];\n isHub?: boolean;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InstanceType = any;\n\ntype ProviderConnectResult = {\n accounts: string[];\n chainId: string;\n derivationPath?: string;\n};\n\ntype GetInstanceOptions = {\n network?: Network;\n currentProvider: InstanceType;\n meta: BlockchainMeta[];\n getState: () => WalletState;\n /**\n * We always get the instance once and reuse it whenever we needs. By using this option\n * We can force the library to get a new instance and replace it with the old one.\n *\n * Originally, we used this option for wallet connect 1 and its switching network challenge.\n */\n force?: boolean;\n updateChainId: (chainId: number | string) => void;\n};\n\ntype TryGetInstance =\n | (() => InstanceType)\n | ((\n options: Pick<GetInstanceOptions, 'force' | 'network'>\n ) => Promise<InstanceType>);\n\ntype Connect = (options: {\n instance: InstanceType;\n network?: Network;\n meta: BlockchainMeta[];\n namespaces?: NamespaceData[];\n}) => Promise<ProviderConnectResult | ProviderConnectResult[]>;\n\ntype Disconnect = (options: {\n instance: InstanceType;\n destroyInstance: () => void;\n}) => Promise<void>;\n\ntype CleanupSubscribe = () => void;\n\ntype Subscribe = (options: {\n instance: InstanceType;\n state: WalletState;\n meta: BlockchainMeta[];\n updateChainId: (chainId: string) => void;\n updateAccounts: (accounts: string[], chainId?: string) => void;\n connect: (network?: Network) => void;\n disconnect: () => void;\n}) => CleanupSubscribe | void;\n\ntype SwitchNetwork = (options: {\n instance: InstanceType;\n network: Network;\n meta: BlockchainMeta[];\n newInstance?: TryGetInstance;\n getState?: () => WalletState;\n updateChainId: (chainId: string) => void;\n}) => Promise<void>;\n\ntype Suggest = (options: {\n instance: InstanceType;\n network: Network;\n meta: BlockchainMeta[];\n}) => Promise<void>;\n\ntype CanSwitchNetwork = (options: {\n network: Network;\n meta: BlockchainMeta[];\n provider: InstanceType;\n}) => boolean;\n\ntype CanEagerConnect = (options: {\n instance: InstanceType;\n meta: BlockchainMeta[];\n}) => Promise<boolean>;\n\ninterface WalletActions {\n connect: Connect;\n getInstance: InstanceType;\n disconnect?: Disconnect;\n subscribe?: Subscribe;\n // unsubscribe, // coupled to subscribe.\n\n // Optional, but should be provided at the same time.\n suggest?: Suggest;\n switchNetwork?: SwitchNetwork;\n getSigners: (provider: InstanceType) => Promise<SignerFactory>;\n canSwitchNetworkTo?: CanSwitchNetwork;\n canEagerConnect?: CanEagerConnect;\n getWalletInfo(allBlockChains: BlockchainMeta[]): WalletInfo;\n}\n\ninterface WalletConfig {\n type: WalletType;\n defaultNetwork?: Network;\n checkInstallation?: boolean;\n isAsyncInstance?: boolean;\n isAsyncSwitchNetwork?: boolean;\n}\n\n/**\n * @deprecated Pass a hub `Provider` instead. This type will be removed in future versions.\n */\nexport type ProviderInterface = { config: WalletConfig } & WalletActions;\n", "import { WalletTypes } from '@rango-dev/provider-all';\n\nexport const HUB_LAST_CONNECTED_WALLETS = 'hub-v1-last-connected-wallets';\n\n// Wallets that always report themselves installed (hardware wallets and connection protocols).\nexport const WALLET_DETECTED_SKIPPED_IDS: string[] = [\n WalletTypes.LEDGER,\n WalletTypes.TREZOR,\n WalletTypes.LEDGER_WALLET,\n WalletTypes.WALLET_CONNECT_2,\n WalletTypes.TON_CONNECT,\n WalletTypes.DEFAULT,\n];\n", "import type { AllProxiedNamespaces } from './types.js';\nimport type { ProviderProps } from '../types.js';\nimport type { Accounts, AccountsWithActiveChain } from '@hub3js/std/types';\nimport type { Result } from 'ts-results';\n\nimport {\n CAIP_BITCOIN_CHAIN_ID,\n CAIP_BITCOINCASH_CHAIN_ID,\n CAIP_DOGECOIN_CHAIN_ID,\n CAIP_LITECOIN_CHAIN_ID,\n CAIP_ZCASH_CHAIN_ID,\n} from '@hub3js/bip122';\nimport { CAIP_TRON_CHAIN_ID } from '@hub3js/tron';\nimport { CAIP_NAMESPACE as CAIP_TON_NAMESPACE } from '@hub3js/tvm';\nimport { formatAddressWithNetwork } from '@rango-dev/internal-blockchains';\nimport { AccountId, type ChainIdParams } from 'caip';\nimport { Err, Ok } from 'ts-results';\n\nexport function mapCaipNamespaceToLegacyNetworkName(\n chainId: ChainIdParams | string\n): string {\n if (typeof chainId === 'string') {\n return chainId;\n }\n const useNamespaceAsNetworkFor = ['solana', 'xrpl', 'stellar'];\n\n if (useNamespaceAsNetworkFor.includes(chainId.namespace.toLowerCase())) {\n return chainId.namespace.toUpperCase();\n }\n\n if (chainId.namespace.toLowerCase() === 'eip155') {\n return 'ETH';\n } else if (chainId.reference === CAIP_BITCOIN_CHAIN_ID) {\n return 'BTC';\n } else if (chainId.reference === CAIP_ZCASH_CHAIN_ID) {\n return 'ZCASH';\n } else if (chainId.reference === CAIP_LITECOIN_CHAIN_ID) {\n return 'LTC';\n } else if (chainId.reference === CAIP_DOGECOIN_CHAIN_ID) {\n return 'DOGE';\n } else if (chainId.reference === CAIP_BITCOINCASH_CHAIN_ID) {\n return 'BCH';\n }\n\n if (chainId.namespace.toLowerCase() === CAIP_TON_NAMESPACE) {\n return 'TON';\n }\n if (chainId.namespace === 'sui' || chainId.reference === CAIP_TRON_CHAIN_ID) {\n return chainId.reference.toUpperCase();\n }\n if (chainId.namespace === 'starknet') {\n return chainId.namespace.toUpperCase();\n }\n\n return chainId.reference;\n}\n\n/**\n * CAIP's accountId has a format like this: eip155:1:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb\n * Legacy format is something like this: ETH:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb\n * This function will try to convert this two format.\n *\n * @see https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md\n */\nexport function fromAccountIdToLegacyAddressFormat(account: string): string {\n const { chainId, address } = AccountId.parse(account);\n const network = mapCaipNamespaceToLegacyNetworkName(chainId);\n return formatAddressWithNetwork(address, network);\n}\n\n/**\n * Getting a list of (lazy) promises and run them one after another.\n */\n\nexport async function runSequentiallyWithoutFailure<R>(\n promises: Array<() => Promise<R>>\n): Promise<Result<R, unknown>[]> {\n return promises.reduce(async (prevPromise, task) => {\n const previousResults = await prevPromise;\n try {\n const taskResult = await task();\n return [...previousResults, new Ok(taskResult)];\n } catch (error) {\n return [...previousResults, new Err(error)];\n }\n }, Promise.resolve<Result<R, unknown>[]>([]));\n}\n\nexport function isConnectResultEvm(\n result: Awaited<ReturnType<AllProxiedNamespaces['connect']>>\n): result is AccountsWithActiveChain {\n return typeof result === 'object' && !Array.isArray(result);\n}\n\nexport function isConnectResultSolana(\n result: Awaited<ReturnType<AllProxiedNamespaces['connect']>>\n): result is Accounts {\n return Array.isArray(result);\n}\n\ntype QueueItem<T> = {\n task: () => Promise<T>;\n resolve: (value: Result<T, unknown>) => void;\n key: string;\n};\n/**\n * Creates a queue manager that ensures sequential execution of tasks by key.\n * When multiple tasks with the same key are queued, they are executed one at a time\n * in the order they were added. This prevents race conditions and ensures\n * predictable task execution order.\n *\n */\nexport function createQueue(options?: {\n onError?: (\n error: unknown,\n actions: {\n removeCurrentKeyFromQueue: () => void;\n }\n ) => void;\n}) {\n const processingKeys = new Set<string>();\n let queue: QueueItem<unknown>[] = [];\n\n const removeKeyFromQueue = (\n key: string,\n result: Result<unknown, unknown>\n ) => {\n queue = queue.filter((q) => {\n if (q.key !== key) {\n return true;\n }\n q.resolve(result);\n return false;\n });\n };\n\n const processQueue = async () => {\n const currentItem = queue.find((item) => !processingKeys.has(item.key));\n if (!currentItem) {\n return;\n }\n\n const { task, resolve, key } = currentItem;\n processingKeys.add(key);\n\n try {\n const result = await task();\n resolve(new Ok(result));\n } catch (error) {\n if (options?.onError) {\n options.onError(error, {\n removeCurrentKeyFromQueue: () =>\n removeKeyFromQueue(key, new Err(error)),\n });\n }\n\n resolve(new Err(error));\n } finally {\n const indexOfCurrentItem = queue.findIndex((item) => item.key === key);\n if (indexOfCurrentItem >= 0) {\n queue.splice(indexOfCurrentItem, 1);\n }\n processingKeys.delete(key);\n void processQueue();\n }\n };\n\n const queueTask = async <T>(\n task: () => Promise<T>,\n key: string\n ): Promise<Result<T, unknown>> =>\n new Promise((resolve) => {\n queue.push({\n task,\n resolve: resolve as (value: Result<unknown, unknown>) => void,\n key,\n });\n void processQueue();\n });\n\n return queueTask;\n}\n\nexport function shouldTryAutoConnect(\n props: Pick<ProviderProps, 'allBlockChains' | 'autoConnect'>\n): boolean {\n return !!props.allBlockChains?.length && !!props.autoConnect;\n}\n", "export interface PersistStorage<T> {\n getItem: (name: string) => T | null;\n setItem: (name: string, value: T) => void;\n removeItem: (name: string) => void;\n}\n\nexport class Persistor<T> implements PersistStorage<T> {\n getItem(name: string) {\n const item = localStorage.getItem(name);\n const parsedItem = item ? (JSON.parse(item) as T) : null;\n return parsedItem;\n }\n setItem(name: string, value: T) {\n localStorage.setItem(name, JSON.stringify(value));\n }\n removeItem(name: string) {\n localStorage.removeItem(name);\n }\n}\n", "import type { Namespace } from '@hub3js/namespaces';\n\nimport { HUB_LAST_CONNECTED_WALLETS } from './constants.js';\nimport { Persistor } from './persistor.js';\n\nexport interface NamespaceInput {\n namespace: Namespace;\n network: string | undefined;\n}\n\nexport interface LastConnectedWalletsStorage {\n [providerId: string]: NamespaceInput[];\n}\n\n/**\n * We are doing some certain actions on storage for `last-connected-wallets` key.\n * This class helps us to define them in one place.\n */\nexport class LastConnectedWalletsFromStorage {\n #storageKey: string;\n\n constructor(storageKey: string) {\n this.#storageKey = storageKey;\n }\n\n addWallet(providerId: string, namespaces: NamespaceInput[]): void {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#addWalletToHub(providerId, namespaces);\n }\n throw new Error('Not implemented');\n }\n removeWallets(providerIds?: string[]): void {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#removeWalletsFromHub(providerIds);\n }\n throw new Error('Not implemented');\n }\n list(): LastConnectedWalletsStorage {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#listFromHub();\n }\n throw new Error('Not implemented');\n }\n removeNamespacesFromWallet(providerId: string, namespaceIds: string[]) {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#removeNamespaceFromWalletHub(providerId, namespaceIds);\n }\n throw new Error('Not implemented');\n }\n\n #listFromHub(): LastConnectedWalletsStorage {\n const persistor = new Persistor<LastConnectedWalletsStorage>();\n const lastConnectedWallets =\n persistor.getItem(HUB_LAST_CONNECTED_WALLETS) || {};\n return lastConnectedWallets;\n }\n #addWalletToHub(providerId: string, namespaces: NamespaceInput[]): void {\n const storage = new Persistor<LastConnectedWalletsStorage>();\n const storageState = storage.getItem(this.#storageKey) || {};\n\n let toBeAddedNamespaces = namespaces;\n\n // If provider already exits in the storage, we should just add new namespaces to the previously added namespaces.\n if (!!storageState[providerId]) {\n const storedNamespaces = storageState[providerId];\n toBeAddedNamespaces = storedNamespaces.concat(\n namespaces.filter(\n (namespace) =>\n !storedNamespaces.some(\n (storedNamespace) =>\n storedNamespace.namespace === namespace.namespace\n )\n )\n );\n }\n\n storage.setItem(this.#storageKey, {\n ...storageState,\n [providerId]: toBeAddedNamespaces,\n });\n }\n #removeWalletsFromHub(providerIds?: string[]): void {\n const persistor = new Persistor<LastConnectedWalletsStorage>();\n const storageState = persistor.getItem(this.#storageKey) || {};\n\n // Remove all wallets\n if (!providerIds) {\n persistor.setItem(this.#storageKey, {});\n return;\n }\n\n // Remove some of the wallets\n providerIds.forEach((providerId) => {\n if (storageState[providerId]) {\n delete storageState[providerId];\n }\n });\n\n persistor.setItem(this.#storageKey, storageState);\n }\n #removeNamespaceFromWalletHub(\n providerId: string,\n namespaceIds: string[]\n ): void {\n const persistor = new Persistor<LastConnectedWalletsStorage>();\n const storageState = persistor.getItem(this.#storageKey) || {};\n\n const currentProviderNamespaces = storageState[providerId];\n const newProviderNamespaces = currentProviderNamespaces?.filter(\n (namespace) => !namespaceIds.includes(namespace.namespace)\n );\n\n this.#removeWalletsFromHub([providerId]);\n if (newProviderNamespaces?.length > 0) {\n this.#addWalletToHub(providerId, newProviderNamespaces);\n }\n }\n}\n", "import type { AllProxiedNamespaces, ExtensionLink } from './types.js';\nimport type {\n ConnectResult,\n EventHandler,\n NamespaceInputForConnect,\n WalletInfo,\n} from '../legacy/mod.js';\nimport type { ProviderContext, ProviderProps } from '../types.js';\nimport type { Provider, WalletType } from '@hub3js/core';\nimport type { Event } from '@hub3js/core/store';\nimport type { Accounts, AccountsWithActiveChain } from '@hub3js/std/types';\n\nimport { utils } from '@hub3js/evm';\nimport {\n getSupportedChainsFromNamespace,\n getSupportedChainsFromProvider,\n} from '@rango-dev/internal-blockchains';\nimport { useEffect, useRef, useState } from 'react';\nimport { Ok, Result } from 'ts-results';\n\nimport {\n emitWalletDetectedOnce,\n toBlockchainName,\n WalletEventChannel,\n WalletEventTypes,\n} from '../events.js';\nimport { withErrorLoggingApi } from '../helpers.js';\nimport { Events } from '../legacy/mod.js';\n\nimport { autoConnect } from './autoConnect.js';\nimport { HUB_LAST_CONNECTED_WALLETS } from './constants.js';\nimport { createQueue, fromAccountIdToLegacyAddressFormat } from './helpers.js';\nimport { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';\nimport { useAutoConnect } from './useAutoConnect.js';\nimport { useHubRefs } from './useHubRefs.js';\nimport {\n isEvmNamespace,\n isSolanaNamespace,\n isUtxoNamespace,\n mapHubEventsToLegacy,\n transformHubResultToLegacyResult,\n tryConvertNamespaceNetworkToChainInfo,\n} from './utils.js';\n\nexport type UseAdapterParams = Omit<ProviderProps, 'providers'> & {\n providers: Provider[];\n};\n\nexport function useHubAdapter(params: UseAdapterParams): ProviderContext {\n const { getStore, getHub } = useHubRefs(params.providers);\n const [, rerender] = useState(0);\n // useEffect will run `subscribe` once, so we need a reference and mutate the value if it's changes.\n const dataRef = useRef({\n onUpdateState: params.onUpdateState,\n allBlockChains: params.allBlockChains,\n emitter: params.emitter,\n });\n const hubInitiated = useRef(false);\n\n /*\n * Params of each connection attempt for each wallet type are stored here.\n * Derivation path from params is used in `mapHubEventsToLegacy` to be added to the payload of connect events.\n */\n const lastConnectAttemptParamsRef = useRef<{\n [type: WalletType]: NamespaceInputForConnect[];\n }>({});\n\n const updateLastConnectAttemptParams = (\n type: WalletType,\n namespaces: NamespaceInputForConnect[] | undefined\n ) => {\n lastConnectAttemptParamsRef.current[type] = namespaces || [];\n };\n\n const queueTask = createQueue({\n onError: (error, actions) => {\n if (utils.isUserRejectionError(error)) {\n actions.removeCurrentKeyFromQueue();\n }\n },\n });\n\n useEffect(() => {\n dataRef.current = {\n onUpdateState: params.onUpdateState,\n allBlockChains: params.allBlockChains,\n emitter: params.emitter,\n };\n }, [params]);\n\n useEffect(() => {\n const onUpdateState: EventHandler = (type, event, value, state, info) => {\n if (event === Events.INSTALLED && state.installed) {\n emitWalletDetectedOnce(type, dataRef.current.emitter);\n }\n dataRef.current.onUpdateState?.(type, event, value, state, info);\n };\n\n const onStoreEvent = (event: Event) => {\n try {\n mapHubEventsToLegacy(getHub(), event, onUpdateState, {\n allBlockChains: dataRef.current.allBlockChains,\n lastConnectAttemptParams: lastConnectAttemptParamsRef.current,\n });\n } catch (e) {\n console.error(e);\n }\n rerender((currentRender) => currentRender + 1);\n };\n\n getStore().subscribe(onStoreEvent).flushEvents();\n }, []);\n\n // Initialize hub only after blockchain meta is available (e.g. WalletConnect needs it at init).\n useEffect(() => {\n if (hubInitiated.current || !params.allBlockChains?.length) {\n return;\n }\n\n getHub().init(params.configs?.walletOptions);\n rerender((currentRender) => currentRender + 1);\n hubInitiated.current = true;\n }, [params.allBlockChains, params.configs?.walletOptions]);\n\n useAutoConnect({\n autoConnect: params.autoConnect,\n allBlockChains: params.allBlockChains,\n autoConnectHandler: () => {\n void autoConnect({\n allBlockChains: params.allBlockChains,\n getHub,\n wallets: params.configs?.wallets,\n emitter: dataRef.current.emitter,\n });\n },\n });\n\n const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n HUB_LAST_CONNECTED_WALLETS\n );\n\n const api: ProviderContext = {\n canSwitchNetworkTo(type, network, namespace) {\n const provider = getHub().get(type);\n\n if (!provider) {\n // TODO: should throw an error\n return false;\n }\n\n if (!namespace) {\n throw new Error(\n 'Passing namespace to `canSwitchNetworkTo` is required.'\n );\n }\n\n const proxiedNamespace = provider.findByNamespace(namespace.namespace);\n if (!proxiedNamespace) {\n throw new Error(\n `We couldn't find any matched namespace on your request provider. (requested namespace: ${namespace.namespace})`\n );\n }\n if (!('canSwitchNetwork' in proxiedNamespace)) {\n return false;\n }\n const namespacesProperty = provider\n .info()\n ?.metadata?.properties?.find(\n (property) => property.name === 'namespaces'\n );\n\n if (!dataRef.current.allBlockChains) {\n throw new Error(`Blockchains are not available`);\n }\n\n const namespaceMeta = namespacesProperty?.value.data.find(\n (providerNamespace) => providerNamespace.value === namespace.namespace\n );\n\n if (!namespaceMeta) {\n throw new Error(\n `NamespaceMeta is not defined for requested namespace: ${namespace.namespace}`\n );\n }\n\n const supportedChains = getSupportedChainsFromNamespace(\n namespaceMeta,\n dataRef.current.allBlockChains\n );\n\n return proxiedNamespace.canSwitchNetwork({\n network,\n supportedChains,\n });\n },\n async connect(type, namespaces) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(\n `You should add ${type} to provider first then call 'connect'.`\n );\n }\n\n if (!namespaces) {\n throw new Error('Passing namespace to `connect` is required.');\n }\n\n updateLastConnectAttemptParams(type, namespaces);\n\n // Check `namespace` and look into hub to see how it can match given namespace to hub namespace.\n const targetNamespaces: [\n NamespaceInputForConnect,\n AllProxiedNamespaces\n ][] = [];\n namespaces.forEach((namespace) => {\n const targetNamespace = namespace.namespace;\n\n const result = wallet.findByNamespace(targetNamespace);\n if (!result) {\n throw new Error(\n `We couldn't find any provider matched with your request namespace. (requested namespace: ${namespace.namespace})`\n );\n }\n\n targetNamespaces.push([namespace, result]);\n });\n\n // Try to run `connect` on matched namespaces\n const connectResultFromTargetNamespaces = targetNamespaces.map(\n async ([namespaceInput, namespace]) => {\n const network = tryConvertNamespaceNetworkToChainInfo(\n namespaceInput,\n params.allBlockChains || []\n );\n\n let connectNamespacePromise: () => Promise<\n Accounts | AccountsWithActiveChain\n >;\n\n if (isSolanaNamespace(namespace)) {\n connectNamespacePromise = async () =>\n namespace.connect({\n derivationPath: namespaceInput.derivationPath,\n });\n } else if (isEvmNamespace(namespace)) {\n connectNamespacePromise = async () =>\n namespace.connect(network, {\n derivationPath: namespaceInput.derivationPath,\n });\n } else if (isUtxoNamespace(namespace)) {\n connectNamespacePromise = async () =>\n namespace.connect({\n derivationPath: namespaceInput.derivationPath,\n });\n } else {\n connectNamespacePromise = async () => namespace.connect();\n }\n\n const connectNamespaceProcess = async () =>\n connectNamespacePromise()\n .then<ConnectResult>(transformHubResultToLegacyResult)\n .then((connectResult) => {\n return {\n response: connectResult,\n input: {\n namespace: namespaceInput.namespace,\n network: namespaceInput.network,\n supportsEagerConnect: 'canEagerConnect' in namespace,\n },\n };\n });\n\n // Reconnecting an already connected namespace (e.g. only to switch its network) isn't reported.\n const connectNamespaceProcessWithEvents = async () => {\n if (namespace.state()[0]().connected) {\n return connectNamespaceProcess();\n }\n\n const eventPayload = {\n walletName: type,\n namespace: namespaceInput.namespace,\n origin: 'manual' as const,\n };\n const requestedChain = namespaceInput.network || null;\n\n dataRef.current.emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECT_INITIATED,\n payload: { ...eventPayload, chain: requestedChain },\n });\n try {\n const result = await connectNamespaceProcess();\n dataRef.current.emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECTED,\n payload: {\n ...eventPayload,\n chain: toBlockchainName(\n result.response.network,\n params.allBlockChains\n ),\n },\n });\n return result;\n } catch (error) {\n dataRef.current.emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECT_FAILED,\n payload: { ...eventPayload, chain: requestedChain },\n });\n throw error;\n }\n };\n return queueTask(connectNamespaceProcessWithEvents, type);\n }\n );\n\n /*\n * We need to connect to namespace one after another, sending multiple requests at the same time may be failed.\n * e.g. when wallet popup opens and asking for the password from the user, it should be resolved first, then other request will be resolved.\n */\n const connectResultWithLegacyFormat = await Promise.all(\n connectResultFromTargetNamespaces\n );\n\n // Keeping only namespaces that connected successfully and support eager connect, then we'll store them on storage for auto connect functionality.\n const successfullyConnectedSupportingEagerConnectNamespaces =\n connectResultWithLegacyFormat\n .filter(<T, E>(result: Result<T, E>): result is Ok<T> => result.ok)\n .filter((result) => result.val.input.supportsEagerConnect)\n .map((result) => ({\n namespace: result.val.input.namespace,\n network: result.val.input.network,\n }));\n\n if (successfullyConnectedSupportingEagerConnectNamespaces.length > 0) {\n lastConnectedWalletsFromStorage.addWallet(\n type,\n successfullyConnectedSupportingEagerConnectNamespaces\n );\n }\n\n // Getting rid of `input` from Result\n const connectResults = connectResultWithLegacyFormat.map((result) =>\n result.andThen((okResult) => new Ok(okResult.response))\n );\n\n const allResult = Result.all(...connectResults);\n if (allResult.err) {\n throw allResult.val;\n }\n\n return allResult.unwrap();\n },\n async disconnect(type, namespaces) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(\n `You should add ${type} to provider first then call 'disconnect'.`\n );\n }\n\n wallet.getAll().forEach((namespace) => {\n const namespaceShouldBeDisconnected =\n !namespaces || namespaces.includes(namespace.namespaceId);\n const namespaceIsConnected = namespace.state()[0]().connected;\n if (namespaceShouldBeDisconnected && namespaceIsConnected) {\n dataRef.current.emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_DISCONNECTED,\n payload: { walletName: type, namespace: namespace.namespaceId },\n });\n return namespace.disconnect();\n }\n });\n\n if (params.autoConnect) {\n if (namespaces) {\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n type,\n namespaces\n );\n } else {\n lastConnectedWalletsFromStorage.removeWallets([type]);\n }\n }\n },\n async disconnectAll() {\n const disconnectPromises: Promise<void>[] = Array.from(\n getHub().getAll().values()\n ).map(async (provider) => this.disconnect(provider.id));\n\n return await Promise.allSettled(disconnectPromises);\n },\n async getSigners(type) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n const info = wallet.info();\n if (!info) {\n throw new Error('Your provider should have required `info`.');\n }\n\n const providerProperties = info.metadata.properties;\n\n const signerProperty = providerProperties?.find(\n (property) => property.name === 'signers'\n );\n if (!signerProperty) {\n throw new Error('Your provider should contain signers property.');\n }\n\n return signerProperty.value.getSigners();\n },\n getWalletInfo(type) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n const info = wallet.info();\n if (!info) {\n throw new Error('Your provider should have required `info`.');\n }\n\n const installLink: Exclude<WalletInfo['installLink'], string> = {\n DEFAULT: '',\n };\n\n const { metadata } = info;\n const { extensions } = metadata;\n // `extensions` in legacy format was uppercase and also `DEFAULT` was used instead of `homepage`\n Object.keys(extensions).forEach((k) => {\n const key = k as ExtensionLink;\n\n if (key === 'homepage') {\n installLink.DEFAULT = extensions[key] || '';\n }\n\n const allowedKeys: ExtensionLink[] = [\n 'firefox',\n 'chrome',\n 'brave',\n 'edge',\n ];\n if (allowedKeys.includes(key)) {\n const upperCasedKey = key.toUpperCase() as keyof Exclude<\n WalletInfo['installLink'],\n string\n >;\n installLink[upperCasedKey] = extensions[key] || '';\n }\n });\n\n const providerProperties = metadata.properties;\n\n const namespacesProperty = providerProperties?.find(\n (property) => property.name === 'namespaces'\n );\n const derivationPathProperty = providerProperties?.find(\n (property) => property.name === 'derivationPath'\n );\n const detailsProperty = providerProperties?.find(\n (property) => property.name === 'details'\n );\n\n return {\n name: metadata.name,\n img: metadata.icon,\n installLink: installLink,\n // We don't have this values anymore, fill them with some values that communicate this.\n color: 'red',\n supportedChains: getSupportedChainsFromProvider(\n wallet,\n dataRef.current.allBlockChains\n ),\n isContractWallet: detailsProperty?.value?.isContractWallet,\n mobileWallet: detailsProperty?.value?.mobileWallet,\n // if set to false here, it will not show the wallet in mobile in anyways. to be compatible with old behavior, undefined is more appropirate.\n showOnMobile: detailsProperty?.value?.showOnMobile,\n needsNamespace: namespacesProperty?.value,\n needsDerivationPath: derivationPathProperty?.value,\n isHub: true,\n properties: metadata.properties,\n };\n },\n state(type) {\n const hubState = getHub().state();\n const wallet = getHub().get(type);\n const walletState = hubState[type];\n\n if (!walletState || !wallet) {\n // TODO: should throw an error\n return {\n connected: false,\n connecting: false,\n installed: false,\n reachable: false,\n accounts: null,\n network: null,\n namespaces: new Map(),\n };\n }\n\n const accounts = walletState.namespaces\n .filter((namespace) => namespace.connected)\n .flatMap((namespace) =>\n namespace.accounts?.map((accounts) =>\n fromAccountIdToLegacyAddressFormat(accounts)\n )\n )\n .filter((account): account is string => !!account);\n\n const namespacesState = new Map(\n Array.from(wallet.getAll(), ([_, value]) => [\n value.namespaceId,\n value.state()[0](),\n ])\n );\n\n const coreState = {\n connected: walletState.connected,\n connecting: walletState.connecting,\n installed: walletState.installed,\n reachable: true,\n accounts: accounts,\n network: null,\n namespaces: namespacesState,\n };\n return coreState;\n },\n async suggestAndConnect(type, namespace): Promise<ConnectResult> {\n const provider = getHub().get(type);\n\n if (!provider) {\n throw new Error(\n `You should add ${type} to provider first then call 'suggestAndConnect'.`\n );\n }\n const proxiedNamespace = provider.findByNamespace(namespace.namespace);\n if (!proxiedNamespace) {\n throw new Error(\n `We couldn't find any matched namespace on your request provider. (requested namespace: ${namespace.namespace})`\n );\n }\n if (!('suggest' in proxiedNamespace)) {\n throw new Error('Suggest is not implemented on the provider');\n }\n if (!namespace.network) {\n throw new Error('You should pass network to the suggest and connect');\n }\n throw new Error(\n `Suggest has not been implemented for given chain: ${namespace.network}`\n );\n },\n hubProvider(type) {\n /*\n * Return the instance registered in the hub, which holds the store. A\n * provider list can be rebuilt with the same ids, and the hub keeps the\n * instances it registered first, so a rebuilt one would have no store.\n */\n const provider = getHub().get(type);\n\n if (!provider) {\n throw new Error(\n `You're trying to access ${type} provider which is not found in hub providers. it may not be registered yet.`\n );\n }\n\n return provider;\n },\n };\n\n return withErrorLoggingApi(api);\n}\n", "import type { WalletType } from '@hub3js/core';\nimport type { Namespace } from '@hub3js/namespaces';\nimport type { BlockchainMeta } from 'rango-types';\n\nimport { getBlockChainNameFromId } from '@rango-dev/internal-blockchains';\n\nimport { WALLET_DETECTED_SKIPPED_IDS } from './hub/constants.js';\n\nexport const WalletEventChannel = 'walletEvent';\n\nexport enum WalletEventTypes {\n WALLET_DETECTED = 'walletDetected',\n WALLET_CONNECT_INITIATED = 'walletConnectInitiated',\n WALLET_CONNECTED = 'walletConnected',\n WALLET_CONNECT_FAILED = 'walletConnectFailed',\n WALLET_DISCONNECTED = 'walletDisconnected',\n}\n\nexport type WalletConnectOrigin = 'manual' | 'auto';\n\ntype WalletConnectEventPayload = {\n /** Wallet type id, e.g. `metamask`. */\n walletName: WalletType;\n namespace: Namespace;\n /** Rango blockchain name (e.g. `ETH`), or `null` when it isn't known. */\n chain: string | null;\n origin: WalletConnectOrigin;\n};\n\nexport type WalletDetectedEventPayload = {\n walletName: WalletType;\n};\nexport type WalletConnectInitiatedEventPayload = WalletConnectEventPayload;\nexport type WalletConnectedEventPayload = WalletConnectEventPayload;\nexport type WalletConnectFailedEventPayload = WalletConnectEventPayload;\nexport type WalletDisconnectedEventPayload = {\n walletName: WalletType;\n namespace: Namespace;\n};\n\ntype EventData<T extends WalletEventTypes, U> = { type: T; payload: U };\n\nexport type WalletEventData =\n | EventData<WalletEventTypes.WALLET_DETECTED, WalletDetectedEventPayload>\n | EventData<\n WalletEventTypes.WALLET_CONNECT_INITIATED,\n WalletConnectInitiatedEventPayload\n >\n | EventData<WalletEventTypes.WALLET_CONNECTED, WalletConnectedEventPayload>\n | EventData<\n WalletEventTypes.WALLET_CONNECT_FAILED,\n WalletConnectFailedEventPayload\n >\n | EventData<\n WalletEventTypes.WALLET_DISCONNECTED,\n WalletDisconnectedEventPayload\n >;\n\nexport type WalletEvents = {\n [WalletEventChannel]: WalletEventData;\n};\n\nexport interface Emitter<Events extends Record<string, unknown>> {\n emit<K extends keyof Events>(type: K, event: Events[K]): void;\n}\n\nexport type WalletEventEmitter = Emitter<WalletEvents>;\n\nconst detectedWallets = new Set<WalletType>();\n\nexport function emitWalletDetectedOnce(\n walletName: WalletType,\n emitter?: WalletEventEmitter\n): void {\n if (\n detectedWallets.has(walletName) ||\n WALLET_DETECTED_SKIPPED_IDS.includes(walletName)\n ) {\n return;\n }\n detectedWallets.add(walletName);\n emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_DETECTED,\n payload: { walletName },\n });\n}\n\n/**\n * Connect results may carry an EVM chain id (e.g. `0x1`); events always carry a Rango blockchain name.\n */\nexport function toBlockchainName(\n network: string | null | undefined,\n allBlockChains: BlockchainMeta[] | undefined\n): string | null {\n if (!network) {\n return null;\n }\n return getBlockChainNameFromId(network, allBlockChains || []);\n}\n", "import type { ProviderContext } from './types.js';\n\nimport { debug } from '@rango-dev/logging-core';\n\nfunction logError(method: string, args: unknown[], error: unknown) {\n const err = error instanceof Error ? error : new Error(String(error));\n debug(err, {\n context: { method, args },\n tags: { type: 'wallet-error' },\n });\n}\n\nfunction withErrorLogging<TArgs extends unknown[], TReturn>(\n method: string,\n fn: (...args: TArgs) => TReturn\n): (...args: TArgs) => TReturn {\n return (...args: TArgs): TReturn => {\n try {\n const result = fn(...args);\n // Async method: catch the rejection, log, then throw the rejection.\n if (result instanceof Promise) {\n return result.catch((error: unknown) => {\n logError(method, args, error);\n throw error;\n }) as TReturn;\n }\n return result;\n } catch (error) {\n // Sync method: log and rethrow.\n logError(method, args, error);\n throw error;\n }\n };\n}\n\nexport function withErrorLoggingApi(api: ProviderContext): ProviderContext {\n const entries = Object.entries(api).map(([key, value]) => [\n key,\n withErrorLogging(key, (value as (...args: unknown[]) => unknown).bind(api)),\n ]);\n\n return Object.fromEntries(entries) as ProviderContext;\n}\n", "import type { AllProxiedNamespaces } from './types.js';\nimport type { UseAdapterParams } from './useHubAdapter.js';\nimport type { NamespaceInputForConnect } from '../legacy/types.js';\nimport type { Hub, Provider, WalletType } from '@hub3js/core';\nimport type { DefaultNamespaces, Namespace } from '@hub3js/namespaces';\nimport type { Accounts, AccountsWithActiveChain } from '@hub3js/std/types';\n\nimport { Result } from 'ts-results';\n\nimport {\n toBlockchainName,\n WalletEventChannel,\n type WalletEventEmitter,\n WalletEventTypes,\n} from '../events.js';\n\nimport { HUB_LAST_CONNECTED_WALLETS } from './constants.js';\nimport { runSequentiallyWithoutFailure } from './helpers.js';\nimport { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';\nimport {\n convertNamespaceNetworkToEvmChainId,\n isEvmNamespace,\n transformHubResultToLegacyResult,\n} from './utils.js';\n\nfunction createAutoConnectEventPayload(\n walletName: WalletType,\n namespaceInput: NamespaceInputForConnect\n) {\n return {\n walletName,\n namespace: namespaceInput.namespace,\n chain: namespaceInput.network || null,\n origin: 'auto' as const,\n };\n}\n\nfunction isEvmNamespaceInput(\n namespace: NamespaceInputForConnect\n): namespace is NamespaceInputForConnect<'EVM'> {\n return namespace.namespace === 'EVM';\n}\n\n// Getting connected wallets from storage\nconst lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n HUB_LAST_CONNECTED_WALLETS\n);\n\n/**\n * Run `.connect` action on some selected namespaces (passed as param) for a provider.\n */\nasync function eagerConnect(\n type: string,\n namespacesInput: NamespaceInputForConnect[] | undefined,\n params: {\n getHub: () => Hub;\n allBlockChains: UseAdapterParams['allBlockChains'];\n emitter?: WalletEventEmitter;\n }\n) {\n const { getHub, allBlockChains, emitter } = params;\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(\n `You should add ${type} to provider first then call 'connect'.`\n );\n }\n\n if (!namespacesInput) {\n throw new Error('Passing namespace to `connect` is required. ');\n }\n\n const targetNamespaces: [NamespaceInputForConnect, AllProxiedNamespaces][] =\n [];\n namespacesInput.forEach((namespaceInput) => {\n const targetNamespace: Namespace = namespaceInput.namespace;\n\n const result = wallet.findByNamespace(targetNamespace);\n\n if (!result) {\n throw new Error(\n `We couldn't find any provider matched with your request namespace. (requested namespace: ${namespaceInput.namespace})`\n );\n }\n\n targetNamespaces.push([namespaceInput, result]);\n });\n\n const connectNamespacesPromises = targetNamespaces.map(\n ([info, namespace]) => {\n const evmChain = isEvmNamespaceInput(info)\n ? convertNamespaceNetworkToEvmChainId(info, allBlockChains || [])\n : undefined;\n const chain = evmChain || info.network;\n\n return async () => {\n let connectNamespacePromise: () => Promise<\n Accounts | AccountsWithActiveChain\n >;\n if (isEvmNamespace(namespace)) {\n connectNamespacePromise = async () => namespace.connect(chain);\n } else {\n connectNamespacePromise = async () => namespace.connect();\n }\n const eventPayload = createAutoConnectEventPayload(type, info);\n try {\n const result = await connectNamespacePromise();\n emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECTED,\n payload: {\n ...eventPayload,\n chain: toBlockchainName(\n transformHubResultToLegacyResult(result).network,\n allBlockChains\n ),\n },\n });\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any) {\n emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECT_FAILED,\n payload: eventPayload,\n });\n /*\n * Since we check for connect failures using `instanceof Error`\n * this check is added here to make sure the thrown error always is an instance of `Error`\n */\n if (e instanceof Error) {\n throw e;\n }\n throw new Error(e);\n }\n };\n }\n );\n\n /**\n * Sometimes calling methods on a instance in parallel, would cause an error in wallet.\n * We are running a method at a time to make sure we are covering this.\n * e.g. when we are trying to eagerConnect evm and solana on phantom at the same time, the last namespace throw an error.\n */\n const connectNamespacesResult = await runSequentiallyWithoutFailure(\n connectNamespacesPromises\n );\n\n const failedNamespaces: NamespaceInputForConnect[] = targetNamespaces\n .filter((_, index) => connectNamespacesResult[index].err)\n .map((targetNamespace) => targetNamespace[0]);\n\n if (failedNamespaces.length > 0) {\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n type,\n failedNamespaces.map((namespace) => namespace.namespace)\n );\n }\n\n const atLeastOneNamespaceConnectedSuccessfully = connectNamespacesResult.some(\n (result) => result.ok\n );\n if (!atLeastOneNamespaceConnectedSuccessfully) {\n throw new Error(`No namespace connected for ${type}`);\n }\n return Result.all(\n ...connectNamespacesResult.filter((result) => result.ok)\n ).unwrap();\n}\n\n/**\n * Run `.canEagerConnect` action on some selected namespaces of a wallet.\n */\nasync function tryRunCanEagerConnect(\n namespaces: NamespaceInputForConnect[],\n wallet: Provider<DefaultNamespaces>\n): Promise<{\n successNamespaces: NamespaceInputForConnect[];\n failedNamespaces: NamespaceInputForConnect[];\n}> {\n const foundNamespaces: NamespaceInputForConnect[] = [];\n const successNamespaces: NamespaceInputForConnect[] = [];\n const failedNamespaces: NamespaceInputForConnect[] = [];\n const canEagerConnectPromises: (() => Promise<boolean>)[] = [];\n\n // 1. Try find namespace instances and create canEagerConnect promises\n namespaces.forEach((namespace) => {\n const namespaceInstance = wallet.findByNamespace(namespace.namespace);\n if (namespaceInstance) {\n foundNamespaces.push(namespace);\n canEagerConnectPromises.push(\n async () => await namespaceInstance.canEagerConnect()\n );\n } else {\n failedNamespaces.push(namespace);\n }\n });\n\n // 2. Run canEagerConnect sequentially on namespaces\n const canEagerConnectResults = await runSequentiallyWithoutFailure(\n canEagerConnectPromises\n );\n\n // 3. Separate success and failed namespaces based on canEagerConnect result\n foundNamespaces.forEach((namespace, index) => {\n if (canEagerConnectResults[index].ok && canEagerConnectResults[index].val) {\n successNamespaces.push(namespace);\n } else {\n failedNamespaces.push(namespace);\n }\n });\n\n return { successNamespaces, failedNamespaces };\n}\n\n/*\n * Get last connected wallets and last connected namespaces for each of them from storage\n * Then run `.connect` on each namespace if `.canEagerConnect` returns true.\n */\nexport async function autoConnect(deps: {\n getHub: () => Hub;\n allBlockChains: UseAdapterParams['allBlockChains'];\n wallets?: (WalletType | Provider)[];\n emitter?: WalletEventEmitter;\n}): Promise<void> {\n const { getHub, allBlockChains, wallets, emitter } = deps;\n const lastConnectedWallets = lastConnectedWalletsFromStorage.list();\n const walletIds = Object.keys(lastConnectedWallets);\n\n const walletsToRemoveFromPersistence: string[] = [];\n\n if (walletIds.length) {\n const eagerConnectQueue: Promise<unknown>[] = [];\n\n const configWalletNames = wallets?.map((wallet) =>\n typeof wallet === 'string' ? wallet : wallet.id\n );\n // Run `.connect` if `.canEagerConnect` returns `true`.\n walletIds.forEach(async (providerName) => {\n if (configWalletNames && !configWalletNames.includes(providerName)) {\n console.warn(\n 'Trying to run auto connect for a wallet which is not included in config. Desired wallet:',\n providerName\n );\n walletsToRemoveFromPersistence.push(providerName);\n return;\n }\n\n const wallet = getHub().get(providerName);\n\n const lastConnectedNamespaces: NamespaceInputForConnect[] =\n lastConnectedWallets[providerName].map((namespace) => ({\n namespace: namespace.namespace,\n network: namespace.network,\n }));\n\n if (!lastConnectedNamespaces.length || !wallet) {\n walletsToRemoveFromPersistence.push(providerName);\n return;\n }\n\n lastConnectedNamespaces.forEach((namespace) => {\n emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECT_INITIATED,\n payload: createAutoConnectEventPayload(providerName, namespace),\n });\n });\n\n const { successNamespaces, failedNamespaces } =\n await tryRunCanEagerConnect(lastConnectedNamespaces, wallet);\n\n failedNamespaces.forEach((namespace) => {\n emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECT_FAILED,\n payload: createAutoConnectEventPayload(providerName, namespace),\n });\n });\n\n if (!successNamespaces.length) {\n walletsToRemoveFromPersistence.push(providerName);\n return;\n } else if (failedNamespaces.length) {\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n wallet.id,\n failedNamespaces.map((namespace) => namespace.namespace)\n );\n }\n eagerConnectQueue.push(\n eagerConnect(providerName, successNamespaces, {\n allBlockChains,\n getHub,\n emitter,\n }).catch((error) => console.warn(error))\n );\n });\n\n lastConnectedWalletsFromStorage.removeWallets(\n walletsToRemoveFromPersistence\n );\n\n await Promise.all(eagerConnectQueue);\n }\n}\n", "import type { ProviderProps } from '../types.js';\n\nimport { useEffect, useRef } from 'react';\n\nimport { shouldTryAutoConnect } from './helpers.js';\n\nexport function useAutoConnect(\n props: Pick<ProviderProps, 'allBlockChains' | 'autoConnect'> & {\n /**\n * A function to run autoConnect on instances\n */\n autoConnectHandler: () => void;\n }\n) {\n const autoConnectInitiated = useRef(false);\n\n useEffect(() => {\n if (shouldTryAutoConnect(props) && !autoConnectInitiated.current) {\n autoConnectInitiated.current = true;\n props.autoConnectHandler();\n }\n }, [props.autoConnect, props.allBlockChains]);\n}\n", "import type { Provider, Store } from '@hub3js/core';\n\nimport { createStore, Hub } from '@hub3js/core';\nimport { useRef } from 'react';\n\nimport { synchronizeHubWithConfigProviders } from './utils.js';\n\nexport function useHubRefs(providers: Provider[]) {\n const store = useRef<Store | null>(null);\n\n const hub = useRef<Hub | null>(null);\n\n function createHub() {\n const createdHub = new Hub({\n store: getStore(),\n });\n /*\n * First add providers to hub\n * This helps to `getWalletInfo` be usable, before initialize.\n */\n providers.forEach((provider) => {\n createdHub.add(provider.id, provider);\n });\n hub.current = createdHub;\n return createdHub;\n }\n\n // https://react.dev/reference/react/useRef#avoiding-recreating-the-ref-contents\n function getStore() {\n if (store.current !== null) {\n return store.current;\n }\n const createdStore = createStore();\n store.current = createdStore;\n return createdStore;\n }\n\n function getHub(): Hub {\n const hubProviders = hub.current?.getAll();\n\n if (!hub.current || !hubProviders) {\n return createHub();\n }\n\n synchronizeHubWithConfigProviders(hub.current, providers);\n return hub.current;\n }\n\n return { getStore, getHub };\n}\n", "import type { ProviderContext } from './types.js';\n\nimport { useContext } from 'react';\n\nimport { WalletContext } from './context.js';\n\nexport function useWallets(): ProviderContext {\n const context = useContext(WalletContext);\n if (!context) {\n throw Error('useWallet can only be used within the Provider component');\n }\n return context;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["React", "createContext", "defaultErrorMessage", "defaultContext", "WalletContext", "convertEvmBlockchainMetaToEvmChainInfo", "formatAddressWithNetwork", "getBlockChainNameFromId", "getSupportedChainsFromProvider", "AccountId", "isEvmBlockchain", "Events", "WalletTypes", "HUB_LAST_CONNECTED_WALLETS", "WALLET_DETECTED_SKIPPED_IDS", "CAIP_BITCOIN_CHAIN_ID", "CAIP_BITCOINCASH_CHAIN_ID", "CAIP_DOGECOIN_CHAIN_ID", "CAIP_LITECOIN_CHAIN_ID", "CAIP_ZCASH_CHAIN_ID", "CAIP_TRON_CHAIN_ID", "CAIP_TON_NAMESPACE", "formatAddressWithNetwork", "AccountId", "Err", "Ok", "mapCaipNamespaceToLegacyNetworkName", "chainId", "CAIP_BITCOIN_CHAIN_ID", "CAIP_ZCASH_CHAIN_ID", "CAIP_LITECOIN_CHAIN_ID", "CAIP_DOGECOIN_CHAIN_ID", "CAIP_BITCOINCASH_CHAIN_ID", "CAIP_TON_NAMESPACE", "CAIP_TRON_CHAIN_ID", "__name", "fromAccountIdToLegacyAddressFormat", "account", "address", "AccountId", "network", "formatAddressWithNetwork", "runSequentiallyWithoutFailure", "promises", "prevPromise", "task", "previousResults", "taskResult", "Ok", "error", "Err", "isConnectResultEvm", "result", "isConnectResultSolana", "createQueue", "options", "processingKeys", "queue", "removeKeyFromQueue", "key", "q", "processQueue", "currentItem", "item", "resolve", "indexOfCurrentItem", "shouldTryAutoConnect", "props", "Persistor", "__name", "name", "item", "value", "LastConnectedWalletsFromStorage", "__name", "#storageKey", "storageKey", "providerId", "namespaces", "HUB_LAST_CONNECTED_WALLETS", "#addWalletToHub", "providerIds", "#removeWalletsFromHub", "#listFromHub", "namespaceIds", "#removeNamespaceFromWalletHub", "Persistor", "storage", "storageState", "toBeAddedNamespaces", "storedNamespaces", "namespace", "storedNamespace", "persistor", "newProviderNamespaces", "lastConnectedWalletsFromStorage", "LastConnectedWalletsFromStorage", "HUB_LAST_CONNECTED_WALLETS", "mapHubEventsToLegacy", "hub", "event", "onUpdateState", "metadata", "
|
|
3
|
+
"sources": ["../src/provider.tsx", "../src/context.ts", "../src/hub/utils.ts", "../src/legacy/types.ts", "../src/hub/constants.ts", "../src/hub/helpers.ts", "../src/hub/persistor.ts", "../src/hub/lastConnectedWallets.ts", "../src/hub/useHubAdapter.ts", "../src/events.ts", "../src/hub/autoConnect.ts", "../src/hub/errors.ts", "../src/hub/useAutoConnect.ts", "../src/hub/useHubRefs.ts", "../src/hooks.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ProviderProps } from './types.js';\n\nimport React from 'react';\n\nimport { WalletContext } from './context.js';\nimport { useHubAdapter } from './hub/mod.js';\n\nfunction Provider(props: ProviderProps) {\n const api = useHubAdapter(props);\n\n return (\n <WalletContext.Provider value={api}>\n {props.children}\n </WalletContext.Provider>\n );\n}\n\nexport default Provider;\n", "import type { ProviderContext } from './types.js';\n\nimport { createContext } from 'react';\n\nconst defaultErrorMessage = \"Context hasn't been initialized yet.\";\nconst defaultContext: ProviderContext = {\n async connect() {\n throw new Error(defaultErrorMessage);\n },\n async disconnect() {\n throw new Error(defaultErrorMessage);\n },\n async disconnectAll() {\n throw new Error(defaultErrorMessage);\n },\n async suggestAndConnect() {\n throw new Error(defaultErrorMessage);\n },\n state() {\n throw new Error(defaultErrorMessage);\n },\n canSwitchNetworkTo() {\n throw new Error(defaultErrorMessage);\n },\n getWalletInfo() {\n throw new Error(defaultErrorMessage);\n },\n getSigners() {\n throw new Error(defaultErrorMessage);\n },\n hubProvider() {\n throw new Error(defaultErrorMessage);\n },\n};\n\nexport const WalletContext = createContext<ProviderContext>(defaultContext);\n", "import type { AllProxiedNamespaces } from './types.js';\nimport type {\n ConnectResult,\n NamespaceInputForConnect,\n EventHandler as WalletEventHandler,\n} from '../legacy/mod.js';\nimport type { ProviderProps } from '../types.js';\nimport type { UtxoActions } from '@hub3js/bip122';\nimport type { Hub, Provider, ProxiedNamespace, WalletType } from '@hub3js/core';\nimport type { Event } from '@hub3js/core/store';\nimport type {\n Chain as AddEthereumChainParameter,\n EvmActions,\n} from '@hub3js/evm';\nimport type { SolanaActions } from '@hub3js/solana';\n\nimport {\n convertEvmBlockchainMetaToEvmChainInfo,\n formatAddressWithNetwork,\n getBlockChainNameFromId,\n getSupportedChainsFromProvider,\n} from '@rango-dev/internal-blockchains';\nimport { AccountId } from 'caip';\nimport { type BlockchainMeta, isEvmBlockchain } from 'rango-types';\n\nimport { Events } from '../legacy/mod.js';\n\nimport { HUB_LAST_CONNECTED_WALLETS } from './constants.js';\nimport {\n fromAccountIdToLegacyAddressFormat,\n isConnectResultEvm,\n isConnectResultSolana,\n} from './helpers.js';\nimport { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';\n\nexport function findProviderByType(\n providers: Provider[],\n type: string\n): Provider | undefined {\n return providers.find((provider) => provider.id === type);\n}\n\n/**\n * We will call this function on hub's `subscribe`.\n * it will check states and will emit legacy events for backward compatibility.\n */\n\nconst lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n HUB_LAST_CONNECTED_WALLETS\n);\n\nexport function mapHubEventsToLegacy(\n hub: Hub,\n event: Event,\n onUpdateState: WalletEventHandler,\n metadata: {\n allBlockChains: ProviderProps['allBlockChains'];\n lastConnectAttemptParams: {\n [type: WalletType]: NamespaceInputForConnect[];\n };\n }\n): void {\n const provider = hub.get(event.provider);\n if (!provider) {\n throw new Error(\n \"Currently all the events have assigned to a provider. The event doesn't include one.\",\n {\n cause: event,\n }\n );\n }\n\n // @ts-expect-error for those events that doesn't have namespace, it will be undefinded\n const namespaceId: string | undefined = event.namespace;\n\n const namespace = namespaceId\n ? provider.findByNamespace(namespaceId)\n : undefined;\n let accounts: string[] | null = null;\n let network: string | null = null;\n let derivationPath: string | undefined;\n\n if (namespace) {\n const [getNamespaceState] = namespace.state();\n accounts = getNamespaceState().accounts;\n network = getNamespaceState().network;\n\n if (metadata.lastConnectAttemptParams[event.provider]) {\n derivationPath = metadata.lastConnectAttemptParams[event.provider].find(\n (namespace) => namespace.namespace === namespaceId\n )?.derivationPath;\n }\n }\n\n const [getProviderState] = provider.state();\n const coreState = {\n connected: getProviderState().connected,\n connecting: getProviderState().connecting,\n installed: getProviderState().installed,\n accounts,\n network,\n reachable: true,\n derivationPath,\n };\n\n const detailsProperty = provider\n .info()\n ?.metadata.properties?.find((property) => property.name === 'details');\n\n const eventInfo = {\n supportedBlockchains: getSupportedChainsFromProvider(\n provider,\n metadata.allBlockChains\n ),\n isContractWallet: detailsProperty?.value?.isContractWallet ?? false,\n isHub: true,\n namespace: namespaceId,\n };\n\n switch (event.type) {\n case 'provider_detected':\n onUpdateState(\n event.provider,\n Events.INSTALLED,\n true,\n coreState,\n eventInfo\n );\n break;\n case 'provider_connecting':\n onUpdateState(\n event.provider,\n Events.CONNECTING,\n event.value,\n coreState,\n eventInfo\n );\n break;\n case 'provider_connected':\n onUpdateState(\n event.provider,\n Events.CONNECTED,\n true,\n coreState,\n eventInfo\n );\n break;\n case 'provider_disconnected':\n onUpdateState(\n event.provider,\n Events.PROVIDER_DISCONNECTED,\n event.provider,\n coreState,\n eventInfo\n );\n onUpdateState(\n event.provider,\n Events.CONNECTED,\n false,\n coreState,\n eventInfo\n );\n onUpdateState(\n event.provider,\n Events.ACCOUNTS,\n null,\n coreState,\n eventInfo\n );\n break;\n case 'namespace_disconnected':\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n event.provider,\n [event.namespace]\n );\n\n onUpdateState(\n event.provider,\n Events.NAMESPACE_DISCONNECTED,\n event.namespace,\n coreState,\n {\n ...eventInfo,\n namespace: event.namespace,\n }\n );\n // onUpdateState(event.provider, Events.ACCOUNTS, null, coreState, eventInfo);\n break;\n case 'namespace_connected':\n case 'namespace_account_switched':\n {\n if (event.type === 'namespace_account_switched') {\n onUpdateState(\n event.provider,\n Events.NAMESPACE_DISCONNECTED,\n event.namespace,\n coreState,\n eventInfo\n );\n }\n\n let formattedAddresses: string[] = [];\n if (eventInfo.isContractWallet) {\n formattedAddresses = event.accounts.map((account) => {\n const { chainId, address } = AccountId.parse(account);\n if (typeof chainId === 'string') {\n throw new Error('Should be in CAIP format');\n }\n const blockchainName = getBlockChainNameFromId(\n chainId.reference,\n eventInfo.supportedBlockchains\n );\n\n return blockchainName\n ? formatAddressWithNetwork(address, blockchainName)\n : fromAccountIdToLegacyAddressFormat(account);\n });\n } else {\n formattedAddresses = event.accounts.map((accounts) =>\n fromAccountIdToLegacyAddressFormat(accounts)\n );\n }\n\n onUpdateState(\n event.provider,\n Events.ACCOUNTS,\n formattedAddresses,\n coreState,\n {\n ...eventInfo,\n namespace: event.namespace,\n }\n );\n }\n break;\n case 'namespace_network_switched':\n onUpdateState(event.provider, Events.NETWORK, event.network, coreState, {\n ...eventInfo,\n namespace: event.namespace,\n });\n break;\n }\n}\n\n/**\n * In legacy mode, for those who have switch network functionality (like evm), we are using an enum for network names\n * this enum only has meaning for us, and when we are going to connect an instance (e.g. window.ethereum) we should pass chain id.\n */\nexport function convertNamespaceNetworkToEvmChainId(\n namespace: NamespaceInputForConnect,\n meta: BlockchainMeta[]\n): AddEthereumChainParameter | undefined {\n if (!namespace.network) {\n return undefined;\n }\n\n const evmBlockchainsList = meta.filter(isEvmBlockchain);\n const evmChains = convertEvmBlockchainMetaToEvmChainInfo(evmBlockchainsList);\n\n return evmChains[namespace.network];\n}\n\n/**\n * We are passing an string for chain id (e.g. ETH, POLYGON), but wallet's instances (e.g. window.ethereum) needs chainId (e.g. 0x1).\n * This function will help us to map these strings to proper hex ids.\n */\nexport function tryConvertNamespaceNetworkToChainInfo(\n namespace: NamespaceInputForConnect,\n meta: BlockchainMeta[]\n): string | AddEthereumChainParameter | undefined {\n // `undefined` means it's not evm or we couldn't find it in meta.\n const evmChain = convertNamespaceNetworkToEvmChainId(namespace, meta);\n const network = evmChain || namespace.network;\n\n return network;\n}\n\nexport function transformHubResultToLegacyResult(\n res: Awaited<ReturnType<AllProxiedNamespaces['connect']>>\n): ConnectResult {\n if (isConnectResultEvm(res)) {\n return {\n accounts: res.accounts,\n network: res.network,\n };\n } else if (isConnectResultSolana(res)) {\n return {\n accounts: res,\n network: null,\n };\n }\n\n return {\n accounts: [res],\n network: null,\n };\n}\n\n/**\n * Synchronizes providers in the hub with the configuration providers.\n * - Registers and initializes any configuration providers not yet in the hub\n * - Removes providers from the hub that aren't in the configuration\n */\nexport function synchronizeHubWithConfigProviders(\n hub: Hub,\n configurationProviders: Provider[]\n) {\n const registeredProviders = hub.getAll();\n\n // Register and initialize providers that exist in config but not in hub\n const providersToRegister = configurationProviders.filter(\n (configProvider) => !registeredProviders.get(configProvider.id)\n );\n\n providersToRegister.forEach((providerToRegister) => {\n hub.add(providerToRegister.id, providerToRegister);\n providerToRegister.init();\n });\n\n // Remove providers that exist in hub but not in config\n registeredProviders.forEach((registeredProvider) => {\n const isProviderInConfig = configurationProviders.some(\n (configProvider) => configProvider.id === registeredProvider.id\n );\n\n if (!isProviderInConfig) {\n hub.remove(registeredProvider.id);\n }\n });\n}\n\nexport function isSolanaNamespace(\n ns: AllProxiedNamespaces\n): ns is AllProxiedNamespaces &\n ProxiedNamespace<SolanaActions> & { namespaceId: 'Solana' } {\n return ns.namespaceId === 'Solana';\n}\nexport function isEvmNamespace(\n ns: AllProxiedNamespaces\n): ns is AllProxiedNamespaces &\n ProxiedNamespace<EvmActions> & { namespaceId: 'EVM' } {\n return ns.namespaceId === 'EVM';\n}\nexport function isUtxoNamespace(\n ns: AllProxiedNamespaces\n): ns is AllProxiedNamespaces &\n ProxiedNamespace<UtxoActions> & { namespaceId: 'UTXO' } {\n return ns.namespaceId === 'UTXO';\n}\n", "import type {\n DerivationPathProperty,\n NamespacesProperty,\n ProviderMetadata,\n WalletType,\n} from '@hub3js/core';\nimport type { Namespace } from '@hub3js/namespaces';\nimport type { Network } from '@rango-dev/internal-blockchains';\nimport type { BlockchainMeta, SignerFactory } from 'rango-types';\n\nexport type NamespaceMeta = NamespacesProperty['value']['data'][number];\nexport type NeedsNamespace = NamespacesProperty['value'];\nexport type NeedsDerivationPath = DerivationPathProperty['value'];\n\nexport type InstallObjects = {\n CHROME?: string;\n FIREFOX?: string;\n EDGE?: string;\n BRAVE?: string;\n DEFAULT: string;\n};\n\nexport type WalletInfo = {\n name: string;\n img: string;\n installLink: InstallObjects | string;\n /**\n * @deprecated we don't use this value anymore.\n */\n color: string;\n supportedChains: BlockchainMeta[];\n showOnMobile?: boolean;\n isContractWallet?: boolean;\n mobileWallet?: boolean;\n\n needsDerivationPath?: NeedsDerivationPath;\n needsNamespace?: NeedsNamespace;\n};\n\nexport type WalletState = {\n connected: boolean;\n connecting: boolean;\n /**\n * @deprecated it always returns `false`. don't use it.\n */\n reachable: boolean;\n installed: boolean;\n accounts: string[] | null;\n network: Network | null;\n derivationPath?: string;\n};\n\ntype NamespaceData = {\n namespace: Namespace;\n derivationPath?: string;\n};\n\nexport type NamespaceInputForConnect<T extends Namespace = Namespace> = {\n /**\n * By default, you should specify namespace (e.g. evm).\n */\n namespace: T;\n /**\n * In some cases, we need to connect a specific network on a namespace. e.g. Polygon on EVM.\n */\n network: Network | undefined;\n derivationPath?: string;\n};\n\nexport enum Events {\n CONNECTED = 'connected',\n CONNECTING = 'connecting',\n REACHABLE = 'reachable',\n INSTALLED = 'installed',\n ACCOUNTS = 'accounts',\n NETWORK = 'network',\n // Hub only events\n NAMESPACE_DISCONNECTED = 'namespace_disconnected',\n\n PROVIDER_DISCONNECTED = 'provider_disconnected',\n}\n\nexport type EventInfo = {\n supportedBlockchains: BlockchainMeta[];\n isContractWallet: boolean;\n isHub: boolean;\n // will be set alongside ACCOUNT event\n namespace?: Namespace;\n derivationPath?: string;\n};\n\nexport type EventHandler = (\n type: WalletType,\n event: Events,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n value: any,\n coreState: WalletState,\n info: EventInfo\n) => void;\n\nexport type ConnectResult = {\n accounts: string[] | null;\n network: Network | null;\n};\n\nexport type ExtendedWalletInfo = WalletInfo & {\n properties?: ProviderMetadata['properties'];\n isHub?: boolean;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InstanceType = any;\n\ntype ProviderConnectResult = {\n accounts: string[];\n chainId: string;\n derivationPath?: string;\n};\n\ntype GetInstanceOptions = {\n network?: Network;\n currentProvider: InstanceType;\n meta: BlockchainMeta[];\n getState: () => WalletState;\n /**\n * We always get the instance once and reuse it whenever we needs. By using this option\n * We can force the library to get a new instance and replace it with the old one.\n *\n * Originally, we used this option for wallet connect 1 and its switching network challenge.\n */\n force?: boolean;\n updateChainId: (chainId: number | string) => void;\n};\n\ntype TryGetInstance =\n | (() => InstanceType)\n | ((\n options: Pick<GetInstanceOptions, 'force' | 'network'>\n ) => Promise<InstanceType>);\n\ntype Connect = (options: {\n instance: InstanceType;\n network?: Network;\n meta: BlockchainMeta[];\n namespaces?: NamespaceData[];\n}) => Promise<ProviderConnectResult | ProviderConnectResult[]>;\n\ntype Disconnect = (options: {\n instance: InstanceType;\n destroyInstance: () => void;\n}) => Promise<void>;\n\ntype CleanupSubscribe = () => void;\n\ntype Subscribe = (options: {\n instance: InstanceType;\n state: WalletState;\n meta: BlockchainMeta[];\n updateChainId: (chainId: string) => void;\n updateAccounts: (accounts: string[], chainId?: string) => void;\n connect: (network?: Network) => void;\n disconnect: () => void;\n}) => CleanupSubscribe | void;\n\ntype SwitchNetwork = (options: {\n instance: InstanceType;\n network: Network;\n meta: BlockchainMeta[];\n newInstance?: TryGetInstance;\n getState?: () => WalletState;\n updateChainId: (chainId: string) => void;\n}) => Promise<void>;\n\ntype Suggest = (options: {\n instance: InstanceType;\n network: Network;\n meta: BlockchainMeta[];\n}) => Promise<void>;\n\ntype CanSwitchNetwork = (options: {\n network: Network;\n meta: BlockchainMeta[];\n provider: InstanceType;\n}) => boolean;\n\ntype CanEagerConnect = (options: {\n instance: InstanceType;\n meta: BlockchainMeta[];\n}) => Promise<boolean>;\n\ninterface WalletActions {\n connect: Connect;\n getInstance: InstanceType;\n disconnect?: Disconnect;\n subscribe?: Subscribe;\n // unsubscribe, // coupled to subscribe.\n\n // Optional, but should be provided at the same time.\n suggest?: Suggest;\n switchNetwork?: SwitchNetwork;\n getSigners: (provider: InstanceType) => Promise<SignerFactory>;\n canSwitchNetworkTo?: CanSwitchNetwork;\n canEagerConnect?: CanEagerConnect;\n getWalletInfo(allBlockChains: BlockchainMeta[]): WalletInfo;\n}\n\ninterface WalletConfig {\n type: WalletType;\n defaultNetwork?: Network;\n checkInstallation?: boolean;\n isAsyncInstance?: boolean;\n isAsyncSwitchNetwork?: boolean;\n}\n\n/**\n * @deprecated Pass a hub `Provider` instead. This type will be removed in future versions.\n */\nexport type ProviderInterface = { config: WalletConfig } & WalletActions;\n", "import { WalletTypes } from '@rango-dev/provider-all';\n\nexport const HUB_LAST_CONNECTED_WALLETS = 'hub-v1-last-connected-wallets';\n\n// Wallets that always report themselves installed (hardware wallets and connection protocols).\nexport const WALLET_DETECTED_SKIPPED_IDS: string[] = [\n WalletTypes.LEDGER,\n WalletTypes.TREZOR,\n WalletTypes.LEDGER_WALLET,\n WalletTypes.WALLET_CONNECT_2,\n WalletTypes.TON_CONNECT,\n WalletTypes.DEFAULT,\n];\n", "import type { AllProxiedNamespaces } from './types.js';\nimport type { ProviderProps } from '../types.js';\nimport type { Accounts, AccountsWithActiveChain } from '@hub3js/std/types';\nimport type { Result } from 'ts-results';\n\nimport {\n CAIP_BITCOIN_CHAIN_ID,\n CAIP_BITCOINCASH_CHAIN_ID,\n CAIP_DOGECOIN_CHAIN_ID,\n CAIP_LITECOIN_CHAIN_ID,\n CAIP_ZCASH_CHAIN_ID,\n} from '@hub3js/bip122';\nimport { CAIP_TRON_CHAIN_ID } from '@hub3js/tron';\nimport { CAIP_NAMESPACE as CAIP_TON_NAMESPACE } from '@hub3js/tvm';\nimport { formatAddressWithNetwork } from '@rango-dev/internal-blockchains';\nimport { AccountId, type ChainIdParams } from 'caip';\nimport { Err, Ok } from 'ts-results';\n\nexport function mapCaipNamespaceToLegacyNetworkName(\n chainId: ChainIdParams | string\n): string {\n if (typeof chainId === 'string') {\n return chainId;\n }\n const useNamespaceAsNetworkFor = ['solana', 'xrpl', 'stellar'];\n\n if (useNamespaceAsNetworkFor.includes(chainId.namespace.toLowerCase())) {\n return chainId.namespace.toUpperCase();\n }\n\n if (chainId.namespace.toLowerCase() === 'eip155') {\n return 'ETH';\n } else if (chainId.reference === CAIP_BITCOIN_CHAIN_ID) {\n return 'BTC';\n } else if (chainId.reference === CAIP_ZCASH_CHAIN_ID) {\n return 'ZCASH';\n } else if (chainId.reference === CAIP_LITECOIN_CHAIN_ID) {\n return 'LTC';\n } else if (chainId.reference === CAIP_DOGECOIN_CHAIN_ID) {\n return 'DOGE';\n } else if (chainId.reference === CAIP_BITCOINCASH_CHAIN_ID) {\n return 'BCH';\n }\n\n if (chainId.namespace.toLowerCase() === CAIP_TON_NAMESPACE) {\n return 'TON';\n }\n if (chainId.namespace === 'sui' || chainId.reference === CAIP_TRON_CHAIN_ID) {\n return chainId.reference.toUpperCase();\n }\n if (chainId.namespace === 'starknet') {\n return chainId.namespace.toUpperCase();\n }\n\n return chainId.reference;\n}\n\n/**\n * CAIP's accountId has a format like this: eip155:1:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb\n * Legacy format is something like this: ETH:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb\n * This function will try to convert this two format.\n *\n * @see https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md\n */\nexport function fromAccountIdToLegacyAddressFormat(account: string): string {\n const { chainId, address } = AccountId.parse(account);\n const network = mapCaipNamespaceToLegacyNetworkName(chainId);\n return formatAddressWithNetwork(address, network);\n}\n\n/**\n * Getting a list of (lazy) promises and run them one after another.\n */\n\nexport async function runSequentiallyWithoutFailure<R>(\n promises: Array<() => Promise<R>>\n): Promise<Result<R, unknown>[]> {\n return promises.reduce(async (prevPromise, task) => {\n const previousResults = await prevPromise;\n try {\n const taskResult = await task();\n return [...previousResults, new Ok(taskResult)];\n } catch (error) {\n return [...previousResults, new Err(error)];\n }\n }, Promise.resolve<Result<R, unknown>[]>([]));\n}\n\nexport function isConnectResultEvm(\n result: Awaited<ReturnType<AllProxiedNamespaces['connect']>>\n): result is AccountsWithActiveChain {\n return typeof result === 'object' && !Array.isArray(result);\n}\n\nexport function isConnectResultSolana(\n result: Awaited<ReturnType<AllProxiedNamespaces['connect']>>\n): result is Accounts {\n return Array.isArray(result);\n}\n\ntype QueueItem<T> = {\n task: () => Promise<T>;\n resolve: (value: Result<T, unknown>) => void;\n key: string;\n};\n/**\n * Creates a queue manager that ensures sequential execution of tasks by key.\n * When multiple tasks with the same key are queued, they are executed one at a time\n * in the order they were added. This prevents race conditions and ensures\n * predictable task execution order.\n *\n */\nexport function createQueue(options?: {\n onError?: (\n error: unknown,\n actions: {\n removeCurrentKeyFromQueue: () => void;\n }\n ) => void;\n}) {\n const processingKeys = new Set<string>();\n let queue: QueueItem<unknown>[] = [];\n\n const removeKeyFromQueue = (\n key: string,\n result: Result<unknown, unknown>\n ) => {\n queue = queue.filter((q) => {\n if (q.key !== key) {\n return true;\n }\n q.resolve(result);\n return false;\n });\n };\n\n const processQueue = async () => {\n const currentItem = queue.find((item) => !processingKeys.has(item.key));\n if (!currentItem) {\n return;\n }\n\n const { task, resolve, key } = currentItem;\n processingKeys.add(key);\n\n try {\n const result = await task();\n resolve(new Ok(result));\n } catch (error) {\n if (options?.onError) {\n options.onError(error, {\n removeCurrentKeyFromQueue: () =>\n removeKeyFromQueue(key, new Err(error)),\n });\n }\n\n resolve(new Err(error));\n } finally {\n const indexOfCurrentItem = queue.findIndex((item) => item.key === key);\n if (indexOfCurrentItem >= 0) {\n queue.splice(indexOfCurrentItem, 1);\n }\n processingKeys.delete(key);\n void processQueue();\n }\n };\n\n const queueTask = async <T>(\n task: () => Promise<T>,\n key: string\n ): Promise<Result<T, unknown>> =>\n new Promise((resolve) => {\n queue.push({\n task,\n resolve: resolve as (value: Result<unknown, unknown>) => void,\n key,\n });\n void processQueue();\n });\n\n return queueTask;\n}\n\nexport function shouldTryAutoConnect(\n props: Pick<ProviderProps, 'allBlockChains' | 'autoConnect'>\n): boolean {\n return !!props.allBlockChains?.length && !!props.autoConnect;\n}\n", "export interface PersistStorage<T> {\n getItem: (name: string) => T | null;\n setItem: (name: string, value: T) => void;\n removeItem: (name: string) => void;\n}\n\nexport class Persistor<T> implements PersistStorage<T> {\n getItem(name: string) {\n const item = localStorage.getItem(name);\n const parsedItem = item ? (JSON.parse(item) as T) : null;\n return parsedItem;\n }\n setItem(name: string, value: T) {\n localStorage.setItem(name, JSON.stringify(value));\n }\n removeItem(name: string) {\n localStorage.removeItem(name);\n }\n}\n", "import type { Namespace } from '@hub3js/namespaces';\n\nimport { HUB_LAST_CONNECTED_WALLETS } from './constants.js';\nimport { Persistor } from './persistor.js';\n\nexport interface NamespaceInput {\n namespace: Namespace;\n network: string | undefined;\n}\n\nexport interface LastConnectedWalletsStorage {\n [providerId: string]: NamespaceInput[];\n}\n\n/**\n * We are doing some certain actions on storage for `last-connected-wallets` key.\n * This class helps us to define them in one place.\n */\nexport class LastConnectedWalletsFromStorage {\n #storageKey: string;\n\n constructor(storageKey: string) {\n this.#storageKey = storageKey;\n }\n\n addWallet(providerId: string, namespaces: NamespaceInput[]): void {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#addWalletToHub(providerId, namespaces);\n }\n throw new Error('Not implemented');\n }\n removeWallets(providerIds?: string[]): void {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#removeWalletsFromHub(providerIds);\n }\n throw new Error('Not implemented');\n }\n list(): LastConnectedWalletsStorage {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#listFromHub();\n }\n throw new Error('Not implemented');\n }\n removeNamespacesFromWallet(providerId: string, namespaceIds: string[]) {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#removeNamespaceFromWalletHub(providerId, namespaceIds);\n }\n throw new Error('Not implemented');\n }\n\n #listFromHub(): LastConnectedWalletsStorage {\n const persistor = new Persistor<LastConnectedWalletsStorage>();\n const lastConnectedWallets =\n persistor.getItem(HUB_LAST_CONNECTED_WALLETS) || {};\n return lastConnectedWallets;\n }\n #addWalletToHub(providerId: string, namespaces: NamespaceInput[]): void {\n const storage = new Persistor<LastConnectedWalletsStorage>();\n const storageState = storage.getItem(this.#storageKey) || {};\n\n let toBeAddedNamespaces = namespaces;\n\n // If provider already exits in the storage, we should just add new namespaces to the previously added namespaces.\n if (!!storageState[providerId]) {\n const storedNamespaces = storageState[providerId];\n toBeAddedNamespaces = storedNamespaces.concat(\n namespaces.filter(\n (namespace) =>\n !storedNamespaces.some(\n (storedNamespace) =>\n storedNamespace.namespace === namespace.namespace\n )\n )\n );\n }\n\n storage.setItem(this.#storageKey, {\n ...storageState,\n [providerId]: toBeAddedNamespaces,\n });\n }\n #removeWalletsFromHub(providerIds?: string[]): void {\n const persistor = new Persistor<LastConnectedWalletsStorage>();\n const storageState = persistor.getItem(this.#storageKey) || {};\n\n // Remove all wallets\n if (!providerIds) {\n persistor.setItem(this.#storageKey, {});\n return;\n }\n\n // Remove some of the wallets\n providerIds.forEach((providerId) => {\n if (storageState[providerId]) {\n delete storageState[providerId];\n }\n });\n\n persistor.setItem(this.#storageKey, storageState);\n }\n #removeNamespaceFromWalletHub(\n providerId: string,\n namespaceIds: string[]\n ): void {\n const persistor = new Persistor<LastConnectedWalletsStorage>();\n const storageState = persistor.getItem(this.#storageKey) || {};\n\n const currentProviderNamespaces = storageState[providerId];\n const newProviderNamespaces = currentProviderNamespaces?.filter(\n (namespace) => !namespaceIds.includes(namespace.namespace)\n );\n\n this.#removeWalletsFromHub([providerId]);\n if (newProviderNamespaces?.length > 0) {\n this.#addWalletToHub(providerId, newProviderNamespaces);\n }\n }\n}\n", "import type { AllProxiedNamespaces, ExtensionLink } from './types.js';\nimport type {\n ConnectResult,\n EventHandler,\n NamespaceInputForConnect,\n WalletInfo,\n} from '../legacy/mod.js';\nimport type { ProviderContext, ProviderProps } from '../types.js';\nimport type { Provider, WalletType } from '@hub3js/core';\nimport type { Event } from '@hub3js/core/store';\nimport type { Accounts, AccountsWithActiveChain } from '@hub3js/std/types';\n\nimport { Hub3Error } from '@hub3js/core';\nimport {\n getSupportedChainsFromNamespace,\n getSupportedChainsFromProvider,\n} from '@rango-dev/internal-blockchains';\nimport { useEffect, useRef, useState } from 'react';\nimport { Ok, Result } from 'ts-results';\n\nimport {\n emitWalletDetectedOnce,\n toBlockchainName,\n WalletEventChannel,\n WalletEventTypes,\n} from '../events.js';\nimport { Events } from '../legacy/mod.js';\n\nimport { autoConnect } from './autoConnect.js';\nimport { HUB_LAST_CONNECTED_WALLETS } from './constants.js';\nimport { reportConnectionFailure } from './errors.js';\nimport { createQueue, fromAccountIdToLegacyAddressFormat } from './helpers.js';\nimport { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';\nimport { useAutoConnect } from './useAutoConnect.js';\nimport { useHubRefs } from './useHubRefs.js';\nimport {\n findProviderByType,\n isEvmNamespace,\n isSolanaNamespace,\n isUtxoNamespace,\n mapHubEventsToLegacy,\n transformHubResultToLegacyResult,\n tryConvertNamespaceNetworkToChainInfo,\n} from './utils.js';\n\nexport type UseAdapterParams = Omit<ProviderProps, 'providers'> & {\n providers: Provider[];\n};\n\nexport function useHubAdapter(params: UseAdapterParams): ProviderContext {\n const { getStore, getHub } = useHubRefs(params.providers);\n const [, rerender] = useState(0);\n // useEffect will run `subscribe` once, so we need a reference and mutate the value if it's changes.\n const dataRef = useRef({\n onUpdateState: params.onUpdateState,\n allBlockChains: params.allBlockChains,\n emitter: params.emitter,\n });\n const hubInitiated = useRef(false);\n\n /*\n * Params of each connection attempt for each wallet type are stored here.\n * Derivation path from params is used in `mapHubEventsToLegacy` to be added to the payload of connect events.\n */\n const lastConnectAttemptParamsRef = useRef<{\n [type: WalletType]: NamespaceInputForConnect[];\n }>({});\n\n const updateLastConnectAttemptParams = (\n type: WalletType,\n namespaces: NamespaceInputForConnect[] | undefined\n ) => {\n lastConnectAttemptParamsRef.current[type] = namespaces || [];\n };\n\n const queueTask = createQueue({\n // Once the user rejects one of a wallet's namespaces, or the wallet is locked, its remaining queued namespaces are abandoned.\n onError: (error, actions) => {\n if (error instanceof Hub3Error && error.type !== 'PROVIDER_UNEXPECTED') {\n actions.removeCurrentKeyFromQueue();\n }\n },\n });\n\n useEffect(() => {\n dataRef.current = {\n onUpdateState: params.onUpdateState,\n allBlockChains: params.allBlockChains,\n emitter: params.emitter,\n };\n }, [params]);\n\n useEffect(() => {\n const onUpdateState: EventHandler = (type, event, value, state, info) => {\n if (event === Events.INSTALLED && state.installed) {\n emitWalletDetectedOnce(type, dataRef.current.emitter);\n }\n dataRef.current.onUpdateState?.(type, event, value, state, info);\n };\n\n const onStoreEvent = (event: Event) => {\n try {\n mapHubEventsToLegacy(getHub(), event, onUpdateState, {\n allBlockChains: dataRef.current.allBlockChains,\n lastConnectAttemptParams: lastConnectAttemptParamsRef.current,\n });\n } catch (e) {\n console.error(e);\n }\n rerender((currentRender) => currentRender + 1);\n };\n\n getStore().subscribe(onStoreEvent).flushEvents();\n }, []);\n\n // Initialize hub only after blockchain meta is available (e.g. WalletConnect needs it at init).\n useEffect(() => {\n if (hubInitiated.current || !params.allBlockChains?.length) {\n return;\n }\n\n getHub().init(params.configs?.walletOptions);\n rerender((currentRender) => currentRender + 1);\n hubInitiated.current = true;\n }, [params.allBlockChains, params.configs?.walletOptions]);\n\n useAutoConnect({\n autoConnect: params.autoConnect,\n allBlockChains: params.allBlockChains,\n autoConnectHandler: () => {\n void autoConnect({\n allBlockChains: params.allBlockChains,\n getHub,\n wallets: params.configs?.wallets,\n emitter: dataRef.current.emitter,\n });\n },\n });\n\n const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n HUB_LAST_CONNECTED_WALLETS\n );\n\n const api: ProviderContext = {\n canSwitchNetworkTo(type, network, namespace) {\n const provider = getHub().get(type);\n\n if (!provider) {\n // TODO: should throw an error\n return false;\n }\n\n if (!namespace) {\n throw new Error(\n 'Passing namespace to `canSwitchNetworkTo` is required.'\n );\n }\n\n const proxiedNamespace = provider.findByNamespace(namespace.namespace);\n if (!proxiedNamespace) {\n throw new Error(\n `We couldn't find any matched namespace on your request provider. (requested namespace: ${namespace.namespace})`\n );\n }\n if (!('canSwitchNetwork' in proxiedNamespace)) {\n return false;\n }\n const namespacesProperty = provider\n .info()\n ?.metadata?.properties?.find(\n (property) => property.name === 'namespaces'\n );\n\n if (!dataRef.current.allBlockChains) {\n throw new Error(`Blockchains are not available`);\n }\n\n const namespaceMeta = namespacesProperty?.value.data.find(\n (providerNamespace) => providerNamespace.value === namespace.namespace\n );\n\n if (!namespaceMeta) {\n throw new Error(\n `NamespaceMeta is not defined for requested namespace: ${namespace.namespace}`\n );\n }\n\n const supportedChains = getSupportedChainsFromNamespace(\n namespaceMeta,\n dataRef.current.allBlockChains\n );\n\n return proxiedNamespace.canSwitchNetwork({\n network,\n supportedChains,\n });\n },\n async connect(type, namespaces) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(\n `You should add ${type} to provider first then call 'connect'.`\n );\n }\n\n if (!namespaces) {\n throw new Error('Passing namespace to `connect` is required.');\n }\n\n updateLastConnectAttemptParams(type, namespaces);\n\n // Check `namespace` and look into hub to see how it can match given namespace to hub namespace.\n const targetNamespaces: [\n NamespaceInputForConnect,\n AllProxiedNamespaces\n ][] = [];\n namespaces.forEach((namespace) => {\n const targetNamespace = namespace.namespace;\n\n const result = wallet.findByNamespace(targetNamespace);\n if (!result) {\n throw new Error(\n `We couldn't find any provider matched with your request namespace. (requested namespace: ${namespace.namespace})`\n );\n }\n\n targetNamespaces.push([namespace, result]);\n });\n\n // Try to run `connect` on matched namespaces\n const connectResultFromTargetNamespaces = targetNamespaces.map(\n async ([namespaceInput, namespace]) => {\n const network = tryConvertNamespaceNetworkToChainInfo(\n namespaceInput,\n params.allBlockChains || []\n );\n\n let connectNamespacePromise: () => Promise<\n Accounts | AccountsWithActiveChain\n >;\n\n if (isSolanaNamespace(namespace)) {\n connectNamespacePromise = async () =>\n namespace.connect({\n derivationPath: namespaceInput.derivationPath,\n });\n } else if (isEvmNamespace(namespace)) {\n connectNamespacePromise = async () =>\n namespace.connect(network, {\n derivationPath: namespaceInput.derivationPath,\n });\n } else if (isUtxoNamespace(namespace)) {\n connectNamespacePromise = async () =>\n namespace.connect({\n derivationPath: namespaceInput.derivationPath,\n });\n } else {\n connectNamespacePromise = async () => namespace.connect();\n }\n\n const connectNamespaceProcess = async () =>\n connectNamespacePromise()\n .catch((error: unknown) => {\n reportConnectionFailure(error, {\n walletType: type,\n namespace: namespaceInput.namespace,\n origin: 'manual',\n });\n throw error;\n })\n .then<ConnectResult>(transformHubResultToLegacyResult)\n .then((connectResult) => {\n return {\n response: connectResult,\n input: {\n namespace: namespaceInput.namespace,\n network: namespaceInput.network,\n supportsEagerConnect: 'canEagerConnect' in namespace,\n },\n };\n });\n\n // Reconnecting an already connected namespace (e.g. only to switch its network) isn't reported.\n const connectNamespaceProcessWithEvents = async () => {\n if (namespace.state()[0]().connected) {\n return connectNamespaceProcess();\n }\n\n const eventPayload = {\n walletName: type,\n namespace: namespaceInput.namespace,\n origin: 'manual' as const,\n };\n const requestedChain = namespaceInput.network || null;\n\n dataRef.current.emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECT_INITIATED,\n payload: { ...eventPayload, chain: requestedChain },\n });\n try {\n const result = await connectNamespaceProcess();\n dataRef.current.emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECTED,\n payload: {\n ...eventPayload,\n chain: toBlockchainName(\n result.response.network,\n params.allBlockChains\n ),\n },\n });\n return result;\n } catch (error) {\n dataRef.current.emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECT_FAILED,\n payload: { ...eventPayload, chain: requestedChain },\n });\n throw error;\n }\n };\n return queueTask(connectNamespaceProcessWithEvents, type);\n }\n );\n\n /*\n * We need to connect to namespace one after another, sending multiple requests at the same time may be failed.\n * e.g. when wallet popup opens and asking for the password from the user, it should be resolved first, then other request will be resolved.\n */\n const connectResultWithLegacyFormat = await Promise.all(\n connectResultFromTargetNamespaces\n );\n\n // Keeping only namespaces that connected successfully and support eager connect, then we'll store them on storage for auto connect functionality.\n const successfullyConnectedSupportingEagerConnectNamespaces =\n connectResultWithLegacyFormat\n .filter(<T, E>(result: Result<T, E>): result is Ok<T> => result.ok)\n .filter((result) => result.val.input.supportsEagerConnect)\n .map((result) => ({\n namespace: result.val.input.namespace,\n network: result.val.input.network,\n }));\n\n if (successfullyConnectedSupportingEagerConnectNamespaces.length > 0) {\n lastConnectedWalletsFromStorage.addWallet(\n type,\n successfullyConnectedSupportingEagerConnectNamespaces\n );\n }\n\n // Getting rid of `input` from Result\n const connectResults = connectResultWithLegacyFormat.map((result) =>\n result.andThen((okResult) => new Ok(okResult.response))\n );\n\n const allResult = Result.all(...connectResults);\n if (allResult.err) {\n throw allResult.val;\n }\n\n return allResult.unwrap();\n },\n async disconnect(type, namespaces) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(\n `You should add ${type} to provider first then call 'disconnect'.`\n );\n }\n\n wallet.getAll().forEach((namespace) => {\n const namespaceShouldBeDisconnected =\n !namespaces || namespaces.includes(namespace.namespaceId);\n const namespaceIsConnected = namespace.state()[0]().connected;\n if (namespaceShouldBeDisconnected && namespaceIsConnected) {\n dataRef.current.emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_DISCONNECTED,\n payload: { walletName: type, namespace: namespace.namespaceId },\n });\n return namespace.disconnect();\n }\n });\n\n if (params.autoConnect) {\n if (namespaces) {\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n type,\n namespaces\n );\n } else {\n lastConnectedWalletsFromStorage.removeWallets([type]);\n }\n }\n },\n async disconnectAll() {\n const disconnectPromises: Promise<void>[] = Array.from(\n getHub().getAll().values()\n ).map(async (provider) => this.disconnect(provider.id));\n\n return await Promise.allSettled(disconnectPromises);\n },\n async getSigners(type) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n const info = wallet.info();\n if (!info) {\n throw new Error('Your provider should have required `info`.');\n }\n\n const providerProperties = info.metadata.properties;\n\n const signerProperty = providerProperties?.find(\n (property) => property.name === 'signers'\n );\n if (!signerProperty) {\n throw new Error('Your provider should contain signers property.');\n }\n\n return signerProperty.value.getSigners();\n },\n getWalletInfo(type) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n const info = wallet.info();\n if (!info) {\n throw new Error('Your provider should have required `info`.');\n }\n\n const installLink: Exclude<WalletInfo['installLink'], string> = {\n DEFAULT: '',\n };\n\n const { metadata } = info;\n const { extensions } = metadata;\n // `extensions` in legacy format was uppercase and also `DEFAULT` was used instead of `homepage`\n Object.keys(extensions).forEach((k) => {\n const key = k as ExtensionLink;\n\n if (key === 'homepage') {\n installLink.DEFAULT = extensions[key] || '';\n }\n\n const allowedKeys: ExtensionLink[] = [\n 'firefox',\n 'chrome',\n 'brave',\n 'edge',\n ];\n if (allowedKeys.includes(key)) {\n const upperCasedKey = key.toUpperCase() as keyof Exclude<\n WalletInfo['installLink'],\n string\n >;\n installLink[upperCasedKey] = extensions[key] || '';\n }\n });\n\n const providerProperties = metadata.properties;\n\n const namespacesProperty = providerProperties?.find(\n (property) => property.name === 'namespaces'\n );\n const derivationPathProperty = providerProperties?.find(\n (property) => property.name === 'derivationPath'\n );\n const detailsProperty = providerProperties?.find(\n (property) => property.name === 'details'\n );\n\n return {\n name: metadata.name,\n img: metadata.icon,\n installLink: installLink,\n // We don't have this values anymore, fill them with some values that communicate this.\n color: 'red',\n supportedChains: getSupportedChainsFromProvider(\n wallet,\n dataRef.current.allBlockChains\n ),\n isContractWallet: detailsProperty?.value?.isContractWallet,\n mobileWallet: detailsProperty?.value?.mobileWallet,\n // if set to false here, it will not show the wallet in mobile in anyways. to be compatible with old behavior, undefined is more appropirate.\n showOnMobile: detailsProperty?.value?.showOnMobile,\n needsNamespace: namespacesProperty?.value,\n needsDerivationPath: derivationPathProperty?.value,\n isHub: true,\n properties: metadata.properties,\n };\n },\n state(type) {\n const hubState = getHub().state();\n const wallet = getHub().get(type);\n const walletState = hubState[type];\n\n if (!walletState || !wallet) {\n // TODO: should throw an error\n return {\n connected: false,\n connecting: false,\n installed: false,\n reachable: false,\n accounts: null,\n network: null,\n namespaces: new Map(),\n };\n }\n\n const accounts = walletState.namespaces\n .filter((namespace) => namespace.connected)\n .flatMap((namespace) =>\n namespace.accounts?.map((accounts) =>\n fromAccountIdToLegacyAddressFormat(accounts)\n )\n )\n .filter((account): account is string => !!account);\n\n const namespacesState = new Map(\n Array.from(wallet.getAll(), ([_, value]) => [\n value.namespaceId,\n value.state()[0](),\n ])\n );\n\n const coreState = {\n connected: walletState.connected,\n connecting: walletState.connecting,\n installed: walletState.installed,\n reachable: true,\n accounts: accounts,\n network: null,\n namespaces: namespacesState,\n };\n return coreState;\n },\n async suggestAndConnect(type, namespace): Promise<ConnectResult> {\n const provider = getHub().get(type);\n\n if (!provider) {\n throw new Error(\n `You should add ${type} to provider first then call 'suggestAndConnect'.`\n );\n }\n const proxiedNamespace = provider.findByNamespace(namespace.namespace);\n if (!proxiedNamespace) {\n throw new Error(\n `We couldn't find any matched namespace on your request provider. (requested namespace: ${namespace.namespace})`\n );\n }\n if (!('suggest' in proxiedNamespace)) {\n throw new Error('Suggest is not implemented on the provider');\n }\n if (!namespace.network) {\n throw new Error('You should pass network to the suggest and connect');\n }\n throw new Error(\n `Suggest has not been implemented for given chain: ${namespace.network}`\n );\n },\n hubProvider(type) {\n const provider = findProviderByType(params.providers, type);\n\n if (!provider) {\n throw new Error(\n `You're trying to access ${type} provider which is not found in hub providers. it may not be registered yet.`\n );\n }\n\n return provider;\n },\n };\n\n return api;\n}\n", "import type { WalletType } from '@hub3js/core';\nimport type { Namespace } from '@hub3js/namespaces';\nimport type { BlockchainMeta } from 'rango-types';\n\nimport { getBlockChainNameFromId } from '@rango-dev/internal-blockchains';\n\nimport { WALLET_DETECTED_SKIPPED_IDS } from './hub/constants.js';\n\nexport const WalletEventChannel = 'walletEvent';\n\nexport enum WalletEventTypes {\n WALLET_DETECTED = 'walletDetected',\n WALLET_CONNECT_INITIATED = 'walletConnectInitiated',\n WALLET_CONNECTED = 'walletConnected',\n WALLET_CONNECT_FAILED = 'walletConnectFailed',\n WALLET_DISCONNECTED = 'walletDisconnected',\n}\n\nexport type WalletConnectOrigin = 'manual' | 'auto';\n\ntype WalletConnectEventPayload = {\n /** Wallet type id, e.g. `metamask`. */\n walletName: WalletType;\n namespace: Namespace;\n /** Rango blockchain name (e.g. `ETH`), or `null` when it isn't known. */\n chain: string | null;\n origin: WalletConnectOrigin;\n};\n\nexport type WalletDetectedEventPayload = {\n walletName: WalletType;\n};\nexport type WalletConnectInitiatedEventPayload = WalletConnectEventPayload;\nexport type WalletConnectedEventPayload = WalletConnectEventPayload;\nexport type WalletConnectFailedEventPayload = WalletConnectEventPayload;\nexport type WalletDisconnectedEventPayload = {\n walletName: WalletType;\n namespace: Namespace;\n};\n\ntype EventData<T extends WalletEventTypes, U> = { type: T; payload: U };\n\nexport type WalletEventData =\n | EventData<WalletEventTypes.WALLET_DETECTED, WalletDetectedEventPayload>\n | EventData<\n WalletEventTypes.WALLET_CONNECT_INITIATED,\n WalletConnectInitiatedEventPayload\n >\n | EventData<WalletEventTypes.WALLET_CONNECTED, WalletConnectedEventPayload>\n | EventData<\n WalletEventTypes.WALLET_CONNECT_FAILED,\n WalletConnectFailedEventPayload\n >\n | EventData<\n WalletEventTypes.WALLET_DISCONNECTED,\n WalletDisconnectedEventPayload\n >;\n\nexport type WalletEvents = {\n [WalletEventChannel]: WalletEventData;\n};\n\nexport interface Emitter<Events extends Record<string, unknown>> {\n emit<K extends keyof Events>(type: K, event: Events[K]): void;\n}\n\nexport type WalletEventEmitter = Emitter<WalletEvents>;\n\nconst detectedWallets = new Set<WalletType>();\n\nexport function emitWalletDetectedOnce(\n walletName: WalletType,\n emitter?: WalletEventEmitter\n): void {\n if (\n detectedWallets.has(walletName) ||\n WALLET_DETECTED_SKIPPED_IDS.includes(walletName)\n ) {\n return;\n }\n detectedWallets.add(walletName);\n emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_DETECTED,\n payload: { walletName },\n });\n}\n\n/**\n * Connect results may carry an EVM chain id (e.g. `0x1`); events always carry a Rango blockchain name.\n */\nexport function toBlockchainName(\n network: string | null | undefined,\n allBlockChains: BlockchainMeta[] | undefined\n): string | null {\n if (!network) {\n return null;\n }\n return getBlockChainNameFromId(network, allBlockChains || []);\n}\n", "import type { AllProxiedNamespaces } from './types.js';\nimport type { UseAdapterParams } from './useHubAdapter.js';\nimport type { NamespaceInputForConnect } from '../legacy/types.js';\nimport type { Hub, Provider, WalletType } from '@hub3js/core';\nimport type { DefaultNamespaces, Namespace } from '@hub3js/namespaces';\nimport type { Accounts, AccountsWithActiveChain } from '@hub3js/std/types';\n\nimport { Result } from 'ts-results';\n\nimport {\n toBlockchainName,\n WalletEventChannel,\n type WalletEventEmitter,\n WalletEventTypes,\n} from '../events.js';\n\nimport { HUB_LAST_CONNECTED_WALLETS } from './constants.js';\nimport { reportConnectionFailure } from './errors.js';\nimport { runSequentiallyWithoutFailure } from './helpers.js';\nimport { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';\nimport {\n convertNamespaceNetworkToEvmChainId,\n isEvmNamespace,\n transformHubResultToLegacyResult,\n} from './utils.js';\n\nfunction createAutoConnectEventPayload(\n walletName: WalletType,\n namespaceInput: NamespaceInputForConnect\n) {\n return {\n walletName,\n namespace: namespaceInput.namespace,\n chain: namespaceInput.network || null,\n origin: 'auto' as const,\n };\n}\n\nfunction isEvmNamespaceInput(\n namespace: NamespaceInputForConnect\n): namespace is NamespaceInputForConnect<'EVM'> {\n return namespace.namespace === 'EVM';\n}\n\n// Getting connected wallets from storage\nconst lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n HUB_LAST_CONNECTED_WALLETS\n);\n\n/**\n * Run `.connect` action on some selected namespaces (passed as param) for a provider.\n */\nasync function eagerConnect(\n type: string,\n namespacesInput: NamespaceInputForConnect[] | undefined,\n params: {\n getHub: () => Hub;\n allBlockChains: UseAdapterParams['allBlockChains'];\n emitter?: WalletEventEmitter;\n }\n) {\n const { getHub, allBlockChains, emitter } = params;\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(\n `You should add ${type} to provider first then call 'connect'.`\n );\n }\n\n if (!namespacesInput) {\n throw new Error('Passing namespace to `connect` is required. ');\n }\n\n const targetNamespaces: [NamespaceInputForConnect, AllProxiedNamespaces][] =\n [];\n namespacesInput.forEach((namespaceInput) => {\n const targetNamespace: Namespace = namespaceInput.namespace;\n\n const result = wallet.findByNamespace(targetNamespace);\n\n if (!result) {\n throw new Error(\n `We couldn't find any provider matched with your request namespace. (requested namespace: ${namespaceInput.namespace})`\n );\n }\n\n targetNamespaces.push([namespaceInput, result]);\n });\n\n const connectNamespacesPromises = targetNamespaces.map(\n ([info, namespace]) => {\n const evmChain = isEvmNamespaceInput(info)\n ? convertNamespaceNetworkToEvmChainId(info, allBlockChains || [])\n : undefined;\n const chain = evmChain || info.network;\n\n return async () => {\n let connectNamespacePromise: () => Promise<\n Accounts | AccountsWithActiveChain\n >;\n if (isEvmNamespace(namespace)) {\n connectNamespacePromise = async () => namespace.connect(chain);\n } else {\n connectNamespacePromise = async () => namespace.connect();\n }\n const eventPayload = createAutoConnectEventPayload(type, info);\n try {\n const result = await connectNamespacePromise();\n emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECTED,\n payload: {\n ...eventPayload,\n chain: toBlockchainName(\n transformHubResultToLegacyResult(result).network,\n allBlockChains\n ),\n },\n });\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any) {\n reportConnectionFailure(e, {\n walletType: type,\n namespace: info.namespace,\n origin: 'auto',\n });\n emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECT_FAILED,\n payload: eventPayload,\n });\n /*\n * Since we check for connect failures using `instanceof Error`\n * this check is added here to make sure the thrown error always is an instance of `Error`\n */\n if (e instanceof Error) {\n throw e;\n }\n throw new Error(e);\n }\n };\n }\n );\n\n /**\n * Sometimes calling methods on a instance in parallel, would cause an error in wallet.\n * We are running a method at a time to make sure we are covering this.\n * e.g. when we are trying to eagerConnect evm and solana on phantom at the same time, the last namespace throw an error.\n */\n const connectNamespacesResult = await runSequentiallyWithoutFailure(\n connectNamespacesPromises\n );\n\n const failedNamespaces: NamespaceInputForConnect[] = targetNamespaces\n .filter((_, index) => connectNamespacesResult[index].err)\n .map((targetNamespace) => targetNamespace[0]);\n\n if (failedNamespaces.length > 0) {\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n type,\n failedNamespaces.map((namespace) => namespace.namespace)\n );\n }\n\n const atLeastOneNamespaceConnectedSuccessfully = connectNamespacesResult.some(\n (result) => result.ok\n );\n if (!atLeastOneNamespaceConnectedSuccessfully) {\n throw new Error(`No namespace connected for ${type}`);\n }\n return Result.all(\n ...connectNamespacesResult.filter((result) => result.ok)\n ).unwrap();\n}\n\n/**\n * Run `.canEagerConnect` action on some selected namespaces of a wallet.\n */\nasync function tryRunCanEagerConnect(\n namespaces: NamespaceInputForConnect[],\n wallet: Provider<DefaultNamespaces>\n): Promise<{\n successNamespaces: NamespaceInputForConnect[];\n failedNamespaces: NamespaceInputForConnect[];\n}> {\n const foundNamespaces: NamespaceInputForConnect[] = [];\n const successNamespaces: NamespaceInputForConnect[] = [];\n const failedNamespaces: NamespaceInputForConnect[] = [];\n const canEagerConnectPromises: (() => Promise<boolean>)[] = [];\n\n // 1. Try find namespace instances and create canEagerConnect promises\n namespaces.forEach((namespace) => {\n const namespaceInstance = wallet.findByNamespace(namespace.namespace);\n if (namespaceInstance) {\n foundNamespaces.push(namespace);\n canEagerConnectPromises.push(\n async () => await namespaceInstance.canEagerConnect()\n );\n } else {\n failedNamespaces.push(namespace);\n }\n });\n\n // 2. Run canEagerConnect sequentially on namespaces\n const canEagerConnectResults = await runSequentiallyWithoutFailure(\n canEagerConnectPromises\n );\n\n // 3. Separate success and failed namespaces based on canEagerConnect result\n foundNamespaces.forEach((namespace, index) => {\n if (canEagerConnectResults[index].ok && canEagerConnectResults[index].val) {\n successNamespaces.push(namespace);\n } else {\n failedNamespaces.push(namespace);\n }\n });\n\n return { successNamespaces, failedNamespaces };\n}\n\n/*\n * Get last connected wallets and last connected namespaces for each of them from storage\n * Then run `.connect` on each namespace if `.canEagerConnect` returns true.\n */\nexport async function autoConnect(deps: {\n getHub: () => Hub;\n allBlockChains: UseAdapterParams['allBlockChains'];\n wallets?: (WalletType | Provider)[];\n emitter?: WalletEventEmitter;\n}): Promise<void> {\n const { getHub, allBlockChains, wallets, emitter } = deps;\n const lastConnectedWallets = lastConnectedWalletsFromStorage.list();\n const walletIds = Object.keys(lastConnectedWallets);\n\n const walletsToRemoveFromPersistence: string[] = [];\n\n if (walletIds.length) {\n const eagerConnectQueue: Promise<unknown>[] = [];\n\n const configWalletNames = wallets?.map((wallet) =>\n typeof wallet === 'string' ? wallet : wallet.id\n );\n // Run `.connect` if `.canEagerConnect` returns `true`.\n walletIds.forEach(async (providerName) => {\n if (configWalletNames && !configWalletNames.includes(providerName)) {\n console.warn(\n 'Trying to run auto connect for a wallet which is not included in config. Desired wallet:',\n providerName\n );\n walletsToRemoveFromPersistence.push(providerName);\n return;\n }\n\n const wallet = getHub().get(providerName);\n\n const lastConnectedNamespaces: NamespaceInputForConnect[] =\n lastConnectedWallets[providerName].map((namespace) => ({\n namespace: namespace.namespace,\n network: namespace.network,\n }));\n\n if (!lastConnectedNamespaces.length || !wallet) {\n walletsToRemoveFromPersistence.push(providerName);\n return;\n }\n\n lastConnectedNamespaces.forEach((namespace) => {\n emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECT_INITIATED,\n payload: createAutoConnectEventPayload(providerName, namespace),\n });\n });\n\n const { successNamespaces, failedNamespaces } =\n await tryRunCanEagerConnect(lastConnectedNamespaces, wallet);\n\n failedNamespaces.forEach((namespace) => {\n emitter?.emit(WalletEventChannel, {\n type: WalletEventTypes.WALLET_CONNECT_FAILED,\n payload: createAutoConnectEventPayload(providerName, namespace),\n });\n });\n\n if (!successNamespaces.length) {\n walletsToRemoveFromPersistence.push(providerName);\n return;\n } else if (failedNamespaces.length) {\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n wallet.id,\n failedNamespaces.map((namespace) => namespace.namespace)\n );\n }\n eagerConnectQueue.push(\n eagerConnect(providerName, successNamespaces, {\n allBlockChains,\n getHub,\n emitter,\n }).catch((error) => console.warn(error))\n );\n });\n\n lastConnectedWalletsFromStorage.removeWallets(\n walletsToRemoveFromPersistence\n );\n\n await Promise.all(eagerConnectQueue);\n }\n}\n", "import type { WalletConnectOrigin } from '../events.js';\nimport type { WalletType } from '@hub3js/core';\nimport type { Namespace } from '@hub3js/namespaces';\n\nimport { getErrorMessage, Hub3Error } from '@hub3js/core';\nimport { error as logError } from '@rango-dev/logging-core';\n\nconst NON_ERROR_THROWN_NAME = 'NonErrorThrown';\nconst NON_ERROR_THROWN_MESSAGE = 'Non-Error value thrown during connect.';\n\nfunction wrapNonError(value: unknown): Error {\n const message =\n typeof value === 'string'\n ? value\n : getErrorMessage(value) ?? NON_ERROR_THROWN_MESSAGE;\n const wrapper = new Error(message, { cause: value });\n wrapper.name = NON_ERROR_THROWN_NAME;\n return wrapper;\n}\n\n/*\n * An allow list: among `Hub3Error`s only `PROVIDER_UNEXPECTED` is logged, so a type added later\n * (something the user can act on, like a rejection or a locked wallet) stays out of the logs.\n */\nexport function reportConnectionFailure(\n error: unknown,\n options: {\n walletType: WalletType;\n namespace: Namespace;\n origin: WalletConnectOrigin;\n }\n): void {\n if (error instanceof Hub3Error) {\n if (error.type !== 'PROVIDER_UNEXPECTED') {\n return;\n }\n logError(error, {\n tags: { name: error.name, type: error.type, ...options },\n });\n return;\n }\n\n const reported = error instanceof Error ? error : wrapNonError(error);\n logError(reported, { tags: { name: reported.name, ...options } });\n}\n", "import type { ProviderProps } from '../types.js';\n\nimport { useEffect, useRef } from 'react';\n\nimport { shouldTryAutoConnect } from './helpers.js';\n\nexport function useAutoConnect(\n props: Pick<ProviderProps, 'allBlockChains' | 'autoConnect'> & {\n /**\n * A function to run autoConnect on instances\n */\n autoConnectHandler: () => void;\n }\n) {\n const autoConnectInitiated = useRef(false);\n\n useEffect(() => {\n if (shouldTryAutoConnect(props) && !autoConnectInitiated.current) {\n autoConnectInitiated.current = true;\n props.autoConnectHandler();\n }\n }, [props.autoConnect, props.allBlockChains]);\n}\n", "import type { Provider, Store } from '@hub3js/core';\n\nimport { createStore, Hub } from '@hub3js/core';\nimport { useRef } from 'react';\n\nimport { synchronizeHubWithConfigProviders } from './utils.js';\n\nexport function useHubRefs(providers: Provider[]) {\n const store = useRef<Store | null>(null);\n\n const hub = useRef<Hub | null>(null);\n\n function createHub() {\n const createdHub = new Hub({\n store: getStore(),\n });\n /*\n * First add providers to hub\n * This helps to `getWalletInfo` be usable, before initialize.\n */\n providers.forEach((provider) => {\n createdHub.add(provider.id, provider);\n });\n hub.current = createdHub;\n return createdHub;\n }\n\n // https://react.dev/reference/react/useRef#avoiding-recreating-the-ref-contents\n function getStore() {\n if (store.current !== null) {\n return store.current;\n }\n const createdStore = createStore();\n store.current = createdStore;\n return createdStore;\n }\n\n function getHub(): Hub {\n const hubProviders = hub.current?.getAll();\n\n if (!hub.current || !hubProviders) {\n return createHub();\n }\n\n synchronizeHubWithConfigProviders(hub.current, providers);\n return hub.current;\n }\n\n return { getStore, getHub };\n}\n", "import type { ProviderContext } from './types.js';\n\nimport { useContext } from 'react';\n\nimport { WalletContext } from './context.js';\n\nexport function useWallets(): ProviderContext {\n const context = useContext(WalletContext);\n if (!context) {\n throw Error('useWallet can only be used within the Provider component');\n }\n return context;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["React", "createContext", "defaultErrorMessage", "defaultContext", "WalletContext", "convertEvmBlockchainMetaToEvmChainInfo", "formatAddressWithNetwork", "getBlockChainNameFromId", "getSupportedChainsFromProvider", "AccountId", "isEvmBlockchain", "Events", "WalletTypes", "HUB_LAST_CONNECTED_WALLETS", "WALLET_DETECTED_SKIPPED_IDS", "CAIP_BITCOIN_CHAIN_ID", "CAIP_BITCOINCASH_CHAIN_ID", "CAIP_DOGECOIN_CHAIN_ID", "CAIP_LITECOIN_CHAIN_ID", "CAIP_ZCASH_CHAIN_ID", "CAIP_TRON_CHAIN_ID", "CAIP_TON_NAMESPACE", "formatAddressWithNetwork", "AccountId", "Err", "Ok", "mapCaipNamespaceToLegacyNetworkName", "chainId", "CAIP_BITCOIN_CHAIN_ID", "CAIP_ZCASH_CHAIN_ID", "CAIP_LITECOIN_CHAIN_ID", "CAIP_DOGECOIN_CHAIN_ID", "CAIP_BITCOINCASH_CHAIN_ID", "CAIP_TON_NAMESPACE", "CAIP_TRON_CHAIN_ID", "__name", "fromAccountIdToLegacyAddressFormat", "account", "address", "AccountId", "network", "formatAddressWithNetwork", "runSequentiallyWithoutFailure", "promises", "prevPromise", "task", "previousResults", "taskResult", "Ok", "error", "Err", "isConnectResultEvm", "result", "isConnectResultSolana", "createQueue", "options", "processingKeys", "queue", "removeKeyFromQueue", "key", "q", "processQueue", "currentItem", "item", "resolve", "indexOfCurrentItem", "shouldTryAutoConnect", "props", "Persistor", "__name", "name", "item", "value", "LastConnectedWalletsFromStorage", "__name", "#storageKey", "storageKey", "providerId", "namespaces", "HUB_LAST_CONNECTED_WALLETS", "#addWalletToHub", "providerIds", "#removeWalletsFromHub", "#listFromHub", "namespaceIds", "#removeNamespaceFromWalletHub", "Persistor", "storage", "storageState", "toBeAddedNamespaces", "storedNamespaces", "namespace", "storedNamespace", "persistor", "newProviderNamespaces", "findProviderByType", "providers", "type", "provider", "__name", "lastConnectedWalletsFromStorage", "LastConnectedWalletsFromStorage", "HUB_LAST_CONNECTED_WALLETS", "mapHubEventsToLegacy", "hub", "event", "onUpdateState", "metadata", "namespaceId", "namespace", "accounts", "network", "derivationPath", "getNamespaceState", "getProviderState", "coreState", "detailsProperty", "property", "eventInfo", "getSupportedChainsFromProvider", "formattedAddresses", "account", "chainId", "address", "AccountId", "blockchainName", "getBlockChainNameFromId", "formatAddressWithNetwork", "fromAccountIdToLegacyAddressFormat", "convertNamespaceNetworkToEvmChainId", "meta", "evmBlockchainsList", "isEvmBlockchain", "convertEvmBlockchainMetaToEvmChainInfo", "tryConvertNamespaceNetworkToChainInfo", "transformHubResultToLegacyResult", "res", "isConnectResultEvm", "isConnectResultSolana", "synchronizeHubWithConfigProviders", "configurationProviders", "registeredProviders", "configProvider", "providerToRegister", "registeredProvider", "isSolanaNamespace", "ns", "isEvmNamespace", "isUtxoNamespace", "Hub3Error", "getSupportedChainsFromNamespace", "getSupportedChainsFromProvider", "useEffect", "useRef", "useState", "Ok", "Result", "getBlockChainNameFromId", "WalletEventChannel", "WalletEventTypes", "detectedWallets", "emitWalletDetectedOnce", "walletName", "emitter", "WALLET_DETECTED_SKIPPED_IDS", "__name", "toBlockchainName", "network", "allBlockChains", "getBlockChainNameFromId", "Result", "getErrorMessage", "Hub3Error", "logError", "NON_ERROR_THROWN_NAME", "NON_ERROR_THROWN_MESSAGE", "wrapNonError", "value", "message", "getErrorMessage", "wrapper", "__name", "reportConnectionFailure", "error", "options", "Hub3Error", "logError", "reported", "createAutoConnectEventPayload", "walletName", "namespaceInput", "__name", "isEvmNamespaceInput", "namespace", "lastConnectedWalletsFromStorage", "LastConnectedWalletsFromStorage", "HUB_LAST_CONNECTED_WALLETS", "eagerConnect", "type", "namespacesInput", "params", "getHub", "allBlockChains", "emitter", "wallet", "targetNamespaces", "targetNamespace", "result", "connectNamespacesPromises", "info", "chain", "convertNamespaceNetworkToEvmChainId", "connectNamespacePromise", "isEvmNamespace", "eventPayload", "WalletEventChannel", "toBlockchainName", "transformHubResultToLegacyResult", "e", "reportConnectionFailure", "connectNamespacesResult", "runSequentiallyWithoutFailure", "failedNamespaces", "_", "index", "Result", "tryRunCanEagerConnect", "namespaces", "foundNamespaces", "successNamespaces", "canEagerConnectPromises", "namespaceInstance", "canEagerConnectResults", "autoConnect", "deps", "wallets", "lastConnectedWallets", "walletIds", "walletsToRemoveFromPersistence", "eagerConnectQueue", "configWalletNames", "providerName", "lastConnectedNamespaces", "error", "useEffect", "useRef", "useAutoConnect", "props", "autoConnectInitiated", "useRef", "useEffect", "shouldTryAutoConnect", "__name", "createStore", "Hub", "useRef", "useHubRefs", "providers", "store", "useRef", "hub", "createHub", "createdHub", "Hub", "getStore", "provider", "__name", "createdStore", "createStore", "getHub", "hubProviders", "synchronizeHubWithConfigProviders", "useHubAdapter", "params", "getStore", "getHub", "useHubRefs", "rerender", "useState", "dataRef", "useRef", "hubInitiated", "lastConnectAttemptParamsRef", "updateLastConnectAttemptParams", "__name", "type", "namespaces", "queueTask", "createQueue", "error", "actions", "Hub3Error", "useEffect", "onUpdateState", "event", "value", "state", "info", "emitWalletDetectedOnce", "onStoreEvent", "mapHubEventsToLegacy", "e", "currentRender", "useAutoConnect", "autoConnect", "lastConnectedWalletsFromStorage", "LastConnectedWalletsFromStorage", "HUB_LAST_CONNECTED_WALLETS", "network", "namespace", "provider", "proxiedNamespace", "namespacesProperty", "property", "namespaceMeta", "providerNamespace", "supportedChains", "getSupportedChainsFromNamespace", "wallet", "targetNamespaces", "targetNamespace", "result", "connectResultFromTargetNamespaces", "namespaceInput", "tryConvertNamespaceNetworkToChainInfo", "connectNamespacePromise", "isSolanaNamespace", "isEvmNamespace", "isUtxoNamespace", "connectNamespaceProcess", "reportConnectionFailure", "transformHubResultToLegacyResult", "connectResult", "eventPayload", "requestedChain", "WalletEventChannel", "toBlockchainName", "connectResultWithLegacyFormat", "successfullyConnectedSupportingEagerConnectNamespaces", "connectResults", "okResult", "Ok", "allResult", "Result", "namespaceShouldBeDisconnected", "namespaceIsConnected", "disconnectPromises", "signerProperty", "installLink", "metadata", "extensions", "k", "key", "upperCasedKey", "providerProperties", "derivationPathProperty", "detailsProperty", "getSupportedChainsFromProvider", "hubState", "walletState", "accounts", "fromAccountIdToLegacyAddressFormat", "account", "namespacesState", "_", "findProviderByType", "Provider", "props", "api", "useHubAdapter", "React", "WalletContext", "__name", "provider_default", "useContext", "useWallets", "context", "useContext", "WalletContext", "__name"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rango-dev/wallets-react",
|
|
3
|
-
"version": "0.0.0-experimental-
|
|
3
|
+
"version": "0.0.0-experimental-2938686c-20261012",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"source": "./src/index.ts",
|
|
@@ -31,18 +31,18 @@
|
|
|
31
31
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@hub3js/bip122": "
|
|
35
|
-
"@hub3js/core": "
|
|
36
|
-
"@hub3js/evm": "0.0.0-experimental-
|
|
37
|
-
"@hub3js/namespaces": "0.0.0-experimental-
|
|
38
|
-
"@hub3js/solana": "
|
|
39
|
-
"@hub3js/std": "
|
|
40
|
-
"@hub3js/sui": "
|
|
41
|
-
"@hub3js/tron": "
|
|
42
|
-
"@hub3js/tvm": "
|
|
43
|
-
"@rango-dev/internal-blockchains": "^0.0.0-experimental-
|
|
44
|
-
"@rango-dev/logging-core": "^0.0.0-experimental-
|
|
45
|
-
"@rango-dev/provider-all": "^0.0.0-experimental-
|
|
34
|
+
"@hub3js/bip122": "0.0.0-experimental-c87c8dd0-20261009",
|
|
35
|
+
"@hub3js/core": "0.0.0-experimental-c87c8dd0-20261009",
|
|
36
|
+
"@hub3js/evm": "0.0.0-experimental-c87c8dd0-20261009",
|
|
37
|
+
"@hub3js/namespaces": "0.0.0-experimental-c87c8dd0-20261009",
|
|
38
|
+
"@hub3js/solana": "0.0.0-experimental-c87c8dd0-20261009",
|
|
39
|
+
"@hub3js/std": "0.0.0-experimental-c87c8dd0-20261009",
|
|
40
|
+
"@hub3js/sui": "0.0.0-experimental-c87c8dd0-20261009",
|
|
41
|
+
"@hub3js/tron": "0.0.0-experimental-c87c8dd0-20261009",
|
|
42
|
+
"@hub3js/tvm": "0.0.0-experimental-c87c8dd0-20261009",
|
|
43
|
+
"@rango-dev/internal-blockchains": "^0.0.0-experimental-2938686c-20261012",
|
|
44
|
+
"@rango-dev/logging-core": "^0.0.0-experimental-2938686c-20261012",
|
|
45
|
+
"@rango-dev/provider-all": "^0.0.0-experimental-2938686c-20261012",
|
|
46
46
|
"caip": "^1.1.1",
|
|
47
47
|
"rango-types": "^0.6.0",
|
|
48
48
|
"ts-results": "^3.3.0"
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import type { Hub } from '@hub3js/core';
|
|
2
|
+
|
|
3
|
+
import { Hub3Error } from '@hub3js/core';
|
|
4
|
+
import { error as logError } from '@rango-dev/logging-core';
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import { autoConnect } from './autoConnect.js';
|
|
8
|
+
import { HUB_LAST_CONNECTED_WALLETS } from './constants.js';
|
|
9
|
+
|
|
10
|
+
vi.mock('@rango-dev/logging-core', () => ({
|
|
11
|
+
error: vi.fn(),
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
const WALLET = 'phantom';
|
|
15
|
+
|
|
16
|
+
type FakeNamespace = {
|
|
17
|
+
namespaceId: string;
|
|
18
|
+
canEagerConnect: () => Promise<boolean>;
|
|
19
|
+
connect: () => Promise<string[]>;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function unexpectedError() {
|
|
23
|
+
return new Hub3Error('PROVIDER_UNEXPECTED', 'Something went wrong', {
|
|
24
|
+
cause: new Error('Something went wrong'),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function fakeNamespace(
|
|
29
|
+
namespaceId: string,
|
|
30
|
+
overrides: Partial<FakeNamespace> = {}
|
|
31
|
+
): FakeNamespace {
|
|
32
|
+
return {
|
|
33
|
+
namespaceId,
|
|
34
|
+
canEagerConnect: vi.fn(async () => true),
|
|
35
|
+
connect: vi.fn(async () => [`${namespaceId}:address`]),
|
|
36
|
+
...overrides,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function runAutoConnect(namespaces: FakeNamespace[]) {
|
|
41
|
+
localStorage.setItem(
|
|
42
|
+
HUB_LAST_CONNECTED_WALLETS,
|
|
43
|
+
JSON.stringify({
|
|
44
|
+
[WALLET]: namespaces.map((namespace) => ({
|
|
45
|
+
namespace: namespace.namespaceId,
|
|
46
|
+
network: undefined,
|
|
47
|
+
})),
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const wallet = {
|
|
52
|
+
id: WALLET,
|
|
53
|
+
findByNamespace: (namespaceId: string) =>
|
|
54
|
+
namespaces.find((namespace) => namespace.namespaceId === namespaceId),
|
|
55
|
+
};
|
|
56
|
+
const hub = { get: (type: string) => (type === WALLET ? wallet : undefined) };
|
|
57
|
+
|
|
58
|
+
void autoConnect({
|
|
59
|
+
getHub: () => hub as unknown as Hub,
|
|
60
|
+
allBlockChains: [],
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// `autoConnect` resolves before its per-wallet work finishes, so wait for a visible effect and let the rest settle.
|
|
65
|
+
async function settle(condition: () => void) {
|
|
66
|
+
await vi.waitFor(condition);
|
|
67
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
describe('autoConnect', () => {
|
|
71
|
+
beforeEach(() => {
|
|
72
|
+
localStorage.clear();
|
|
73
|
+
vi.mocked(logError).mockClear();
|
|
74
|
+
vi.spyOn(console, 'warn').mockImplementation(() => undefined);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
afterEach(() => {
|
|
78
|
+
vi.restoreAllMocks();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('report a saved namespace that fails to reconnect with an unexpected error', async () => {
|
|
82
|
+
const error = unexpectedError();
|
|
83
|
+
const solana = fakeNamespace('Solana', {
|
|
84
|
+
connect: vi.fn(async () => Promise.reject(error)),
|
|
85
|
+
});
|
|
86
|
+
const sui = fakeNamespace('Sui');
|
|
87
|
+
|
|
88
|
+
runAutoConnect([solana, sui]);
|
|
89
|
+
await settle(() => expect(sui.connect).toHaveBeenCalled());
|
|
90
|
+
|
|
91
|
+
expect(logError).toHaveBeenCalledOnce();
|
|
92
|
+
expect(logError).toHaveBeenCalledWith(error, {
|
|
93
|
+
tags: {
|
|
94
|
+
name: 'Hub3Error',
|
|
95
|
+
type: 'PROVIDER_UNEXPECTED',
|
|
96
|
+
walletType: WALLET,
|
|
97
|
+
namespace: 'Solana',
|
|
98
|
+
origin: 'auto',
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('report a plain error with the auto origin and no type', async () => {
|
|
104
|
+
const error = new Error('Before hook failed');
|
|
105
|
+
const solana = fakeNamespace('Solana', {
|
|
106
|
+
connect: vi.fn(async () => Promise.reject(error)),
|
|
107
|
+
});
|
|
108
|
+
const sui = fakeNamespace('Sui');
|
|
109
|
+
|
|
110
|
+
runAutoConnect([solana, sui]);
|
|
111
|
+
await settle(() => expect(sui.connect).toHaveBeenCalled());
|
|
112
|
+
|
|
113
|
+
expect(logError).toHaveBeenCalledOnce();
|
|
114
|
+
expect(logError).toHaveBeenCalledWith(error, {
|
|
115
|
+
tags: {
|
|
116
|
+
name: 'Error',
|
|
117
|
+
walletType: WALLET,
|
|
118
|
+
namespace: 'Solana',
|
|
119
|
+
origin: 'auto',
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it.each(['PROVIDER_USER_REJECTED_REQUEST', 'PROVIDER_LOCKED'] as const)(
|
|
125
|
+
'skip a namespace that fails with %s',
|
|
126
|
+
async (type) => {
|
|
127
|
+
const solana = fakeNamespace('Solana', {
|
|
128
|
+
connect: vi.fn(async () => Promise.reject(new Hub3Error(type))),
|
|
129
|
+
});
|
|
130
|
+
const sui = fakeNamespace('Sui');
|
|
131
|
+
|
|
132
|
+
runAutoConnect([solana, sui]);
|
|
133
|
+
await settle(() => expect(sui.connect).toHaveBeenCalled());
|
|
134
|
+
|
|
135
|
+
expect(logError).not.toHaveBeenCalled();
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
it('skip a namespace that fails its eager connect check', async () => {
|
|
140
|
+
const solana = fakeNamespace('Solana', {
|
|
141
|
+
canEagerConnect: vi.fn(async () => Promise.reject(unexpectedError())),
|
|
142
|
+
});
|
|
143
|
+
const sui = fakeNamespace('Sui');
|
|
144
|
+
|
|
145
|
+
runAutoConnect([solana, sui]);
|
|
146
|
+
await settle(() => expect(sui.connect).toHaveBeenCalled());
|
|
147
|
+
|
|
148
|
+
expect(solana.connect).not.toHaveBeenCalled();
|
|
149
|
+
expect(logError).not.toHaveBeenCalled();
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('report only the namespace failure when no namespace connects', async () => {
|
|
153
|
+
runAutoConnect([
|
|
154
|
+
fakeNamespace('Solana', {
|
|
155
|
+
connect: vi.fn(async () => Promise.reject(unexpectedError())),
|
|
156
|
+
}),
|
|
157
|
+
]);
|
|
158
|
+
await settle(() =>
|
|
159
|
+
expect(console.warn).toHaveBeenCalledWith(
|
|
160
|
+
new Error(`No namespace connected for ${WALLET}`)
|
|
161
|
+
)
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
expect(logError).toHaveBeenCalledOnce();
|
|
165
|
+
expect(logError).toHaveBeenCalledWith(
|
|
166
|
+
expect.any(Hub3Error),
|
|
167
|
+
expect.objectContaining({
|
|
168
|
+
tags: expect.objectContaining({ namespace: 'Solana', origin: 'auto' }),
|
|
169
|
+
})
|
|
170
|
+
);
|
|
171
|
+
});
|
|
172
|
+
});
|
package/src/hub/autoConnect.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from '../events.js';
|
|
16
16
|
|
|
17
17
|
import { HUB_LAST_CONNECTED_WALLETS } from './constants.js';
|
|
18
|
+
import { reportConnectionFailure } from './errors.js';
|
|
18
19
|
import { runSequentiallyWithoutFailure } from './helpers.js';
|
|
19
20
|
import { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';
|
|
20
21
|
import {
|
|
@@ -117,6 +118,11 @@ async function eagerConnect(
|
|
|
117
118
|
});
|
|
118
119
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
119
120
|
} catch (e: any) {
|
|
121
|
+
reportConnectionFailure(e, {
|
|
122
|
+
walletType: type,
|
|
123
|
+
namespace: info.namespace,
|
|
124
|
+
origin: 'auto',
|
|
125
|
+
});
|
|
120
126
|
emitter?.emit(WalletEventChannel, {
|
|
121
127
|
type: WalletEventTypes.WALLET_CONNECT_FAILED,
|
|
122
128
|
payload: eventPayload,
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Hub3Error } from '@hub3js/core';
|
|
2
|
+
import { error as logError } from '@rango-dev/logging-core';
|
|
3
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
+
|
|
5
|
+
import { reportConnectionFailure } from './errors.js';
|
|
6
|
+
|
|
7
|
+
vi.mock('@rango-dev/logging-core', () => ({
|
|
8
|
+
error: vi.fn(),
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
describe('reportConnectionFailure', () => {
|
|
12
|
+
const options = {
|
|
13
|
+
walletType: 'metamask',
|
|
14
|
+
namespace: 'EVM',
|
|
15
|
+
origin: 'manual',
|
|
16
|
+
} as const;
|
|
17
|
+
const context = {
|
|
18
|
+
walletType: 'metamask',
|
|
19
|
+
namespace: 'EVM',
|
|
20
|
+
origin: 'manual',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
vi.mocked(logError).mockClear();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it.each(['PROVIDER_USER_REJECTED_REQUEST', 'PROVIDER_LOCKED'] as const)(
|
|
28
|
+
'drop a %s error',
|
|
29
|
+
(type) => {
|
|
30
|
+
reportConnectionFailure(new Hub3Error(type, 'Declined'), options);
|
|
31
|
+
|
|
32
|
+
expect(logError).not.toHaveBeenCalled();
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
it('log a PROVIDER_UNEXPECTED error tagged only with its name, type, wallet, namespace and origin', () => {
|
|
37
|
+
const error = new Hub3Error('PROVIDER_UNEXPECTED', 'Something went wrong', {
|
|
38
|
+
cause: new Error('Something went wrong'),
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
reportConnectionFailure(error, options);
|
|
42
|
+
|
|
43
|
+
expect(logError).toHaveBeenCalledOnce();
|
|
44
|
+
expect(logError).toHaveBeenCalledWith(error, {
|
|
45
|
+
tags: { name: 'Hub3Error', type: 'PROVIDER_UNEXPECTED', ...context },
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('log a plain error with its name and no type', () => {
|
|
50
|
+
const error = new TypeError('Something went wrong');
|
|
51
|
+
|
|
52
|
+
reportConnectionFailure(error, options);
|
|
53
|
+
|
|
54
|
+
expect(logError).toHaveBeenCalledOnce();
|
|
55
|
+
expect(logError).toHaveBeenCalledWith(error, {
|
|
56
|
+
tags: { name: 'TypeError', ...context },
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it.each([
|
|
61
|
+
['a string', 'Something went wrong', 'Something went wrong'],
|
|
62
|
+
[
|
|
63
|
+
"an object's own message",
|
|
64
|
+
{ code: 4001, message: 'rejected' },
|
|
65
|
+
'rejected',
|
|
66
|
+
],
|
|
67
|
+
[
|
|
68
|
+
'the fixed message for an object without one',
|
|
69
|
+
{ code: 4001 },
|
|
70
|
+
'Non-Error value thrown during connect.',
|
|
71
|
+
],
|
|
72
|
+
[
|
|
73
|
+
'the fixed message for anything else',
|
|
74
|
+
undefined,
|
|
75
|
+
'Non-Error value thrown during connect.',
|
|
76
|
+
],
|
|
77
|
+
])(
|
|
78
|
+
'wrap a non-error as NonErrorThrown and log it, using %s',
|
|
79
|
+
(_, value, message) => {
|
|
80
|
+
reportConnectionFailure(value, options);
|
|
81
|
+
|
|
82
|
+
expect(logError).toHaveBeenCalledOnce();
|
|
83
|
+
const [logged, data] = vi.mocked(logError).mock.calls[0];
|
|
84
|
+
expect(logged).toBeInstanceOf(Error);
|
|
85
|
+
expect(logged.name).toBe('NonErrorThrown');
|
|
86
|
+
expect(logged.message).toBe(message);
|
|
87
|
+
expect(logged.cause).toBe(value);
|
|
88
|
+
expect(data).toEqual({ tags: { name: 'NonErrorThrown', ...context } });
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { WalletConnectOrigin } from '../events.js';
|
|
2
|
+
import type { WalletType } from '@hub3js/core';
|
|
3
|
+
import type { Namespace } from '@hub3js/namespaces';
|
|
4
|
+
|
|
5
|
+
import { getErrorMessage, Hub3Error } from '@hub3js/core';
|
|
6
|
+
import { error as logError } from '@rango-dev/logging-core';
|
|
7
|
+
|
|
8
|
+
const NON_ERROR_THROWN_NAME = 'NonErrorThrown';
|
|
9
|
+
const NON_ERROR_THROWN_MESSAGE = 'Non-Error value thrown during connect.';
|
|
10
|
+
|
|
11
|
+
function wrapNonError(value: unknown): Error {
|
|
12
|
+
const message =
|
|
13
|
+
typeof value === 'string'
|
|
14
|
+
? value
|
|
15
|
+
: getErrorMessage(value) ?? NON_ERROR_THROWN_MESSAGE;
|
|
16
|
+
const wrapper = new Error(message, { cause: value });
|
|
17
|
+
wrapper.name = NON_ERROR_THROWN_NAME;
|
|
18
|
+
return wrapper;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/*
|
|
22
|
+
* An allow list: among `Hub3Error`s only `PROVIDER_UNEXPECTED` is logged, so a type added later
|
|
23
|
+
* (something the user can act on, like a rejection or a locked wallet) stays out of the logs.
|
|
24
|
+
*/
|
|
25
|
+
export function reportConnectionFailure(
|
|
26
|
+
error: unknown,
|
|
27
|
+
options: {
|
|
28
|
+
walletType: WalletType;
|
|
29
|
+
namespace: Namespace;
|
|
30
|
+
origin: WalletConnectOrigin;
|
|
31
|
+
}
|
|
32
|
+
): void {
|
|
33
|
+
if (error instanceof Hub3Error) {
|
|
34
|
+
if (error.type !== 'PROVIDER_UNEXPECTED') {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
logError(error, {
|
|
38
|
+
tags: { name: error.name, type: error.type, ...options },
|
|
39
|
+
});
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const reported = error instanceof Error ? error : wrapNonError(error);
|
|
44
|
+
logError(reported, { tags: { name: reported.name, ...options } });
|
|
45
|
+
}
|
package/src/hub/useHubAdapter.ts
CHANGED
|
@@ -10,7 +10,7 @@ import type { Provider, WalletType } from '@hub3js/core';
|
|
|
10
10
|
import type { Event } from '@hub3js/core/store';
|
|
11
11
|
import type { Accounts, AccountsWithActiveChain } from '@hub3js/std/types';
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import { Hub3Error } from '@hub3js/core';
|
|
14
14
|
import {
|
|
15
15
|
getSupportedChainsFromNamespace,
|
|
16
16
|
getSupportedChainsFromProvider,
|
|
@@ -24,16 +24,17 @@ import {
|
|
|
24
24
|
WalletEventChannel,
|
|
25
25
|
WalletEventTypes,
|
|
26
26
|
} from '../events.js';
|
|
27
|
-
import { withErrorLoggingApi } from '../helpers.js';
|
|
28
27
|
import { Events } from '../legacy/mod.js';
|
|
29
28
|
|
|
30
29
|
import { autoConnect } from './autoConnect.js';
|
|
31
30
|
import { HUB_LAST_CONNECTED_WALLETS } from './constants.js';
|
|
31
|
+
import { reportConnectionFailure } from './errors.js';
|
|
32
32
|
import { createQueue, fromAccountIdToLegacyAddressFormat } from './helpers.js';
|
|
33
33
|
import { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';
|
|
34
34
|
import { useAutoConnect } from './useAutoConnect.js';
|
|
35
35
|
import { useHubRefs } from './useHubRefs.js';
|
|
36
36
|
import {
|
|
37
|
+
findProviderByType,
|
|
37
38
|
isEvmNamespace,
|
|
38
39
|
isSolanaNamespace,
|
|
39
40
|
isUtxoNamespace,
|
|
@@ -73,8 +74,9 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
|
|
|
73
74
|
};
|
|
74
75
|
|
|
75
76
|
const queueTask = createQueue({
|
|
77
|
+
// Once the user rejects one of a wallet's namespaces, or the wallet is locked, its remaining queued namespaces are abandoned.
|
|
76
78
|
onError: (error, actions) => {
|
|
77
|
-
if (
|
|
79
|
+
if (error instanceof Hub3Error && error.type !== 'PROVIDER_UNEXPECTED') {
|
|
78
80
|
actions.removeCurrentKeyFromQueue();
|
|
79
81
|
}
|
|
80
82
|
},
|
|
@@ -258,6 +260,14 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
|
|
|
258
260
|
|
|
259
261
|
const connectNamespaceProcess = async () =>
|
|
260
262
|
connectNamespacePromise()
|
|
263
|
+
.catch((error: unknown) => {
|
|
264
|
+
reportConnectionFailure(error, {
|
|
265
|
+
walletType: type,
|
|
266
|
+
namespace: namespaceInput.namespace,
|
|
267
|
+
origin: 'manual',
|
|
268
|
+
});
|
|
269
|
+
throw error;
|
|
270
|
+
})
|
|
261
271
|
.then<ConnectResult>(transformHubResultToLegacyResult)
|
|
262
272
|
.then((connectResult) => {
|
|
263
273
|
return {
|
|
@@ -552,12 +562,7 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
|
|
|
552
562
|
);
|
|
553
563
|
},
|
|
554
564
|
hubProvider(type) {
|
|
555
|
-
|
|
556
|
-
* Return the instance registered in the hub, which holds the store. A
|
|
557
|
-
* provider list can be rebuilt with the same ids, and the hub keeps the
|
|
558
|
-
* instances it registered first, so a rebuilt one would have no store.
|
|
559
|
-
*/
|
|
560
|
-
const provider = getHub().get(type);
|
|
565
|
+
const provider = findProviderByType(params.providers, type);
|
|
561
566
|
|
|
562
567
|
if (!provider) {
|
|
563
568
|
throw new Error(
|
|
@@ -569,5 +574,5 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
|
|
|
569
574
|
},
|
|
570
575
|
};
|
|
571
576
|
|
|
572
|
-
return
|
|
577
|
+
return api;
|
|
573
578
|
}
|
|
@@ -7,7 +7,7 @@ import type {
|
|
|
7
7
|
import type { Provider as HubProvider } from '@hub3js/core';
|
|
8
8
|
import type { EvmBlockchainMeta } from 'rango-types';
|
|
9
9
|
|
|
10
|
-
import { NamespaceBuilder, ProviderBuilder } from '@hub3js/core';
|
|
10
|
+
import { Hub3Error, NamespaceBuilder, ProviderBuilder } from '@hub3js/core';
|
|
11
11
|
import { garbageWalletMetaData } from '@hub3js/core/test-utils';
|
|
12
12
|
import { act, renderHook } from '@testing-library/react-hooks/dom';
|
|
13
13
|
import { TransactionType } from 'rango-types';
|
|
@@ -282,7 +282,7 @@ describe('manual connect', () => {
|
|
|
282
282
|
|
|
283
283
|
test('emits nothing for namespaces cancelled after a rejection', async () => {
|
|
284
284
|
const { events, emitter } = createRecordingEmitter();
|
|
285
|
-
const rejection =
|
|
285
|
+
const rejection = new Hub3Error('PROVIDER_USER_REJECTED_REQUEST');
|
|
286
286
|
const wallet = buildWallet('manual-cancelled', {
|
|
287
287
|
evm: { connect: rejectWith(rejection) },
|
|
288
288
|
solana: {},
|
package/dist/helpers.d.ts
DELETED
package/dist/helpers.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAmClD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,GAAG,eAAe,CAOzE"}
|
package/src/helpers.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { ProviderContext } from './types.js';
|
|
2
|
-
|
|
3
|
-
import { debug } from '@rango-dev/logging-core';
|
|
4
|
-
|
|
5
|
-
function logError(method: string, args: unknown[], error: unknown) {
|
|
6
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
7
|
-
debug(err, {
|
|
8
|
-
context: { method, args },
|
|
9
|
-
tags: { type: 'wallet-error' },
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function withErrorLogging<TArgs extends unknown[], TReturn>(
|
|
14
|
-
method: string,
|
|
15
|
-
fn: (...args: TArgs) => TReturn
|
|
16
|
-
): (...args: TArgs) => TReturn {
|
|
17
|
-
return (...args: TArgs): TReturn => {
|
|
18
|
-
try {
|
|
19
|
-
const result = fn(...args);
|
|
20
|
-
// Async method: catch the rejection, log, then throw the rejection.
|
|
21
|
-
if (result instanceof Promise) {
|
|
22
|
-
return result.catch((error: unknown) => {
|
|
23
|
-
logError(method, args, error);
|
|
24
|
-
throw error;
|
|
25
|
-
}) as TReturn;
|
|
26
|
-
}
|
|
27
|
-
return result;
|
|
28
|
-
} catch (error) {
|
|
29
|
-
// Sync method: log and rethrow.
|
|
30
|
-
logError(method, args, error);
|
|
31
|
-
throw error;
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function withErrorLoggingApi(api: ProviderContext): ProviderContext {
|
|
37
|
-
const entries = Object.entries(api).map(([key, value]) => [
|
|
38
|
-
key,
|
|
39
|
-
withErrorLogging(key, (value as (...args: unknown[]) => unknown).bind(api)),
|
|
40
|
-
]);
|
|
41
|
-
|
|
42
|
-
return Object.fromEntries(entries) as ProviderContext;
|
|
43
|
-
}
|