feat: Initial non working code

This commit is contained in:
Nathan Woodburn 2025-01-30 14:25:13 +11:00
commit ee94bc4f7d
Signed by: nathanwoodburn
GPG Key ID: 203B000478AD0EF1
6 changed files with 1440 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

209
atomic-swap.js Normal file
View File

@ -0,0 +1,209 @@
'use strict';
const assert = require('bsert');
const Network = require('hsd/lib/protocol/network');
const FullNode = require('hsd/lib/node/fullnode');
const MTX = require('hsd/lib/primitives/mtx');
const Address = require('hsd/lib/primitives/address');
const Output = require('hsd/lib/primitives/output');
const Script = require('hsd/lib/script/script');
const rules = require('hsd/lib/covenants/rules');
const {types} = rules;
const {Resource} = require('hsd/lib/dns/resource');
// const WalletClient = require('hsd/lib/client/wallet');
const { NodeClient, WalletClient } = require('hs-client');
const network = Network.get('main');
const minimist = require('minimist');
const args = minimist(process.argv.slice(2));
//! TODO this needs to hook into existing node
// const node = new FullNode({
// memory: true,
// network: 'main'
// });
const nclient = new NodeClient({
url: args.hsdIP || 'localhost',
apiKey: args.apiKey || '',
ssl: false,
host: args.hsdIP || 'localhost',
port: 12037
});
const wclient = new WalletClient({
url: args.hsdIP || 'localhost',
apiKey: args.apiKey || '',
ssl: false,
host: args.hsdIP || 'localhost',
port: 12039,
});
nclient.open();
wclient.open();
// const {wdb} = wclient.require('walletdb');
const price = args.price/1000000 || 1.234567; // 1.234567 HNS
const domainAddress = args.domainAddress || 'hs1qsyy6eujpt2wv0caa0d26tvwejx77zdks2pj8nz';
const buyerAddress = args.buyer || 'hs1qcq8nzmlus8z5qqn6wvls9r0vg98tr6d6ga3fau';
const sellerAddress = args.seller || 'hs1q962sf24659wm6ev26gshrfwg8ruhve4c34f0ur';
const ns = args.nameInfo || {"name": "woodburn1","nameHash": "c93640a7772f786391c1c3ff2e99e4aaa442b6f2cf1fc6ec1790f2ea818dec08","state": "CLOSED","height": 175454,"renewal": 252162,"owner": {"hash": "337edb6e00aaf602a218d35d499b088872d2e74b9463066da845edccbe797c27","index": 4},"value": 1000000,"highest": 1000000,"data": "0001036e733108776f6f646275726e0001036e7332c006060204546573740548656c6c6f","transfer": 0,"revoked": 0,"claimed": 0,"renewals": 4,"registered": true,"expired": false,"weak": false,"stats": {"renewalPeriodStart": 252162,"renewalPeriodEnd": 357282,"blocksUntilExpire": 95192,"daysUntilExpire": 661.06}};
const walletId = args.walletId || 'hot';
const name = ns.name;
const nameHash = ns.nameHash;
// Alice constructs an incomplete transaction.
// input 0 and output 1 are committed by Alice's SINGLEREVERSE signature.
// output 0 can be added by either party since it's construction is
// dictated completely by consensus rules (it isn't signed yet).
//
// input 0: TRANSFER UTXO --> output 0: FINALIZE covenant
// (null) --- output 1: payment to Alice
const owner = ns.owner;
wclient.execute('selectwallet', [walletId]);
const coin = wclient.getCoin(owner.hash, owner.index);
const output0 = new Output();
output0.value = coin.value;
output0.address = buyerAddress;
output0.covenant.setFinalize(
nameHash,
ns.height,
Buffer.from(name, 'ascii'),
0, // flags, may be required if name was CLAIMed
ns.claimed,
ns.renewals,
wdb.getRenewalBlock()
);
const output1 = new Output();
output1.address = sellerAddress;
output1.value = price;
const mtx = new MTX();
mtx.addCoin(coin);
mtx.outputs.push(output0);
mtx.outputs.push(output1);
// Sign
const rings = wclient.deriveInputs(mtx);
assert(rings.length === 1);
const signed = mtx.sign(
rings,
Script.hashType.SINGLEREVERSE | Script.hashType.ANYONECANPAY
);
assert(signed === 1);
assert(mtx.verify());
blob = mtx.encode().toString('hex');
console.log(blob);
// COMPLETE TX
// it('should complete transaction', async () => {
// // Bob receives the hex string as a blob and decodes.
// const mtx = MTX.decode(Buffer.from(blob, 'hex'));
// // Bob should verify all the data in the MTX to ensure everything is valid,
// // but this is the minimum.
// const input0 = mtx.input(0).clone(); // copy input with Alice's signature
// const coinEntry = await nclient.chain.db.readCoin(input0.prevout);
// assert(coinEntry); // ensures that coin exists and is still unspent
// const coin = coinEntry.toCoin(input0.prevout);
// assert(coin.covenant.type === types.TRANSFER);
// const addr = new Address({
// version: coin.covenant.items[2].readInt8(),
// hash: coin.covenant.items[3]
// });
// assert.deepStrictEqual(addr, bobReceive); // transfer is to Bob's address
// // Fund the TX.
// // The hsd wallet is not designed to handle partially-signed TXs
// // or coins from outside the wallet, so a little hacking is needed.
// const changeAddress = await bob.changeAddress();
// const rate = await wdb.estimateFee();
// const coins = await bob.getSmartCoins();
// // Add the external coin to the coin selector so we don't fail assertions
// coins.push(coin);
// await mtx.fund(coins, {changeAddress, rate});
// // The funding mechanism starts by wiping out existing inputs
// // which for us includes Alice's signature. Replace it from our backup.
// mtx.inputs[0].inject(input0);
// // Rearrange outputs.
// // Since we added a change output, the SINGELREVERSE is now broken:
// //
// // input 0: TRANSFER UTXO --> output 0: FINALIZE covenant
// // input 1: Bob's funds --- output 1: payment to Alice
// // (null) --- output 2: change to Bob
// const outputs = mtx.outputs.slice();
// mtx.outputs = [outputs[0], outputs[2], outputs[1]];
// // Prepare to wait for mempool acceptance (race condition)
// const waiter = new Promise((resolve, reject) => {
// node.mempool.once('tx', resolve);
// });
// // Sign & Broadcast
// // Bob uses SIGHASHALL. The final TX looks like this:
// //
// // input 0: TRANSFER UTXO --> output 0: FINALIZE covenant
// // input 1: Bob's funds --- output 1: change to Bob
// // (null) --- output 2: payment to Alice
// const tx = await bob.sendMTX(mtx);
// bobFee = tx.getFee(mtx.view);
// assert(tx.verify(mtx.view));
// // Wait for mempool and check
// await waiter;
// assert(node.mempool.hasEntry(tx.hash()));
// // Confirm
// await mineBlocks(1);
// });
// it('should verify that name has been swapped', async () => {
// const aliceNewBalance = await alice.getBalance();
// const bobNewBalance = await bob.getBalance();
// // Alice got the monies
// // Note: This test works right now because the value of the name
// // Alice won in the auction is ZERO (she had the only bid)
// // See https://github.com/handshake-org/hsd/pull/464 for explanation
// // Currently hsd wallet does not account for FINALIZE correctly
// assert.strictEqual(
// aliceNewBalance.confirmed,
// aliceOriginalBalance.confirmed + price
// );
// assert.strictEqual(
// bobNewBalance.confirmed,
// bobOriginalBalance.confirmed - price - bobFee
// );
// // Bob got the name
// const ns = await node.getNameStatus(nameHash);
// const owner = ns.owner;
// let coin = await alice.getCoin(owner.hash, owner.index);
// assert(!coin);
// coin = await bob.getCoin(owner.hash, owner.index);
// assert(coin);
// const resource = Resource.fromJSON({
// records: [{type: 'TXT', txt: ['Thanks Alice! --Bob']}]
// });
// await bob.sendUpdate(name, resource);
// await mineBlocks(network.names.treeInterval);
// const actual = await node.chain.db.getNameState(nameHash);
// assert.bufferEqual(resource.encode(), actual.data);
// // The End
// });

