@rango-dev/wallets-react 0.1.1-next.0

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.
@@ -0,0 +1,2 @@
1
+ export declare const LAST_CONNECTED_WALLETS = "last-connected-wallets";
2
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,2BAA2B,CAAC"}
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import { ProviderContext } from './types';
3
+ export declare const WalletContext: import("react").Context<ProviderContext>;
4
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA8B1C,eAAO,MAAM,aAAa,0CAAiD,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { WalletConfig, WalletType } from '@rango-dev/wallets-shared';
2
+ import Wallet from '@rango-dev/wallets-core';
3
+ import type { Options, State as WalletState, EventHandler as WalletEventHandler } from '@rango-dev/wallets-core';
4
+ import { State, WalletActions, ProviderInterface, WalletProviders } from './types';
5
+ export declare function choose(wallets: any[], type: WalletType): any | null;
6
+ export declare const defaultWalletState: WalletState;
7
+ export declare function state_reducer(state: State, action: any): State;
8
+ export declare function connectedWallets(providersState: State): WalletType[];
9
+ export declare function availableWallets(providersState: State): WalletType[];
10
+ export declare function checkWalletProviders(list: ProviderInterface[]): WalletProviders;
11
+ export declare function isAsync(fn: Function): boolean;
12
+ export declare function needsCheckInstallation(options: Options): boolean;
13
+ export declare function tryPersistWallet({ type, walletActions, getState, }: {
14
+ type: WalletType;
15
+ walletActions: WalletActions;
16
+ getState: (walletType: WalletType) => WalletState;
17
+ }): Promise<void>;
18
+ export declare function tryRemoveWalletFromPersistance({ type, walletActions, }: {
19
+ type: WalletType;
20
+ walletActions: WalletActions;
21
+ }): void;
22
+ export declare function clearPersistance(): void;
23
+ export declare function autoConnect(wallets: WalletProviders, getWalletInstance: (wallet: {
24
+ actions: WalletActions;
25
+ config: WalletConfig;
26
+ }) => Wallet<any>): Promise<void>;
27
+ export declare function makeEventHandler(dispatcher: any, onUpdateState?: WalletEventHandler): WalletEventHandler;
28
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,MAAqB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EACV,OAAO,EACP,KAAK,IAAI,WAAW,EACpB,YAAY,IAAI,kBAAkB,EACnC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,KAAK,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EAChB,MAAM,SAAS,CAAC;AAGjB,wBAAgB,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,GAAG,GAAG,GAAG,IAAI,CAEnE;AAED,eAAO,MAAM,kBAAkB,EAAE,WAOhC,CAAC;AAEF,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SA0BtD;AAED,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,KAAK,GAAG,UAAU,EAAE,CAQpE;AAED,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,KAAK,GAAG,UAAU,EAAE,CAIpE;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,iBAAiB,EAAE,GACxB,eAAe,CAYjB;AAGD,wBAAgB,OAAO,CAAC,EAAE,EAAE,QAAQ,WAEnC;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,WAGtD;AAED,wBAAsB,gBAAgB,CAAC,EACrC,IAAI,EACJ,aAAa,EACb,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,UAAU,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,WAAW,CAAC;CACnD,iBAoBA;AAED,wBAAgB,8BAA8B,CAAC,EAC7C,IAAI,EACJ,aAAa,GACd,EAAE;IACD,IAAI,EAAE,UAAU,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;CAC9B,QAUA;AAED,wBAAgB,gBAAgB,SAI/B;AAMD,wBAAsB,WAAW,CAC/B,OAAO,EAAE,eAAe,EACxB,iBAAiB,EAAE,CAAC,MAAM,EAAE;IAC1B,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;CACtB,KAAK,MAAM,CAAC,GAAG,CAAC,iBAqDlB;AAOD,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,GAAG,EACf,aAAa,CAAC,EAAE,kBAAkB,sBAoBnC"}
@@ -0,0 +1,12 @@
1
+ import { ProviderContext, WalletActions, WalletConfig } from './types';
2
+ import Wallet, { EventHandler as WalletEventHandler } from '@rango-dev/wallets-core';
3
+ /**
4
+ *
5
+ *
6
+ */
7
+ export declare function useInitializers(onChangeState: WalletEventHandler): (wallet: {
8
+ actions: WalletActions;
9
+ config: WalletConfig;
10
+ }) => Wallet;
11
+ export declare function useWallets(): ProviderContext;
12
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,MAAM,EAAE,EACb,YAAY,IAAI,kBAAkB,EACnC,MAAM,yBAAyB,CAAC;AAEjC;;;GAGG;AACH,wBAAgB,eAAe,CAAC,aAAa,EAAE,kBAAkB,YAQtC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;CACtB,KAAG,MAAM,CAiBX;AAED,wBAAgB,UAAU,IAAI,eAAe,CAK5C"}
@@ -0,0 +1,7 @@
1
+ export * from './helpers';
2
+ export { default as Provider } from './provider';
3
+ export { useWallets } from './hooks';
4
+ export * from './types';
5
+ export type { EventHandler } from '@rango-dev/wallets-core';
6
+ export { Events, readAccountAddress } from '@rango-dev/wallets-core';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,cAAc,SAAS,CAAC;AAExB,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ var N=Object.defineProperty;var c=(e,t)=>N(e,"name",{value:t,configurable:!0});import{Persistor as m}from"@rango-dev/wallets-core";var p="last-connected-wallets";function K(e,t){return e.find(i=>i.type===t)||null}c(K,"choose");var g={connected:!1,connecting:!1,reachable:!1,installed:!1,accounts:null,network:null};function P(e,t){if(t.type==="new_state"){let i=e[t.wallet];return i?{...e,[t.wallet]:{...i,[t.name]:t.value}}:{...e,[t.wallet]:{...g,[t.name]:t.value}}}return e}c(P,"state_reducer");function I(e){return Object.entries(e).filter(([,t])=>t?.connected).map(([t])=>t)}c(I,"connectedWallets");function k(e){return Object.entries(e).map(([t])=>t)}c(k,"availableWallets");function x(e){let t=new Map;return e.forEach(i=>{let{config:a,...o}=i;t.set(a.type,{actions:o,config:a})}),t}c(x,"checkWalletProviders");function q(e){return e?.constructor?.name==="AsyncFunction"}c(q,"isAsync");function J(e){let{checkInstallation:t=!0}=e.config;return t}c(J,"needsCheckInstallation");async function S({type:e,walletActions:t,getState:i}){if(t.canEagerConnect){let a=new m,o=a.getItem(p);o?.find(s=>!i(s).connected)&&C();let d=!!o?.find(s=>s===e);o&&!d?a.setItem(p,o.concat(e)):a.setItem(p,[e])}}c(S,"tryPersistWallet");function E({type:e,walletActions:t}){if(t.canEagerConnect){let i=new m,a=i.getItem(p);a&&i.setItem(p,a.filter(o=>o!==e))}}c(E,"tryRemoveWalletFromPersistance");function C(){let e=new m;e.getItem(p)&&e.removeItem(p)}c(C,"clearPersistance");async function T(e,t){let i=new m,a=i.getItem(p);if(a&&a.length){let o=[];a.forEach(s=>{let n=e.get(s);if(n){let r=t(n);o.push({walletType:s,eagerConnect:r.eagerConnect.bind(r)})}});let u=await Promise.allSettled(o.map(({eagerConnect:s})=>s()));if(!!u.find(({status:s})=>s==="fulfilled")){let s=[];u.forEach(({status:n},r)=>{n==="rejected"&&s.push(o[r].walletType)}),s.length&&i.setItem(p,a.filter(n=>!s.includes(n)))}}}c(T,"autoConnect");function v(e,t){return c((a,o,u,d,s)=>{e({type:"new_state",wallet:a,name:o,value:u}),t&&t(a,o,u,d,s)},"handler")}c(v,"makeEventHandler");import L,{useEffect as h,useReducer as _,useRef as F}from"react";import{useContext as R,useRef as H}from"react";import{createContext as b}from"react";var w="Context hasn't been initialized yet.",B={async connect(){throw new Error(w)},async disconnect(){throw new Error(w)},async disconnectAll(){throw new Error(w)},state(){throw new Error(w)},canSwitchNetworkTo(){throw new Error(w)},providers(){throw new Error(w)},getWalletInfo(){throw new Error(w)},getSigners(){throw new Error(w)}},W=b(B);import O from"@rango-dev/wallets-core";function A(e){let t=H({});function i(a){let o=a.config.type;return typeof t.current[o]>"u"&&(t.current[o]=new O({config:a.config,handler:e},a.actions)),t.current[o]}return c(i,"updater"),i}c(A,"useInitializers");function M(){let e=R(W);if(!e)throw Error("useWallet can only be used within the Provider component");return e}c(M,"useWallets");function D(e){let[t,i]=_(P,{}),a=F(!1),o=A(v(i,e.onUpdateState)),u=e.providers,d=x(u),s={async connect(n,r){let l=d.get(n);if(!l)throw new Error(`You should add ${n} to provider first.`);let y=await o(l).connect(r);return e.autoConnect&&S({type:n,walletActions:l.actions,getState:s.state}),y},async disconnect(n){let r=d.get(n);if(!r)throw new Error(`You should add ${n} to provider first.`);await o(r).disconnect(),e.autoConnect&&E({type:n,walletActions:r.actions})},async disconnectAll(){let n=[];return I(t).forEach(r=>{let l=d.get(r);if(l){let f=o(l);n.push(f.disconnect())}}),e.autoConnect&&C(),await Promise.allSettled(n)},state(n){return t[n]||g},canSwitchNetworkTo(n,r){let l=d.get(n);if(!l)return!1;let f=o(l);return f.canSwitchNetworkTo?f.canSwitchNetworkTo(r,f.provider):!1},providers(){let n={};return k(t).forEach(r=>{let l=d.get(r);if(l){let f=o(l);n[r]=f.provider}}),n},getWalletInfo(n){let r=d.get(n);if(!r)throw new Error(`You should add ${n} to provider first.`);return r.actions.getWalletInfo(e.allBlockChains||[])},getSigners(n){let r=d.get(n);if(!r)throw new Error(`You should add ${n} to provider first.`);let l=o(r),f=l.provider;return l.getSigners(f)}};return h(()=>{d.forEach(n=>{let r=o(n),l=c(()=>{r.onInit&&r.onInit()},"runOnInit"),f=c(y=>{y.target&&y.target.readyState==="complete"&&(l(),document.removeEventListener("readystatechange",f))},"initWhenPageIsReady");l(),document.addEventListener("readystatechange",f)})},[]),h(()=>{e.allBlockChains&&d.forEach(r=>{let l=o(r),f=l.getWalletInfo(e.allBlockChains||[]).supportedChains;l.setMeta(f)})},[e.allBlockChains]),h(()=>{d.forEach(n=>{o(n).setHandler(v(i,e.onUpdateState))})},[e.onUpdateState]),h(()=>{e.allBlockChains&&e.allBlockChains.length&&e.autoConnect&&!a.current&&(a.current=!0,(async()=>await T(d,o))())},[e.autoConnect,e.allBlockChains]),L.createElement(W.Provider,{value:s},e.children)}c(D,"Provider");var G=D;import{Events as ge,readAccountAddress as Ce}from"@rango-dev/wallets-core";export{ge as Events,G as Provider,T as autoConnect,k as availableWallets,x as checkWalletProviders,K as choose,C as clearPersistance,I as connectedWallets,g as defaultWalletState,q as isAsync,v as makeEventHandler,J as needsCheckInstallation,Ce as readAccountAddress,P as state_reducer,S as tryPersistWallet,E as tryRemoveWalletFromPersistance,M as useWallets};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/helpers.ts", "../src/constants.ts", "../src/provider.tsx", "../src/hooks.ts", "../src/context.ts", "../src/index.ts"],
4
+ "sourcesContent": ["import { WalletConfig, WalletType } from '@rango-dev/wallets-shared';\nimport Wallet, { Persistor } from '@rango-dev/wallets-core';\nimport type {\n Options,\n State as WalletState,\n EventHandler as WalletEventHandler,\n} from '@rango-dev/wallets-core';\nimport {\n State,\n WalletActions,\n ProviderInterface,\n WalletProviders,\n} from './types';\nimport { LAST_CONNECTED_WALLETS } from './constants';\n\nexport function choose(wallets: any[], type: WalletType): any | null {\n return wallets.find((wallet) => wallet.type === type) || null;\n}\n\nexport const defaultWalletState: WalletState = {\n connected: false,\n connecting: false,\n reachable: false,\n installed: false,\n accounts: null,\n network: null,\n};\n\nexport function state_reducer(state: State, action: any) {\n if (action.type === 'new_state') {\n // TODO fix problem and remove ts-ignore\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const target_wallet = state[action.wallet];\n if (!target_wallet) {\n return {\n ...state,\n [action.wallet]: {\n ...defaultWalletState,\n [action.name]: action.value,\n },\n };\n }\n\n return {\n ...state,\n [action.wallet]: {\n ...target_wallet,\n [action.name]: action.value,\n },\n };\n }\n\n return state;\n}\n\nexport function connectedWallets(providersState: State): WalletType[] {\n return Object.entries(providersState)\n .filter(([, wallet_state]) => {\n return wallet_state?.connected;\n })\n .map(([type]) => {\n return type;\n });\n}\n\nexport function availableWallets(providersState: State): WalletType[] {\n return Object.entries(providersState).map(([type]) => {\n return type;\n });\n}\n\nexport function checkWalletProviders(\n list: ProviderInterface[]\n): WalletProviders {\n const wallets: WalletProviders = new Map();\n\n list.forEach((provider) => {\n const { config, ...actions } = provider;\n wallets.set(config.type, {\n actions,\n config,\n });\n });\n\n return wallets;\n}\n\n/* eslint-disable @typescript-eslint/ban-types */\nexport function isAsync(fn: Function) {\n return fn?.constructor?.name === 'AsyncFunction';\n}\n\nexport function needsCheckInstallation(options: Options) {\n const { checkInstallation = true } = options.config;\n return checkInstallation;\n}\n\nexport async function tryPersistWallet({\n type,\n walletActions,\n getState,\n}: {\n type: WalletType;\n walletActions: WalletActions;\n getState: (walletType: WalletType) => WalletState;\n}) {\n if (walletActions.canEagerConnect) {\n const persistor = new Persistor<string[]>();\n const wallets = persistor.getItem(LAST_CONNECTED_WALLETS);\n\n /*\n If on the last attempt we are unable to eagerly connect to any wallet and the user connects any wallet manualy,\n persistance will be outdated and will need to be removed.\n */\n const shouldClearPersistance = wallets?.find(\n (walletType) => !getState(walletType).connected\n );\n\n if (shouldClearPersistance) clearPersistance();\n\n const walletAlreadyPersisted = !!wallets?.find((wallet) => wallet === type);\n if (wallets && !walletAlreadyPersisted)\n persistor.setItem(LAST_CONNECTED_WALLETS, wallets.concat(type));\n else persistor.setItem(LAST_CONNECTED_WALLETS, [type]);\n }\n}\n\nexport function tryRemoveWalletFromPersistance({\n type,\n walletActions,\n}: {\n type: WalletType;\n walletActions: WalletActions;\n}) {\n if (walletActions.canEagerConnect) {\n const persistor = new Persistor<string[]>();\n const wallets = persistor.getItem(LAST_CONNECTED_WALLETS);\n if (wallets)\n persistor.setItem(\n LAST_CONNECTED_WALLETS,\n wallets.filter((wallet) => wallet !== type)\n );\n }\n}\n\nexport function clearPersistance() {\n const persistor = new Persistor<string[]>();\n const wallets = persistor.getItem(LAST_CONNECTED_WALLETS);\n if (wallets) persistor.removeItem(LAST_CONNECTED_WALLETS);\n}\n\n/*\n If a wallet has multiple providers and one of them can be eagerly connected,\n then the whole wallet will support it at that point and we try to connect to that wallet as usual in eagerConnect method.\n*/\nexport async function autoConnect(\n wallets: WalletProviders,\n getWalletInstance: (wallet: {\n actions: WalletActions;\n config: WalletConfig;\n }) => Wallet<any>\n) {\n const persistor = new Persistor<string[]>();\n const lastConnectedWallets = persistor.getItem(LAST_CONNECTED_WALLETS);\n if (lastConnectedWallets && lastConnectedWallets.length) {\n const connect_promises: {\n walletType: WalletType;\n eagerConnect: () => Promise<any>;\n }[] = [];\n lastConnectedWallets.forEach((walletType) => {\n const wallet = wallets.get(walletType);\n\n if (!!wallet) {\n const walletInstance = getWalletInstance(wallet);\n connect_promises.push({\n walletType,\n eagerConnect: walletInstance.eagerConnect.bind(walletInstance),\n });\n }\n });\n\n const result = await Promise.allSettled(\n connect_promises.map(({ eagerConnect }) => eagerConnect())\n );\n\n const canRestoreAnyConnection = !!result.find(\n ({ status }) => status === 'fulfilled'\n );\n\n /*\n After successfully connecting to at least one wallet,\n we will removing the other wallets from persistence.\n If we are unable to connect to any wallet,\n the persistence will not be removed and the eager connection will be retried with another page load.\n */\n if (canRestoreAnyConnection) {\n const walletsToRemoveFromPersistance: WalletType[] = [];\n result.forEach(({ status }, index) => {\n if (status === 'rejected')\n walletsToRemoveFromPersistance.push(\n connect_promises[index].walletType\n );\n });\n\n if (walletsToRemoveFromPersistance.length)\n persistor.setItem(\n LAST_CONNECTED_WALLETS,\n lastConnectedWallets.filter(\n (walletType) => !walletsToRemoveFromPersistance.includes(walletType)\n )\n );\n }\n }\n}\n/*\n Our event handler includes an internal state updater, and a notifier\n for the outside listener.\n On creating first wallet refrence, and on chaning `props.onUpdateState`\n we are using this function.\n*/\nexport function makeEventHandler(\n dispatcher: any,\n onUpdateState?: WalletEventHandler\n) {\n const handler: WalletEventHandler = (\n type,\n name,\n value,\n coreState,\n supportedChains\n ) => {\n const action = { type: 'new_state', wallet: type, name, value };\n // Update state\n dispatcher(action);\n\n // Giving the event to the outside listener\n if (onUpdateState) {\n onUpdateState(type, name, value, coreState, supportedChains);\n }\n };\n\n return handler;\n}\n", "export const LAST_CONNECTED_WALLETS = 'last-connected-wallets';\n", "import React, { useEffect, useReducer, useRef } from 'react';\nimport { WalletType } from '@rango-dev/wallets-shared';\n\nimport {\n autoConnect,\n availableWallets,\n checkWalletProviders,\n clearPersistance,\n connectedWallets,\n defaultWalletState,\n tryPersistWallet,\n tryRemoveWalletFromPersistance,\n makeEventHandler,\n state_reducer,\n} from './helpers';\nimport { ProviderProps, ProviderContext } from './types';\nimport { useInitializers } from './hooks';\nimport { WalletContext } from './context';\n\nfunction Provider(props: ProviderProps) {\n const [providersState, dispatch] = useReducer(state_reducer, {});\n const autoConnectInitiated = useRef(false);\n\n // Get (or add) wallet instance (`provider`s will be wraped in a `Wallet`)\n const getWalletInstance = useInitializers(\n makeEventHandler(dispatch, props.onUpdateState)\n );\n\n // Getting providers from props and put all of them in a `Map` with an appropriate interface.\n const listOfProviders = props.providers;\n const wallets = checkWalletProviders(listOfProviders);\n\n // Final API we put in context and it will be available to use for users.\n const api: ProviderContext = {\n async connect(type, network) {\n const wallet = wallets.get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n const walletInstance = getWalletInstance(wallet);\n const result = await walletInstance.connect(network);\n if (props.autoConnect)\n tryPersistWallet({\n type,\n walletActions: wallet.actions,\n getState: api.state,\n });\n\n return result;\n },\n async disconnect(type) {\n const wallet = wallets.get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n const walletInstance = getWalletInstance(wallet);\n await walletInstance.disconnect();\n if (props.autoConnect)\n tryRemoveWalletFromPersistance({ type, walletActions: wallet.actions });\n },\n async disconnectAll() {\n const disconnect_promises: Promise<any>[] = [];\n\n // When a wallet is initializing, a record will be added to `providersState`\n // So we use them to know what wallet has been initialized then we need to\n // filter connected wallets only.\n connectedWallets(providersState).forEach((type) => {\n const wallet = wallets.get(type);\n\n if (wallet) {\n const walletInstance = getWalletInstance(wallet);\n disconnect_promises.push(walletInstance.disconnect());\n }\n });\n\n if (props.autoConnect) clearPersistance();\n return await Promise.allSettled(disconnect_promises);\n },\n state(type) {\n return providersState[type] || defaultWalletState;\n },\n canSwitchNetworkTo(type, network) {\n const wallet = wallets.get(type);\n if (!wallet) {\n return false;\n }\n\n const walletInstance = getWalletInstance(wallet);\n return walletInstance.canSwitchNetworkTo\n ? walletInstance.canSwitchNetworkTo(network, walletInstance.provider)\n : false;\n },\n providers() {\n const providers: { [type in WalletType]?: any } = {};\n availableWallets(providersState).forEach((type) => {\n const wallet = wallets.get(type);\n if (wallet) {\n const walletInstance = getWalletInstance(wallet);\n providers[type] = walletInstance.provider;\n }\n });\n\n return providers;\n },\n getWalletInfo(type) {\n const wallet = wallets.get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n // Get wallet info could be used in render methods to show wallets data\n // So, addWalletRef method shouldn't be called in this method\n\n return wallet.actions.getWalletInfo(props.allBlockChains || []);\n },\n getSigners(type) {\n const wallet = wallets.get(type);\n\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n const walletInstance = getWalletInstance(wallet);\n const provider = walletInstance.provider;\n const result = walletInstance.getSigners(provider);\n\n return result;\n },\n };\n\n useEffect(() => {\n wallets.forEach((wallet) => {\n const walletInstance = getWalletInstance(wallet);\n const runOnInit = () => {\n if (walletInstance.onInit) {\n walletInstance.onInit();\n }\n };\n\n const initWhenPageIsReady = (event: Event) => {\n if (\n event.target &&\n (event.target as Document).readyState === 'complete'\n ) {\n runOnInit();\n\n document.removeEventListener('readystatechange', initWhenPageIsReady);\n }\n };\n\n // Try to run, maybe it's ready.\n runOnInit();\n\n // Try again when the page has been completely loaded.\n // Some of wallets, take some time to be fully injected and loaded.\n document.addEventListener('readystatechange', initWhenPageIsReady);\n });\n }, []);\n\n useEffect(() => {\n const allBlockChains = props.allBlockChains;\n if (allBlockChains) {\n wallets.forEach((wallet) => {\n const walletInstance = getWalletInstance(wallet);\n const supportedChains = walletInstance.getWalletInfo(\n props.allBlockChains || []\n ).supportedChains;\n walletInstance.setMeta(supportedChains);\n });\n }\n }, [props.allBlockChains]);\n\n useEffect(() => {\n wallets.forEach((wallet) => {\n const walletInstance = getWalletInstance(wallet);\n walletInstance.setHandler(\n makeEventHandler(dispatch, props.onUpdateState)\n );\n });\n }, [props.onUpdateState]);\n\n useEffect(() => {\n const shouldTryAutoConnect =\n props.allBlockChains &&\n props.allBlockChains.length &&\n props.autoConnect &&\n !autoConnectInitiated.current;\n\n if (shouldTryAutoConnect) {\n autoConnectInitiated.current = true;\n (async () => {\n await autoConnect(wallets, getWalletInstance);\n })();\n }\n }, [props.autoConnect, props.allBlockChains]);\n\n return (\n <WalletContext.Provider value={api}>\n {props.children}\n </WalletContext.Provider>\n );\n}\n\nexport default Provider;\n", "import { useContext, useRef } from 'react';\nimport { WalletContext } from './context';\nimport { ProviderContext, WalletActions, WalletConfig } from './types';\nimport Wallet, {\n EventHandler as WalletEventHandler,\n} from '@rango-dev/wallets-core';\n\n/**\n *\n *\n */\nexport function useInitializers(onChangeState: WalletEventHandler) {\n const availableWallets = useRef<{\n [key: string]: Wallet | undefined;\n }>({});\n\n // If `wallet` hasn't been added to `availableWallets`,\n // Get a instance of `Wallet` and save the refrence in `availableWallets`.\n // Otherwise, return the already created instance.\n function updater(wallet: {\n actions: WalletActions;\n config: WalletConfig;\n }): Wallet {\n const type = wallet.config.type;\n // We only update, if there is no instance available.\n if (typeof availableWallets.current[type] === 'undefined') {\n availableWallets.current[type] = new Wallet(\n {\n config: wallet.config,\n handler: onChangeState,\n },\n wallet.actions\n );\n }\n\n return availableWallets.current[type]!;\n }\n\n return updater;\n}\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 return context;\n}\n", "import { createContext } from 'react';\nimport { ProviderContext } from './types';\n\nconst defaultErrorMesssage = \"Context hasn't been initialized yet.\";\nconst defaultContext: ProviderContext = {\n async connect() {\n throw new Error(defaultErrorMesssage);\n },\n async disconnect() {\n throw new Error(defaultErrorMesssage);\n },\n async disconnectAll() {\n throw new Error(defaultErrorMesssage);\n },\n state() {\n throw new Error(defaultErrorMesssage);\n },\n canSwitchNetworkTo() {\n throw new Error(defaultErrorMesssage);\n },\n providers() {\n throw new Error(defaultErrorMesssage);\n },\n getWalletInfo() {\n throw new Error(defaultErrorMesssage);\n },\n getSigners() {\n throw new Error(defaultErrorMesssage);\n },\n};\n\nexport const WalletContext = createContext<ProviderContext>(defaultContext);\n", "export * from './helpers';\nexport { default as Provider } from './provider';\nexport { useWallets } from './hooks';\nexport * from './types';\n\nexport type { EventHandler } from '@rango-dev/wallets-core';\nexport { Events, readAccountAddress } from '@rango-dev/wallets-core';\n"],
5
+ "mappings": "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",
6
+ "names": ["Persistor", "LAST_CONNECTED_WALLETS", "choose", "wallets", "type", "wallet", "__name", "defaultWalletState", "state_reducer", "state", "action", "target_wallet", "connectedWallets", "providersState", "wallet_state", "availableWallets", "checkWalletProviders", "list", "provider", "config", "actions", "isAsync", "fn", "needsCheckInstallation", "options", "checkInstallation", "tryPersistWallet", "walletActions", "getState", "persistor", "Persistor", "LAST_CONNECTED_WALLETS", "walletType", "clearPersistance", "walletAlreadyPersisted", "tryRemoveWalletFromPersistance", "autoConnect", "getWalletInstance", "lastConnectedWallets", "connect_promises", "walletInstance", "result", "eagerConnect", "status", "walletsToRemoveFromPersistance", "index", "makeEventHandler", "dispatcher", "onUpdateState", "name", "value", "coreState", "supportedChains", "React", "useEffect", "useReducer", "useRef", "useContext", "useRef", "createContext", "defaultErrorMesssage", "defaultContext", "WalletContext", "Wallet", "useInitializers", "onChangeState", "availableWallets", "useRef", "updater", "wallet", "type", "Wallet", "__name", "useWallets", "context", "useContext", "WalletContext", "Provider", "props", "providersState", "dispatch", "useReducer", "state_reducer", "autoConnectInitiated", "useRef", "getWalletInstance", "useInitializers", "makeEventHandler", "listOfProviders", "wallets", "checkWalletProviders", "api", "type", "network", "wallet", "result", "tryPersistWallet", "tryRemoveWalletFromPersistance", "disconnect_promises", "connectedWallets", "walletInstance", "clearPersistance", "defaultWalletState", "providers", "availableWallets", "provider", "useEffect", "runOnInit", "__name", "initWhenPageIsReady", "event", "supportedChains", "autoConnect", "React", "WalletContext", "provider_default", "Events", "readAccountAddress"]
7
+ }
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { ProviderProps } from './types';
3
+ declare function Provider(props: ProviderProps): React.JSX.Element;
4
+ export default Provider;
5
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAe7D,OAAO,EAAE,aAAa,EAAmB,MAAM,SAAS,CAAC;AAIzD,iBAAS,QAAQ,CAAC,KAAK,EAAE,aAAa,qBAsLrC;AAED,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,117 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { Network, WalletType, WalletInfo } from '@rango-dev/wallets-shared';
3
+ import { EventHandler as WalletEventHandler, State as WalletState } from '@rango-dev/wallets-core';
4
+ import { SignerFactory, BlockchainMeta } from 'rango-types';
5
+ export type State = {
6
+ [key: string]: WalletState | undefined;
7
+ };
8
+ export type ConnectResult = {
9
+ accounts: string[] | null;
10
+ network: Network | null;
11
+ provider: any;
12
+ };
13
+ export type Providers = {
14
+ [type in WalletType]?: any;
15
+ };
16
+ export type ProviderContext = {
17
+ connect(type: WalletType, network?: Network): Promise<ConnectResult>;
18
+ disconnect(type: WalletType): Promise<void>;
19
+ disconnectAll(): Promise<PromiseSettledResult<any>[]>;
20
+ state(type: WalletType): WalletState;
21
+ canSwitchNetworkTo(type: WalletType, network: Network): boolean;
22
+ providers(): Providers;
23
+ getSigners(type: WalletType): SignerFactory;
24
+ getWalletInfo(type: WalletType): WalletInfo;
25
+ };
26
+ export type ProviderProps = PropsWithChildren<{
27
+ onUpdateState?: WalletEventHandler;
28
+ allBlockChains?: BlockchainMeta[];
29
+ autoConnect?: boolean;
30
+ providers: ProviderInterface[];
31
+ }>;
32
+ export declare enum Events {
33
+ CONNECTED = "connected",
34
+ CONNECTING = "connecting",
35
+ REACHABLE = "reachable",
36
+ INSTALLED = "installed",
37
+ ACCOUNTS = "accounts",
38
+ NETWORK = "network"
39
+ }
40
+ export type ProviderConnectResult = {
41
+ accounts: string[];
42
+ chainId: string;
43
+ };
44
+ export type GetInstanceOptions = {
45
+ network?: Network;
46
+ currentProvider: any;
47
+ meta: BlockchainMeta[];
48
+ getState: () => WalletState;
49
+ /**
50
+ * We always get the instance once and reuse it whenever we needs. By using this option
51
+ * We can force the library to get a new instance and replace it with the old one.
52
+ *
53
+ * Originally, we used this option for wallet connect 1 and its switching network challenge.
54
+ */
55
+ force?: boolean;
56
+ updateChainId: (chainId: number | string) => void;
57
+ };
58
+ export type GetInstance = (() => any) | ((options: GetInstanceOptions) => Promise<any>);
59
+ export type TryGetInstance = (() => any) | ((options: Pick<GetInstanceOptions, 'force' | 'network'>) => Promise<any>);
60
+ export type Connect = (options: {
61
+ instance: any;
62
+ network?: Network;
63
+ meta: BlockchainMeta[];
64
+ }) => Promise<ProviderConnectResult | ProviderConnectResult[]>;
65
+ export type Disconnect = (options: {
66
+ instance: any;
67
+ destroyInstance: () => void;
68
+ }) => Promise<void>;
69
+ export type Subscribe = (options: {
70
+ instance: any;
71
+ state: WalletState;
72
+ meta: BlockchainMeta[];
73
+ updateChainId: (chainId: string) => void;
74
+ updateAccounts: (accounts: string[], chainId?: string) => void;
75
+ connect: (network?: Network) => void;
76
+ disconnect: () => void;
77
+ }) => void;
78
+ export type SwitchNetwork = (options: {
79
+ instance: any;
80
+ network: Network;
81
+ meta: BlockchainMeta[];
82
+ newInstance?: TryGetInstance;
83
+ }) => Promise<void>;
84
+ export type CanSwitchNetwork = (options: {
85
+ network: Network;
86
+ meta: BlockchainMeta[];
87
+ provider: any;
88
+ }) => boolean;
89
+ export type CanEagerConnect = (options: {
90
+ instance: any;
91
+ meta: BlockchainMeta[];
92
+ }) => Promise<boolean>;
93
+ export interface WalletActions {
94
+ connect: Connect;
95
+ getInstance: any;
96
+ disconnect?: Disconnect;
97
+ subscribe?: Subscribe;
98
+ switchNetwork?: SwitchNetwork;
99
+ getSigners: (provider: any) => SignerFactory;
100
+ canSwitchNetworkTo?: CanSwitchNetwork;
101
+ canEagerConnect?: CanEagerConnect;
102
+ getWalletInfo(allBlockChains: BlockchainMeta[]): WalletInfo;
103
+ }
104
+ export interface WalletConfig {
105
+ type: WalletType;
106
+ defaultNetwork?: Network;
107
+ checkInstallation?: boolean;
108
+ isAsyncInstance?: boolean;
109
+ }
110
+ export type WalletProviders = Map<WalletType, {
111
+ actions: WalletActions;
112
+ config: WalletConfig;
113
+ }>;
114
+ export type ProviderInterface = {
115
+ config: WalletConfig;
116
+ } & WalletActions;
117
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@rango-dev/wallets-react",
3
+ "version": "0.1.1-next.0",
4
+ "license": "MIT",
5
+ "type": "module",
6
+ "module": "./dist/index.js",
7
+ "main": "./dist/index.js",
8
+ "exports": {
9
+ ".": "./dist/index.js"
10
+ },
11
+ "typings": "dist/index.d.ts",
12
+ "files": [
13
+ "dist",
14
+ "src"
15
+ ],
16
+ "scripts": {
17
+ "build": "node ../../scripts/build/command.mjs --path wallets/react",
18
+ "clean": "rimraf dist",
19
+ "format": "prettier --write '{.,src}/**/*.{ts,tsx}'",
20
+ "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore"
21
+ },
22
+ "peerDependencies": {
23
+ "@types/react": "^17.0.0 || ^18.0.0",
24
+ "react": "^17.0.0 || ^18.0.0",
25
+ "react-dom": "^17.0.0 || ^18.0.0"
26
+ },
27
+ "dependencies": {
28
+ "@rango-dev/wallets-core": "^0.14.1-next.0",
29
+ "@rango-dev/wallets-shared": "^0.14.0",
30
+ "rango-types": "^0.1.46"
31
+ },
32
+ "publishConfig": {
33
+ "access": "public"
34
+ }
35
+ }
package/readme.md ADDED
@@ -0,0 +1 @@
1
+ # @rango-dev/wallets-react
@@ -0,0 +1 @@
1
+ export const LAST_CONNECTED_WALLETS = 'last-connected-wallets';
package/src/context.ts ADDED
@@ -0,0 +1,32 @@
1
+ import { createContext } from 'react';
2
+ import { ProviderContext } from './types';
3
+
4
+ const defaultErrorMesssage = "Context hasn't been initialized yet.";
5
+ const defaultContext: ProviderContext = {
6
+ async connect() {
7
+ throw new Error(defaultErrorMesssage);
8
+ },
9
+ async disconnect() {
10
+ throw new Error(defaultErrorMesssage);
11
+ },
12
+ async disconnectAll() {
13
+ throw new Error(defaultErrorMesssage);
14
+ },
15
+ state() {
16
+ throw new Error(defaultErrorMesssage);
17
+ },
18
+ canSwitchNetworkTo() {
19
+ throw new Error(defaultErrorMesssage);
20
+ },
21
+ providers() {
22
+ throw new Error(defaultErrorMesssage);
23
+ },
24
+ getWalletInfo() {
25
+ throw new Error(defaultErrorMesssage);
26
+ },
27
+ getSigners() {
28
+ throw new Error(defaultErrorMesssage);
29
+ },
30
+ };
31
+
32
+ export const WalletContext = createContext<ProviderContext>(defaultContext);
package/src/helpers.ts ADDED
@@ -0,0 +1,244 @@
1
+ import { WalletConfig, WalletType } from '@rango-dev/wallets-shared';
2
+ import Wallet, { Persistor } from '@rango-dev/wallets-core';
3
+ import type {
4
+ Options,
5
+ State as WalletState,
6
+ EventHandler as WalletEventHandler,
7
+ } from '@rango-dev/wallets-core';
8
+ import {
9
+ State,
10
+ WalletActions,
11
+ ProviderInterface,
12
+ WalletProviders,
13
+ } from './types';
14
+ import { LAST_CONNECTED_WALLETS } from './constants';
15
+
16
+ export function choose(wallets: any[], type: WalletType): any | null {
17
+ return wallets.find((wallet) => wallet.type === type) || null;
18
+ }
19
+
20
+ export const defaultWalletState: WalletState = {
21
+ connected: false,
22
+ connecting: false,
23
+ reachable: false,
24
+ installed: false,
25
+ accounts: null,
26
+ network: null,
27
+ };
28
+
29
+ export function state_reducer(state: State, action: any) {
30
+ if (action.type === 'new_state') {
31
+ // TODO fix problem and remove ts-ignore
32
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
33
+ // @ts-ignore
34
+ const target_wallet = state[action.wallet];
35
+ if (!target_wallet) {
36
+ return {
37
+ ...state,
38
+ [action.wallet]: {
39
+ ...defaultWalletState,
40
+ [action.name]: action.value,
41
+ },
42
+ };
43
+ }
44
+
45
+ return {
46
+ ...state,
47
+ [action.wallet]: {
48
+ ...target_wallet,
49
+ [action.name]: action.value,
50
+ },
51
+ };
52
+ }
53
+
54
+ return state;
55
+ }
56
+
57
+ export function connectedWallets(providersState: State): WalletType[] {
58
+ return Object.entries(providersState)
59
+ .filter(([, wallet_state]) => {
60
+ return wallet_state?.connected;
61
+ })
62
+ .map(([type]) => {
63
+ return type;
64
+ });
65
+ }
66
+
67
+ export function availableWallets(providersState: State): WalletType[] {
68
+ return Object.entries(providersState).map(([type]) => {
69
+ return type;
70
+ });
71
+ }
72
+
73
+ export function checkWalletProviders(
74
+ list: ProviderInterface[]
75
+ ): WalletProviders {
76
+ const wallets: WalletProviders = new Map();
77
+
78
+ list.forEach((provider) => {
79
+ const { config, ...actions } = provider;
80
+ wallets.set(config.type, {
81
+ actions,
82
+ config,
83
+ });
84
+ });
85
+
86
+ return wallets;
87
+ }
88
+
89
+ /* eslint-disable @typescript-eslint/ban-types */
90
+ export function isAsync(fn: Function) {
91
+ return fn?.constructor?.name === 'AsyncFunction';
92
+ }
93
+
94
+ export function needsCheckInstallation(options: Options) {
95
+ const { checkInstallation = true } = options.config;
96
+ return checkInstallation;
97
+ }
98
+
99
+ export async function tryPersistWallet({
100
+ type,
101
+ walletActions,
102
+ getState,
103
+ }: {
104
+ type: WalletType;
105
+ walletActions: WalletActions;
106
+ getState: (walletType: WalletType) => WalletState;
107
+ }) {
108
+ if (walletActions.canEagerConnect) {
109
+ const persistor = new Persistor<string[]>();
110
+ const wallets = persistor.getItem(LAST_CONNECTED_WALLETS);
111
+
112
+ /*
113
+ If on the last attempt we are unable to eagerly connect to any wallet and the user connects any wallet manualy,
114
+ persistance will be outdated and will need to be removed.
115
+ */
116
+ const shouldClearPersistance = wallets?.find(
117
+ (walletType) => !getState(walletType).connected
118
+ );
119
+
120
+ if (shouldClearPersistance) clearPersistance();
121
+
122
+ const walletAlreadyPersisted = !!wallets?.find((wallet) => wallet === type);
123
+ if (wallets && !walletAlreadyPersisted)
124
+ persistor.setItem(LAST_CONNECTED_WALLETS, wallets.concat(type));
125
+ else persistor.setItem(LAST_CONNECTED_WALLETS, [type]);
126
+ }
127
+ }
128
+
129
+ export function tryRemoveWalletFromPersistance({
130
+ type,
131
+ walletActions,
132
+ }: {
133
+ type: WalletType;
134
+ walletActions: WalletActions;
135
+ }) {
136
+ if (walletActions.canEagerConnect) {
137
+ const persistor = new Persistor<string[]>();
138
+ const wallets = persistor.getItem(LAST_CONNECTED_WALLETS);
139
+ if (wallets)
140
+ persistor.setItem(
141
+ LAST_CONNECTED_WALLETS,
142
+ wallets.filter((wallet) => wallet !== type)
143
+ );
144
+ }
145
+ }
146
+
147
+ export function clearPersistance() {
148
+ const persistor = new Persistor<string[]>();
149
+ const wallets = persistor.getItem(LAST_CONNECTED_WALLETS);
150
+ if (wallets) persistor.removeItem(LAST_CONNECTED_WALLETS);
151
+ }
152
+
153
+ /*
154
+ If a wallet has multiple providers and one of them can be eagerly connected,
155
+ then the whole wallet will support it at that point and we try to connect to that wallet as usual in eagerConnect method.
156
+ */
157
+ export async function autoConnect(
158
+ wallets: WalletProviders,
159
+ getWalletInstance: (wallet: {
160
+ actions: WalletActions;
161
+ config: WalletConfig;
162
+ }) => Wallet<any>
163
+ ) {
164
+ const persistor = new Persistor<string[]>();
165
+ const lastConnectedWallets = persistor.getItem(LAST_CONNECTED_WALLETS);
166
+ if (lastConnectedWallets && lastConnectedWallets.length) {
167
+ const connect_promises: {
168
+ walletType: WalletType;
169
+ eagerConnect: () => Promise<any>;
170
+ }[] = [];
171
+ lastConnectedWallets.forEach((walletType) => {
172
+ const wallet = wallets.get(walletType);
173
+
174
+ if (!!wallet) {
175
+ const walletInstance = getWalletInstance(wallet);
176
+ connect_promises.push({
177
+ walletType,
178
+ eagerConnect: walletInstance.eagerConnect.bind(walletInstance),
179
+ });
180
+ }
181
+ });
182
+
183
+ const result = await Promise.allSettled(
184
+ connect_promises.map(({ eagerConnect }) => eagerConnect())
185
+ );
186
+
187
+ const canRestoreAnyConnection = !!result.find(
188
+ ({ status }) => status === 'fulfilled'
189
+ );
190
+
191
+ /*
192
+ After successfully connecting to at least one wallet,
193
+ we will removing the other wallets from persistence.
194
+ If we are unable to connect to any wallet,
195
+ the persistence will not be removed and the eager connection will be retried with another page load.
196
+ */
197
+ if (canRestoreAnyConnection) {
198
+ const walletsToRemoveFromPersistance: WalletType[] = [];
199
+ result.forEach(({ status }, index) => {
200
+ if (status === 'rejected')
201
+ walletsToRemoveFromPersistance.push(
202
+ connect_promises[index].walletType
203
+ );
204
+ });
205
+
206
+ if (walletsToRemoveFromPersistance.length)
207
+ persistor.setItem(
208
+ LAST_CONNECTED_WALLETS,
209
+ lastConnectedWallets.filter(
210
+ (walletType) => !walletsToRemoveFromPersistance.includes(walletType)
211
+ )
212
+ );
213
+ }
214
+ }
215
+ }
216
+ /*
217
+ Our event handler includes an internal state updater, and a notifier
218
+ for the outside listener.
219
+ On creating first wallet refrence, and on chaning `props.onUpdateState`
220
+ we are using this function.
221
+ */
222
+ export function makeEventHandler(
223
+ dispatcher: any,
224
+ onUpdateState?: WalletEventHandler
225
+ ) {
226
+ const handler: WalletEventHandler = (
227
+ type,
228
+ name,
229
+ value,
230
+ coreState,
231
+ supportedChains
232
+ ) => {
233
+ const action = { type: 'new_state', wallet: type, name, value };
234
+ // Update state
235
+ dispatcher(action);
236
+
237
+ // Giving the event to the outside listener
238
+ if (onUpdateState) {
239
+ onUpdateState(type, name, value, coreState, supportedChains);
240
+ }
241
+ };
242
+
243
+ return handler;
244
+ }
package/src/hooks.ts ADDED
@@ -0,0 +1,47 @@
1
+ import { useContext, useRef } from 'react';
2
+ import { WalletContext } from './context';
3
+ import { ProviderContext, WalletActions, WalletConfig } from './types';
4
+ import Wallet, {
5
+ EventHandler as WalletEventHandler,
6
+ } from '@rango-dev/wallets-core';
7
+
8
+ /**
9
+ *
10
+ *
11
+ */
12
+ export function useInitializers(onChangeState: WalletEventHandler) {
13
+ const availableWallets = useRef<{
14
+ [key: string]: Wallet | undefined;
15
+ }>({});
16
+
17
+ // If `wallet` hasn't been added to `availableWallets`,
18
+ // Get a instance of `Wallet` and save the refrence in `availableWallets`.
19
+ // Otherwise, return the already created instance.
20
+ function updater(wallet: {
21
+ actions: WalletActions;
22
+ config: WalletConfig;
23
+ }): Wallet {
24
+ const type = wallet.config.type;
25
+ // We only update, if there is no instance available.
26
+ if (typeof availableWallets.current[type] === 'undefined') {
27
+ availableWallets.current[type] = new Wallet(
28
+ {
29
+ config: wallet.config,
30
+ handler: onChangeState,
31
+ },
32
+ wallet.actions
33
+ );
34
+ }
35
+
36
+ return availableWallets.current[type]!;
37
+ }
38
+
39
+ return updater;
40
+ }
41
+
42
+ export function useWallets(): ProviderContext {
43
+ const context = useContext(WalletContext);
44
+ if (!context)
45
+ throw Error('useWallet can only be used within the Provider component');
46
+ return context;
47
+ }
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ export * from './helpers';
2
+ export { default as Provider } from './provider';
3
+ export { useWallets } from './hooks';
4
+ export * from './types';
5
+
6
+ export type { EventHandler } from '@rango-dev/wallets-core';
7
+ export { Events, readAccountAddress } from '@rango-dev/wallets-core';
@@ -0,0 +1,204 @@
1
+ import React, { useEffect, useReducer, useRef } from 'react';
2
+ import { WalletType } from '@rango-dev/wallets-shared';
3
+
4
+ import {
5
+ autoConnect,
6
+ availableWallets,
7
+ checkWalletProviders,
8
+ clearPersistance,
9
+ connectedWallets,
10
+ defaultWalletState,
11
+ tryPersistWallet,
12
+ tryRemoveWalletFromPersistance,
13
+ makeEventHandler,
14
+ state_reducer,
15
+ } from './helpers';
16
+ import { ProviderProps, ProviderContext } from './types';
17
+ import { useInitializers } from './hooks';
18
+ import { WalletContext } from './context';
19
+
20
+ function Provider(props: ProviderProps) {
21
+ const [providersState, dispatch] = useReducer(state_reducer, {});
22
+ const autoConnectInitiated = useRef(false);
23
+
24
+ // Get (or add) wallet instance (`provider`s will be wraped in a `Wallet`)
25
+ const getWalletInstance = useInitializers(
26
+ makeEventHandler(dispatch, props.onUpdateState)
27
+ );
28
+
29
+ // Getting providers from props and put all of them in a `Map` with an appropriate interface.
30
+ const listOfProviders = props.providers;
31
+ const wallets = checkWalletProviders(listOfProviders);
32
+
33
+ // Final API we put in context and it will be available to use for users.
34
+ const api: ProviderContext = {
35
+ async connect(type, network) {
36
+ const wallet = wallets.get(type);
37
+ if (!wallet) {
38
+ throw new Error(`You should add ${type} to provider first.`);
39
+ }
40
+ const walletInstance = getWalletInstance(wallet);
41
+ const result = await walletInstance.connect(network);
42
+ if (props.autoConnect)
43
+ tryPersistWallet({
44
+ type,
45
+ walletActions: wallet.actions,
46
+ getState: api.state,
47
+ });
48
+
49
+ return result;
50
+ },
51
+ async disconnect(type) {
52
+ const wallet = wallets.get(type);
53
+ if (!wallet) {
54
+ throw new Error(`You should add ${type} to provider first.`);
55
+ }
56
+
57
+ const walletInstance = getWalletInstance(wallet);
58
+ await walletInstance.disconnect();
59
+ if (props.autoConnect)
60
+ tryRemoveWalletFromPersistance({ type, walletActions: wallet.actions });
61
+ },
62
+ async disconnectAll() {
63
+ const disconnect_promises: Promise<any>[] = [];
64
+
65
+ // When a wallet is initializing, a record will be added to `providersState`
66
+ // So we use them to know what wallet has been initialized then we need to
67
+ // filter connected wallets only.
68
+ connectedWallets(providersState).forEach((type) => {
69
+ const wallet = wallets.get(type);
70
+
71
+ if (wallet) {
72
+ const walletInstance = getWalletInstance(wallet);
73
+ disconnect_promises.push(walletInstance.disconnect());
74
+ }
75
+ });
76
+
77
+ if (props.autoConnect) clearPersistance();
78
+ return await Promise.allSettled(disconnect_promises);
79
+ },
80
+ state(type) {
81
+ return providersState[type] || defaultWalletState;
82
+ },
83
+ canSwitchNetworkTo(type, network) {
84
+ const wallet = wallets.get(type);
85
+ if (!wallet) {
86
+ return false;
87
+ }
88
+
89
+ const walletInstance = getWalletInstance(wallet);
90
+ return walletInstance.canSwitchNetworkTo
91
+ ? walletInstance.canSwitchNetworkTo(network, walletInstance.provider)
92
+ : false;
93
+ },
94
+ providers() {
95
+ const providers: { [type in WalletType]?: any } = {};
96
+ availableWallets(providersState).forEach((type) => {
97
+ const wallet = wallets.get(type);
98
+ if (wallet) {
99
+ const walletInstance = getWalletInstance(wallet);
100
+ providers[type] = walletInstance.provider;
101
+ }
102
+ });
103
+
104
+ return providers;
105
+ },
106
+ getWalletInfo(type) {
107
+ const wallet = wallets.get(type);
108
+ if (!wallet) {
109
+ throw new Error(`You should add ${type} to provider first.`);
110
+ }
111
+
112
+ // Get wallet info could be used in render methods to show wallets data
113
+ // So, addWalletRef method shouldn't be called in this method
114
+
115
+ return wallet.actions.getWalletInfo(props.allBlockChains || []);
116
+ },
117
+ getSigners(type) {
118
+ const wallet = wallets.get(type);
119
+
120
+ if (!wallet) {
121
+ throw new Error(`You should add ${type} to provider first.`);
122
+ }
123
+ const walletInstance = getWalletInstance(wallet);
124
+ const provider = walletInstance.provider;
125
+ const result = walletInstance.getSigners(provider);
126
+
127
+ return result;
128
+ },
129
+ };
130
+
131
+ useEffect(() => {
132
+ wallets.forEach((wallet) => {
133
+ const walletInstance = getWalletInstance(wallet);
134
+ const runOnInit = () => {
135
+ if (walletInstance.onInit) {
136
+ walletInstance.onInit();
137
+ }
138
+ };
139
+
140
+ const initWhenPageIsReady = (event: Event) => {
141
+ if (
142
+ event.target &&
143
+ (event.target as Document).readyState === 'complete'
144
+ ) {
145
+ runOnInit();
146
+
147
+ document.removeEventListener('readystatechange', initWhenPageIsReady);
148
+ }
149
+ };
150
+
151
+ // Try to run, maybe it's ready.
152
+ runOnInit();
153
+
154
+ // Try again when the page has been completely loaded.
155
+ // Some of wallets, take some time to be fully injected and loaded.
156
+ document.addEventListener('readystatechange', initWhenPageIsReady);
157
+ });
158
+ }, []);
159
+
160
+ useEffect(() => {
161
+ const allBlockChains = props.allBlockChains;
162
+ if (allBlockChains) {
163
+ wallets.forEach((wallet) => {
164
+ const walletInstance = getWalletInstance(wallet);
165
+ const supportedChains = walletInstance.getWalletInfo(
166
+ props.allBlockChains || []
167
+ ).supportedChains;
168
+ walletInstance.setMeta(supportedChains);
169
+ });
170
+ }
171
+ }, [props.allBlockChains]);
172
+
173
+ useEffect(() => {
174
+ wallets.forEach((wallet) => {
175
+ const walletInstance = getWalletInstance(wallet);
176
+ walletInstance.setHandler(
177
+ makeEventHandler(dispatch, props.onUpdateState)
178
+ );
179
+ });
180
+ }, [props.onUpdateState]);
181
+
182
+ useEffect(() => {
183
+ const shouldTryAutoConnect =
184
+ props.allBlockChains &&
185
+ props.allBlockChains.length &&
186
+ props.autoConnect &&
187
+ !autoConnectInitiated.current;
188
+
189
+ if (shouldTryAutoConnect) {
190
+ autoConnectInitiated.current = true;
191
+ (async () => {
192
+ await autoConnect(wallets, getWalletInstance);
193
+ })();
194
+ }
195
+ }, [props.autoConnect, props.allBlockChains]);
196
+
197
+ return (
198
+ <WalletContext.Provider value={api}>
199
+ {props.children}
200
+ </WalletContext.Provider>
201
+ );
202
+ }
203
+
204
+ export default Provider;
package/src/types.ts ADDED
@@ -0,0 +1,142 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { Network, WalletType, WalletInfo } from '@rango-dev/wallets-shared';
3
+ import {
4
+ EventHandler as WalletEventHandler,
5
+ State as WalletState,
6
+ } from '@rango-dev/wallets-core';
7
+ import { SignerFactory, BlockchainMeta } from 'rango-types';
8
+
9
+ export type State = {
10
+ [key: string]: WalletState | undefined;
11
+ };
12
+
13
+ export type ConnectResult = {
14
+ accounts: string[] | null;
15
+ network: Network | null;
16
+ provider: any;
17
+ };
18
+
19
+ export type Providers = { [type in WalletType]?: any };
20
+
21
+ export type ProviderContext = {
22
+ connect(type: WalletType, network?: Network): Promise<ConnectResult>;
23
+ disconnect(type: WalletType): Promise<void>;
24
+ disconnectAll(): Promise<PromiseSettledResult<any>[]>;
25
+ state(type: WalletType): WalletState;
26
+ canSwitchNetworkTo(type: WalletType, network: Network): boolean;
27
+ providers(): Providers;
28
+ getSigners(type: WalletType): SignerFactory;
29
+ getWalletInfo(type: WalletType): WalletInfo;
30
+ };
31
+
32
+ export type ProviderProps = PropsWithChildren<{
33
+ onUpdateState?: WalletEventHandler;
34
+ allBlockChains?: BlockchainMeta[];
35
+ autoConnect?: boolean;
36
+ providers: ProviderInterface[];
37
+ }>;
38
+
39
+ export enum Events {
40
+ CONNECTED = 'connected',
41
+ CONNECTING = 'connecting',
42
+ REACHABLE = 'reachable',
43
+ INSTALLED = 'installed',
44
+ ACCOUNTS = 'accounts',
45
+ NETWORK = 'network',
46
+ }
47
+
48
+ export type ProviderConnectResult = {
49
+ accounts: string[];
50
+ chainId: string;
51
+ };
52
+
53
+ export type GetInstanceOptions = {
54
+ network?: Network;
55
+ currentProvider: any;
56
+ meta: BlockchainMeta[];
57
+ getState: () => WalletState;
58
+ /**
59
+ * We always get the instance once and reuse it whenever we needs. By using this option
60
+ * We can force the library to get a new instance and replace it with the old one.
61
+ *
62
+ * Originally, we used this option for wallet connect 1 and its switching network challenge.
63
+ */
64
+ force?: boolean;
65
+ updateChainId: (chainId: number | string) => void;
66
+ };
67
+
68
+ export type GetInstance =
69
+ | (() => any)
70
+ | ((options: GetInstanceOptions) => Promise<any>);
71
+ export type TryGetInstance =
72
+ | (() => any)
73
+ | ((options: Pick<GetInstanceOptions, 'force' | 'network'>) => Promise<any>);
74
+ export type Connect = (options: {
75
+ instance: any;
76
+ network?: Network;
77
+ meta: BlockchainMeta[];
78
+ }) => Promise<ProviderConnectResult | ProviderConnectResult[]>;
79
+
80
+ export type Disconnect = (options: {
81
+ instance: any;
82
+ destroyInstance: () => void;
83
+ }) => Promise<void>;
84
+ export type Subscribe = (options: {
85
+ instance: any;
86
+ state: WalletState;
87
+ meta: BlockchainMeta[];
88
+ updateChainId: (chainId: string) => void;
89
+ updateAccounts: (accounts: string[], chainId?: string) => void;
90
+ connect: (network?: Network) => void;
91
+ disconnect: () => void;
92
+ }) => void;
93
+
94
+ export type SwitchNetwork = (options: {
95
+ instance: any;
96
+ network: Network;
97
+ meta: BlockchainMeta[];
98
+ newInstance?: TryGetInstance;
99
+ }) => Promise<void>;
100
+
101
+ export type CanSwitchNetwork = (options: {
102
+ network: Network;
103
+ meta: BlockchainMeta[];
104
+ provider: any;
105
+ }) => boolean;
106
+
107
+ export type CanEagerConnect = (options: {
108
+ instance: any;
109
+ meta: BlockchainMeta[];
110
+ }) => Promise<boolean>;
111
+
112
+ export interface WalletActions {
113
+ connect: Connect;
114
+ getInstance: any;
115
+ disconnect?: Disconnect;
116
+ subscribe?: Subscribe;
117
+ // unsubscribe, // coupled to subscribe.
118
+
119
+ // Optional, but should be provided at the same time.
120
+ switchNetwork?: SwitchNetwork;
121
+ getSigners: (provider: any) => SignerFactory;
122
+ canSwitchNetworkTo?: CanSwitchNetwork;
123
+ canEagerConnect?: CanEagerConnect;
124
+ getWalletInfo(allBlockChains: BlockchainMeta[]): WalletInfo;
125
+ }
126
+
127
+ export interface WalletConfig {
128
+ type: WalletType;
129
+ defaultNetwork?: Network;
130
+ checkInstallation?: boolean;
131
+ isAsyncInstance?: boolean;
132
+ }
133
+
134
+ export type WalletProviders = Map<
135
+ WalletType,
136
+ {
137
+ actions: WalletActions;
138
+ config: WalletConfig;
139
+ }
140
+ >;
141
+
142
+ export type ProviderInterface = { config: WalletConfig } & WalletActions;