diff --git a/README.md b/README.md index e1ada92c..b66565d0 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ npm install @blockshake/defly-connect @perawallet/connect @daffiwallet/connect In the root of your app, initialize the `WalletProvider` with the `useInitializeProviders` hook. -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. +This example initializes Defly, Pera, Daffi, Exodus, and Lute 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: @@ -117,6 +117,7 @@ import { WalletProvider, useInitializeProviders, PROVIDER_ID } from '@txnlab/use import { DeflyWalletConnect } from '@blockshake/defly-connect' import { PeraWalletConnect } from '@perawallet/connect' import { DaffiWalletConnect } from '@daffiwallet/connect' +import LuteConnect from 'lute-connect' export default function App() { const providers = useInitializeProviders({ @@ -124,7 +125,12 @@ export default function App() { { id: PROVIDER_ID.DEFLY, clientStatic: DeflyWalletConnect }, { id: PROVIDER_ID.PERA, clientStatic: PeraWalletConnect }, { id: PROVIDER_ID.DAFFI, clientStatic: DaffiWalletConnect }, - { id: PROVIDER_ID.EXODUS } + { id: PROVIDER_ID.EXODUS }, + { + id: PROVIDER_ID.LUTE, + clientStatic: LuteConnect, + clientOptions: { siteName: 'YourSiteName' } + } ] }) @@ -157,13 +163,23 @@ const getDynamicDaffiWalletConnect = async () => { return DaffiWalletConnect } +const getDynamicLuteConnect = async () => { + const LuteConnect = (await import('lute-connect')).default + return LuteConnect +} + 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 } + { id: PROVIDER_ID.EXODUS }, + { + id: PROVIDER_ID.LUTE, + getDynamicClient: getDynamicLuteConnect, + clientOptions: { siteName: 'YourSiteName' } + } ] }) @@ -477,6 +493,11 @@ useEffect(() => { - Website - https://www.exodus.com/ - Download - https://www.exodus.com/download/ +### Lute Wallet + +- Website - https://lute.app/ +- Install dependency - `npm install lute-connect` + ### KMD (Algorand Key Management Daemon) - Documentation - https://developer.algorand.org/docs/rest-apis/kmd @@ -617,6 +638,7 @@ import { DeflyWalletConnect } from '@blockshake/defly-connect' import { PeraWalletConnect } from '@perawallet/connect' import { DaffiWalletConnect } from '@daffiwallet/connect' import { WalletConnectModalSign } from '@walletconnect/modal-sign-html' +import LuteConnect from 'lute-connect' export default function App() { const providers = useInitializeProviders({ @@ -640,7 +662,12 @@ export default function App() { } } }, - { id: PROVIDER_ID.EXODUS } + { id: PROVIDER_ID.EXODUS }, + { + id: PROVIDER_ID.LUTE, + clientStatic: LuteConnect, + clientOptions: { siteName: 'YourSiteName' } + } ], nodeConfig: { network: 'mainnet', diff --git a/package.json b/package.json index f1834f6d..48f60822 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "jest": "^29.1.2", "jest-canvas-mock": "^2.5.0", "jest-environment-jsdom": "^29.3.1", + "lute-connect": "^1.0.7", "postcss": "^8.4.17", "prettier": "2.8.8", "react": "^18.2.0", diff --git a/src/clients/index.ts b/src/clients/index.ts index 0df3d957..aed4cbee 100644 --- a/src/clients/index.ts +++ b/src/clients/index.ts @@ -4,6 +4,7 @@ import myalgo from './myalgo' import defly from './defly' import exodus from './exodus' import algosigner from './algosigner' +import lute from './lute' import walletconnect from './walletconnect2' import kmd from './kmd' import mnemonic from './mnemonic' @@ -16,6 +17,7 @@ export { defly, exodus, algosigner, + lute, walletconnect, kmd, mnemonic, @@ -30,6 +32,7 @@ export default { [defly.metadata.id]: defly, [exodus.metadata.id]: exodus, [algosigner.metadata.id]: algosigner, + [lute.metadata.id]: lute, [walletconnect.metadata.id]: walletconnect, [kmd.metadata.id]: kmd, [mnemonic.metadata.id]: mnemonic, diff --git a/src/clients/lute/client.ts b/src/clients/lute/client.ts new file mode 100644 index 00000000..c9ffe17a --- /dev/null +++ b/src/clients/lute/client.ts @@ -0,0 +1,186 @@ +import { WalletTransaction } from 'lute-connect' +import Algod, { getAlgodClient } from '../../algod' +import { DEFAULT_NETWORK, PROVIDER_ID } from '../../constants' +import { DecodedSignedTransaction, DecodedTransaction, Network } from '../../types/node' +import type { InitParams } from '../../types/providers' +import { debugLog } from '../../utils/debugLog' +import BaseClient from '../base' +import { ICON } from './constants' +import type { LuteClientConstructor, LuteConnectOptions } from './types' +import type LuteConnect from 'lute-connect' + +class LuteClient extends BaseClient { + #client: LuteConnect + clientOptions?: LuteConnectOptions + network: Network + + constructor({ + metadata, + client, + clientOptions, + algosdk, + algodClient, + network + }: LuteClientConstructor) { + super(metadata, algosdk, algodClient) + this.#client = client + this.clientOptions = clientOptions + this.network = network + this.metadata = LuteClient.metadata + } + + static metadata = { + id: PROVIDER_ID.LUTE, + name: 'Lute', + icon: ICON, + isWalletConnect: false + } + + static async init({ + clientOptions, + algodOptions, + clientStatic, + getDynamicClient, + algosdkStatic, + network = DEFAULT_NETWORK + }: InitParams): Promise { + try { + debugLog(`${PROVIDER_ID.LUTE.toUpperCase()} initializing...`) + + let LuteConnect + if (clientStatic) { + LuteConnect = clientStatic + } else if (getDynamicClient) { + LuteConnect = await getDynamicClient() + } else { + throw new Error('Lute provider missing required property: clientStatic or getDynamicClient') + } + + const algosdk = algosdkStatic || (await Algod.init(algodOptions)).algosdk + const algodClient = getAlgodClient(algosdk, algodOptions) + + if (!clientOptions) { + throw new Error('Lute provider missing required property: clientOptions') + } + const lute = new LuteConnect(clientOptions.siteName) + const provider = new LuteClient({ + metadata: LuteClient.metadata, + client: lute, + clientOptions, + algosdk: algosdk, + algodClient: algodClient, + network + }) + + debugLog(`${PROVIDER_ID.LUTE.toUpperCase()} initialized`, '✅') + + return provider + } catch (e) { + console.error('Error initializing...', e) + return null + } + } + + async connect() { + const genesis = (await this.algodClient.genesis().do()) as { network: string; id: string } + const genesisID = `${genesis.network}-${genesis.id}` + const addresses = await this.#client.connect(genesisID) + + if (addresses.length === 0) { + throw new Error(`No accounts found for ${LuteClient.metadata.id}`) + } + + const mappedAccounts = addresses.map((address: string, index: number) => ({ + name: `Lute Wallet ${index + 1}`, + address, + providerId: LuteClient.metadata.id + })) + + return { + ...LuteClient.metadata, + accounts: mappedAccounts + } + } + + // eslint-disable-next-line @typescript-eslint/require-await + async reconnect() { + return null + } + + // eslint-disable-next-line @typescript-eslint/require-await + async disconnect() { + return + } + + shouldSignTxnObject( + txn: DecodedTransaction | DecodedSignedTransaction, + addresses: string[], + indexesToSign: number[] | undefined, + idx: number + ): boolean { + const isIndexMatch = !indexesToSign || indexesToSign.includes(idx) + const isSigned = 'txn' in txn + const canSign = !isSigned && addresses.includes(this.algosdk.encodeAddress(txn.snd)) + const shouldSign = isIndexMatch && canSign + + return shouldSign + } + + async signTransactions( + connectedAccounts: string[], + transactions: Uint8Array[], + indexesToSign?: number[], + returnGroup = true + ) { + // Decode the transactions to access their properties. + const decodedTxns = transactions.map((txn) => { + return this.algosdk.decodeObj(txn) + }) as Array + + const signedIndexes: number[] = [] + + // Marshal the transactions, + // and add the signers property if they shouldn't be signed. + const txnsToSign = decodedTxns.reduce((acc, txn, idx) => { + const isSigned = 'txn' in txn + const shouldSign = this.shouldSignTxnObject(txn, connectedAccounts, indexesToSign, idx) + + if (shouldSign) { + signedIndexes.push(idx) + acc.push({ + txn: Buffer.from(transactions[idx]).toString('base64') + }) + } else { + acc.push({ + txn: isSigned + ? Buffer.from( + this.algosdk.decodeSignedTransaction(transactions[idx]).txn.toByte() + ).toString('base64') + : Buffer.from(transactions[idx]).toString('base64'), + stxn: isSigned ? Buffer.from(transactions[idx]).toString('base64') : undefined, + signers: [] + }) + } + + return acc + }, []) + + // Sign them with the client. + const result = (await this.#client.signTxns(txnsToSign)) as (Uint8Array | null)[] + + const signedTxns = transactions.reduce((acc, txn, i) => { + if (signedIndexes.includes(i)) { + const signedByUser = result.shift() + signedByUser && acc.push(signedByUser) + } else if (returnGroup) { + acc.push(txn) + } + + return acc + }, []) + + return signedTxns + } +} + +export default LuteClient diff --git a/src/clients/lute/constants.ts b/src/clients/lute/constants.ts new file mode 100644 index 00000000..d03e6c8e --- /dev/null +++ b/src/clients/lute/constants.ts @@ -0,0 +1,3 @@ +export const ICON = + 'data:image/svg+xml;base64,' + + 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNjAuMjUxIiBoZWlnaHQ9IjU2LjU1NSIgZmlsbD0iI2FiNDdiYyIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgNjAuMjUxIDU2LjU1NSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KIDxwYXRoIGQ9Im00Ni45MzQgNDEuMDU1Yy0wLjExNjM3IDZlLTMgLTAuMjUzOTItMC4wMjM5LTAuMzU3OTQtMC4wNzYxLTAuMTExMDUtMC4wNTU3LTAuMjIyNDEtMC4xNTQ5LTAuMjk0MjgtMC4yNTYxNi0wLjA4LTAuMTEyNzUtMC4xNDAxMS0wLjI2NjE3LTAuMTYzNzUtMC40MDIzNC0wLjAyNjktMC4xNTQ4LTAuMDE3Ni0wLjM0MDI2IDAuMDE4Ni0wLjQ5MzE1IDAuMDQxMy0wLjE3NDI5IDAuMTMwMTEtMC4zNjUxOSAwLjIzMTg5LTAuNTEyNTMgMC4xMTU0LTAuMTY3MjcgMC4yODUtMC4zMzQ2MyAwLjQ1MDQ1LTAuNDUyNTkgMC4xODY1NC0wLjEzMjg3IDAuNDI4MjItMC4yNDc1NCAwLjY0NzY0LTAuMzEzMDEgMC4yNDQ5OS0wLjA3MzIgMC41NDA5Ni0wLjEwOTQ1IDAuNzk2NTgtMC4xMDI4NSAwLjI4MyA3ZS0zIDAuNjA3MDggMC4wNjg4IDAuODc0NzQgMC4xNjA5OCAwLjI5NDE3IDAuMTAxMzUgMC42MTQgMC4yNzExNyAwLjg2NTM2IDAuNDU0NSAwLjI3NDM2IDAuMjAwMDYgMC41NTQzOCAwLjQ3ODU3IDAuNzU5NDMgMC43NDkyMSAwLjIyMjQgMC4yOTM2NCAwLjQyNzA0IDAuNjY5NTggMC41NTY5MyAxLjAxNDIgMC4xNDAyMSAwLjM3MTc4IDAuMjM3NzQgMC44MjI4OCAwLjI2ODA4IDEuMjE5IDAuMDMyNSAwLjQyNTIzLTJlLTMgMC45MTkzNC0wLjA4ODUgMS4zMzY5LTAuMDkyOCAwLjQ0NjMxLTAuMjczNzMgMC45NDM3My0wLjQ4NTcgMS4zNDcyLTAuMjI1NzEgMC40Mjk1OS0wLjU1NTg3IDAuODg2MDMtMC44OTAzOCAxLjIzNzctMC4zNTQ5NiAwLjM3MzA2LTAuODIzNzMgMC43NDM1Ni0xLjI2NjYgMS4wMDYxLTAuNDY4NDYgMC4yNzc3Ny0xLjA1MTggMC41MjA3NC0xLjU3NzggMC42NjE0OC0wLjU1NDggMC4xNDg1Mi0xLjIxNjIgMC4yMjk0NC0xLjc5MDUgMC4yMjMwNS0wLjYwNDE5LTZlLTMgLTEuMjk3MS0wLjExMTM3LTEuODc3My0wLjI3OTc5LTAuNjA4ODgtMC4xNzY4NS0xLjI4MDItMC40NzczLTEuODE5Ni0wLjgxMDMyLTAuNTY0OTItMC4zNDg5LTEuMTU4NC0wLjgzOTYtMS42MS0xLjMyNjQtMC40NzE4Ni0wLjUwODctMC45MzMyOS0xLjE2OC0xLjI1MjktMS43ODQtMC4zMzM0Ni0wLjY0MjYzLTAuNjE0ODQtMS40MzM1LTAuNzY1OTItMi4xNDE1LTAuMTU3MzYtMC43Mzc0LTAuMjIxNjctMS42MDk0LTAuMTc4MTItMi4zNjIgMC4wNDU0LTAuNzgyNzUgMC4yMjA1OS0xLjY3NDggMC40NzEyMy0yLjQxNzYgMC4yNjAzLTAuNzcxNDYgMC42ODA0Mi0xLjYxNjcgMS4xMzUtMi4yOTIxIDAuNDcxNDMtMC43MDAzNSAxLjEyMjgtMS40MzA5IDEuNzYyMS0xLjk4MjIgMC42NjIyMi0wLjU3MDk4IDEuNTEyMi0xLjEyMzIgMi4zMDE1LTEuNDk5NyAwLjgxNjM4LTAuMzg5NTYgMS44MTUtMC43MDkzOCAyLjcwNTEtMC44NzA0NyAwLjkxOTc3LTAuMTY2NCAyLjAwMjItMC4yMTQxIDIuOTMzNC0wLjEzMzA4IDAuOTYxMjkgMC4wODM3IDIuMDUyNSAwLjMyOTUxIDIuOTU4MSAwLjY2MjU1IDAuOTMzOTMgMC4zNDM1NiAxLjk1MzQgMC44ODMzNSAyLjc2NDQgMS40NTk2IDAuODM1ODcgMC41OTM5NyAxLjcwMzcgMS40MDYgMi4zNTQ1IDIuMTk4MSAwLjY3MDIyIDAuODE1NTQgMS4zMTM0IDEuODU2MiAxLjc0NjYgMi44MTg4IDAuNDQ1NTcgMC45OTAxNCAwLjgwMzkyIDIuMTk2NSAwLjk3NDggMy4yNjg3IDAuMTc1NjggMS4xMDIyIDAuMjA2ODcgMi4zOTUzIDAuMDg4MSAzLjUwNS0wLjEyMTkgMS4xMzk3LTAuNDM4MzIgMi40MzAxLTAuODUzODcgMy40OTgzLTAuNDI2NjEgMS4wOTY1LTEuMDg2MiAyLjI5LTEuNzg0NCAzLjIzNjktMC43MTYzMSAwLjk3MTMtMS42ODkgMS45NzYzLTIuNjM0IDIuNzI2OC0wLjk2ODc1IDAuNzY5MzMtMi4yMDAzIDEuNTAzNS0zLjMzNjIgMS45OTMzLTEuMTYzOCAwLjUwMTc5LTIuNTc4IDAuODk4NjktMy44MzI0IDEuMDc5NC0xLjI4NDQgMC4xODUwMy0yLjc4ODMgMC4xOTk2Mi00LjA3NjQgMC4wNDMxLTEuMzE4My0wLjE2MDAyLTIuODA3OC0wLjU0NjkzLTQuMDM4Ny0xLjA0NTItMS4yNTktMC41MDk2Ni0yLjYyNjctMS4yODg5LTMuNzA5My0yLjEwOTEtMS4xMDY4LTAuODM4NTMtMi4yNDkxLTEuOTcyLTMuMDk5MS0zLjA2OTktMC44Njg1NS0xLjEyMi0xLjY5MzgtMi41NDQxLTIuMjQwMS0zLjg1MzctMC41NTgtMS4zMzczLTAuOTkzNDQtMi45NTk0LTEuMTgzOC00LjM5Ni0wLjE3NzM4LTEuMTkzNi0wLjU2MTUxLTIuNTM4Ni0xLjA0NDQtMy42NDQ1LTAuNDcwOS0xLjA3ODItMS4xNzQ5LTIuMjQ2MS0xLjkxMTEtMy4xNjM4LTAuNzE3MjctMC44OTQxLTEuNjc2Ni0xLjgxMzItMi42MDI3LTIuNDg4Ny0wLjkwMTY3LTAuNjU3NjUtMi4wMzcxLTEuMjc3My0zLjA3OTQtMS42NzYxLTEuMDE0LTAuMzg4MTgtMi4yMzgtMC42ODA5Ni0zLjMxODMtMC43OTAxOS0xLjA1MDItMC4xMDYxNS0yLjI3MzEtMC4wNjk0LTMuMzE0NCAwLjEwMzE2LTEuMDExNSAwLjE2NzU4LTIuMTQ4NiAwLjUxMzE3LTMuMDgwOCAwLjk0LTAuOTA0NzYgMC40MTQyNi0xLjg4MiAxLjAyNzItMi42NDY1IDEuNjY0My0wLjc0MTIgMC42MTc3My0xLjQ5OTYgMS40Mzk4LTIuMDUyOCAyLjIzMDQtMC41MzU4MSAwLjc2NTkyLTEuMDM1NyAxLjcyNzMtMS4zNTE1IDIuNjA3LTAuMzA1NTYgMC44NTEzMS0wLjUyNzg2IDEuODc2Mi0wLjU5ODc4IDIuNzc3OC0wLjA2ODUgMC44NzE3NC0wLjAxNTMgMS44ODQgMC4xNDgxIDIuNzQzIDAuMTU3NzUgMC44MjkzOCAwLjQ2NDc5IDEuNzU4NyAwLjgzNTU3IDIuNTE3MiAwLjM1NzU2IDAuNzMxNDQgMC44Nzk1MyAxLjUxNzkgMS40MTc1IDIuMTI5IDAuNTE4MDYgMC41ODg0MyAxLjIwMjkgMS4xODYyIDEuODU4MSAxLjYxNjkgMC42MzAwNiAwLjQxNDA1IDEuNDE3NCAwLjc5NDI0IDIuMTM0NSAxLjAyNjggMC42ODg3NCAwLjIyMzE2IDEuNTE0NCAwLjM3NDg3IDIuMjM3NiAwLjQwNzM0IDAuNjkzMjEgMC4wMzEyIDEuNDk0OS0wLjAzODcgMi4xNzE1LTAuMTkzMDIgMC42NDczMi0wLjE0NzY3IDEuMzY5LTAuNDE2MjggMS45NTM2LTAuNzMxMTEgMC41NTgyLTAuMzAwNjYgMS4xNTQtMC43MzE3NSAxLjYxMTYtMS4xNzA3IDAuNDM1OTktMC40MTgyMSAwLjg3MzEzLTAuOTY1OTggMS4xODA5LTEuNDg1OSAwLjI5MjY4LTAuNDk0MjIgMC41NTMzMS0xLjEwNzUgMC43MDIxNS0xLjY2MjIgMC4xNDEwNi0wLjUyNTk0IDAuMjIyMy0xLjE1MjYgMC4yMTYwMi0xLjY5NzItNmUtMyAtMC41MTQ4Ny0wLjA5MjQtMS4xMDYxLTAuMjM4MDYtMS42LTAuMTM3MjMtMC40NjU0OC0wLjM2NzQyLTAuOTc5NzItMC42MjY1NS0xLjM4OTktMC4yNDM1LTAuMzg1NDItMC41ODM4OC0wLjc5MDczLTAuOTIzOTItMS4wOTQyLTAuMzE4MjQtMC4yODM5Ni0wLjcyOTEtMC41NjA2Ni0xLjExMzYtMC43NDUxNi0wLjM1ODE1LTAuMTcxODQtMC43OTc2NS0wLjMxMjkyLTEuMTg5Ny0wLjM3NzMzLTAuMzYzNDgtMC4wNTk4LTAuNzkxMzgtMC4wNzA3LTEuMTU2OS0wLjAyNDgtMC4zMzY4NiAwLjA0MjMtMC43MTgxMiAwLjE0NTQ0LTEuMDI4NSAwLjI4MzEtMC4yODQ0NyAwLjEyNjA1LTAuNTkxNTIgMC4zMTgwMi0wLjgyNjQgMC41MjIxMi0wLjIxMzY3IDAuMTg1NzgtMC40Mjg4NSAwLjQzNTY2LTAuNTc2NzMgMC42NzcxMi0wLjEzMzUxIDAuMjE4MDQtMC4yNTAwOSAwLjQ5MjYzLTAuMzA5MTggMC43NDEzMy0wLjA1MzEgMC4yMjI3My0wLjA3NDYgMC40ODk0My0wLjA1MjcgMC43MTcyNyAwLjAxOTQgMC4yMDIyOCAwLjA3OTUgMC40MzI3OCAwLjE2NjYzIDAuNjE2NDQgMC4wNzY4IDAuMTYxODMgMC4xOTc3MSAwLjMzNDIgMC4zMjgwMiAwLjQ1NzA2IDAuMTE0MjQgMC4xMDc3NSAwLjI3MDIyIDAuMjA4NTcgMC40MTc2NyAwLjI2MjY2IDAuMTI5NzggMC4wNDc4IDAuMjkyNjggMC4wNzIzIDAuNDMwMzQgMC4wNTk0IDAuMTIzNi0wLjAxMTYgMC4yNjUyMS0wLjA1ODQgMC4zNjkwMS0wLjEyNjcgMC4wOTczLTAuMDY0IDAuMTkxOTYtMC4xNjgyMiAwLjI0NDg4LTAuMjcxOTEgMC4wNTI4LTAuMTAzODEgMC4xNDc1NS0wLjIwODAzIDAuMjQ0ODctMC4yNzIwMyAwLjEwMzY5LTAuMDY4MiAwLjI0NTMtMC4xMTUwOCAwLjM2OTAxLTAuMTI2NjkgMC4xMzc2Ni0wLjAxMjkgMC4zMDA0NiAwLjAxMTkgMC40MzAyMyAwLjA1OTQgMC4xNDc0NiAwLjA1NDEgMC4zMDM1NCAwLjE1NDkxIDAuNDE3NzggMC4yNjI2NSAwLjEzMDMyIDAuMTIyODcgMC4yNTEyNiAwLjI5NTI0IDAuMzI4MDIgMC40NTcwNyAwLjA4NzEgMC4xODM2NCAwLjE0NzE0IDAuNDE0MTUgMC4xNjY2MyAwLjYxNjQ0IDAuMDIxOCAwLjIyNzk0IDJlLTQgMC40OTQ2NC0wLjA1MjcgMC43MTcyNy0wLjA1OTIgMC4yNDg4MS0wLjE3NTc4IDAuNTIzMjgtMC4zMDkzIDAuNzQxMzItMC4xNDc3NyAwLjI0MTQ4LTAuMzYzMDQgMC40OTEzNS0wLjU3NjcyIDAuNjc3MTQtMC4yMzQ4NiAwLjIwNDEtMC41NDE5MiAwLjM5NjA1LTAuODI2MjkgMC41MjIxMS0wLjMxMDQ2IDAuMTM3NjYtMC42OTE2MSAwLjI0MDgzLTEuMDI4NiAwLjI4MzEtMC4zNjU0IDAuMDQ1Ny0wLjc5MzM5IDAuMDM1LTEuMTU2OC0wLjAyNDctMC4zOTIxMi0wLjA2NDUtMC44MzE1LTAuMjA1NTktMS4xODk4LTAuMzc3NDItMC4zODQ1Ni0wLjE4NDUyLTAuNzk1MzEtMC40NjEyMi0xLjExMzYtMC43NDUxNi0wLjM0MDE1LTAuMzAzNDMtMC42ODA0My0wLjcwODc1LTAuOTIzOTItMS4wOTQyLTAuMjU5MjQtMC40MTAyMi0wLjQ4OTQyLTAuOTI0NDQtMC42MjY2Ni0xLjM4OTktMC4xNDU2NC0wLjQ5Mzg5LTAuMjMyMS0xLjA4NTEtMC4yMzgwNi0xLjYtNmUtMyAtMC41NDQ1NyAwLjA3NDktMS4xNzEyIDAuMjE2MTMtMS42OTcyIDAuMTQ4ODQtMC41NTQ2OSAwLjQwOTM3LTEuMTY3OSAwLjcwMjA0LTEuNjYyMiAwLjMwNzkxLTAuNTE5ODggMC43NDUwNi0xLjA2NzYgMS4xODEtMS40ODU4IDAuNDU3NDktMC40Mzg5NyAxLjA1MzMtMC44NzAwNiAxLjYxMTYtMS4xNzA3IDAuNTg0NS0wLjMxNDgzIDEuMzA2Mi0wLjU4MzQ0IDEuOTUzNi0wLjczMTExIDAuNjc2NDktMC4xNTQyNyAxLjQ3ODItMC4yMjQyMiAyLjE3MTUtMC4xOTMwMiAwLjcyMzIzIDAuMDMyNSAxLjU0ODggMC4xODQxOSAyLjIzNzUgMC40MDc0NCAwLjcxNzI2IDAuMjMyNDIgMS41MDQ1IDAuNjEyNjEgMi4xMzQ2IDEuMDI2OCAwLjY1NTIgMC40MzA1NSAxLjM0MDEgMS4wMjg0IDEuODU4MiAxLjYxNjggMC41Mzc5NyAwLjYxMTExIDEuMDU5OSAxLjM5NzYgMS40MTc1IDIuMTI5IDAuMzcwNzEgMC43NTg0NyAwLjY3Nzc3IDEuNjg3OCAwLjgzNTU1IDIuNTE3MiAwLjE2MzMzIDAuODU4OTcgMC4yMTY2NiAxLjg3MTMgMC4xNDgxMSAyLjc0My0wLjA3MDkgMC45MDE3OC0wLjI5MzIyIDEuOTI2NS0wLjU5ODc3IDIuNzc3OC0wLjMxNTc5IDAuODc5ODQtMC44MTU2NiAxLjg0MTEtMS4zNTE1IDIuNjA3MS0wLjU1MzExIDAuNzkwNjEtMS4zMTE2IDEuNjEyNi0yLjA1MjggMi4yMzA0LTAuNzY0NDIgMC42MzcxMS0xLjc0MTYgMS4yNS0yLjY0NjMgMS42NjQzLTAuOTMyMjIgMC40MjY4NC0yLjA2OTQgMC43NzI0Mi0zLjA4MDkgMC45NDAwMS0xLjA0MTIgMC4xNzI1OC0yLjI2NDIgMC4yMDkzMS0zLjMxNDQgMC4xMDMxNi0xLjA4MDItMC4xMDkyNC0yLjMwNDItMC40MDIwMi0zLjMxODMtMC43OTAwOS0xLjA0MjItMC4zOTg5NC0yLjE3NzctMS4wMTg2LTMuMDc5NC0xLjY3NjItMC45MjYwOS0wLjY3NTQyLTEuODg1NC0xLjU5NDYtMi42MDI3LTIuNDg4Ny0wLjczNjI1LTAuOTE3NjQtMS40NDAxLTIuMDg1Ni0xLjkxMS0zLjE2MzgtMC40ODMwMi0xLjEwNTktMC44NjcwOC0yLjQ1MDktMS4wNDQ1LTMuNjQ0NS0wLjE4MTktMS4yMjM2LTAuMjAxOTktMi42NTczLTAuMDU4Mi0zLjg4NTkgMC4xNDczNS0xLjI1ODggMC41MTA3NS0yLjY4MTkgMC45ODE0Ni0zLjg1ODYgMC40ODE5Ny0xLjIwNDggMS4yMjEzLTIuNTE0NSAyLjAwMDgtMy41NTE4IDAuNzk3NzUtMS4wNjE2IDEuODc3Ni0yLjE1ODIgMi45MjQ2LTIuOTc1IDEuMDcwOC0wLjgzNTU1IDIuNDI5Ni0xLjYzMDQgMy42ODEyLTIuMTU3OSAxLjI3OTUtMC41MzkyNiAyLjgzMjItMC45NjE4MyA0LjIwODEtMS4xNDkgMS40MDU5LTAuMTkxMiAzLjA1MDMtMC4xOTQ3MiA0LjQ1NzMtMC4wMTMxIDEuNDM3MyAwLjE4NTQ2IDMuMDU5NyAwLjYxOTQyIDQuMzk5IDEuMTcyOCAxLjEyMjUgMC40NDMxMSAyLjQ3OTIgMC43ODI5NiAzLjY3ODQgMC45MTc2MyAxLjE2OTIgMC4xMzEyOCAyLjUzMjUgMC4xMDU2MiAzLjY5NTUtMC4wNzMxIDEuMTMyOS0wLjE3NDE3IDIuNDA4Ni0wLjU0NTMyIDMuNDU2Ni0xLjAwOTYgMS4wMjA0LTAuNDUyMDYgMi4xMjQ4LTEuMTI1NyAyLjk5MTMtMS44Mjg4IDAuODQzMTEtMC42ODQxNSAxLjcwODgtMS41OTc4IDIuMzQzNC0yLjQ3ODYgMC42MTY5OC0wLjg1NjQzIDEuMTk2Ny0xLjkzMzkgMS41Njc5LTIuOTIyIDAuMzYwNTEtMC45NTk3OSAwLjYyOTg2LTIuMTE3MyAwLjcyNjMzLTMuMTM4MSAwLjA5MzYtMC45OTA2OCAwLjA1MTUtMi4xNDM0LTAuMTE4MDgtMy4xMjQtMC4xNjQzOS0wLjk1MDc0LTAuNDk3MS0yLjAxODYtMC45MDUyOC0yLjg5MjktMC4zOTUzMi0wLjg0NzA2LTAuOTc4MDEtMS43NjA3LTEuNTgyLTIuNDc0LTAuNTg0NS0wLjY5MDIyLTEuMzYwOS0xLjM5NTEtMi4xMDYzLTEuOTA3NS0wLjcyMDU3LTAuNDk1MTgtMS42MjQtMC45NTUyMi0yLjQ0OTUtMS4yNDMyLTAuNzk3MTItMC4yNzgwOS0xLjc1NTUtMC40NzY4Ny0yLjU5NzgtMC41MzUtMC44MTIyNC0wLjA1Ni0xLjc1NDMgM2UtMyAtMi41NTI0IDAuMTYzMTEtMC43Njg2OCAwLjE1NDM4LTEuNjI4OCAwLjQ0ODU1LTIuMzI5NCAwLjgwMDc0LTAuNjczNjIgMC4zMzg1Ni0xLjM5NjUgMC44MzAyMi0xLjk1NjQgMS4zMzUyLTAuNTM3NjcgMC40ODQ4NC0xLjA4MTkgMS4xMjQtMS40NzE3IDEuNzM0LTAuMzczNDkgMC41ODQ4My0wLjcxMzg2IDEuMzE0LTAuOTE4NDkgMS45NzcxLTAuMTk1OCAwLjYzNDQ0LTAuMzI0MDggMS4zOTM4LTAuMzQzNjggMi4wNTc1LTAuMDE4NiAwLjYzMzY4IDAuMDU2OCAxLjM2NTIgMC4yMDgxNCAxLjk4MDkgMC4xNDQxNiAwLjU4Njc0IDAuNCAxLjIzOTIgMC42OTYxOSAxLjc2NTggMC4yODE3MiAwLjUwMDUxIDAuNjgyNDYgMS4wMzI4IDEuMDg4NSAxLjQzOTEgMC4zODQ4NyAwLjM4NTIgMC44ODY5OCAwLjc2ODkgMS4zNjE3IDEuMDM1NyAwLjQ0ODg2IDAuMjUyMjIgMS4wMDQyIDAuNDczMDMgMS41MDQ3IDAuNTkzODcgMC40NzE3NSAwLjExMzgyIDEuMDMyMSAwLjE3MTYzIDEuNTE3IDAuMTUyMjUgMC40NTU0Ny0wLjAxODEgMC45NzY2Mi0wLjExMDE5IDEuNDA5NS0wLjI1MzA3IDAuNDA1LTAuMTMzNjIgMC44NTAwNC0wLjM1MTAzIDEuMjAyMS0wLjU5MTc0IDAuMzI3OTEtMC4yMjQzMyAwLjY2OTc4LTAuNTM0NDcgMC45MjE2OC0wLjg0MTczIDAuMjMzNDctMC4yODQ3OSAwLjQ1Njc0LTAuNjQ5OTggMC41OTk3My0wLjk4OTQgMC4xMzE5MS0wLjMxMjkgMC4yMzMxNi0wLjY5NDU5IDAuMjY5MjUtMS4wMzIzIDAuMDMzMS0wLjMwOTQgMC4wMjAyLTAuNjcxMjgtMC4wMzkxLTAuOTc2NjMtMC4wNTQxLTAuMjc3OTktMC4xNjI5LTAuNTg5My0wLjI5OC0wLjgzODEtMC4xMjIxMS0wLjIyNDY1LTAuMzAxNjItMC40NjI4MS0wLjQ4NzQtMC42MzgzNy0wLjE2NjQxLTAuMTU3MjYtMC4zODY1OC0wLjMwOTQtMC41OTQ4My0wLjQwNDM3LTAuMTg0OTMtMC4wODQ0LTAuNDE0NTgtMC4xNDc1Ny0wLjYxNzE4LTAuMTYzODUtMC4xNzg0NS0wLjAxNDUtMC4zODgzIDRlLTMgLTAuNTU5ODIgMC4wNTU1LTAuMTUwNDMgMC4wNDUxLTAuMzE1NzggMC4xMjk3OC0wLjQzNjQgMC4yMzA0LTAuMTA2MTUgMC4wODg2LTAuMjA4ODggMC4yMTczLTAuMjY2NDkgMC4zNDMwMy0wLjA1MTkgMC4xMTI4Ni0wLjA4MjEgMC4yNTg5My0wLjA3NDggMC4zODI4NiA2ZS0zIDAuMTE2MjcgMC4wNDk2IDAuMjUwNDEgMC4xMTMwNyAwLjM0ODA0IDAuMDYzNCAwLjA5NzcgMC4xMDYzNiAwLjIzMTc4IDAuMTEzMTcgMC4zNDgxNSA2ZS0zIDAuMTIzOTItMC4wMjMxIDAuMjctMC4wNzQ4IDAuMzgyODUtMC4wNTc2IDAuMTI1NjMtMC4xNjA0NSAwLjI1NDM1LTAuMjY2NjEgMC4zNDI5My0wLjEyMDUgMC4xMDA3Mi0wLjI4NTg0IDAuMTg1MzYtMC40MzYyOSAwLjIzMDUxLTAuMTcxNTEgMC4wNTEzLTAuMzgxMzYgMC4wNjk5LTAuNTU5ODEgMC4wNTU1LTAuMjAyNi0wLjAxNjQtMC40MzIyNS0wLjA3OTUtMC42MTcxOC0wLjE2Mzk2LTAuMjA4MzUtMC4wOTUtMC40Mjg1My0wLjI0Njk5LTAuNTk0ODMtMC40MDQyNS0wLjE4NTg5LTAuMTc1NTYtMC4zNjUyOS0wLjQxMzgzLTAuNDg3NDEtMC42MzgzOC0wLjEzNTIxLTAuMjQ4ODEtMC4yNDQwMi0wLjU2MDIyLTAuMjk3OTktMC44MzgxLTAuMDU5NS0wLjMwNTQ2LTAuMDcyLTAuNjY3MzQtMC4wMzkxLTAuOTc2NzMgMC4wMzYtMC4zMzc2IDAuMTM3MzQtMC43MTkyOCAwLjI2OTE1LTEuMDMyMiAwLjE0MzEtMC4zMzk0MyAwLjM2NjM2LTAuNzA0NyAwLjU5OTg0LTAuOTg5NSAwLjI1MTktMC4zMDcyNyAwLjU5Mzc2LTAuNjE3MyAwLjkyMTY5LTAuODQxNjMgMC4zNTE5Ny0wLjI0MDgzIDAuNzk3MTItMC40NTgyNCAxLjIwMjEtMC41OTE4NSAwLjQzMjg5LTAuMTQyNzcgMC45NTQwNS0wLjIzNDg2IDEuNDA5NS0wLjI1Mjk3IDAuNDg0OTYtMC4wMTk0IDEuMDQ1MyAwLjAzODMgMS41MTcgMC4xNTIyNSAwLjUwMDUgMC4xMjA4NSAxLjA1NTggMC4zNDE1NSAxLjUwNDcgMC41OTM4OCAwLjQ3NDczIDAuMjY2OCAwLjk3NjczIDAuNjUwNTEgMS4zNjE3IDEuMDM1NyAwLjQwNTk2IDAuNDA2MjcgMC44MDY4IDAuOTM4NTEgMS4wODg0IDEuNDM5MSAwLjI5NjMgMC41MjY0OCAwLjU1MjAzIDEuMTc5IDAuNjk2MjkgMS43NjU2IDAuMTUxNCAwLjYxNTY5IDAuMjI2NzggMS4zNDcyIDAuMjA4MDMgMS45ODEtMC4wMTk1IDAuNjYzNzItMC4xNDc3NyAxLjQyMjktMC4zNDM1NiAyLjA1NzQtMC4yMDQ2MyAwLjY2MzA3LTAuNTQ1IDEuMzkyNC0wLjkxODU5IDEuOTc3MS0wLjM4OTY4IDAuNjEwMTYtMC45MzM5NCAxLjI0OTMtMS40NzE2IDEuNzM0MS0wLjU1OTkxIDAuNTA0ODYtMS4yODI4IDAuOTk2NTItMS45NTY2IDEuMzM1Mi0wLjcwMDQ0IDAuMzUyMDktMS41NjA2IDAuNjQ2MzctMi4zMjkzIDAuODAwNzUtMC43OTgxOSAwLjE2MDMzLTEuNzQwMyAwLjIxOTEtMi41NTI0IDAuMTYzMS0wLjg0MjI3LTAuMDU4Mi0xLjgwMDctMC4yNTY5MS0yLjU5NzgtMC41MzUtMC44MjU2NS0wLjI4ODEtMS43Mjg5LTAuNzQ4MDMtMi40NDk2LTEuMjQzMy0wLjc0NTUtMC41MTIyMS0xLjUyMTctMS4yMTcxLTIuMTA2NC0xLjkwNzUtMC42MDM5OS0wLjcxMzMzLTEuMTg2Ni0xLjYyNjktMS41ODItMi40NzM5LTAuNDA4MDgtMC44NzQzLTAuNzQwNzktMS45NDIyLTAuOTA1MTgtMi44OTMtMC4xNjk1LTAuOTgwNTYtMC4yMTE2Ni0yLjEzMzMtMC4xMTgwNy0zLjEyMzkgMC4wOTY1LTEuMDIwNyAwLjM2NTcxLTIuMTc4MyAwLjcyNjMyLTMuMTM4MSAwLjM3MTI1LTAuOTg4MTEgMC45NTA4NS0yLjA2NTYgMS41Njc5LTIuOTIyIDAuNjM0NjQtMC44ODA5MSAxLjUwMDItMS43OTQ0IDIuMzQzMy0yLjQ3ODYgMC44NjY2NC0wLjcwMzIyIDEuOTcwOS0xLjM3NjcgMi45OTEzLTEuODI4OCAxLjA0OC0wLjQ2NDMgMi4zMjM3LTAuODM1NTUgMy40NTY3LTEuMDA5NyAxLjE2MjgtMC4xNzg3NiAyLjUyNjItMC4yMDQ0MSAzLjY5NTUtMC4wNzMxIDEuMTk5MiAwLjEzNDY4IDIuNTU2IDAuNDc0NTIgMy42Nzg0IDAuOTE3NzUgMS4xNTA2IDAuNDU0MjggMi40MDIyIDEuMTUzNyAzLjM5NDQgMS44OTI2IDEuMDE2NCAwLjc1Njk4IDIuMDY3MyAxLjc4MzMgMi44NTA5IDIuNzc5MyAwLjgwMjQzIDEuMDE5OCAxLjU2NyAyLjMxNDkgMi4wNzU2IDMuNTA4NyAwLjUyMDUyIDEuMjIxNiAwLjkzMDIgMi43MDUxIDEuMTE0MiA0LjAyMDIgMC4xODgxMiAxLjM0NTIgMC4xOTcxNyAyLjkxOTMgMC4wMjgxIDQuMjY3LTAuMTcyODEgMS4zNzc3LTAuNTgzMjMgMi45MzM3LTEuMTA5MSA0LjIxODgtMC41MzczNCAxLjMxMzEtMS4zNTY1IDIuNzM4OS0yLjIxNzMgMy44NjY4LTAuODc5MzEgMS4xNTE5LTIuMDY2MyAyLjMzOTktMy4yMTUyIDMuMjIzMi0wLjk0NSAwLjc1MDQ4LTEuOTE3OCAxLjc1NTUtMi42MzQgMi43MjY4LTAuNjk4MjEgMC45NDY4LTEuMzU3OCAyLjE0MDQtMS43ODQ0IDMuMjM2OC0wLjQxNTY0IDEuMDY4My0wLjczMTk2IDIuMzU4Ny0wLjg1Mzg3IDMuNDk4NC0wLjExODcxIDEuMTA5Ny0wLjA4NzYgMi40MDI5IDAuMDg4MSAzLjUwNSAwLjE3MDk5IDEuMDcyMSAwLjUyOTM1IDIuMjc4NiAwLjk3NDkyIDMuMjY4NyAwLjQzMzExIDAuOTYyNDYgMS4wNzY0IDIuMDAzMyAxLjc0NjUgMi44MTg4IDAuNjUwOTMgMC43OTIxMiAxLjUxODcgMS42MDQxIDIuMzU0NSAyLjE5OCAwLjgxMTE4IDAuNTc2NDIgMS44MzA2IDEuMTE2MiAyLjc2NDUgMS40NTk4IDAuOTA1NjEgMC4zMzMwNCAxLjk5NjggMC41Nzg4NyAyLjk1OCAwLjY2MjU2IDAuOTMxMjcgMC4wODEgMi4wMTM3IDAuMDMzMiAyLjkzMzUtMC4xMzMwOSAwLjg5MDA3LTAuMTYxMDkgMS44ODg3LTAuNDgxMDIgMi43MDUxLTAuODcwNDcgMC43ODkxMy0wLjM3NjQ3IDEuNjM5Mi0wLjkyODcyIDIuMzAxNC0xLjQ5OTcgMC42Mzk0NC0wLjU1MTI4IDEuMjkwOC0xLjI4MTggMS43NjIyLTEuOTgyMiAwLjQ1NDYxLTAuNjc1NDIgMC44NzQ3My0xLjUyMDcgMS4xMzUtMi4yOTIxIDAuMjUwNjMtMC43NDI4MiAwLjQyNTg3LTEuNjM0OSAwLjQ3MTEyLTIuNDE3NiAwLjA0MzYtMC43NTI3Mi0wLjAyMDctMS42MjQ2LTAuMTc4LTIuMzYyLTAuMTUxMDktMC43MDgtMC40MzI0OC0xLjQ5ODgtMC43NjU5My0yLjE0MTUtMC4zMTk3Mi0wLjYxNTktMC43ODEwNC0xLjI3NTMtMS4yNTMtMS43ODQtMC40NTE1My0wLjQ4Njc3LTEuMDQ1LTAuOTc3NTktMS42MDk5LTEuMzI2NC0wLjUzOTU3LTAuMzMzMDMtMS4yMTA3LTAuNjMzNTktMS44MTk2LTAuODEwMzItMC41ODAyNS0wLjE2ODQ0LTEuMjczMi0wLjI3MzE5LTEuODc3My0wLjI3OTgtMC41NzQyOS02ZS0zIC0xLjIzNTYgMC4wNzQ1LTEuNzkwNCAwLjIyMzA0LTAuNTI2MTcgMC4xNDA3NS0xLjEwOTQgMC4zODM3Mi0xLjU3NzggMC42NjE0OS0wLjQ0MjkxIDAuMjYyNTUtMC45MTE3OSAwLjYzMzA0LTEuMjY2NiAxLjAwNjEtMC4zMzQ1MiAwLjM1MTY1LTAuNjY0NzggMC44MDc5OC0wLjg5MDUgMS4yMzc3LTAuMjExOTcgMC40MDM1LTAuMzkyODYgMC45MDA5Mi0wLjQ4NTU5IDEuMzQ3Mi0wLjA4NjggMC40MTc1Ni0wLjEyMTA0IDAuOTExNjctMC4wODg0IDEuMzM2OSAwLjAzMDQgMC4zOTYxNyAwLjEyNzg2IDAuODQ3MjcgMC4yNjc5NyAxLjIxOSAwLjEzIDAuMzQ0NjIgMC4zMzQ2NCAwLjcyMDU2IDAuNTU3MDQgMS4wMTQyIDAuMjA1MDYgMC4yNzA2NCAwLjQ4NDk1IDAuNTQ5MTUgMC43NTk0MyAwLjc0OTIxIDAuMjUxMzcgMC4xODMzNCAwLjU3MTE4IDAuMzUzMTUgMC44NjUzNiAwLjQ1NDUgMC4yNjc2NiAwLjA5MjIgMC41OTE3NCAwLjE1MzY0IDAuODc0NzMgMC4xNjA5OCAwLjI1NTYzIDZlLTMgMC41NTE2MS0wLjAyOTggMC43OTY1OS0wLjEwMjg0IDAuMjE5NDItMC4wNjU1IDAuNDYxMTEtMC4xODAxNSAwLjY0NzUzLTAuMzEzMDEgMC4xNjU1Ni0wLjExODA4IDAuMzM1MDUtMC4yODUzMyAwLjQ1MDU2LTAuNDUyNiAwLjEwMTc4LTAuMTQ3MzUgMC4xOTA1OC0wLjMzODM1IDAuMjMxODktMC41MTI1MyAwLjAzNjItMC4xNTI4OSAwLjA0NTUtMC4zMzgzNSAwLjAxODYtMC40OTMxNS0wLjAyMzgtMC4xMzYxNy0wLjA4MzgtMC4yODk1OS0wLjE2Mzc1LTAuNDAyMzMtMC4wNzE5LTAuMTAxMjctMC4xODMzMy0wLjIwMDQ5LTAuMjk0MjgtMC4yNTYxNy0wLjEwNDEyLTAuMDUyMy0wLjI0MTU2LTAuMDgyMi0wLjM1Nzk0LTAuMDc2MXoiIHN0cm9rZS13aWR0aD0iLjAxMDY0NyIvPgo8L3N2Zz4K' diff --git a/src/clients/lute/index.ts b/src/clients/lute/index.ts new file mode 100644 index 00000000..1aecaaef --- /dev/null +++ b/src/clients/lute/index.ts @@ -0,0 +1,3 @@ +import lute from './client' + +export default lute diff --git a/src/clients/lute/types.ts b/src/clients/lute/types.ts new file mode 100644 index 00000000..a11a8711 --- /dev/null +++ b/src/clients/lute/types.ts @@ -0,0 +1,17 @@ +import type algosdk from 'algosdk' +import type { Network } from '../../types/node' +import type { Metadata } from '../../types/wallet' +import type LuteConnect from 'lute-connect' + +export type LuteConnectOptions = { + siteName: string +} + +export type LuteClientConstructor = { + metadata: Metadata + client: LuteConnect + clientOptions?: LuteConnectOptions + algosdk: typeof algosdk + algodClient: algosdk.Algodv2 + network: Network +} diff --git a/src/components/Example/Example.test.tsx b/src/components/Example/Example.test.tsx index ce5e74cb..30ddfda0 100644 --- a/src/components/Example/Example.test.tsx +++ b/src/components/Example/Example.test.tsx @@ -22,7 +22,8 @@ jest.mock('../../index', () => ({ DEFLY: 'mock_defly_id', PERA: 'mock_pera_id', DAFFI: 'mock_daffi_id', - EXODUS: 'mock_exodus_id' + EXODUS: 'mock_exodus_id', + LUTE: 'mock_lute_id' }, useInitializeProviders: jest.fn() })) diff --git a/src/components/Example/Example.tsx b/src/components/Example/Example.tsx index 4da7dddf..41bb3a2a 100644 --- a/src/components/Example/Example.tsx +++ b/src/components/Example/Example.tsx @@ -1,6 +1,7 @@ import React from 'react' import { DeflyWalletConnect } from '@blockshake/defly-connect' import { DaffiWalletConnect } from '@daffiwallet/connect' +import LuteConnect from 'lute-connect' import { WalletProvider, PROVIDER_ID, useInitializeProviders, Network } from '../../index' import Account from './Account' import Connect from './Connect' @@ -20,6 +21,7 @@ export default function ConnectWallet() { { id: PROVIDER_ID.PERA, getDynamicClient: getDynamicPeraWalletConnect }, { id: PROVIDER_ID.DAFFI, clientStatic: DaffiWalletConnect }, { id: PROVIDER_ID.EXODUS }, + { id: PROVIDER_ID.LUTE, clientStatic: LuteConnect, clientOptions: { siteName: 'Storybook' } }, { id: PROVIDER_ID.CUSTOM, clientOptions: { diff --git a/src/constants/constants.ts b/src/constants/constants.ts index 0aa4a278..0a73e047 100644 --- a/src/constants/constants.ts +++ b/src/constants/constants.ts @@ -5,6 +5,7 @@ export enum PROVIDER_ID { CUSTOM = 'custom', PERA = 'pera', DAFFI = 'daffi', + LUTE = 'lute', MYALGO = 'myalgo', ALGOSIGNER = 'algosigner', DEFLY = 'defly', diff --git a/src/testUtils/mockClients.ts b/src/testUtils/mockClients.ts index 285e22e1..da099797 100644 --- a/src/testUtils/mockClients.ts +++ b/src/testUtils/mockClients.ts @@ -3,12 +3,14 @@ import { DeflyWalletConnect } from '@blockshake/defly-connect' import { DaffiWalletConnect } from '@daffiwallet/connect' import { PeraWalletConnect } from '@perawallet/connect' import MyAlgoConnect from '@randlabs/myalgo-connect' +import LuteConnect from 'lute-connect' import { WalletConnectModalSign } from '@walletconnect/modal-sign-html' import algosdk from 'algosdk' import AlgoSignerClient from '../clients/algosigner/client' import DaffiWalletClient from '../clients/daffi/client' import DeflyWalletClient from '../clients/defly/client' import ExodusClient from '../clients/exodus/client' +import LuteClient from '../clients/lute/client' import KMDWalletClient from '../clients/kmd/client' import MnemonicWalletClient from '../clients/mnemonic/client' import MyAlgoWalletClient from '../clients/myalgo/client' @@ -31,6 +33,7 @@ type ClientTypeMap = { [PROVIDER_ID.MYALGO]: MyAlgoWalletClient [PROVIDER_ID.PERA]: PeraWalletClient [PROVIDER_ID.WALLETCONNECT]: WalletConnectClient + [PROVIDER_ID.LUTE]: LuteClient } export const createMockClient = ( @@ -53,7 +56,8 @@ export const createMockClient = ( [PROVIDER_ID.MNEMONIC]: createMnemonicMockInstance, [PROVIDER_ID.MYALGO]: createMyAlgoMockInstance, [PROVIDER_ID.PERA]: createPeraMockInstance, - [PROVIDER_ID.WALLETCONNECT]: createWalletConnectMockInstance + [PROVIDER_ID.WALLETCONNECT]: createWalletConnectMockInstance, + [PROVIDER_ID.LUTE]: createLuteMockInstance } return mockClientFactoryMap[providerId](clientOptions, accounts) @@ -232,6 +236,43 @@ export const createExodusMockInstance = ( return mockExodusClient } +// LUTE +export const createLuteMockInstance = ( + clientOptions?: ClientOptions, + accounts: Array = [] +): LuteClient => { + const mockLuteClient = new LuteClient({ + metadata: { + id: PROVIDER_ID.LUTE, + name: 'Lute', + icon: 'lute-icon-b64', + isWalletConnect: false + }, + client: new LuteConnect('Test'), + algosdk, + algodClient: { + accountInformation: () => ({ + do: () => Promise.resolve({}) + }) + } as any, + network: 'test-network', + ...(clientOptions && clientOptions) + }) + + // Mock the connect method + mockLuteClient.connect = jest.fn().mockImplementation(() => + Promise.resolve({ + ...mockLuteClient.metadata, + accounts + }) + ) + + // Mock the disconnect method + mockLuteClient.disconnect = jest.fn().mockImplementation(() => Promise.resolve()) + + return mockLuteClient +} + // KMD export const createKmdMockInstance = ( clientOptions?: ClientOptions, diff --git a/src/types/providers.ts b/src/types/providers.ts index 535a917f..ebca3587 100644 --- a/src/types/providers.ts +++ b/src/types/providers.ts @@ -2,6 +2,7 @@ import type { PROVIDER_ID } from '../constants' import type { PeraWalletConnect } from '@perawallet/connect' import type { DeflyWalletConnect } from '@blockshake/defly-connect' import type { DaffiWalletConnect } from '@daffiwallet/connect' +import type LuteConnect from 'lute-connect' import type MyAlgoConnect from '@randlabs/myalgo-connect' import type { WalletConnectModalSign, @@ -13,6 +14,7 @@ import type { PeraWalletConnectOptions } from '../clients/pera/types' import type { DeflyWalletConnectOptions } from '../clients/defly/types' import type { ExodusOptions } from '../clients/exodus/types' import type { KmdOptions } from '../clients/kmd/types' +import type { LuteConnectOptions } from '../clients/lute/types' import type { MyAlgoConnectOptions } from '../clients/myalgo/types' import type { DaffiWalletConnectOptions } from '../clients/daffi/types' import type { NonEmptyArray } from './utilities' @@ -40,6 +42,11 @@ export type ProviderConfigMapping = { clientStatic?: typeof WalletConnectModalSign getDynamicClient?: () => Promise } + [PROVIDER_ID.LUTE]: { + clientOptions?: LuteConnectOptions + clientStatic?: typeof LuteConnect + getDynamicClient?: () => Promise + } [PROVIDER_ID.MYALGO]: { clientOptions?: MyAlgoConnectOptions clientStatic?: typeof MyAlgoConnect @@ -118,6 +125,8 @@ type ProviderDef = | (ProviderConfig & OneOfStaticOrDynamicClient) | (ProviderConfig & OneOfStaticOrDynamicClient) | (ProviderConfig & OneOfStaticOrDynamicClient) + | (ProviderConfig & + OneOfStaticOrDynamicClient & { clientOptions: LuteConnectOptions }) | (ProviderConfig & OneOfStaticOrDynamicClient & { clientOptions: WalletConnectModalSignOptions diff --git a/yarn.lock b/yarn.lock index 88b2f4ba..eb3adb76 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10820,6 +10820,11 @@ lru-cache@^7.14.1: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== +lute-connect@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/lute-connect/-/lute-connect-1.0.7.tgz#298af4c8d007b800dcc2a78890b029ea84ad7ed4" + integrity sha512-m1AuiUQv75vTM7UScnKWiS0QJulr7Z2Vb6H1XlceVFJ8qDuf5LJicUzkxvlpR0Fy0kGLIhha0sqTYnFjQ/01uQ== + lz-string@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941"