35
domain.json Normal file
View File

@ -0,0 +1,35 @@
{
"start": {
"reserved": false,
"week": 12,
"start": 14112,
"locked": false
},
"info": {
"name": "woodburn1",
"nameHash": "c93640a7772f786391c1c3ff2e99e4aaa442b6f2cf1fc6ec1790f2ea818dec08",
"state": "CLOSED",
"height": 175454,
"renewal": 252162,
"owner": {
"hash": "337edb6e00aaf602a218d35d499b088872d2e74b9463066da845edccbe797c27",
"index": 4
},
"value": 1000000,
"highest": 1000000,
"data": "0001036e733108776f6f646275726e0001036e7332c006060204546573740548656c6c6f",
"transfer": 0,
"revoked": 0,
"claimed": 0,
"renewals": 4,
"registered": true,
"expired": false,
"weak": false,
"stats": {
"renewalPeriodStart": 252162,
"renewalPeriodEnd": 357282,
"blocksUntilExpire": 95192,
"daysUntilExpire": 661.06
}
}
}

654
hsd-ledger Executable file
View File

@ -0,0 +1,654 @@
#!/usr/bin/env node
'use strict';
/**
* Module imports
*/
const Config = require('bcfg');
const { NodeClient, WalletClient } = require('hs-client');
const { hd, MTX, Network } = require('hsd');
const { Rules } = require('hsd/lib/covenants');
const { hashName, types } = Rules;
const { util, HID, LedgerHSD, LedgerChange, LedgerCovenant } = require('..');
const { Device } = HID;
// Import from renewal.js the functions to fetch domains and create a batch
const { fetchDomains, createBatch } = require('./renewal.js');
/**
* Global constants
*/
const VALID_CMDS = [
'createwallet',
'createaccount',
'createaddress',
'sendtoaddress',
'getwallets',
'getaccounts',
'getaccount',
'getbalance',
'sendraw',
'signraw',
'renew'
];
const VERSION = require('../package').version;
async function createWallet(client, config, ledger, args) {
if (args.length !== 1)
throw new Error('Invalid arguments');
const id = args[0];
const index = config.uint('account-index');
const xpub = await ledger.getAccountXPUB(index);
const wallet = await client.createWallet(id, {
watchOnly: true,
accountKey: xpub.xpubkey(config.str('network'))
});
console.log(`Created wallet (id=hsd-ledger, wid=${wallet.wid}).`);
console.log(`Created account (name=default, account-index=${index}').`);
}
async function createAccount(client, config, ledger, args) {
if (args.length !== 2)
throw new Error('Invalid arguments');
const id = config.str('wallet-id');
const name = args[0];
const index = parseInt(args[1], 10);
const xpub = await ledger.getAccountXPUB(index);
await client.createAccount(id, name, {
watchOnly: true,
accountKey: xpub.xpubkey(config.str('network'))
});
console.log(`Created account (name=${name}, account-index=${index}').`);
}
async function createAddress(client, config, ledger, args) {
if (args.length !== 0)
throw new Error('Invalid arguments');
const id = config.str('wallet-id');
const name = config.str('account-name');
const addr = await client.createAddress(id, name);
const acct = await client.getAccount(id, name);
const xpub = hd.PublicKey.fromBase58(acct.accountKey, config.str('network'));
const account = (xpub.childIndex ^ hd.common.HARDENED) >>> 0;
console.log(`Verify address on Ledger device: ${addr.address}`);
await ledger.getAddress(account, addr.branch, addr.index, { confirm: true });
}
async function sendToAddress(wclient, nclient, config, ledger, args) {
if (args.length !== 2)
throw new Error('Invalid arguments');
const network = Network.get(config.str('network'));
const id = config.str('wallet-id');
const acct = config.str('account-name');
const address = args[0];
const amount = parseFloat(args[1]);
await wclient.execute('selectwallet', [id]);
const params = [address, amount, '', '', false, acct];
const json = await wclient.execute('createsendtoaddress', params);
const mtx = MTX.fromJSON(json);
let i, key;
for (i = mtx.outputs.length - 1; i >= 0; i--) {
const output = mtx.outputs[i];
const addr = output.address.toString(network.type);
key = await wclient.getKey(id, addr);
if (key && key.branch)
break;
}
if (!key || !key.branch)
throw new Error('Expected change address.');
const { account, branch, index } = key;
const coinType = network.keyPrefix.coinType;
const options = {
change: new LedgerChange({
path: `m/44'/${coinType}'/${account}'/${branch}/${index}`,
index: i,
version: 0
})
};
util.displayDetails(console, network, mtx, options);
const signed = await ledger.signTransaction(mtx, options);
const rawtx = signed.encode().toString('hex');
const txid = await nclient.execute('sendrawtransaction', [rawtx]);
console.log(`Submitted TXID: ${txid}`);
}
async function sendRaw(wclient, nclient, config, ledger, args) { // Create a function to sign raw transactions
if (args.length !== 2) // Make sure there are two arguments (batch, names)
throw new Error('Invalid arguments'); // Throw an error if there are not two arguments
const network = Network.get(config.str('network')); // Get the network
const id = config.str('wallet-id'); // Get the wallet id
const acct = config.str('account-name'); // Get the account name
// Log the arguments to the console (for debugging)
const batch = JSON.parse(args[0]); // Get the batch
const names = JSON.parse(args[1]); // Get the names
await wclient.execute('selectwallet', [id]); // Select the wallet
try {
const mtx = MTX.fromJSON(batch.result); // Create a new MTX from the JSON
const hashes = {}; // Create an empty object to store the hashes
for (const name of names) { // Loop through the names
const hash = hashName(name); // Hash the name
hashes[hash] = name; // Add the hash to the hashes object to use later
}
let i, key; // Create variables to use later
const options = []; // Create an empty array to store the options
for (i = mtx.outputs.length - 1; i >= 0; i--) { // Loop through the outputs
const output = mtx.outputs[i]; // Get the output
const addr = output.address.toString(network.type); // Get the address
key = await wclient.getKey(id, addr); // Get the key
if (!key) // If there is no key
continue; // Continue to the next output
if (key.branch === 1) { // If the key is a change address
if (options.change) // If there is already a change address
throw new Error('Transaction should only have one change output.'); // Throw an error
const path = `m/44'/${network.keyPrefix.coinType}'/${key.account}'/${key.branch}/${key.index}`; // Create the derivation path
options.change = new LedgerChange({ path: `m/44'/${network.keyPrefix.coinType}'/${key.account}'/${key.branch}/${key.index}`, index: i, version: 0 }); // Add the change address to the options
}
const { account, branch, index } = key; // Get the account, branch, and index from the key
const coinType = network.keyPrefix.coinType; // Get the coin type from the network
switch (output.covenant.type) {
case types.NONE:
case types.BID:
case types.FINALIZE:
break;
case types.OPEN:
case types.REVEAL:
case types.REDEEM:
case types.REGISTER:
case types.UPDATE:
case types.RENEW:
case types.TRANSFER:
case types.REVOKE: { // If the covenant type is any of REVEAL, REDEEM, REGISTER, UPDATE, RENEW, TRANSFER, or REVOKE
if (options.covenants == null) // If there are no covenants
options.covenants = []; // Create an empty array for the covenants
const hash = output.covenant.items[0]; // Get the hash from the covenant
const name = hashes[hash]; // Get the name from the hashes object (is needed for SPV nodes)
if (name == undefined) { // If the name is not found
console.log("Name not found in file"); // Log that the name was not found
console.log(hash); // Log the hash (for debugging)
}
options.covenants.push(new LedgerCovenant({ index: i, name })); // Add the covenant to the options
break;
}
default:
throw new Error('Unrecognized covenant type.');
}
} // end for loop
util.displayDetails(console, network, mtx, options); // Display the details to the log for user verification
const signed = await ledger.signTransaction(mtx, options); // Sign the transaction with the ledger
const rawtx = signed.encode().toString('hex'); // Encode the transaction as hex
const txid = await nclient.execute('sendrawtransaction', [rawtx]); // Send the transaction to the network
console.log(`Submitted TXID: ${txid}`); // Log the TXID to the console to view the transaction on a block explorer
} catch (err) { // Catch any errors
console.error(err); // Log the error to the console
}
}
async function renew(wclient, nclient, config, ledger, args) { // Create a function to sign raw transactions
if (args.length !== 1) // Make sure there are two arguments (batch, names)
throw new Error('Invalid arguments'); // Throw an error if there are not two arguments
const network = Network.get(config.str('network')); // Get the network
const id = config.str('wallet-id'); // Get the wallet id
const acct = config.str('account-name'); // Get the account name
// Log the arguments to the console (for debugging)
const type = args[0]; // Get the batch type
var batch; // Create a variable to store the batch
var names
if (type === 'all') {
names = await fetchDomains(id,0); // Fetch the domains
console.log(names.length);
if (names.length === 0) {
console.log("No domains to renew");
return;
}
}
else {
const days = parseInt(type, 10); // Get the number of days
names = await fetchDomains(id,days); // Fetch the domains
}
console.log("Renewing domains: ", names.length);
if (names.length === 0) {
console.log("No domains to renew");
return;
}
batch = await createBatch(names); // Create the batch
await wclient.execute('selectwallet', [id]); // Select the wallet
try {
const mtx = MTX.fromJSON(batch.result); // Create a new MTX from the JSON
const hashes = {}; // Create an empty object to store the hashes
for (const name of names) { // Loop through the names
const hash = hashName(name); // Hash the name
hashes[hash] = name; // Add the hash to the hashes object to use later
}
let i, key; // Create variables to use later
const options = []; // Create an empty array to store the options
for (i = mtx.outputs.length - 1; i >= 0; i--) { // Loop through the outputs
const output = mtx.outputs[i]; // Get the output
const addr = output.address.toString(network.type); // Get the address
key = await wclient.getKey(id, addr); // Get the key
if (!key) // If there is no key
continue; // Continue to the next output
if (key.branch === 1) { // If the key is a change address
if (options.change) // If there is already a change address
throw new Error('Transaction should only have one change output.'); // Throw an error
const path = `m/44'/${network.keyPrefix.coinType}'/${key.account}'/${key.branch}/${key.index}`; // Create the derivation path
options.change = new LedgerChange({ path: `m/44'/${network.keyPrefix.coinType}'/${key.account}'/${key.branch}/${key.index}`, index: i, version: 0 }); // Add the change address to the options
}
const { account, branch, index } = key; // Get the account, branch, and index from the key
const coinType = network.keyPrefix.coinType; // Get the coin type from the network
switch (output.covenant.type) {
case types.NONE:
case types.BID:
case types.FINALIZE:
break;
case types.OPEN:
case types.REVEAL:
case types.REDEEM:
case types.REGISTER:
case types.UPDATE:
case types.RENEW:
case types.TRANSFER:
case types.REVOKE: { // If the covenant type is any of REVEAL, REDEEM, REGISTER, UPDATE, RENEW, TRANSFER, or REVOKE
if (options.covenants == null) // If there are no covenants
options.covenants = []; // Create an empty array for the covenants
const hash = output.covenant.items[0]; // Get the hash from the covenant
const name = hashes[hash]; // Get the name from the hashes object (is needed for SPV nodes)
if (name == undefined) { // If the name is not found
console.log("Name not found in file"); // Log that the name was not found
console.log(hash); // Log the hash (for debugging)
}
options.covenants.push(new LedgerCovenant({ index: i, name })); // Add the covenant to the options
break;
}
default:
throw new Error('Unrecognized covenant type.');
}
} // end for loop
util.displayDetails(console, network, mtx, options); // Display the details to the log for user verification
const signed = await ledger.signTransaction(mtx, options); // Sign the transaction with the ledger
const rawtx = signed.encode().toString('hex'); // Encode the transaction as hex
const txid = await nclient.execute('sendrawtransaction', [rawtx]); // Send the transaction to the network
console.log(`Submitted TXID: ${txid}`); // Log the TXID to the console to view the transaction on a block explorer
} catch (err) { // Catch any errors
console.error(err); // Log the error to the console
}
}
async function signRaw(wclient, nclient, config, ledger, args) { // Create a function to sign raw transactions
if (args.length !== 2) // Make sure there are two arguments (batch, names)
throw new Error('Invalid arguments'); // Throw an error if there are not two arguments
const network = Network.get(config.str('network')); // Get the network
const id = config.str('wallet-id'); // Get the wallet id
const acct = config.str('account-name'); // Get the account name
// Log the arguments to the console (for debugging)
const batch = JSON.parse(args[0]); // Get the batch
const names = JSON.parse(args[1]); // Get the names
await wclient.execute('selectwallet', [id]); // Select the wallet
try {
const mtx = MTX.fromJSON(batch.result); // Create a new MTX from the JSON
const hashes = {}; // Create an empty object to store the hashes
for (const name of names) { // Loop through the names
const hash = hashName(name); // Hash the name
hashes[hash] = name; // Add the hash to the hashes object to use later
}
let i, key; // Create variables to use later
const options = []; // Create an empty array to store the options
for (i = mtx.outputs.length - 1; i >= 0; i--) { // Loop through the outputs
const output = mtx.outputs[i]; // Get the output
const addr = output.address.toString(network.type); // Get the address
key = await wclient.getKey(id, addr); // Get the key
if (!key) // If there is no key
continue; // Continue to the next output
if (key.branch === 1) { // If the key is a change address
if (options.change) // If there is already a change address
throw new Error('Transaction should only have one change output.'); // Throw an error
const path = `m/44'/${network.keyPrefix.coinType}'/${key.account}'/${key.branch}/${key.index}`; // Create the derivation path
options.change = new LedgerChange({ path: `m/44'/${network.keyPrefix.coinType}'/${key.account}'/${key.branch}/${key.index}`, index: i, version: 0 }); // Add the change address to the options
}
const { account, branch, index } = key; // Get the account, branch, and index from the key
const coinType = network.keyPrefix.coinType; // Get the coin type from the network
switch (output.covenant.type) {
case types.NONE:
case types.BID:
case types.FINALIZE:
break;
case types.OPEN:
case types.REVEAL:
case types.REDEEM:
case types.REGISTER:
case types.UPDATE:
case types.RENEW:
case types.TRANSFER:
case types.REVOKE: { // If the covenant type is any of REVEAL, REDEEM, REGISTER, UPDATE, RENEW, TRANSFER, or REVOKE
if (options.covenants == null) // If there are no covenants
options.covenants = []; // Create an empty array for the covenants
const hash = output.covenant.items[0]; // Get the hash from the covenant
const name = hashes[hash]; // Get the name from the hashes object (is needed for SPV nodes)
if (name == undefined) { // If the name is not found
console.log("Name not found in file"); // Log that the name was not found
console.log(hash); // Log the hash (for debugging)
}
options.covenants.push(new LedgerCovenant({ index: i, name })); // Add the covenant to the options
break;
}
default:
throw new Error('Unrecognized covenant type.');
}
} // end for loop
util.displayDetails(console, network, mtx, options); // Display the details to the log for user verification
const signed = await ledger.signTransaction(mtx, options); // Sign the transaction with the ledger
console.log(signed); // Log the TX to the console
} catch (err) { // Catch any errors
console.error(err); // Log the error to the console
}
}
async function getWallets(client, args) {
if (args.length)
throw new Error('Too many arguments');
const wallets = await client.getWallets();
console.log(wallets);
}
async function getAccounts(client, config, args) {
if (args.length)
throw new Error('Too many arguments');
const id = config.str('wallet-id');
const accounts = await client.getAccounts(id);
console.log(accounts);
}
async function getAccount(client, config, args) {
if (args.length !== 1)
throw new Error('Invalid arguments');
const id = config.str('wallet-id');
const name = args[0];
const account = await client.getAccount(id, name);
console.log(account);
}
async function getBalance(client, config, args) {
if (args.length !== 0)
throw new Error('Invalid arguments');
const id = config.str('wallet-id');
const name = config.str('account-name');
const balance = await client.getBalance(id, name);
console.log(balance);
}
async function main() {
const device = await Device.requestDevice();
device.set({
timeout: 300000 // 5 minutes.
});
await device.open();
const config = new Config('hsd', {
suffix: 'network',
fallback: 'main',
alias: {
'h': 'help',
'i': 'accountindex',
'a': 'accountname',
'n': 'network',
'p': 'projectsponsor',
'q': 'qrcode',
'k': 'showkey',
'w': 'walletid'
}
});
config.load({
argv: true,
env: true
});
config.inject({
accountIndex: 0,
accountName: 'default',
network: 'main',
walletId: 'hsd-ledger',
token: ''
});
const argv = config.argv;
const cmd = argv.shift();
const args = argv;
const type = config.str('network');
const network = Network.get(type);
const id = config.str('wallet-id');
const token = config.str('token');
if (config.str('help') && argv.length === 0) {
usage();
process.exit(0);
}
if (config.str('version') && argv.length === 0) {
version();
process.exit(0);
}
const ledger = new LedgerHSD({
device: device,
network: type
});
const nclient = new NodeClient({
url: config.str('url') || config.str('node-url'),
apiKey: config.str('api-key') || config.str('node-api-key'),
ssl: config.bool('ssl') || config.str('node-ssl'),
host: config.str('http-host') || config.str('node-http-host'),
port: config.uint('node-http-port') || network.rpcPort
});
const wclient = new WalletClient({
url: config.str('url') || config.str('wallet-url'),
apiKey: config.str('api-key') || config.str('wallet-api-key'),
ssl: config.bool('ssl') || config.bool('wallet-ssl'),
host: config.str('http-host') || config.str('wallet-http-host'),
port: config.uint('wallet-http-port') || network.walletPort,
token
});
await nclient.open();
await wclient.open();
try {
const wallets = await wclient.getWallets();
if (!wallets.includes(id)) {
if (id !== 'hsd-ledger')
throw new Error(`Wallet "${id}" does not exist.`);
console.log('Default hsd-ledger wallet not detected.');
await createWallet(wclient, config, ledger, [id]);
}
switch (cmd) {
case VALID_CMDS[0]:
await createWallet(wclient, config, ledger, args);
break;
case VALID_CMDS[1]:
await createAccount(wclient, config, ledger, args);
break;
case VALID_CMDS[2]:
await createAddress(wclient, config, ledger, args);
break;
case VALID_CMDS[3]:
await sendToAddress(wclient, nclient, config, ledger, args);
break;
case VALID_CMDS[4]:
await getWallets(wclient, args);
break;
case VALID_CMDS[5]:
await getAccounts(wclient, config, args);
break;
case VALID_CMDS[6]:
await getAccount(wclient, config, args);
break;
case VALID_CMDS[7]:
await getBalance(wclient, config, args);
break;
case VALID_CMDS[8]:
await sendRaw(wclient, nclient, config, ledger, args);
break;
case VALID_CMDS[9]:
await signRaw(wclient, nclient, config, ledger, args);
break;
case VALID_CMDS[10]:
await renew(wclient, nclient, config, ledger, args);
break;
default:
usage(new Error('Must provide valid command.'));
process.exit(1);
break;
}
} catch (e) {
throw (e);
} finally {
await wclient.close();
await nclient.close();
await device.close();
}
process.exit(0);
}
/**
* Displays application version.
*/
function version() {
console.log(`hsd-ledger v${VERSION}`);
console.log('');
}
/**
* Displays usage or error message.
* @param {String|Error} err - the error message or object
*/
function usage(err) {
if (err) {
console.error(`${err.stack}`);
console.error('');
return;
}
console.log('usage:');
console.log(' $ hsd-ledger createwallet <wallet-id>');
console.log(' $ hsd-ledger createaccount <account-name> <account-index>');
console.log(' $ hsd-ledger createaddress');
console.log(' $ hsd-ledger sendtoaddress <address> <amount>');
console.log(' $ hsd-ledger getwallets');
console.log(' $ hsd-ledger getaccounts');
console.log(' $ hsd-ledger getaccount <account-name>');
console.log(' $ hsd-ledger getbalance');
console.log('');
console.log('options:');
console.log(' --help');
console.log(' --version');
console.log(' -n, --network <id> (default "main")');
console.log(' -w, --wallet-id <id> (default "hsd-ledger")');
console.log(' -a, --account-name <name> (default "default")');
console.log(' -i, --account-index <index> (default 0)');
console.log('');
console.log('The following options configure the node and wallet clients:');
console.log(' --ssl');
console.log(' --url <url>');
console.log(' --api-key <api-key>');
console.log(' --host <host> (default "localhost")');
console.log('');
console.log('The following options configure the node client only:');
console.log(' --node-ssl');
console.log(' --node-url <url>');
console.log(' --node-api-key <api-key>');
console.log(' --node-host <host> (default "localhost")');
console.log(' --node-port <port> (default 14037)');
console.log('');
console.log('The following options configure the wallet client only:');
console.log(' --wallet-ssl');
console.log(' --wallet-url <url>');
console.log(' --wallet-api-key <api-key>');
console.log(' --wallet-host <host> (default "localhost")');
console.log(' --wallet-port <port> (default 14039)');
console.log('');
}
/*
* Execute
*/
main().catch((err) => {
usage(err);
process.exit(1);
});

