From 6996b894a199232f6b7f6dbf3a8f563bbb8cc871 Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Wed, 5 Jun 2024 11:56:17 -0400 Subject: [PATCH] improve wallet + test and improve types --- packages/auto-utils/__test__/wallet.test.ts | 30 ++++++++++++++++++ packages/auto-utils/src/api.ts | 2 +- packages/auto-utils/src/constants/network.ts | 2 +- packages/auto-utils/src/network.ts | 2 +- packages/auto-utils/src/types/index.ts | 3 +- .../src/types/{types.ts => network.ts} | 0 packages/auto-utils/src/types/wallet.ts | 13 ++++++++ packages/auto-utils/src/wallet.ts | 31 ++++++++----------- 8 files changed, 61 insertions(+), 22 deletions(-) create mode 100644 packages/auto-utils/__test__/wallet.test.ts rename packages/auto-utils/src/types/{types.ts => network.ts} (100%) create mode 100644 packages/auto-utils/src/types/wallet.ts diff --git a/packages/auto-utils/__test__/wallet.test.ts b/packages/auto-utils/__test__/wallet.test.ts new file mode 100644 index 00000000..aa892847 --- /dev/null +++ b/packages/auto-utils/__test__/wallet.test.ts @@ -0,0 +1,30 @@ +import { defaultNetwork, networks } from '../src/constants/network' +import { setupWallet } from '../src/wallet' + +describe('Verify wallet functions', () => { + const isLocalhost = process.env.LOCALHOST === 'true' + + // Define the test network and its details + const TEST_NETWORK = !isLocalhost + ? { networkId: networks[0].id } + : { networkId: 'autonomys-localhost' } + const TEST_NETWORK_DETAIL = networks.find((network) => network.id === TEST_NETWORK.networkId) + if (!TEST_NETWORK_DETAIL) throw new Error(`Network with id ${TEST_NETWORK.networkId} not found`) + + const TEST_INVALID_NETWORK = { networkId: 'invalid-network' } + + const ALICE_MNEMONIC = 'bottom drive obey lake curtain smoke basket hold race lonely fit walk' //Alice + const ALICE_ADDRESS = '5DFJF7tY4bpbpcKPJcBTQaKuCDEPCpiz8TRjpmLeTtweqmXL' + const BOB_URI = '//BOB' + const BOB_ADDRESS = '5DAw2FpYk2y3JHrsia14KEx7tpezNymdFKkunicZ5ygPGXYF' + + test('Check setupWallet return a pair with matching address and public key when provided with a mnemonic', async () => { + const pair = setupWallet({ mnemonic: ALICE_MNEMONIC }) + expect(pair.address).toEqual(ALICE_ADDRESS) + }) + + test('Check setupWallet return a pair with matching private key when provided with a pk', async () => { + const pair = setupWallet({ uri: BOB_URI }) + expect(pair.address).toEqual(BOB_ADDRESS) + }) +}) diff --git a/packages/auto-utils/src/api.ts b/packages/auto-utils/src/api.ts index 32cdebb1..6bf61e08 100644 --- a/packages/auto-utils/src/api.ts +++ b/packages/auto-utils/src/api.ts @@ -1,6 +1,6 @@ import { ApiPromise, WsProvider } from '@polkadot/api' import { getNetworkDomainRpcUrls, getNetworkRpcUrls } from './network' -import type { DomainInput, NetworkInput } from './types/types' +import type { DomainInput, NetworkInput } from './types/network' let provider: WsProvider | null = null let apiInstance: ApiPromise | null = null diff --git a/packages/auto-utils/src/constants/network.ts b/packages/auto-utils/src/constants/network.ts index 82b88933..591fa777 100644 --- a/packages/auto-utils/src/constants/network.ts +++ b/packages/auto-utils/src/constants/network.ts @@ -1,4 +1,4 @@ -import type { Network } from '../types/types' +import type { Network } from '../types/network' export const networks: Network[] = [ { diff --git a/packages/auto-utils/src/network.ts b/packages/auto-utils/src/network.ts index 147471ba..b54f2203 100644 --- a/packages/auto-utils/src/network.ts +++ b/packages/auto-utils/src/network.ts @@ -1,5 +1,5 @@ import { defaultNetwork, networks } from './constants/network' -import type { DomainInput, NetworkInput } from './types/types' +import type { DomainInput, NetworkInput } from './types/network' export const getNetworkDetails = (input?: NetworkInput) => { // If no id is provided, return the default network diff --git a/packages/auto-utils/src/types/index.ts b/packages/auto-utils/src/types/index.ts index c9f6f047..cf3cfd82 100644 --- a/packages/auto-utils/src/types/index.ts +++ b/packages/auto-utils/src/types/index.ts @@ -1 +1,2 @@ -export * from './types' +export * from './network' +export * from './wallet' diff --git a/packages/auto-utils/src/types/types.ts b/packages/auto-utils/src/types/network.ts similarity index 100% rename from packages/auto-utils/src/types/types.ts rename to packages/auto-utils/src/types/network.ts diff --git a/packages/auto-utils/src/types/wallet.ts b/packages/auto-utils/src/types/wallet.ts new file mode 100644 index 00000000..9323b49c --- /dev/null +++ b/packages/auto-utils/src/types/wallet.ts @@ -0,0 +1,13 @@ +export type Mnemonic = { + mnemonic: string +} + +export type URI = { + uri: string +} + +export type AppName = { + appName: string +} + +export type MnemonicOrURI = Mnemonic | URI diff --git a/packages/auto-utils/src/wallet.ts b/packages/auto-utils/src/wallet.ts index a5ff042d..211baa3a 100644 --- a/packages/auto-utils/src/wallet.ts +++ b/packages/auto-utils/src/wallet.ts @@ -2,36 +2,31 @@ import { Keyring } from '@polkadot/api' import type { KeyringPair } from '@polkadot/keyring/types' import { ed25519PairFromSeed, mnemonicToMiniSecret } from '@polkadot/util-crypto' import { activate, activateDomain } from './api' -import type { DomainInput, NetworkInput } from './types/types' +import type { AppName, DomainInput, Mnemonic, MnemonicOrURI, NetworkInput, URI } from './types' -export const setupWallet = (mnemonicOrPk: string) => { +export const setupWallet = (input: MnemonicOrURI) => { const keyring = new Keyring({ type: 'sr25519' }) let pair: KeyringPair - if (mnemonicOrPk.startsWith('0x') || mnemonicOrPk.length === 64) { - // Treat as private key - const seed = Buffer.from(mnemonicOrPk.replace(/^0x/, ''), 'hex') - pair = keyring.addFromSeed(seed) - } else { + if ((input as URI).uri) { + // Treat as as uri + pair = keyring.addFromUri((input as URI).uri) + } else if ((input as Mnemonic).mnemonic) { // Treat as mnemonic - const seed = mnemonicToMiniSecret(mnemonicOrPk) + const seed = mnemonicToMiniSecret((input as Mnemonic).mnemonic) - const { publicKey, secretKey } = ed25519PairFromSeed(seed) - pair = keyring.addFromSeed(secretKey) - } + pair = keyring.addFromPair(ed25519PairFromSeed(seed)) + } else throw new Error('Invalid mnemonic or private key') return pair } -export type ActivateWalletInput = (NetworkInput | DomainInput) & { - mnemonicOrPk?: string - appName?: string -} +export type ActivateWalletInput = (NetworkInput | DomainInput) & MnemonicOrURI & AppName export const activateWallet = async (input: ActivateWalletInput) => { // Create the API instance const apiInstance = - (input as any).domainId === undefined + (input as DomainInput).domainId === undefined ? await activate(input) : await activateDomain(input as DomainInput) @@ -52,9 +47,9 @@ export const activateWallet = async (input: ActivateWalletInput) => { } else { console.warn('No accounts found in the Polkadot.js extension') } - } else if (input.mnemonicOrPk) { + } else if ((input as Mnemonic).mnemonic || (input as URI).uri) { // Attach the wallet in a node environment - const account = await setupWallet(input.mnemonicOrPk) + const account = await setupWallet(input) if (account) console.log('Wallet attached:', account.address) } else throw new Error('No wallet provided')