diff --git a/packages/neuron-wallet/src/database/address/address-dao.ts b/packages/neuron-wallet/src/database/address/address-dao.ts index c2b48409e6..9d6414ca3f 100644 --- a/packages/neuron-wallet/src/database/address/address-dao.ts +++ b/packages/neuron-wallet/src/database/address/address-dao.ts @@ -96,10 +96,28 @@ export default class AddressDao { && value.txCount === 0 }) return addresses.sort((lhs, rhs) => { - return lhs.addressIndex < rhs.addressIndex ? 1 : -1 + return lhs.addressIndex - rhs.addressIndex })[0] } + public static unusedAddressesCount(walletId: string, version: AddressVersion): [number, number] { + const addresses = AddressStore.getAll() + const receivingCount = addresses.filter(value => { + return value.walletId === walletId + && value.version === version + && value.addressType == AddressType.Receiving + && value.txCount === 0 + }).length + const changeCount = addresses.filter(value => { + return value.walletId === walletId + && value.version === version + && value.addressType == AddressType.Change + && value.txCount === 0 + }).length + + return [receivingCount, changeCount] + } + public static nextUnusedChangeAddress(walletId: string, version: AddressVersion): Address | undefined { const addresses = AddressStore.getAll().filter(value => { return value.walletId === walletId @@ -108,7 +126,7 @@ export default class AddressDao { && value.txCount === 0 }) return addresses.sort((lhs, rhs) => { - return lhs.addressIndex < rhs.addressIndex ? 1 : -1 + return lhs.addressIndex - rhs.addressIndex })[0] } diff --git a/packages/neuron-wallet/src/services/addresses.ts b/packages/neuron-wallet/src/services/addresses.ts index 5c479c4df3..c1aa8bc277 100644 --- a/packages/neuron-wallet/src/services/addresses.ts +++ b/packages/neuron-wallet/src/services/addresses.ts @@ -71,16 +71,15 @@ export default class AddressService { changeAddressCount: number = 10 ) => { const addressVersion = AddressService.getAddressVersion() - const maxIndexReceivingAddress = AddressDao.maxAddressIndex(walletId, AddressType.Receiving, addressVersion) - const maxIndexChangeAddress = AddressDao.maxAddressIndex(walletId, AddressType.Change, addressVersion) + const [unusedReceivingCount, unusedChangeCount] = AddressDao.unusedAddressesCount(walletId, addressVersion) if ( - maxIndexReceivingAddress !== undefined && - maxIndexReceivingAddress.txCount === 0 && - maxIndexChangeAddress !== undefined && - maxIndexChangeAddress.txCount === 0 + unusedReceivingCount > 3 && + unusedChangeCount > 3 ) { return undefined } + const maxIndexReceivingAddress = AddressDao.maxAddressIndex(walletId, AddressType.Receiving, addressVersion) + const maxIndexChangeAddress = AddressDao.maxAddressIndex(walletId, AddressType.Change, addressVersion) const nextReceivingIndex = maxIndexReceivingAddress === undefined ? 0 : maxIndexReceivingAddress.addressIndex + 1 const nextChangeIndex = maxIndexChangeAddress === undefined ? 0 : maxIndexChangeAddress.addressIndex + 1 return AddressService.generateAndSave( diff --git a/packages/neuron-wallet/tests/database/address/dao.test.ts b/packages/neuron-wallet/tests/database/address/dao.test.ts index 5044459f74..68615fad3c 100644 --- a/packages/neuron-wallet/tests/database/address/dao.test.ts +++ b/packages/neuron-wallet/tests/database/address/dao.test.ts @@ -17,6 +17,21 @@ describe('Address Dao tests', () => { version: AddressVersion.Testnet, } + const address2: Address = { + walletId: '1', + address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83', + path: "m/44'/309'/0'/0/1", + addressType: AddressType.Receiving, + addressIndex: 1, + txCount: 0, + liveBalance: '0', + sentBalance: '0', + pendingBalance: '0', + balance: '0', + blake160: '0x36c329ed630d6ce750712a477543672adab57f4c', + version: AddressVersion.Testnet, + } + const usedAddress: Address = { walletId: '2', address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83', @@ -135,4 +150,19 @@ describe('Address Dao tests', () => { expect(one!.address).toEqual(address.address) }) + + it('unusedAddressesCount', () => { + AddressDao.create([address, changeAddress]) + + const counts = AddressDao.unusedAddressesCount(address.walletId, AddressVersion.Testnet) + expect(counts).toEqual([1, 1]) + }) + + it('nextUnusedAddress', () => { + AddressDao.create([address, address2]) + + const next = AddressDao.nextUnusedAddress('1', AddressVersion.Testnet) + + expect(next!.address).toEqual(address.address) + }) })