521
package-lock.json generated Normal file
View File

@ -0,0 +1,521 @@
{
"name": "atomic-swap",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "atomic-swap",
"version": "1.0.0",
"license": "AGPL-3.0-only",
"dependencies": {
"hs-client": "^7.0.0",
"hsd": "^7.0.1",
"minimist": "^1.2.8"
}
},
"node_modules/@handshake-org/bfilter": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@handshake-org/bfilter/-/bfilter-2.3.0.tgz",
"integrity": "sha512-vTKTVJvLHz2knpdnYMT0idb6R+HlOCbYKlw2L9Bk9oKOAXwjOIFUp6hnZKIVb87rYW8eEfUROrFG3+DcYwxm7w==",
"license": "MIT",
"dependencies": {
"bcrypto": "~5.4.0",
"bsert": "~0.0.12",
"bufio": "~1.2.1"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bcfg": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/bcfg/-/bcfg-0.2.2.tgz",
"integrity": "sha512-xa7hYK8ZgEV/Wjh+EJiKLLd+h8A0HGyhyntNMvKCeXIGepLqKUL3KYOE5zFz8EBv8sS3XruD5YPmYIjtwFOrZA==",
"license": "MIT",
"dependencies": {
"bsert": "~0.0.12"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/bcrypto": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/bcrypto/-/bcrypto-5.4.0.tgz",
"integrity": "sha512-KDX2CR29o6ZoqpQndcCxFZAtYA1jDMnXU3jmCfzP44g++Cu7AHHtZN/JbrN/MXAg9SLvtQ8XISG+eVD9zH1+Jg==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"bufio": "~1.0.7",
"loady": "~0.0.5"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bcrypto/node_modules/bufio": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/bufio/-/bufio-1.0.7.tgz",
"integrity": "sha512-bd1dDQhiC+bEbEfg56IdBv7faWa6OipMs/AFFFvtFnB3wAYjlwQpQRZ0pm6ZkgtfL0pILRXhKxOiQj6UzoMR7A==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bcurl": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/bcurl/-/bcurl-0.2.1.tgz",
"integrity": "sha512-7L00pT9SQEDzRIsRn53Il5pYHkeFlIoH0SdNIAbXdqsUMnq4IteTRuSZwC2f/uUKiRE5oW40MBhW72mquO9sQg==",
"license": "MIT",
"dependencies": {
"brq": "~0.1.10",
"bsert": "~0.0.12",
"bsock": "~0.1.10"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bdb": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/bdb/-/bdb-1.6.2.tgz",
"integrity": "sha512-3PxLeNKqwdqMjc/Ox5hontemGFt/AXGQsrEHFA0bynISfqhYI8r1qQNtJHEMonD6kcvkejfLA/5ad3n813kmdw==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"bsert": "~0.0.13",
"loady": "~0.0.5"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/bdns": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/bdns/-/bdns-0.1.5.tgz",
"integrity": "sha512-LNVkfM7ynlAD0CvPvO9cKxW8YXt1KOCRQZlRsGZWeMyymUWVdHQpZudAzH9chaFAz6HiwAnQxwDemCKDPy6Mag==",
"license": "MIT",
"dependencies": {
"bsert": "~0.0.10"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bevent": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/bevent/-/bevent-0.1.6.tgz",
"integrity": "sha512-vu1MYZIbZhz8s4/QDuqJ06L8BloELnMJxf/bGfp5ifqNpKpdCvgDw3ymsyzu27JJinDiGvx775V5NnTmWR7tFA==",
"license": "MIT",
"dependencies": {
"bsert": "~0.0.12"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bfile": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/bfile/-/bfile-0.2.3.tgz",
"integrity": "sha512-BhbmCLqDC+u8rPSeB/I8bRC8luQoUt+wD326CECXYXtE5GyTWL/q/OkNp58aH7XEREguEItvqM18s9vXLvg6fw==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bheep": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/bheep/-/bheep-0.1.6.tgz",
"integrity": "sha512-u44Xgb0Rr+Y/1chKqiUSY44mpBCglDxnapyfA6mssbJE+C7iyAPY4r8WMPqmdvZPYk7EU3ogbt4pKDItDMU87A==",
"license": "MIT",
"dependencies": {
"bsert": "~0.0.12"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/binet": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/binet/-/binet-0.3.9.tgz",
"integrity": "sha512-htptPuT5YTTRThIQAuWyCo+rIvXwAC+CrUq40ldhKHBPbZoMb76SBkI8NtvLkWussJr+lnR5Mc0rh1dpNBrBPg==",
"license": "MIT",
"dependencies": {
"bs32": "~0.1.7",
"bsert": "~0.0.12"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/blgr": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/blgr/-/blgr-0.2.1.tgz",
"integrity": "sha512-ShNWkj8qxjf0JEwDt1h675Lgx9EV8a2lRWVWtZrptqg/tIrISv0TM7s+NVNXEwyIlQYYIu4lQqjlGRYWUn4g5Q==",
"license": "MIT",
"dependencies": {
"bsert": "~0.0.12"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/blru": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/blru/-/blru-0.1.8.tgz",
"integrity": "sha512-9KsgRzBHx4GOJ48bRy0IZf42+f3nAhgAeeuWX5KBditHVqnCFL0ownd1QRr0aJVot7qlKEUYGPfM/tGHW6A3zw==",
"license": "MIT",
"dependencies": {
"bsert": "~0.0.12"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/blst": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/blst/-/blst-0.1.6.tgz",
"integrity": "sha512-P88SBVTdjKsvltTGXPayu9ACSZ36CNpECE8eZjPg+Mj++EB/VHOFUAnVIZ142NceSWYkVMBKiVENH49YHKHjFg==",
"license": "MIT",
"dependencies": {
"bsert": "~0.0.12"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bmutex": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/bmutex/-/bmutex-0.1.8.tgz",
"integrity": "sha512-NEI6oawCTA9hobAIubvpooRkq7hp+dBg0hf1KUJ3uV77PrXlUgLXr6D/mr6+sfJ0hx523lDaz/vEcJIbK9S1uw==",
"license": "MIT",
"dependencies": {
"bsert": "~0.0.13"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bns": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/bns/-/bns-0.15.0.tgz",
"integrity": "sha512-iJWQVE399vQzPfhalFMJGEQ7k5Ot2D6Mz8dkoPeLO8huWAMOiJNJ1tHzOu5j+ZyNNew6ITgG/LsSyaRPxvkXuw==",
"license": "MIT",
"dependencies": {
"bcrypto": "~5.4.0",
"bfile": "~0.2.2",
"bheep": "~0.1.5",
"binet": "~0.3.6",
"bs32": "~0.1.6",
"bsert": "~0.0.10",
"btcp": "~0.1.5",
"budp": "~0.1.6",
"bufio": "~1.0.7"
},
"bin": {
"bns-keygen": "bin/bns-keygen",
"bns-prove": "bin/bns-prove",
"dig.js": "bin/dig.js",
"dig2json": "bin/dig2json",
"json2dig": "bin/json2dig",
"json2rr": "bin/json2rr",
"json2zone": "bin/json2zone",
"named.js": "bin/named.js",
"rr2json": "bin/rr2json",
"whois.js": "bin/whois.js",
"zone2json": "bin/zone2json"
},
"engines": {
"node": ">=8.0.0"
},
"optionalDependencies": {
"unbound": "~0.4.3"
}
},
"node_modules/bns/node_modules/bufio": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/bufio/-/bufio-1.0.7.tgz",
"integrity": "sha512-bd1dDQhiC+bEbEfg56IdBv7faWa6OipMs/AFFFvtFnB3wAYjlwQpQRZ0pm6ZkgtfL0pILRXhKxOiQj6UzoMR7A==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/brq": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/brq/-/brq-0.1.10.tgz",
"integrity": "sha512-iil4TtQWw9Wb2G+mEP0iHqM8Q16mHINJzR5wHTsfKZTtcOVoEGj6yX3ed7yLQ92KR4QO9KjlrlO7/Y7766i7Tw==",
"license": "MIT",
"dependencies": {
"bsert": "~0.0.12"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bs32": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/bs32/-/bs32-0.1.7.tgz",
"integrity": "sha512-I0aKZCBneFTkcVNUIALzsOevqPIF93ynGPX6wj6pXmIBpXVGCqTgdvMx2QyR/NwgOIqMLH++Ovyum28abVG6QA==",
"license": "MIT",
"dependencies": {
"bsert": "~0.0.10"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bsert": {
"version": "0.0.13",
"resolved": "https://registry.npmjs.org/bsert/-/bsert-0.0.13.tgz",
"integrity": "sha512-gYzSj8I2lDTKvl4aRSYs2CZIpeJugq7RjGhLRG+Jl//gEW5B2u1MKB6exVCL09FqYj6JRQAAgRwQHMOWvr7A8A==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bsock": {
"version": "0.1.11",
"resolved": "https://registry.npmjs.org/bsock/-/bsock-0.1.11.tgz",
"integrity": "sha512-4COhlKKBfOQOomNvz1hjoPtN5ytpqbxkuCPvIPbYMvaZwNBKpo8dZa1LJjcN3wuAkjIIJLF/fc4o3e1DYiceQw==",
"license": "MIT",
"dependencies": {
"bsert": "~0.0.12"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bsocks": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/bsocks/-/bsocks-0.2.6.tgz",
"integrity": "sha512-66UkjoB9f7lhT+WKgYq8MQa6nkr96mlX64JYMlIsXe/X4VeqNwvsx7UOE3ZqD6lkwg8GvBhapRTWj0qWO3Pw8w==",
"license": "MIT",
"dependencies": {
"binet": "~0.3.5",
"bsert": "~0.0.10"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/btcp": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/btcp/-/btcp-0.1.5.tgz",
"integrity": "sha512-tkrtMDxeJorn5p0KxaLXELneT8AbfZMpOFeoKYZ5qCCMMSluNuwut7pGccLC5YOJqmuk0DR774vNVQLC9sNq/A==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/budp": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/budp/-/budp-0.1.6.tgz",
"integrity": "sha512-o+a8NPq3DhV91j4nInjht2md6mbU1XL+7ciPltP66rw5uD3KP1m5r8lA94LZVaPKcFdJ0l2HVVzRNxnY26Pefg==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/buffer-map": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/buffer-map/-/buffer-map-0.0.8.tgz",
"integrity": "sha512-RlxrBAk98CqJdwSPgXOWYbC85xuq4H4vyGmW68BJ9IAGkCHQKC+flavb+d3LGxiDluczbTG8NhgKBRllpFGurA==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bufio": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/bufio/-/bufio-1.2.3.tgz",
"integrity": "sha512-5Tt66bRzYUSlVZatc0E92uDenreJ+DpTBmSAUwL4VSxJn3e6cUyYwx+PoqML0GRZatgA/VX8ybhxItF8InZgqA==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bupnp": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/bupnp/-/bupnp-0.2.6.tgz",
"integrity": "sha512-J6ykzJhZMxXKN78K+1NzFi3v/51X2Mvzp2hW42BWwmxIVfau6PaN99gyABZ8x05e8MObWbsAis23gShhj9qpbw==",
"license": "MIT",
"dependencies": {
"binet": "~0.3.5",
"brq": "~0.1.7",
"bsert": "~0.0.10"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bval": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/bval/-/bval-0.1.8.tgz",
"integrity": "sha512-38WQyq94sgKaJbHSmkOwZqba6Ac0KIKPO0SMDNg/mCcwUos2NIrMg5Bb2LkzIer+RzS186IYusNeSrJrKdaqhA==",
"license": "MIT",
"dependencies": {
"bsert": "~0.0.10"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/bweb": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/bweb/-/bweb-0.2.0.tgz",
"integrity": "sha512-JfpXemYqylNySwrhR7b4HZTrxnDhbOzNiIXCPBVQU6O8rTZ1wFDLFDr/7uQqkwzjyNZ4ZWTp5wP/pJY2IizfDA==",
"license": "MIT",
"dependencies": {
"bsert": "~0.0.10",
"bsock": "~0.1.9"
},
"bin": {
"bweb": "bin/bweb"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/goosig": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/goosig/-/goosig-0.10.0.tgz",
"integrity": "sha512-+BVVLfxmawAmGVjjJpXzu5LNcFIOfgXgP7kWEyc3qu/xn9RMqbPbNfYDdHBZKfZkDMIO7Q4vD790iNYQAXhoFA==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"bcrypto": "~5.4.0",
"bsert": "~0.0.10",
"loady": "~0.0.5"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/hs-client": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/hs-client/-/hs-client-7.0.0.tgz",
"integrity": "sha512-vynmtC9pfMC6zTqg5mcnTlM6BTvjtID0P3Y9wQZUPoiE4zAfAyucfBlc6QJ5pK3o+fKmDQnrIZ/g2GoySGR3dQ==",
"license": "MIT",
"dependencies": {
"bcfg": "~0.2.2",
"bcurl": "~0.2.1",
"bsert": "~0.0.13"
},
"bin": {
"hsd-cli": "bin/hsd-cli",
"hsd-rpc": "bin/hsd-rpc",
"hsw-cli": "bin/hsw-cli",
"hsw-rpc": "bin/hsw-rpc"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/hsd": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/hsd/-/hsd-7.0.1.tgz",
"integrity": "sha512-5zju8h08RYENrmFZ5jBsclGt3VC5mH3s/TmNHNtc/EwuOaYnydyY+BfSiNPIaEsBsKVWgcXkb+8btigoB7CGbQ==",
"license": "MIT",
"dependencies": {
"@handshake-org/bfilter": "~2.3.0",
"bcfg": "~0.2.2",
"bcrypto": "~5.4.0",
"bcurl": "~0.2.1",
"bdb": "~1.6.1",
"bdns": "~0.1.5",
"bevent": "~0.1.6",
"bfile": "~0.2.3",
"bheep": "~0.1.6",
"binet": "~0.3.9",
"blgr": "~0.2.1",
"blru": "~0.1.8",
"blst": "~0.1.6",
"bmutex": "~0.1.7",
"bns": "~0.15.0",
"bsert": "~0.0.13",
"bsock": "~0.1.11",
"bsocks": "~0.2.6",
"btcp": "~0.1.5",
"buffer-map": "~0.0.8",
"bufio": "~1.2.2",
"bupnp": "~0.2.6",
"bval": "~0.1.8",
"bweb": "~0.2.0",
"goosig": "~0.10.0",
"n64": "~0.2.10",
"urkel": "~1.0.3"
},
"bin": {
"hs-seeder": "bin/hs-seeder",
"hs-wallet": "bin/hsw",
"hsd": "bin/hsd",
"hsd-cli": "bin/hsd-cli",
"hsd-node": "bin/node",
"hsd-rpc": "bin/hsd-rpc",
"hsd-spvnode": "bin/spvnode",
"hsw-cli": "bin/hsw-cli",
"hsw-rpc": "bin/hsw-rpc"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/loady": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/loady/-/loady-0.0.5.tgz",
"integrity": "sha512-uxKD2HIj042/HBx77NBcmEPsD+hxCgAtjEWlYNScuUjIsh/62Uyu39GOR68TBR68v+jqDL9zfftCWoUo4y03sQ==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/n64": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/n64/-/n64-0.2.10.tgz",
"integrity": "sha512-uH9geV4+roR1tohsrrqSOLCJ9Mh1iFcDI+9vUuydDlDxUS1UCAWUfuGb06p3dj3flzywquJNrGsQ7lHP8+4RVQ==",
"license": "MIT",
"engines": {
"node": ">=2.0.0"
}
},
"node_modules/unbound": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/unbound/-/unbound-0.4.3.tgz",
"integrity": "sha512-2ISqZLXtzp1l9f1V8Yr6S+zuhXxEwE1CjKHjXULFDHJcfhc9Gm3mn19hdPp4rlNGEdCivKYGKjYe3WRGnafYdA==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"dependencies": {
"loady": "~0.0.5"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/urkel": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/urkel/-/urkel-1.0.3.tgz",
"integrity": "sha512-L2M46WWSaz1LpyUYFgnQg7WSOWtNcRx3uH+4GwHK1jbmYj6phLuIwirTVMlhfcZ0o/CWn5Y04UWLhmlvijZiDg==",
"license": "MIT",
"dependencies": {
"bfile": "~0.2.1",
"bmutex": "~0.1.6",
"bsert": "~0.0.10"
},
"engines": {
"node": ">=8.0.0"
}
}
}
}

20
package.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "atomic-swap",
"version": "1.0.0",
"description": "Atomic Swap tools",
"main": "atomic-swap.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://git.woodburn.au/nathanwoodburn/atomic-swap.git"
},
"author": "Nathan.Woodburn/",
"license": "AGPL-3.0-only",
"dependencies": {
"hs-client": "^7.0.0",
"hsd": "^7.0.1",
"minimist": "^1.2.8"
}
}