diff --git a/example.js b/example.js index 8a5345f..675809f 100644 --- a/example.js +++ b/example.js @@ -24,20 +24,19 @@ function sendToAddress(address, amt) { } /* Run this method and monitor memory usage to check there are no memory leaks */ -function checkMemoryLeak() { +async function checkMemoryLeak() { for (let i = 0; i < 50; i++) { - let [wallet, online] = initWallet(); + let [wallet, online] = await initWallet(); rgblib.dropOnline(online); wallet.drop(); } } -function initWallet(vanillaKeychain) { +async function initWallet(vanillaKeychain) { let bitcoinNetwork = rgblib.BitcoinNetwork.Regtest; - let keys = rgblib.generateKeys(bitcoinNetwork); - console.log("Keys: " + JSON.stringify(keys)); + let keys = await rgblib.generateKeys(bitcoinNetwork); - let restoredKeys = rgblib.restoreKeys(bitcoinNetwork, keys.mnemonic); + let restoredKeys = await rgblib.restoreKeys(bitcoinNetwork, keys.mnemonic); console.log("Restored keys: " + JSON.stringify(restoredKeys)); let walletData = { @@ -50,40 +49,49 @@ function initWallet(vanillaKeychain) { vanillaKeychain: vanillaKeychain, }; console.log("Creating wallet..."); - let wallet = new rgblib.Wallet(new rgblib.WalletData(walletData)); + let wallet = await rgblib.Wallet.createInstance( + new rgblib.WalletData(walletData), + ); console.log("Wallet created"); - let btcBalance = wallet.getBtcBalance(null, true); + let btcBalance = await wallet.getBtcBalance(null, true); console.log("BTC balance: " + JSON.stringify(btcBalance)); - let address = wallet.getAddress(); + let address = await wallet.getAddress(); console.log("Address: " + address); sendToAddress(address, 1); console.log("Wallet is going online..."); - let online = wallet.goOnline(false, "tcp://localhost:50001"); + let online = await wallet.goOnline(false, "tcp://localhost:50001"); console.log("Wallet went online"); - btcBalance = wallet.getBtcBalance(online, false); + btcBalance = await wallet.getBtcBalance(online, false); console.log("BTC balance: " + JSON.stringify(btcBalance)); - let created = wallet.createUtxos(online, false, "25", null, "1.0", false); + let created = await wallet.createUtxos( + online, + false, + "25", + null, + "1.0", + false, + ); console.log("Created " + created + " UTXOs"); return [wallet, online]; } -function main() { - let [wallet, online] = initWallet(null); +async function main() { + let [wallet, online] = await initWallet(null); - let asset1 = wallet.issueAssetNIA(online, "USDT", "Tether", "2", [ + let asset1 = await wallet.issueAssetNIA(online, "USDT", "Tether", "2", [ "777", "66", ]); console.log("Issued a NIA asset " + JSON.stringify(asset1)); - let asset2 = wallet.issueAssetCFA( + let asset2 = await wallet.issueAssetCFA( online, "Cfa", "desc", @@ -93,7 +101,7 @@ function main() { ); console.log("Issued a CFA asset: " + JSON.stringify(asset2)); - let asset3 = wallet.issueAssetUDA( + let asset3 = await wallet.issueAssetUDA( online, "TKN", "Token", @@ -104,18 +112,18 @@ function main() { ); console.log("Issued a UDA asset: " + JSON.stringify(asset3)); - let assets1 = wallet.listAssets([ + let assets1 = await wallet.listAssets([ rgblib.AssetSchema.Nia, rgblib.AssetSchema.Cfa, ]); console.log("Assets: " + JSON.stringify(assets1)); - let assets2 = wallet.listAssets([]); + let assets2 = await wallet.listAssets([]); console.log("Assets: " + JSON.stringify(assets2)); - let [rcvWallet, rcvOnline] = initWallet("3"); + let [rcvWallet, rcvOnline] = await initWallet("3"); - let receiveData1 = rcvWallet.blindReceive( + let receiveData1 = await rcvWallet.blindReceive( null, "100", null, @@ -124,7 +132,7 @@ function main() { ); console.log("Receive data: " + JSON.stringify(receiveData1)); - let receiveData2 = rcvWallet.witnessReceive( + let receiveData2 = await rcvWallet.witnessReceive( null, "50", "60", @@ -155,7 +163,7 @@ function main() { ], }; - let sendResult = wallet.send( + let sendResult = await wallet.send( online, recipientMap, false, @@ -165,41 +173,41 @@ function main() { ); console.log("Sent: " + JSON.stringify(sendResult)); - rcvWallet.refresh(rcvOnline, null, [], false); - wallet.refresh(online, null, [], false); + await rcvWallet.refresh(rcvOnline, null, [], false); + await wallet.refresh(online, null, [], false); mine(1); - rcvWallet.refresh(rcvOnline, null, [], false); - wallet.refresh(online, null, [], false); + await rcvWallet.refresh(rcvOnline, null, [], false); + await wallet.refresh(online, null, [], false); - let rcvAssets = rcvWallet.listAssets([]); + let rcvAssets = await rcvWallet.listAssets([]); console.log("Assets: " + JSON.stringify(rcvAssets)); - let rcvAssetBalance = rcvWallet.getAssetBalance(asset1.assetId); + let rcvAssetBalance = await rcvWallet.getAssetBalance(asset1.assetId); console.log("Asset balance: " + JSON.stringify(rcvAssetBalance)); - wallet.sync(online); + await wallet.sync(online); - let transfers = wallet.listTransfers(asset1.assetId); + let transfers = await wallet.listTransfers(asset1.assetId); console.log("Transfers: " + JSON.stringify(transfers)); - let transactions = wallet.listTransactions(online, true); + let transactions = await wallet.listTransactions(online, true); console.log("Transactions: " + JSON.stringify(transactions)); - let unspents = rcvWallet.listUnspents(rcvOnline, false, false); + let unspents = await rcvWallet.listUnspents(rcvOnline, false, false); console.log("Unspents: " + JSON.stringify(unspents)); try { - let feeEstimation = wallet.getFeeEstimation(online, "7"); + let feeEstimation = await wallet.getFeeEstimation(online, "7"); console.log("Fee estimation: " + JSON.stringify(feeEstimation)); } catch (e) { console.log("Error getting fee estimation: " + e); } - let txid = wallet.sendBtc( + let txid = await wallet.sendBtc( online, - rcvWallet.getAddress(), + await rcvWallet.getAddress(), "700", "1.6", false, diff --git a/swig.i b/swig.i index 631cd27..a3e513a 100644 --- a/swig.i +++ b/swig.i @@ -3,31 +3,35 @@ #include "./rgb-lib/bindings/c-ffi/rgblib.hpp" %} -%typemap(out) CResult %{ +%typemap(out) CResult (v8::Local resolver) %{ + resolver = v8::Promise::Resolver::New(v8::Isolate::GetCurrent()->GetCurrentContext()).ToLocalChecked(); switch ($1.result) { case CResultValue::Ok: - $result = SWIG_NewPointerObj((new COpaqueStruct(static_cast< const COpaqueStruct& >($1.inner))), SWIGTYPE_p_COpaqueStruct, SWIG_POINTER_OWN | 0 ); + resolver->Resolve(v8::Isolate::GetCurrent()->GetCurrentContext(), SWIG_NewPointerObj((new COpaqueStruct(static_cast< const COpaqueStruct& >($1.inner))), SWIGTYPE_p_COpaqueStruct, SWIG_POINTER_OWN | 0 )).Check(); break; case CResultValue::Err: - SWIG_V8_Raise((const char*) $1.inner.ptr); + resolver->Reject(v8::Isolate::GetCurrent()->GetCurrentContext(), v8::String::NewFromUtf8(args.GetIsolate(), (const char*) $1.inner.ptr).ToLocalChecked()).Check(); break; } + $result = resolver->GetPromise(); %} -%typemap(out) CResultString %{ +%typemap(out) CResultString (v8::Local resolver) %{ + resolver = v8::Promise::Resolver::New(v8::Isolate::GetCurrent()->GetCurrentContext()).ToLocalChecked(); switch ($1.result) { case CResultValue::Ok: if ($1.inner == nullptr) { - $result = v8::Null(v8::Isolate::GetCurrent()); + resolver->Resolve(v8::Isolate::GetCurrent()->GetCurrentContext(), v8::Null(v8::Isolate::GetCurrent())).Check(); } else { - $result = v8::String::NewFromUtf8(args.GetIsolate(), (const char*) $1.inner).ToLocalChecked(); + resolver->Resolve(v8::Isolate::GetCurrent()->GetCurrentContext(), v8::String::NewFromUtf8(args.GetIsolate(), (const char*) $1.inner).ToLocalChecked()).Check(); delete ($1.inner); } break; case CResultValue::Err: - SWIG_V8_Raise((const char*) $1.inner); + resolver->Reject(v8::Isolate::GetCurrent()->GetCurrentContext(), v8::String::NewFromUtf8(args.GetIsolate(), (const char*) $1.inner).ToLocalChecked()).Check(); break; } + $result = resolver->GetPromise(); %} diff --git a/wrapper.js b/wrapper.js index eed40d0..bad8a03 100644 --- a/wrapper.js +++ b/wrapper.js @@ -167,17 +167,17 @@ exports.dropOnline = function dropOnline(online) { lib.free_online(online); }; -exports.generateKeys = function generateKeys(bitcoinNetwork) { +exports.generateKeys = async function generateKeys(bitcoinNetwork) { validateEnumValues( { bitcoinNetwork }, { bitcoinNetwork: BitcoinNetwork, }, ); - return JSON.parse(lib.rgblib_generate_keys(bitcoinNetwork)); + return JSON.parse(await lib.rgblib_generate_keys(bitcoinNetwork)); }; -exports.restoreKeys = function (bitcoinNetwork, mnemonic) { +exports.restoreKeys = async function (bitcoinNetwork, mnemonic) { validateEnumValues( { bitcoinNetwork }, { @@ -185,7 +185,7 @@ exports.restoreKeys = function (bitcoinNetwork, mnemonic) { }, ); validateTypes({ mnemonic }, { mnemonic: "string" }); - return JSON.parse(lib.rgblib_restore_keys(bitcoinNetwork, mnemonic)); + return JSON.parse(await lib.rgblib_restore_keys(bitcoinNetwork, mnemonic)); }; exports.WalletData = class WalletData { @@ -208,8 +208,13 @@ exports.WalletData = class WalletData { }; exports.Wallet = class Wallet { - constructor(walletData) { - this.wallet = lib.rgblib_new_wallet(JSON.stringify(walletData)); + constructor(wallet) { + this.wallet = wallet; + } + + static async createInstance(walletData) { + const wallet = await lib.rgblib_new_wallet(JSON.stringify(walletData)); + return new Wallet(wallet); } drop() { @@ -217,7 +222,7 @@ exports.Wallet = class Wallet { this.wallet = null; } - blindReceive( + async blindReceive( assetId, amount, durationSeconds, @@ -240,7 +245,7 @@ exports.Wallet = class Wallet { }; validateTypes(params, expectedTypes); return JSON.parse( - lib.rgblib_blind_receive( + await lib.rgblib_blind_receive( this.wallet, assetId, amount, @@ -251,7 +256,7 @@ exports.Wallet = class Wallet { ); } - createUtxos(online, upTo, num, size, feeRate, skipSync) { + async createUtxos(online, upTo, num, size, feeRate, skipSync) { const params = { online, upTo, num, size, feeRate, skipSync }; const expectedTypes = { online: "object", @@ -262,7 +267,7 @@ exports.Wallet = class Wallet { skipSync: "boolean", }; validateTypes(params, expectedTypes); - return lib.rgblib_create_utxos( + return await lib.rgblib_create_utxos( this.wallet, online, upTo, @@ -273,20 +278,22 @@ exports.Wallet = class Wallet { ); } - getAddress() { - return lib.rgblib_get_address(this.wallet); + async getAddress() { + return await lib.rgblib_get_address(this.wallet); } - getAssetBalance(assetId) { + async getAssetBalance(assetId) { const params = { assetId }; const expectedTypes = { assetId: "string", }; validateTypes(params, expectedTypes); - return JSON.parse(lib.rgblib_get_asset_balance(this.wallet, assetId)); + return JSON.parse( + await lib.rgblib_get_asset_balance(this.wallet, assetId), + ); } - getBtcBalance(online, skipSync) { + async getBtcBalance(online, skipSync) { const params = { online, skipSync }; const expectedTypes = { online: "object?", @@ -294,35 +301,35 @@ exports.Wallet = class Wallet { }; validateTypes(params, expectedTypes); return JSON.parse( - lib.rgblib_get_btc_balance(this.wallet, online, skipSync), + await lib.rgblib_get_btc_balance(this.wallet, online, skipSync), ); } - getFeeEstimation(online, blocks) { + async getFeeEstimation(online, blocks) { const params = { online, blocks }; const expectedTypes = { online: "object", blocks: "u16", }; validateTypes(params, expectedTypes); - return lib.rgblib_get_fee_estimation(this.wallet, online, blocks); + return await lib.rgblib_get_fee_estimation(this.wallet, online, blocks); } - goOnline(skipConsistencyCheck, electrumUrl) { + async goOnline(skipConsistencyCheck, electrumUrl) { const params = { skipConsistencyCheck, electrumUrl }; const expectedTypes = { skipConsistencyCheck: "boolean", electrumUrl: "string", }; validateTypes(params, expectedTypes); - return lib.rgblib_go_online( + return await lib.rgblib_go_online( this.wallet, skipConsistencyCheck, electrumUrl, ); } - issueAssetCFA(online, name, details, precision, amounts, filePath) { + async issueAssetCFA(online, name, details, precision, amounts, filePath) { const params = { online, name, @@ -341,7 +348,7 @@ exports.Wallet = class Wallet { }; validateTypes(params, expectedTypes); return JSON.parse( - lib.rgblib_issue_asset_cfa( + await lib.rgblib_issue_asset_cfa( this.wallet, online, name, @@ -353,7 +360,7 @@ exports.Wallet = class Wallet { ); } - issueAssetNIA(online, ticker, name, precision, amounts) { + async issueAssetNIA(online, ticker, name, precision, amounts) { const params = { online, ticker, @@ -369,7 +376,7 @@ exports.Wallet = class Wallet { }; validateTypes(params, expectedTypes); return JSON.parse( - lib.rgblib_issue_asset_nia( + await lib.rgblib_issue_asset_nia( this.wallet, online, ticker, @@ -380,7 +387,7 @@ exports.Wallet = class Wallet { ); } - issueAssetUDA( + async issueAssetUDA( online, ticker, name, @@ -409,7 +416,7 @@ exports.Wallet = class Wallet { }; validateTypes(params, expectedTypes); return JSON.parse( - lib.rgblib_issue_asset_uda( + await lib.rgblib_issue_asset_uda( this.wallet, online, ticker, @@ -422,7 +429,7 @@ exports.Wallet = class Wallet { ); } - listAssets(filterAssetSchemas) { + async listAssets(filterAssetSchemas) { const params = { filterAssetSchemas, }; @@ -431,14 +438,14 @@ exports.Wallet = class Wallet { }; validateTypes(params, expectedTypes); return JSON.parse( - lib.rgblib_list_assets( + await lib.rgblib_list_assets( this.wallet, JSON.stringify(filterAssetSchemas), ), ); } - listTransactions(online, skipSync) { + async listTransactions(online, skipSync) { const params = { online, skipSync }; const expectedTypes = { online: "object", @@ -446,11 +453,11 @@ exports.Wallet = class Wallet { }; validateTypes(params, expectedTypes); return JSON.parse( - lib.rgblib_list_transactions(this.wallet, online, skipSync), + await lib.rgblib_list_transactions(this.wallet, online, skipSync), ); } - listTransfers(assetId) { + async listTransfers(assetId) { const params = { assetId, }; @@ -458,10 +465,12 @@ exports.Wallet = class Wallet { assetId: "string", }; validateTypes(params, expectedTypes); - return JSON.parse(lib.rgblib_list_transfers(this.wallet, assetId)); + return JSON.parse( + await lib.rgblib_list_transfers(this.wallet, assetId), + ); } - listUnspents(online, settledOnly, skipSync) { + async listUnspents(online, settledOnly, skipSync) { const params = { online, settledOnly, @@ -474,7 +483,7 @@ exports.Wallet = class Wallet { }; validateTypes(params, expectedTypes); return JSON.parse( - lib.rgblib_list_unspents( + await lib.rgblib_list_unspents( this.wallet, online, settledOnly, @@ -483,7 +492,7 @@ exports.Wallet = class Wallet { ); } - refresh(online, assetId, filter, skipSync) { + async refresh(online, assetId, filter, skipSync) { const params = { online, assetId, @@ -498,7 +507,7 @@ exports.Wallet = class Wallet { }; validateTypes(params, expectedTypes); return JSON.parse( - lib.rgblib_refresh( + await lib.rgblib_refresh( this.wallet, online, assetId, @@ -508,7 +517,14 @@ exports.Wallet = class Wallet { ); } - send(online, recipientMap, donation, feeRate, minConfirmations, skipSync) { + async send( + online, + recipientMap, + donation, + feeRate, + minConfirmations, + skipSync, + ) { const params = { online, recipientMap, @@ -527,7 +543,7 @@ exports.Wallet = class Wallet { }; validateTypes(params, expectedTypes); return JSON.parse( - lib.rgblib_send( + await lib.rgblib_send( this.wallet, online, JSON.stringify(recipientMap), @@ -539,7 +555,7 @@ exports.Wallet = class Wallet { ); } - sendBtc(online, address, amount, feeRate, skipSync) { + async sendBtc(online, address, amount, feeRate, skipSync) { const params = { online, address, @@ -555,7 +571,7 @@ exports.Wallet = class Wallet { skipSync: "boolean", }; validateTypes(params, expectedTypes); - return lib.rgblib_send_btc( + return await lib.rgblib_send_btc( this.wallet, online, address, @@ -565,16 +581,16 @@ exports.Wallet = class Wallet { ); } - sync(online) { + async sync(online) { const params = { online }; const expectedTypes = { online: "object", }; validateTypes(params, expectedTypes); - lib.rgblib_sync(this.wallet, online); + await lib.rgblib_sync(this.wallet, online); } - witnessReceive( + async witnessReceive( assetId, amount, durationSeconds, @@ -597,7 +613,7 @@ exports.Wallet = class Wallet { }; validateTypes(params, expectedTypes); return JSON.parse( - lib.rgblib_witness_receive( + await lib.rgblib_witness_receive( this.wallet, assetId, amount,