diff --git a/README.md b/README.md index 62631c77..f188129d 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,18 @@ In the root of your app, initialize the `WalletProvider` with the `useInitialize This example initializes Defly, Pera, Daffi and Exodus wallet providers. The default node configuration (mainnet via [AlgoNode](https://algonode.io/api/)) is used. See [Provider Configuration](#provider-configuration) for more options. +You can initialize your providers in two ways: + +1. **Static Import** - This is the standard way of importing modules in JavaScript. In this method, the import statement is at the top of the file and the modules are imported when the file loads. This is done by passing the clientStatic property. + +2. **Dynamic Import** - With the dynamic import() syntax, you can load modules on demand by calling a function. This can greatly reduce the initial load time of your app by only loading modules when they are needed. This is done by passing the getDynamicClient property which must be a function that returns a promise that resolves to the client. + +Note: For each provider, either clientStatic or getDynamicClient must be passed, not both. + +Here is an example of both: + +### Static Import Example + ```jsx import React from 'react' import { WalletProvider, useInitializeProviders, PROVIDER_ID } from '@txnlab/use-wallet' @@ -119,6 +131,46 @@ export default function App() { } ``` +### Dynamic Import Example + +```jsx +import React from 'react' +import { WalletProvider, useInitializeProviders, PROVIDER_ID } from '@txnlab/use-wallet' + +const getDynamicDeflyWalletConnect = async () => { + const DeflyWalletConnect = (await import("@blockshake/defly-connect")).DeflyWalletConnect; + return DeflyWalletConnect; +}; + +const getDynamicPeraWalletConnect = async () => { + const PeraWalletConnect = (await import("@perawallet/connect")).PeraWalletConnect; + return PeraWalletConnect; +}; + +const getDynamicDaffiWalletConnect = async () => { + const DaffiWalletConnect = (await import("@daffiwallet/connect")).DaffiWalletConnect; + return DaffiWalletConnect; +}; + +export default function App() { + const providers = useInitializeProviders({ + providers: [ + { id: PROVIDER_ID.DEFLY, getDynamicClient: getDynamicDeflyWalletConnect }, + { id: PROVIDER_ID.PERA, getDynamicClient: getDynamicPeraWalletConnect }, + { id: PROVIDER_ID.DAFFI, getDynamicClient: getDynamicDaffiWalletConnect }, + { id: PROVIDER_ID.EXODUS } + ] + }) + + return ( + +
{/* ... */}
+
+ ) +} +``` + + ## The `useWallet` Hook The `useWallet` hook is used to access wallet provider and account state, send unsigned transactions to be signed, and send signed transactions to the node from anywhere in your app. It returns an object with the following properties: diff --git a/src/clients/daffi/client.ts b/src/clients/daffi/client.ts index fb7fa042..254a756f 100644 --- a/src/clients/daffi/client.ts +++ b/src/clients/daffi/client.ts @@ -48,18 +48,24 @@ class DaffiWalletClient extends BaseClient { clientOptions, algodOptions, clientStatic, + getDynamicClient, algosdkStatic, network = DEFAULT_NETWORK }: InitParams) { try { debugLog(`${PROVIDER_ID.DAFFI.toUpperCase()} initializing...`) - if (!clientStatic) { - throw new Error('Daffi Wallet provider missing required property: clientStatic') + let DaffiWalletConnect + if (clientStatic) { + DaffiWalletConnect = clientStatic + } else if (getDynamicClient) { + DaffiWalletConnect = await getDynamicClient() + } else { + throw new Error( + 'Daffi Wallet provider missing required property: clientStatic or getDynamicClient' + ) } - const DaffiWalletConnect = clientStatic - const algosdk = algosdkStatic || (await Algod.init(algodOptions)).algosdk const algodClient = getAlgodClient(algosdk, algodOptions) diff --git a/src/clients/defly/client.ts b/src/clients/defly/client.ts index bcdc4092..3030820f 100644 --- a/src/clients/defly/client.ts +++ b/src/clients/defly/client.ts @@ -48,18 +48,24 @@ class DeflyWalletClient extends BaseClient { clientOptions, algodOptions, clientStatic, + getDynamicClient, algosdkStatic, network = DEFAULT_NETWORK }: InitParams): Promise { try { debugLog(`${PROVIDER_ID.DEFLY.toUpperCase()} initializing...`) - if (!clientStatic) { - throw new Error('Defly Wallet provider missing required property: clientStatic') + let DeflyWalletConnect + if (clientStatic) { + DeflyWalletConnect = clientStatic + } else if (getDynamicClient) { + DeflyWalletConnect = await getDynamicClient() + } else { + throw new Error( + 'Defly Wallet provider missing required property: clientStatic or getDynamicClient' + ) } - const DeflyWalletConnect = clientStatic - const algosdk = algosdkStatic || (await Algod.init(algodOptions)).algosdk const algodClient = getAlgodClient(algosdk, algodOptions) diff --git a/src/clients/myalgo/client.ts b/src/clients/myalgo/client.ts index dfdd4802..da0c98e2 100644 --- a/src/clients/myalgo/client.ts +++ b/src/clients/myalgo/client.ts @@ -43,18 +43,24 @@ class MyAlgoWalletClient extends BaseClient { clientOptions, algodOptions, clientStatic, + getDynamicClient, algosdkStatic, network = DEFAULT_NETWORK }: InitParams): Promise { try { debugLog(`${PROVIDER_ID.MYALGO.toUpperCase()} initializing...`) - if (!clientStatic) { - throw new Error('MyAlgo Wallet provider missing required property: clientStatic') + let MyAlgoConnect + if (clientStatic) { + MyAlgoConnect = clientStatic + } else if (getDynamicClient) { + MyAlgoConnect = await getDynamicClient() + } else { + throw new Error( + 'MyAlgo Wallet provider missing required property: clientStatic or getDynamicClient' + ) } - const MyAlgoConnect = clientStatic - const algosdk = algosdkStatic || (await Algod.init(algodOptions)).algosdk const algodClient = getAlgodClient(algosdk, algodOptions) diff --git a/src/clients/pera/client.ts b/src/clients/pera/client.ts index 50433e84..9d2786c0 100644 --- a/src/clients/pera/client.ts +++ b/src/clients/pera/client.ts @@ -48,18 +48,24 @@ class PeraWalletClient extends BaseClient { clientOptions, algodOptions, clientStatic, + getDynamicClient, algosdkStatic, network = DEFAULT_NETWORK }: InitParams): Promise { try { debugLog(`${PROVIDER_ID.PERA.toUpperCase()} initializing...`) - if (!clientStatic) { - throw new Error('Pera Wallet provider missing required property: clientStatic') + let PeraWalletConnect + if (clientStatic) { + PeraWalletConnect = clientStatic + } else if (getDynamicClient) { + PeraWalletConnect = await getDynamicClient() + } else { + throw new Error( + 'Pera Wallet provider missing required property: clientStatic or getDynamicClient' + ) } - const PeraWalletConnect = clientStatic - const algosdk = algosdkStatic || (await Algod.init(algodOptions)).algosdk const algodClient = getAlgodClient(algosdk, algodOptions) diff --git a/src/clients/walletconnect2/client.ts b/src/clients/walletconnect2/client.ts index 19758690..8da3fd4f 100644 --- a/src/clients/walletconnect2/client.ts +++ b/src/clients/walletconnect2/client.ts @@ -53,14 +53,22 @@ class WalletConnectClient extends BaseClient { clientOptions, algodOptions, clientStatic, + getDynamicClient, algosdkStatic, network = DEFAULT_NETWORK }: InitParams): Promise { try { debugLog(`${PROVIDER_ID.WALLETCONNECT.toUpperCase()} initializing...`) - if (!clientStatic) { - throw new Error('WalletConnect provider missing required property: clientStatic') + let Client + if (clientStatic) { + Client = clientStatic + } else if (getDynamicClient) { + Client = await getDynamicClient() + } else { + throw new Error( + 'WalletConnect provider missing required property: clientStatic or getDynamicClient' + ) } if (!clientOptions) { @@ -75,8 +83,6 @@ class WalletConnectClient extends BaseClient { const chain = ALGORAND_CHAINS[network] - const Client = clientStatic - // Initialize client const client = new Client({ ...clientOptions, diff --git a/src/components/Example/Example.tsx b/src/components/Example/Example.tsx index a07b4900..202d7b83 100644 --- a/src/components/Example/Example.tsx +++ b/src/components/Example/Example.tsx @@ -1,17 +1,21 @@ import React from 'react' import { DeflyWalletConnect } from '@blockshake/defly-connect' -import { PeraWalletConnect } from '@perawallet/connect' import { DaffiWalletConnect } from '@daffiwallet/connect' import { WalletProvider, PROVIDER_ID, useInitializeProviders } from '../../index' import Account from './Account' import Connect from './Connect' import Transact from './Transact' +const getDynamicPeraWalletConnect = async () => { + const PeraWalletConnect = (await import('@perawallet/connect')).PeraWalletConnect + return PeraWalletConnect +} + export default function ConnectWallet() { const walletProviders = useInitializeProviders({ providers: [ { id: PROVIDER_ID.DEFLY, clientStatic: DeflyWalletConnect }, - { id: PROVIDER_ID.PERA, clientStatic: PeraWalletConnect }, + { id: PROVIDER_ID.PERA, getDynamicClient: getDynamicPeraWalletConnect }, { id: PROVIDER_ID.DAFFI, clientStatic: DaffiWalletConnect }, { id: PROVIDER_ID.EXODUS } ] diff --git a/src/types/providers.ts b/src/types/providers.ts index cd874253..44b22f78 100644 --- a/src/types/providers.ts +++ b/src/types/providers.ts @@ -22,38 +22,47 @@ export type ProviderConfigMapping = { [PROVIDER_ID.PERA]: { clientOptions?: PeraWalletConnectOptions clientStatic?: typeof PeraWalletConnect + getDynamicClient?: () => Promise } [PROVIDER_ID.DAFFI]: { clientOptions?: DaffiWalletConnectOptions clientStatic?: typeof DaffiWalletConnect + getDynamicClient?: () => Promise } [PROVIDER_ID.DEFLY]: { clientOptions?: DeflyWalletConnectOptions clientStatic?: typeof DeflyWalletConnect + getDynamicClient?: () => Promise } [PROVIDER_ID.WALLETCONNECT]: { clientOptions?: WalletConnectModalSignOptions clientStatic?: typeof WalletConnectModalSign + getDynamicClient?: () => Promise } [PROVIDER_ID.MYALGO]: { clientOptions?: MyAlgoConnectOptions clientStatic?: typeof MyAlgoConnect + getDynamicClient?: () => Promise } [PROVIDER_ID.EXODUS]: { clientOptions?: ExodusOptions clientStatic?: undefined + getDynamicClient?: undefined } [PROVIDER_ID.KMD]: { clientOptions?: KmdOptions clientStatic?: undefined + getDynamicClient?: undefined } [PROVIDER_ID.ALGOSIGNER]: { clientOptions?: undefined clientStatic?: undefined + getDynamicClient?: undefined } [PROVIDER_ID.MNEMONIC]: { clientOptions?: undefined clientStatic?: undefined + getDynamicClient?: undefined } } @@ -87,15 +96,27 @@ export type NodeConfig = { nodeHeaders?: Record } +type StaticClient = { + clientStatic: T + getDynamicClient?: undefined +} + +type DynamicClient = { + clientStatic?: undefined + getDynamicClient: () => Promise +} + +type OneOfStaticOrDynamicClient = StaticClient | DynamicClient + type ProviderDef = - | (ProviderConfig & { clientStatic: typeof PeraWalletConnect }) - | (ProviderConfig & { clientStatic: typeof DeflyWalletConnect }) - | (ProviderConfig & { clientStatic: typeof DaffiWalletConnect }) - | (ProviderConfig & { - clientStatic: typeof WalletConnectModalSign - clientOptions: WalletConnectModalSignOptions - }) - | (ProviderConfig & { clientStatic: typeof MyAlgoConnect }) + | (ProviderConfig & OneOfStaticOrDynamicClient) + | (ProviderConfig & OneOfStaticOrDynamicClient) + | (ProviderConfig & OneOfStaticOrDynamicClient) + | (ProviderConfig & + OneOfStaticOrDynamicClient & { + clientOptions: WalletConnectModalSignOptions + }) + | (ProviderConfig & OneOfStaticOrDynamicClient) | ProviderConfig | ProviderConfig | PROVIDER_ID.EXODUS