-
Notifications
You must be signed in to change notification settings - Fork 2
Implement promises library with non-blocking methods #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
42b62b9
to
714d91b
Compare
@tmalahie To add more info, I've tried this: const { Wallet, generateKeys, restoreKeys } = require("./promises");
const { WalletData, BitcoinNetwork } = require("./wrapper");
async function main() {
let bitcoinNetwork = BitcoinNetwork.Regtest;
let keys = await generateKeys(bitcoinNetwork);
console.log("Keys: " + JSON.stringify(keys));
let restoredKeys = await restoreKeys(bitcoinNetwork, keys.mnemonic);
console.log("Restored keys: " + JSON.stringify(restoredKeys));
let walletData = {
dataDir: "./data",
bitcoinNetwork: bitcoinNetwork,
databaseType: DatabaseType.Sqlite,
maxAllocationsPerUtxo: "1",
pubkey: keys.accountXpub,
mnemonic: keys.mnemonic,
vanillaKeychain: null,
};
console.log("Creating wallet...");
const wallet = await Wallet(new WalletData(walletData));
console.log("Wallet created");
const balance = await wallet.getBtcBalance(null, true);
console.log("BTC balance: " + balance);
}
try {
main();
} catch (e) {
console.error("Error running example: " + e);
process.exit(1);
} which builds on your usage example. But when executed it returns:
|
Hello @zoedberg thanks for taking time to check it out 🙂
I don't know how we can proceed... Maybe try again your code inside docker to see if it works in this case? |
@tmalahie the link you provided (https://github.com/RGB-Tools/rgb-lib-nodejs/blob/01e36b43388c0244d577c8a552294bdadd7d9996/promises/worker.js#L10) points to an nonexistent commit, not sure it's a just mistake or if you're on a different commit to which I don't have access. Anyway I added a log before the error gets raised: console.log("self " + JSON.stringify(self));
if (typeof self[method] !== "function") {
throw new Error(
`${self[method]} is not a function (calling ${method})`,
);
} and it seems Since it works on your end I guess we're using different node versions. I'm using node v22.13.1. I've just tried the same code with node v20.18.3 and it seems Keys: {"mnemonic":"oyster aim object enter awesome paddle energy forum sustain duty custom horse","xpub":"tpubD6NzVbkrYhZ4YPcL63Nbe8bYTeET16ftByorJY1zM2SYtpyR2R9gmXkdFRxbpKNouWmncdn7KEgK5qEm54i6HzxMUyddZRu9mUZGwuY8fNQ","accountXpub":"tpubDCRv1zbeJZe7cURVSMZpdwuvqu1QrUdz95ido9QKaBugKn5f8zJkB8TJpYHC6r1KgQer3N2yC1MHyp7nvjNr3j8ig41UQVkW9xEuZoNnm2M","accountXpubFingerprint":"3e8e6a85"}
Restored keys: {"mnemonic":"oyster aim object enter awesome paddle energy forum sustain duty custom horse","xpub":"tpubD6NzVbkrYhZ4YPcL63Nbe8bYTeET16ftByorJY1zM2SYtpyR2R9gmXkdFRxbpKNouWmncdn7KEgK5qEm54i6HzxMUyddZRu9mUZGwuY8fNQ","accountXpub":"tpubDCRv1zbeJZe7cURVSMZpdwuvqu1QrUdz95ido9QKaBugKn5f8zJkB8TJpYHC6r1KgQer3N2yC1MHyp7nvjNr3j8ig41UQVkW9xEuZoNnm2M","accountXpubFingerprint":"3e8e6a85"}
Creating wallet...
Wallet created
BTC balance: {"vanilla":{"settled":0,"future":0,"spendable":0},"colored":{"settled":0,"future":0,"spendable":0}} Since the script wasn't exiting though (I had to press ctrl+c to exit), I modified the call to the try {
main().finally(() => {
process.exit(0);
});
} catch (e) {
console.error("Error running example: " + e);
process.exit(1);
} and the output is:
as you can see with this change the output of the Could you please tell me which node version are you using and try the script with node v22? Could you also try to run the script with the modified call to the |
714d91b
to
b271c9f
Compare
@zoedberg you're right, there was a an issue with my code on node 22. I was testing on node 20. About the code not exiting properly it's because of the worker process still running. I added a method So the new sample becomes
Can you test it again with my latest changes and let me know if works this time? 🙌 |
@tmalahie the example you provided fails because the indexer is for another network, but I commented that part and called the Having to call the |
Nice! I also had the indexer error, try to use testnet instead of regtest it should work. The error also occurs when using the non-promise methods so it's not an issue with my changes.
I can't do it unfortunately, nodejs doesn't have the concept of destructors so I can't detect when you no longer needs the wallet. It's the same reason why we have this method |
I know how to overcome the issue and that itsn't related to your changes, but I wanted to point out that's good practice to share a working example if the point of the example is to show code is working ok (especially if the code that you want to show to be working is called after the point where the example is failing).
The |
Well the example using regtest comes from you originally, I didn't want to question it as I thought it was working for you, sorry if you got confused 😕 Anyway ok as you prefer, I still think it would be beneficial to have async behavior out of the box as it's a common practice in node.js. In the end I'm just trying to help you improving the library based on my experience integrating it. But if you don't like it because of minor drawbacks you're the one to decide 🙌 |
My bad, sorry, I must have done a mistake when pasting the example because locally I was running a different code, without the call to the
I also think it would be nice to have an async behavior out of the box but I would like a more standard approach that doesn't need to be documented to be used. I think in the future I'm going to do another attempt with swig and rust (probably exploring also libuv) because fixing the blocking behavior from the source would be the best way to go IMO. Anyway I appreciate your effort, thank you very much. |
This PR adds an alternate version of the wrapper library that supports async operations.
The issue with the current wrapper is that each method is blocking, which is generally an anti-pattern in JS. Concretely it means that when you call a method that takes multiple seconds to complete (like refreshing your assetsà, the whole app will freeze for multiple seconds and you can't do any other operation in between.
I added another module
rgb-lib/promises
where all methods perform the tasks asynchronously instead and return a promise. It uses worker threads under the hood.Usage: