From 010571a042bc442841a7c1679f19e4d5a2c0cc5b Mon Sep 17 00:00:00 2001 From: Alejo Acosta Date: Mon, 28 Oct 2024 14:39:33 -0300 Subject: [PATCH 1/5] export address info interfaces --- src/quais.ts | 2 ++ src/wallet/index.ts | 4 ++-- src/wallet/qi-hdwallet.ts | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/quais.ts b/src/quais.ts index d5ddcce7..a7d0a14c 100644 --- a/src/quais.ts +++ b/src/quais.ts @@ -218,6 +218,8 @@ export { encryptKeystoreJsonSync, SerializedHDWallet, SerializedQiHDWallet, + QiAddressInfo, + NeuteredAddressInfo, } from './wallet/index.js'; // WORDLIST diff --git a/src/wallet/index.ts b/src/wallet/index.ts index 85043b2d..dec13e6d 100644 --- a/src/wallet/index.ts +++ b/src/wallet/index.ts @@ -13,7 +13,7 @@ export { BaseWallet } from './base-wallet.js'; -export type { SerializedHDWallet } from './hdwallet.js'; +export type { SerializedHDWallet, NeuteredAddressInfo } from './hdwallet.js'; export { QuaiHDWallet } from './quai-hdwallet.js'; @@ -31,6 +31,6 @@ export { Wallet } from './wallet.js'; export type { KeystoreAccount, EncryptOptions } from './json-keystore.js'; -export { QiHDWallet, SerializedQiHDWallet } from './qi-hdwallet.js'; +export { QiHDWallet, SerializedQiHDWallet, QiAddressInfo } from './qi-hdwallet.js'; export { HDNodeVoidWallet, HDNodeWallet } from './hdnodewallet.js'; diff --git a/src/wallet/qi-hdwallet.ts b/src/wallet/qi-hdwallet.ts index 46f20253..14eb915a 100644 --- a/src/wallet/qi-hdwallet.ts +++ b/src/wallet/qi-hdwallet.ts @@ -62,7 +62,7 @@ type DerivationPath = 'BIP44:external' | 'BIP44:change' | string; // string for * * @extends NeuteredAddressInfo */ -interface QiAddressInfo extends NeuteredAddressInfo { +export interface QiAddressInfo extends NeuteredAddressInfo { status: AddressStatus; derivationPath: DerivationPath; } From 4d7510e76adcb6e9cee901b93fe326718b736975 Mon Sep 17 00:00:00 2001 From: Alejo Acosta Date: Mon, 28 Oct 2024 17:39:03 -0300 Subject: [PATCH 2/5] add unit test for Qi address derivation --- ...qihdwallet-address-derivation.unit.test.ts | 113 ++++++++++++++++++ testcases/qi-address-derivation.json.gz | Bin 0 -> 2941 bytes 2 files changed, 113 insertions(+) create mode 100644 src/_tests/unit/qihdwallet-address-derivation.unit.test.ts create mode 100644 testcases/qi-address-derivation.json.gz diff --git a/src/_tests/unit/qihdwallet-address-derivation.unit.test.ts b/src/_tests/unit/qihdwallet-address-derivation.unit.test.ts new file mode 100644 index 00000000..5060bad9 --- /dev/null +++ b/src/_tests/unit/qihdwallet-address-derivation.unit.test.ts @@ -0,0 +1,113 @@ +import assert from 'assert'; +import { loadTests } from '../utils.js'; +import { Mnemonic, QiHDWallet, Zone, QiAddressInfo } from '../../index.js'; + +interface TestCaseQiAddressDerivation { + mnemonic: string; + externalAddresses: Array<{ + zone: string; + addresses: Array; + }>; + changeAddresses: Array<{ + zone: string; + addresses: Array; + }>; + paymentCodeAddresses: { + bobMnemonic: string; + sendAddresses: Array<{ + zone: string; + addresses: Array; + }>; + receiveAddresses: Array<{ + zone: string; + addresses: Array; + }>; + }; +} + +describe('QiHDWallet Address Derivation', function () { + this.timeout(2 * 60 * 1000); + const tests = loadTests('qi-address-derivation'); + + for (const test of tests) { + it('derives external addresses correctly', function () { + const mnemonic = Mnemonic.fromPhrase(test.mnemonic); + const qiWallet = QiHDWallet.fromMnemonic(mnemonic); + + for (const externalAddressesInfo of test.externalAddresses) { + const zone = externalAddressesInfo.zone as Zone; + for (const expectedAddressInfo of externalAddressesInfo.addresses) { + const derivedAddressInfo = qiWallet.getNextAddressSync(0, zone); + assert.deepEqual( + derivedAddressInfo, + expectedAddressInfo, + `External address mismatch for zone ${zone}, expected: ${JSON.stringify(expectedAddressInfo)}, derived: ${JSON.stringify(derivedAddressInfo)}`, + ); + } + } + }); + + it('derives change addresses correctly', function () { + const mnemonic = Mnemonic.fromPhrase(test.mnemonic); + const qiWallet = QiHDWallet.fromMnemonic(mnemonic); + + for (const changeAddressesInfo of test.changeAddresses) { + const zone = changeAddressesInfo.zone as Zone; + for (const expectedAddressInfo of changeAddressesInfo.addresses) { + const derivedAddressInfo = qiWallet.getNextChangeAddressSync(0, zone); + assert.deepEqual( + derivedAddressInfo, + expectedAddressInfo, + `Change address mismatch for zone ${zone}, expected: ${JSON.stringify(expectedAddressInfo)}, derived: ${JSON.stringify(derivedAddressInfo)}`, + ); + } + } + }); + + it('derives payment code send addresses correctly', function () { + const mnemonic = Mnemonic.fromPhrase(test.mnemonic); + const qiWallet = QiHDWallet.fromMnemonic(mnemonic); + + const bobMnemonic = Mnemonic.fromPhrase(test.paymentCodeAddresses.bobMnemonic); + const bobQiWallet = QiHDWallet.fromMnemonic(bobMnemonic); + const bobPaymentCode = bobQiWallet.getPaymentCode(0); + + qiWallet.openChannel(bobPaymentCode); + + for (const sendAddressesInfo of test.paymentCodeAddresses.sendAddresses) { + const zone = sendAddressesInfo.zone as Zone; + for (const expectedAddressInfo of sendAddressesInfo.addresses) { + const derivedAddressInfo = qiWallet.getNextSendAddress(bobPaymentCode, zone); + assert.deepEqual( + derivedAddressInfo, + expectedAddressInfo, + `Payment code send address mismatch, expected: ${JSON.stringify(expectedAddressInfo)}, derived: ${JSON.stringify(derivedAddressInfo)}`, + ); + } + } + }); + + it('derives payment code receive addresses correctly', function () { + const mnemonic = Mnemonic.fromPhrase(test.mnemonic); + const qiWallet = QiHDWallet.fromMnemonic(mnemonic); + + const bobMnemonic = Mnemonic.fromPhrase(test.paymentCodeAddresses.bobMnemonic); + const bobQiWallet = QiHDWallet.fromMnemonic(bobMnemonic); + const bobPaymentCode = bobQiWallet.getPaymentCode(0); + + qiWallet.openChannel(bobPaymentCode); + + for (const receiveAddressesInfo of test.paymentCodeAddresses.receiveAddresses) { + const zone = receiveAddressesInfo.zone as Zone; + for (const expectedAddressInfo of receiveAddressesInfo.addresses) { + const derivedAddressInfo = qiWallet.getNextReceiveAddress(bobPaymentCode, zone); + assert.deepEqual( + derivedAddressInfo, + expectedAddressInfo, + `Payment code receive address mismatch, expected: ${JSON.stringify(expectedAddressInfo)}, derived: ${JSON.stringify(derivedAddressInfo)}`, + ); + } + } + }); + } +}); diff --git a/testcases/qi-address-derivation.json.gz b/testcases/qi-address-derivation.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..023247746e817e8a6189d2b6501e43bf614c46a9 GIT binary patch literal 2941 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 Date: Wed, 30 Oct 2024 15:06:15 -0300 Subject: [PATCH 3/5] add new exports --- src/quais.ts | 3 +++ src/wallet/index.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/quais.ts b/src/quais.ts index a7d0a14c..a0727af3 100644 --- a/src/quais.ts +++ b/src/quais.ts @@ -220,6 +220,7 @@ export { SerializedQiHDWallet, QiAddressInfo, NeuteredAddressInfo, + OutpointInfo, } from './wallet/index.js'; // WORDLIST @@ -298,6 +299,8 @@ export type { TransactionReceiptParams, TransactionRequest, TransactionResponse, + QiTransactionResponse, + QuaiTransactionResponse, TransactionResponseParams, WebSocketCreator, WebSocketLike, diff --git a/src/wallet/index.ts b/src/wallet/index.ts index dec13e6d..7c230c18 100644 --- a/src/wallet/index.ts +++ b/src/wallet/index.ts @@ -31,6 +31,6 @@ export { Wallet } from './wallet.js'; export type { KeystoreAccount, EncryptOptions } from './json-keystore.js'; -export { QiHDWallet, SerializedQiHDWallet, QiAddressInfo } from './qi-hdwallet.js'; +export { QiHDWallet, SerializedQiHDWallet, QiAddressInfo, OutpointInfo } from './qi-hdwallet.js'; export { HDNodeVoidWallet, HDNodeWallet } from './hdnodewallet.js'; From 01c7afc197e56691b025e8a89bd49aaf1b294ffb Mon Sep 17 00:00:00 2001 From: Alejo Acosta Date: Wed, 30 Oct 2024 15:07:22 -0300 Subject: [PATCH 4/5] add integration test for qi-wallet roundtrip --- .../qi-wallet-roundtrip.integration.test.ts | 181 ++++++++++++++++++ testcases/qi-wallet-roundtrip.json.gz | Bin 0 -> 3321 bytes 2 files changed, 181 insertions(+) create mode 100644 src/_tests/integration/qi-wallet-roundtrip.integration.test.ts create mode 100644 testcases/qi-wallet-roundtrip.json.gz diff --git a/src/_tests/integration/qi-wallet-roundtrip.integration.test.ts b/src/_tests/integration/qi-wallet-roundtrip.integration.test.ts new file mode 100644 index 00000000..eaa34ce1 --- /dev/null +++ b/src/_tests/integration/qi-wallet-roundtrip.integration.test.ts @@ -0,0 +1,181 @@ +import assert from 'assert'; +import { loadTests } from '../utils.js'; +import { + Mnemonic, + QiHDWallet, + Zone, + QiAddressInfo, + QiTransactionResponse, + OutpointInfo, + JsonRpcProvider, +} from '../../index.js'; + +import dotenv from 'dotenv'; +const env = process.env.NODE_ENV || 'development'; +dotenv.config({ path: `.env.${env}` }); +dotenv.config({ path: `.env`, override: false }); + +interface QiRoundtripTestCase { + alice: { + mnemonic: string; + initialState: { + balance: bigint; + outpoints: Array<{ + account: number; + address: string; + outpoint: OutpointInfo; + zone: string; + }>; + addresses: { + external: Array; + change: Array; + payment: Array; + }; + }; + sendAmount: bigint; + }; + bob: { + mnemonic: string; + initialState: { + balance: bigint; + outpoints: Array; + addresses: { + external: Array; + change: Array; + payment: Array; + }; + }; + sendAmount: bigint; + }; +} + +describe('QiHDWallet Roundtrip Transaction', function () { + const tests = loadTests('qi-wallet-roundtrip'); + let aliceWallet: QiHDWallet; + let bobWallet: QiHDWallet; + let alicePaymentCode: string; + let bobPaymentCode: string; + const provider = new JsonRpcProvider(process.env.RPC_URL); + + for (const test of tests) { + this.timeout(1200000); + const aliceMnemonic = Mnemonic.fromPhrase(test.alice.mnemonic); + aliceWallet = QiHDWallet.fromMnemonic(aliceMnemonic); + aliceWallet.connect(provider); + + const bobMnemonic = Mnemonic.fromPhrase(test.bob.mnemonic); + bobWallet = QiHDWallet.fromMnemonic(bobMnemonic); + bobWallet.connect(provider); + + alicePaymentCode = aliceWallet.getPaymentCode(0); + bobPaymentCode = bobWallet.getPaymentCode(0); + + aliceWallet.openChannel(bobPaymentCode); + bobWallet.openChannel(alicePaymentCode); + + it('validates Alice wallet initial state', async function () { + await aliceWallet.scan(Zone.Cyprus1); + + assert.equal(aliceWallet.getBalanceForZone(Zone.Cyprus1).toString(), test.alice.initialState.balance); + assert.deepEqual(aliceWallet.getOutpoints(Zone.Cyprus1), test.alice.initialState.outpoints); + assert.deepEqual(aliceWallet.getAddressesForZone(Zone.Cyprus1), test.alice.initialState.addresses.external); + assert.deepEqual( + aliceWallet.getChangeAddressesForZone(Zone.Cyprus1), + test.alice.initialState.addresses.change, + ); + assert.deepEqual( + aliceWallet.getPaymentChannelAddressesForZone(bobPaymentCode, Zone.Cyprus1), + test.alice.initialState.addresses.payment, + ); + }); + + it('validates Bob wallet initial state', async function () { + await bobWallet.scan(Zone.Cyprus1); + + assert.equal(bobWallet.getBalanceForZone(Zone.Cyprus1).toString(), test.bob.initialState.balance); + assert.deepEqual(bobWallet.getOutpoints(Zone.Cyprus1), test.bob.initialState.outpoints); + assert.deepEqual(bobWallet.getAddressesForZone(Zone.Cyprus1), test.bob.initialState.addresses.external); + assert.deepEqual(bobWallet.getChangeAddressesForZone(Zone.Cyprus1), test.bob.initialState.addresses.change); + assert.deepEqual( + bobWallet.getPaymentChannelAddressesForZone(alicePaymentCode, Zone.Cyprus1), + test.bob.initialState.addresses.payment, + ); + }); + + it('validates first transaction is sent and confirmed', async function () { + const tx = (await aliceWallet.sendTransaction( + bobPaymentCode, + test.alice.sendAmount, + Zone.Cyprus1, + Zone.Cyprus1, + )) as QiTransactionResponse; + + await assert.doesNotReject(async () => { + await tx.wait(); + }); + console.log(`... succesfully sent ${test.alice.sendAmount} to Bob`); + }); + + let aliceFee: bigint; + it('validates Alice and Bob wallet balance after first transaction', async function () { + await aliceWallet.sync(Zone.Cyprus1); + await bobWallet.sync(Zone.Cyprus1); + + const bobBalance = bobWallet.getBalanceForZone(Zone.Cyprus1); + assert.equal( + bobBalance.toString(), + test.alice.sendAmount.toString(), + `Expected Bob's balance to be ${test.alice.sendAmount.toString()} but got ${bobBalance.toString()}`, + ); + + // Alice's balance should be lower than the initial balance minus the amount sent (because of the tx fee) + const aliceBalance = aliceWallet.getBalanceForZone(Zone.Cyprus1); + const aliceBalanceWithoutFee = BigInt(test.alice.initialState.balance) - BigInt(test.alice.sendAmount); + aliceFee = BigInt(aliceBalanceWithoutFee) - BigInt(aliceBalance); + assert.ok( + aliceBalance < aliceBalanceWithoutFee, + `Expected Alice's balance to be less than ${aliceBalanceWithoutFee.toString()} but got ${aliceBalance.toString()}`, + ); + }); + + it('validates second transaction is sent and confirmed', async function () { + const tx = (await bobWallet.sendTransaction( + alicePaymentCode, + test.bob.sendAmount, + Zone.Cyprus1, + Zone.Cyprus1, + )) as QiTransactionResponse; + + await assert.doesNotReject(async () => { + await tx.wait(); + }); + console.log(`... succesfully sent ${test.bob.sendAmount} to Alice`); + }); + + it('validates Alice and Bob wallet balance after second transaction', async function () { + await aliceWallet.sync(Zone.Cyprus1); + await bobWallet.sync(Zone.Cyprus1); + + const aliceBalance = aliceWallet.getBalanceForZone(Zone.Cyprus1); + const bobBalance = bobWallet.getBalanceForZone(Zone.Cyprus1); + + const bobBalanceWithoutFee = + BigInt(test.bob.initialState.balance) + BigInt(test.alice.sendAmount) - BigInt(test.bob.sendAmount); + const aliceExpectedBalance = + BigInt(test.alice.initialState.balance) - + BigInt(test.alice.sendAmount) + + BigInt(test.bob.sendAmount) - + aliceFee; + assert.equal( + aliceBalance.toString(), + aliceExpectedBalance.toString(), + `Expected Alice's balance to be ${aliceExpectedBalance.toString()} but got ${aliceBalance.toString()}`, + ); + + assert.ok( + bobBalance < bobBalanceWithoutFee, + `Expected Bob's balance to be less than ${bobBalanceWithoutFee.toString()} but got ${bobBalance.toString()}`, + ); + }); + } +}); diff --git a/testcases/qi-wallet-roundtrip.json.gz b/testcases/qi-wallet-roundtrip.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..3b7c2499009ac7e08dc01a4a41cd4b1c2bb27ff6 GIT binary patch literal 3321 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 DY)pkd literal 0 HcmV?d00001 From cbdd3edbe0ef2d5e15ef75aee8ffc3f23c83857a Mon Sep 17 00:00:00 2001 From: Alejo Acosta Date: Wed, 30 Oct 2024 17:16:19 -0300 Subject: [PATCH 5/5] copy qi gen_allo file for reference --- src/_tests/integration/gen_alloc_qi_cyprus1.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/_tests/integration/gen_alloc_qi_cyprus1.json diff --git a/src/_tests/integration/gen_alloc_qi_cyprus1.json b/src/_tests/integration/gen_alloc_qi_cyprus1.json new file mode 100644 index 00000000..4051e417 --- /dev/null +++ b/src/_tests/integration/gen_alloc_qi_cyprus1.json @@ -0,0 +1,7 @@ +{"0x009f1545923a5A1052Aa162F858e2b925863Cd3D": + { + "denomination":13, + "hash":"0x00FF00F8ffab4b3711e9a94159f246907a3041d72f5f849d4de78d78e44ad474", + "index":0 + } +}