Skip to content

Commit

Permalink
Improve address loading logic
Browse files Browse the repository at this point in the history
- Less awaits, more batched processing
- Base POC of "saved" generated via isDisplayedPath
  • Loading branch information
coderofstuff committed Oct 23, 2023
1 parent 5f51cfc commit 383d790
Showing 1 changed file with 81 additions and 47 deletions.
128 changes: 81 additions & 47 deletions app/wallet/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,85 +23,109 @@ import KaspaBIP32 from '../../lib/bip32';
let loadingAddressBatch = false;
let addressInitialized = false;

async function loadAddresses(
function loadAddresses(

Check failure on line 26 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L26

Replace `⏎····bip32,⏎····addressType·=·0,⏎····from·=·0,⏎····to·=·from·+·10⏎` with `bip32,·addressType·=·0,·from·=·0,·to·=·from·+·10` (prettier/prettier)
bip32,
addressType = 0,
from = 0,
to = from + 10,
onPartialSuccess = () => {},
to = from + 10
) {
const addresses = [];

const { chainCode, compressedPublicKey } = await getAddress("44'/111111'/0'");

const bip32 = new KaspaBIP32(compressedPublicKey, chainCode);

for (let addressIndex = from; addressIndex < to; addressIndex++) {
const derivationPath = `44'/111111'/0'/${addressType}/${addressIndex}`;
const address = bip32.getAddress(addressType, addressIndex);

onPartialSuccess({
derivationPath,
address,
});

addresses.push({
derivationPath,
address,
});
}

console.info(addresses);

return addresses;
}

const addressFilter = (addressData, index) => {
return true;
// return index == 0 // Always show the first address
// || addressData.balance > 0 // Always show if balance is positive
// || addressData.txCount > 0; // Always show if address has any transactions (it has been used)
return index == 0 // Always show the first address

Check failure on line 48 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L48

Replace `index·==·0··············` with `(⏎········index·==·0·||` (prettier/prettier)
|| isDisplayedPath(addressData.derivationPath) // Always show if we've "generated" this address

Check failure on line 49 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L49

Replace `||·isDisplayedPath(addressData.derivationPath)·` with `isDisplayedPath(addressData.derivationPath)·||·` (prettier/prettier)
|| addressData.balance > 0 // Always show if balance is positive

Check failure on line 50 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L50

Replace `||·addressData.balance·>·0·` with `addressData.balance·>·0·||` (prettier/prettier)
|| addressData.txCount > 0; // Always show if address has any transactions (it has been used)

Check failure on line 51 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L51

Replace `||·addressData.txCount·>·0` with `addressData.txCount·>·0⏎····)` (prettier/prettier)
};

async function loadAddressBatch(callback) {
async function loadAddressBatch(callback, callbackSetRawAddresses) {
if (loadingAddressBatch || addressInitialized) {
return;
}

loadingAddressBatch = true;

try {
const detailPromises = [];
const rawAddresses = [];
const receiveAddresses = await loadAddresses(0, 0, 10, ({ derivationPath, address }) => {
const addressData = {
key: address,
address,
derivationPath,
balance: 0,
loading: true,
};
rawAddresses.push(addressData);
let rawAddresses = [];
const loadAddressDetails = (rawAddress) => {
const fetchAddressPromise = fetchAddressDetails(rawAddress.address, rawAddress.derivationPath);

Check failure on line 64 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L64

Replace `rawAddress.address,·rawAddress.derivationPath` with `⏎················rawAddress.address,⏎················rawAddress.derivationPath,⏎············` (prettier/prettier)

return fetchAddressPromise.then((addressDetails) => {
rawAddress.balance = addressDetails.balance / 100000000;
rawAddress.utxos = addressDetails.utxos;
rawAddress.txCount = addressDetails.txCount;
rawAddress.loading = false;

return rawAddress;
});
};

const PAGE_SIZE = 5;

const { chainCode, compressedPublicKey } = await getAddress("44'/111111'/0'");

const bip32 = new KaspaBIP32(compressedPublicKey, chainCode);

for (let page = 0, foundWithBalance = true; foundWithBalance; page++) {
foundWithBalance = false;

const receiveAddresses = loadAddresses(bip32, 0, page * PAGE_SIZE, page * PAGE_SIZE + PAGE_SIZE);

Check failure on line 85 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L85

Replace `bip32,·0,·page·*·PAGE_SIZE,·page·*·PAGE_SIZE·+·PAGE_SIZE` with `⏎················bip32,⏎················0,⏎················page·*·PAGE_SIZE,⏎················page·*·PAGE_SIZE·+·PAGE_SIZE,⏎············` (prettier/prettier)
const changeAddresses = loadAddresses(bip32, 1, page * PAGE_SIZE, page * PAGE_SIZE + PAGE_SIZE);

Check failure on line 86 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L86

Replace `bip32,·1,·page·*·PAGE_SIZE,·page·*·PAGE_SIZE·+·PAGE_SIZE` with `⏎················bip32,⏎················1,⏎················page·*·PAGE_SIZE,⏎················page·*·PAGE_SIZE·+·PAGE_SIZE,⏎············` (prettier/prettier)
const allAddresses = [...receiveAddresses, ...changeAddresses];

rawAddresses = [...rawAddresses, ...allAddresses.map(({ derivationPath, address }) => {

Check failure on line 89 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L89

Replace `...rawAddresses,` with `⏎················...rawAddresses,⏎···············` (prettier/prettier)
return {

Check failure on line 90 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L90

Insert `····` (prettier/prettier)
key: address,

Check failure on line 91 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L91

Replace `····················` with `························` (prettier/prettier)
address,

Check failure on line 92 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L92

Insert `····` (prettier/prettier)
derivationPath,

Check failure on line 93 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L93

Insert `····` (prettier/prettier)
balance: 0,

Check failure on line 94 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L94

Insert `····` (prettier/prettier)
loading: true,

Check failure on line 95 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L95

Insert `····` (prettier/prettier)
};

Check failure on line 96 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L96

Insert `····` (prettier/prettier)
})];

Check failure on line 97 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L97

Replace `············})` with `················}),⏎············` (prettier/prettier)

callbackSetRawAddresses(rawAddresses);
callback(rawAddresses.filter(addressFilter));

const fetchAddressPromise = fetchAddressDetails(address, derivationPath);
detailPromises.push(fetchAddressPromise);
let promises = [];
for (const rawAddress of rawAddresses) {
promises.push(loadAddressDetails(rawAddress));

fetchAddressPromise.then((addressDetails) => {
addressData.balance = addressDetails.balance / 100000000;
addressData.utxos = addressDetails.utxos;
addressData.txCount = addressDetails.txCount;
addressData.loading = false;
if (promises.length >= 5) {
const allAddressData = await Promise.all(promises);

Check failure on line 108 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L108

Delete `····················` (prettier/prettier)
for (const addressData of allAddressData) {
foundWithBalance = foundWithBalance || addressData.balance > 0 || addressData.txCount > 0;

Check failure on line 110 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L110

Insert `⏎···························` (prettier/prettier)
}

callback(rawAddresses.filter(addressFilter));
});
});
// FIXME: Handle rate limiting
// const changeAddresses = [];
callback(rawAddresses.filter(addressFilter));
promises = [];
}
}

// const addresses = [...receiveAddresses, ...changeAddresses];
if (promises.length) {
const allAddressData = await Promise.all(promises);

Check failure on line 120 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L120

Delete `················` (prettier/prettier)
for (const addressData of allAddressData) {
foundWithBalance = foundWithBalance || addressData.balance > 0 || addressData.txCount > 0;

Check failure on line 122 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L122

Insert `⏎·······················` (prettier/prettier)
}

const processedAddresses = await Promise.all(detailPromises);
callback(rawAddresses.filter(addressFilter));
promises = [];
}
}
} finally {
addressInitialized = true;
loadingAddressBatch = false;
Expand Down Expand Up @@ -145,7 +169,7 @@ async function loadAddressTransactions(selectedAddress, setTransactions) {

// let demoAddressLoading = false;

async function demoLoadAddress(setAddresses) {
async function demoLoadAddress(setAddresses, setRawAddresses) {
const demoAddresses = [];

for (let i = 0; i < 20; i++) {
Expand All @@ -161,6 +185,7 @@ async function demoLoadAddress(setAddresses) {

demoAddresses.push(currAddress);

setRawAddresses([...demoAddresses]);
setAddresses([...demoAddresses]);

delay(Math.round(Math.random() * 3000)).then(() => {
Expand All @@ -173,6 +198,14 @@ async function demoLoadAddress(setAddresses) {
}
}

function isDisplayedPath(derivationPath) {
// TODO: Switch with actual paths stored in local storage
return derivationPath === "44'/111111'/0'/0/0" ||

Check failure on line 203 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L203

Insert `(⏎········` (prettier/prettier)
derivationPath === "44'/111111'/0'/0/1" ||

Check failure on line 204 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L204

Delete `···` (prettier/prettier)
derivationPath === "44'/111111'/0'/1/0" ||

Check failure on line 205 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L205

Delete `···` (prettier/prettier)
derivationPath === "44'/111111'/0'/1/1";

Check failure on line 206 in app/wallet/page.js

View workflow job for this annotation

GitHub Actions / ESLint

app/wallet/page.js#L206

Replace `···derivationPath·===·"44'/111111'/0'/1/1"` with `derivationPath·===·"44'/111111'/0'/1/1"⏎····)` (prettier/prettier)
}

function delay(ms = 0) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
Expand All @@ -181,6 +214,7 @@ function delay(ms = 0) {

export default function Dashboard(props) {
const [addresses, setAddresses] = useState([]);
const [rawAddresses, setRawAddresses] = useState([]);
const [transactions, setTransactions] = useState([]);
const [selectedAddress, setSelectedAddress] = useState(null);
const [activeTab, setActiveTab] = useState('addresses');
Expand Down Expand Up @@ -216,9 +250,9 @@ export default function Dashboard(props) {
}

if (deviceType === 'usb') {
loadAddressBatch(setAddresses);
loadAddressBatch(setAddresses, setRawAddresses);
} else if (deviceType === 'demo') {
demoLoadAddress(setAddresses);
demoLoadAddress(setAddresses, setRawAddresses);
}
}, [isTransportInitialized, deviceType]);

Expand Down

0 comments on commit 383d790

Please sign in to comment.