Skip to content

Commit

Permalink
feat(data): ✨ batch generate change addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
jojobyte committed Feb 29, 2024
1 parent e1a097e commit e73a682
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 52 deletions.
7 changes: 4 additions & 3 deletions src/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ import {
* @param {String} [phraseOrXkey]
* @param {Number} [accountIndex]
* @param {Number} [addressIndex]
* @param {Number} [use]
* @param {Number} [usageIndex]
*
* @returns {Promise<SeedWallet>}
*/
export async function deriveWalletData(
phraseOrXkey,
accountIndex = 0,
addressIndex = 0,
use = DashHd.RECEIVE
usageIndex = DashHd.RECEIVE,
) {
if (!phraseOrXkey) {
throw new Error('Seed phrase or xkey value empty or invalid')
Expand Down Expand Up @@ -55,7 +55,7 @@ export async function deriveWalletData(
wpub = await DashHd.toXPub(derivedWallet);
id = await DashHd.toId(derivedWallet);
account = await derivedWallet.deriveAccount(accountIndex);
xkey = await account.deriveXKey(use);
xkey = await account.deriveXKey(usageIndex);
xprv = await DashHd.toXPrv(xkey);
}

Expand All @@ -68,6 +68,7 @@ export async function deriveWalletData(
return {
id,
accountIndex,
usageIndex,
addressIndex,
addressKeyId,
addressKey,
Expand Down
167 changes: 129 additions & 38 deletions src/helpers/wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -508,45 +508,115 @@ export async function encryptKeystore(
return keystore
}

export async function generateAddressIterator(
xkey,
walletId,
accountIndex,
addressIndex,
) {
let key = await xkey.deriveAddress(addressIndex);
let address = await DashHd.toAddr(key.publicKey);

console.log(
'generateAddressIterator',
{xkey, key, address, accountIndex, addressIndex},
)

store.addresses.getItem(address)
.then(a => {
let $addr = a || {}
console.log(
'generateAddressIterator store.addresses.getItem',
{address, $addr},
)

store.addresses.setItem(
address,
{
...$addr,
updatedAt: Date.now(),
walletId,
accountIndex,
addressIndex,
usageIndex: xkey.index,
},
)
})

return {
address,
addressIndex,
accountIndex,
usageIndex: xkey.index,
}
}

export async function batchAddressGenerate(
wallet,
accountIndex = 0,
addressIndex = 0,
use = DashHd.RECEIVE,
usageIndex = DashHd.RECEIVE,
batchSize = 20,
) {
// let hdpath = `m/44'/5'/${accountIndex}'/${use}/${addressIndex}`,
// let hdpath = `m/44'/5'/${accountIndex}'/${usageIndex}/${addressIndex}`,
let batchLimit = addressIndex + batchSize
let addresses = []

let account = await wallet.derivedWallet.deriveAccount(accountIndex);
let xkey = await account.deriveXKey(use);
let xkey = await account.deriveXKey(usageIndex);

for (let addrIdx = addressIndex; addrIdx < batchLimit; addrIdx++) {
let key = await xkey.deriveAddress(addrIdx);
let address = await DashHd.toAddr(key.publicKey);
addresses.push(
generateAddressIterator(
xkey,
wallet.id,
accountIndex,
addressIndex,
)
)
}

addresses.push({
address,
addressIndex: addrIdx,
accountIndex,
})
return {
addresses,
finalAddressIndex: batchLimit,
}
}
export async function batchAddressUsageGenerate(
wallet,
accountIndex = 0,
addressIndex = 0,
batchSize = 20,
) {
// let hdpath = `m/44'/5'/${accountIndex}'/${usageIndex}/${addressIndex}`,
let batchLimit = addressIndex + batchSize
let addresses = []

store.addresses.getItem(address)
.then(a => {
let $addr = a || {}

store.addresses.setItem(
address,
{
...$addr,
updatedAt: Date.now(),
walletId: wallet.id,
accountIndex,
addressIndex: addrIdx,
},
)
})
let account = await wallet.derivedWallet.deriveAccount(accountIndex);
let xkeyReceive = await account.deriveXKey(DashHd.RECEIVE);
let xkeyChange = await account.deriveXKey(DashHd.CHANGE);

console.log(
'batchAddressUsageGenerate',
{batchLimit, account, xkeyReceive, xkeyChange},
)

for (let addrIdx = addressIndex; addrIdx < batchLimit; addrIdx++) {
addresses.push(
await generateAddressIterator(
xkeyReceive,
wallet.id,
accountIndex,
addrIdx,
)
)
addresses.push(
await generateAddressIterator(
xkeyChange,
wallet.id,
accountIndex,
addrIdx,
)
)
}

return {
Expand Down Expand Up @@ -581,12 +651,14 @@ export async function initWallet(
wallets.push(id)
}

let addrs = await batchAddressGenerate(
let addrs = await batchAddressUsageGenerate(
wallet,
accountIndex,
addressIndex,
)

console.log('init wallet batchAddressUsageGenerate', addrs)

for (let a of addrs.addresses) {
store.addresses.setItem(
a.address,
Expand All @@ -595,6 +667,7 @@ export async function initWallet(
walletId: wallet.id,
accountIndex: a.accountIndex,
addressIndex: a.addressIndex,
usageIndex: a.usageIndex,
}
)
}
Expand Down Expand Up @@ -646,6 +719,7 @@ export async function checkWalletFunds(addr, wallet = {}) {
address,
accountIndex,
addressIndex,
usageIndex,
} = addr
let updatedAt = Date.now()
let $addr = await store.addresses.getItem(address) || {}
Expand All @@ -654,6 +728,7 @@ export async function checkWalletFunds(addr, wallet = {}) {
walletId: wallet.id,
accountIndex,
addressIndex,
usageIndex,
...$addr,
}
// console.log('checkWalletFunds $addr', $addr)
Expand Down Expand Up @@ -698,6 +773,7 @@ export async function updateAddrFunds(
walletId,
accountIndex,
addressIndex,
usageIndex,
} = $addr
// console.log(
// 'checkWalletFunds $addr',
Expand All @@ -712,6 +788,7 @@ export async function updateAddrFunds(
walletId: wallet.id,
accountIndex,
addressIndex,
usageIndex,
...$addr,
}

Expand Down Expand Up @@ -825,38 +902,51 @@ export async function getAddrsWithFunds(wallet) {
export async function batchGenAcctAddrs(
wallet,
account,
batchSize = 20
usageIndex = -1,
batchSize = 20,
) {
console.log('batchGenAcctAddrs account', account, usageIndex)
let acctAddrsLen = await getFilteredStoreLength(
store.addresses,
{
accountIndex: account.accountIndex,
}
)
let addrIdx = account.addressIndex
let addrUsageIdx = account.usage?.[usageIndex] || 0
let addrIdx = addrUsageIdx
let batSize = batchSize

if (acctAddrsLen === 0) {
addrIdx = 0
batSize = account.addressIndex + batchSize
batSize = addrUsageIdx + batchSize
}

if (acctAddrsLen <= account.addressIndex + (batchSize / 2)) {
return await batchAddressGenerate(
wallet,
account.accountIndex,
addrIdx,
DashHd.RECEIVE,
batSize
)
if (acctAddrsLen <= addrUsageIdx + (batchSize / 2)) {
if (usageIndex >= 0) {
return await batchAddressGenerate(
wallet,
account.accountIndex,
account.usage[usageIndex],
usageIndex,
batSize,
)
} else {
return await batchAddressUsageGenerate(
wallet,
account.accountIndex,
addrIdx,
batSize,
)
}
}

return null
}

export async function batchGenAcctsAddrs(
wallet,
batchSize = 20
usageIndex = -1,
batchSize = 20,
) {
let $accts = await getStoredItems(store.accounts)
let $acctsArr = Object.values($accts)
Expand All @@ -867,6 +957,7 @@ export async function batchGenAcctsAddrs(
accts[`bat__${$a.accountIndex}`] = await batchGenAcctAddrs(
wallet,
$a,
usageIndex,
batchSize,
)
}
Expand Down
24 changes: 18 additions & 6 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
import {
findInStore,
initDashSocket,
batchAddressGenerate,
// batchAddressGenerate,
batchGenAcctAddrs,
batchGenAcctsAddrs,
updateAllFunds,
Expand Down Expand Up @@ -253,15 +253,22 @@ let contactsList = await setupContactsList(
accountIndex
)

console.log('main.js contact account', shareAccount)

let created = (new Date()).toISOString()
let usage = [0,0]
usage[shareAccount.usageIndex] = shareAccount.addressIndex

newAccount = await store.accounts.setItem(
shareAccount.xkeyId,
{
createdAt: created,
updatedAt: (new Date()).toISOString(),
accountIndex,
addressIndex: shareAccount.addressIndex,
// addressIndex: shareAccount.addressIndex,
// changeIndex: shareAccount.addressIndex,
// usageIndex: shareAccount.usageIndex,
usage,
walletId: shareAccount.id,
xkeyId: shareAccount.xkeyId,
addressKeyId: shareAccount.addressKeyId,
Expand Down Expand Up @@ -629,7 +636,12 @@ async function main() {
if (receiveWallet?.xkeyId) {
let tmpWallet = await store.accounts.getItem(
receiveWallet.xkeyId,
)
) || {}

tmpWallet.usage = tmpWallet?.usage || [0,0]
tmpWallet.usage[
receiveWallet.usageIndex
] = receiveWallet.addressIndex

// state.wallet =
let tmpAcct = await store.accounts.setItem(
Expand All @@ -638,7 +650,6 @@ async function main() {
...tmpWallet,
updatedAt: (new Date()).toISOString(),
address: receiveWallet.address,
addressIndex: receiveWallet.addressIndex,
}
)

Expand Down Expand Up @@ -694,8 +705,9 @@ async function main() {
}
})

console.warn('batchGenAcctsAddrs', { wallet })
batchGenAcctsAddrs(wallet)
// .then(data => console.warn('batchGenAcctsAddrs', { data }))
.then(accts => console.warn('batchGenAcctsAddrs', { accts }))

bodyNav.render({
data: {
Expand All @@ -708,7 +720,7 @@ async function main() {

await getUserInfo()

console.log('appTools.storedData', appTools.storedData)
// console.log('appTools.storedData', appTools.storedData)

getStoreData(
store.contacts,
Expand Down
5 changes: 4 additions & 1 deletion src/rigs/phrase-generate.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,16 @@ export let phraseGenerateRig = (async function (globals) {
localStorage.selectedWallet = appState.selectedWallet
localStorage.selectedAlias = appState.selectedAlias

let usage = [0,0]
usage[wallet.usageIndex] = wallet.addressIndex

let newAccount = await store.accounts.setItem(
wallet.xkeyId,
{
createdAt: (new Date()).toISOString(),
updatedAt: (new Date()).toISOString(),
accountIndex: wallet.accountIndex,
addressIndex: wallet.addressIndex,
usage,
walletId: wallet.id,
xkeyId: wallet.xkeyId,
addressKeyId: wallet.addressKeyId,
Expand Down
Loading

0 comments on commit e73a682

Please sign in to comment.