Comparing version 1.4.0-1 to 1.4.0-2
@@ -10,2 +10,5 @@ #!/usr/bin/env node | ||
let Dashcore = require("@dashevo/dashcore-lib"); | ||
let Transaction = Dashcore.Transaction; | ||
let dashsightBaseUrl = | ||
@@ -18,83 +21,8 @@ process.env.DASHSIGHT_BASE_URL || "https://insight.dash.org/insight-api"; | ||
insightBaseUrl: dashsightBaseUrl, | ||
dashsightBaseUrl: "", // not needed here | ||
dashsightBaseUrl: dashsightBaseUrl, | ||
dashsocketBaseUrl: "", // not needed here | ||
}); | ||
let Base58Check = require("@dashincubator/base58check").Base58Check; | ||
let b58c = Base58Check.create({ | ||
pubKeyHashVersion: "4c", | ||
privateKeyVersion: "cc", | ||
}); | ||
let DashTx = require("dashtx"); | ||
let RIPEMD160 = require("@dashincubator/ripemd160"); | ||
let Secp256k1 = require("@dashincubator/secp256k1"); | ||
//@ts-ignore | ||
let Crypto = exports.crypto || require("../shims/crypto-node.js"); | ||
let Pub = require("./_wif-to-addr.js"); | ||
/** | ||
* @param {import('dashtx').TxSignOpts} opts | ||
*/ | ||
async function signTx({ privateKey, hash }) { | ||
let sigOpts = { canonical: true }; | ||
let sigBuf = await Secp256k1.sign(hash, privateKey, sigOpts); | ||
return sigBuf; | ||
} | ||
/** | ||
* @param {import('dashtx').TxPrivateKey} privBuf | ||
*/ | ||
function toPublicKey(privBuf) { | ||
let isCompressed = true; | ||
let pubBuf = Secp256k1.getPublicKey(privBuf, isCompressed); | ||
return pubBuf; | ||
} | ||
/** | ||
* @param {import('dashtx').TxPublicKey} pubBuf | ||
*/ | ||
async function hashPublicKey(pubBuf) { | ||
let sha = await Crypto.subtle.digest("SHA-256", pubBuf); | ||
let shaU8 = new Uint8Array(sha); | ||
let ripemd = RIPEMD160.create(); | ||
let hash = ripemd.update(shaU8); | ||
let pkh = hash.digest("hex"); | ||
return pkh; | ||
} | ||
/** | ||
* @param {String} wif | ||
* @returns {Promise<Uint8Array>} | ||
*/ | ||
async function wifToPrivateKey(wif) { | ||
let parts = await b58c.verify(wif); | ||
let privBuf = Buffer.from(parts.privateKey, "hex"); | ||
return privBuf; | ||
} | ||
/** | ||
* @param {String} wif | ||
* @returns {Promise<String>} | ||
*/ | ||
async function wifToAddr(wif) { | ||
let parts = await b58c.verify(wif); | ||
let privBuf = Buffer.from(parts.privateKey, "hex"); | ||
let isCompressed = true; | ||
let pubBuf = Secp256k1.getPublicKey(privBuf, isCompressed); | ||
let pubKeyHash = await hashPublicKey(pubBuf); | ||
let addr = await b58c.encode({ | ||
version: "4c", | ||
pubKeyHash: pubKeyHash, | ||
}); | ||
return addr; | ||
} | ||
/** | ||
* @param {String} addr - base58check | ||
* @returns {Promise<String>} - pubKeyHash as hex | ||
*/ | ||
async function addrToPubKeyHash(addr) { | ||
let parts = await b58c.verify(addr); | ||
return parts.pubKeyHash; | ||
} | ||
async function main() { | ||
@@ -104,3 +32,3 @@ let addrs = process.argv.slice(2); | ||
if (2 !== addrs.length) { | ||
console.error(`Usage: create-tx <wif> <pay-addr>`); | ||
console.error(`Usage: create-tx <wif> <payaddr>`); | ||
process.exit(1); | ||
@@ -111,3 +39,3 @@ return; | ||
let wifpath = addrs[0]; | ||
let payAddr = addrs[1]; | ||
let payaddr = addrs[1]; | ||
@@ -119,10 +47,9 @@ console.info(); | ||
let source = await wifToAddr(wif); | ||
let source = await Pub.wifToAddr(wif); | ||
console.info(`Source: ${source}`); | ||
console.info(`Destination: ${payAddr}`); | ||
console.info(`Destination: ${payaddr}`); | ||
console.info(); | ||
let insightUtxos = await dashsight.getUtxos(source); | ||
let coreUtxos = Dashsight.toCoreUtxos(insightUtxos); | ||
let hasUtxos = coreUtxos.length > 0; | ||
let utxos = await dashsight.getUtxos(source); | ||
let hasUtxos = utxos.length > 0; | ||
if (!hasUtxos) { | ||
@@ -134,11 +61,17 @@ console.error(`'${source}' is completely spent`); | ||
let coreUtxo = coreUtxos[0]; | ||
let key = await wifToPrivateKey(wif); | ||
let duffs = toDuffs(coreUtxo.satoshis); | ||
let dash = toDash(coreUtxo.satoshis); | ||
let utxo = utxos[0]; | ||
let duffs = toDuffs(utxo.satoshis); | ||
let dash = toDash(utxo.satoshis); | ||
console.info(`First Unspent Tx: ${dash} (${duffs})`); | ||
// max bytes for single tx with both bigint pads is 193 | ||
let fee = 193; | ||
let coreUtxo = { | ||
txId: utxo.txid, | ||
outputIndex: utxo.vout, | ||
address: utxo.address, | ||
script: utxo.scriptPubKey, | ||
satoshis: utxo.satoshis, | ||
}; | ||
let fee = 191; | ||
let feeDash = toDash(fee); | ||
@@ -148,40 +81,16 @@ let feeDuffs = toDuffs(fee); | ||
let units = coreUtxo.satoshis - fee; | ||
let amountDash = toDash(units); | ||
let amountDuffs = toDuffs(units); | ||
let amount = coreUtxo.satoshis - fee; | ||
let amountDash = toDash(amount); | ||
let amountDuffs = toDuffs(amount); | ||
console.info(`Payment Amount: ${amountDash} (${amountDuffs})`); | ||
let keys = [key]; | ||
let inputs = [coreUtxo]; | ||
let pubKeyHash = await addrToPubKeyHash(payAddr); | ||
let outputs = [{ pubKeyHash, units }]; | ||
let txInfo = { | ||
version: 3, // (will be) optional | ||
inputs: inputs, | ||
outputs: outputs, | ||
// TODO any sort of minimum fee guessing? | ||
locktime: 0, // optional | ||
}; | ||
//@ts-ignore - no input required, actually | ||
let tx = new Transaction() | ||
//@ts-ignore - allows single value or array | ||
.from([coreUtxo]); | ||
tx.to(payaddr, amount); | ||
tx.fee(fee); | ||
tx.sign(wif); | ||
let dashTx = DashTx.create({ | ||
version: 3, | ||
//@ts-ignore | ||
sign: signTx, | ||
//@ts-ignore | ||
getPrivateKey: async function (txInput, i) { | ||
let privKey = keys[i]; | ||
return privKey; | ||
}, | ||
//@ts-ignore | ||
getPublicKey: async function (txInput, i) { | ||
let privKey = keys[i]; | ||
let pubKey = toPublicKey(privKey); | ||
return pubKey; | ||
}, | ||
}); | ||
//@ts-ignore | ||
let txInfoSigned = await dashTx.hashAndSignAll(txInfo, keys); | ||
let txHex = txInfoSigned.transaction.toString(); | ||
let txHex = tx.toString(); | ||
console.info(); | ||
@@ -188,0 +97,0 @@ console.info(txHex); |
@@ -8,4 +8,11 @@ (function (exports) { | ||
//@ts-ignore | ||
const dashfetch = exports.__dashsight_fetch || require('./dashfetch.js') | ||
/** | ||
* @type {RequestInit} defaultOpts | ||
*/ | ||
const defaultOpts = { | ||
headers: { | ||
'Accept': 'application/json', | ||
'Content-Type': 'application/json' | ||
}, | ||
} | ||
@@ -77,3 +84,3 @@ const DUFFS = 100000000; | ||
let txUrl = `${insightBaseUrl}/addr/${address}/?noTxList=1`; | ||
let txResp = await dashfetch(txUrl); | ||
let txResp = await Dashsight.fetch(txUrl); | ||
@@ -109,3 +116,3 @@ /** @type {InsightBalance} */ | ||
let utxoUrl = `${insightBaseUrl}/addr/${address}/utxo`; | ||
let utxoResp = await dashfetch(utxoUrl); | ||
let utxoResp = await Dashsight.fetch(utxoUrl); | ||
@@ -132,3 +139,3 @@ /** @type Array<InsightUtxo> */ | ||
let txUrl = `${insightBaseUrl}/tx/${txid}`; | ||
let txResp = await dashfetch(txUrl); | ||
let txResp = await Dashsight.fetch(txUrl); | ||
@@ -143,3 +150,3 @@ /** @type InsightTx */ | ||
let txUrl = `${insightBaseUrl}/txs?address=${addr}&pageNum=0`; | ||
let txResp = await dashfetch(txUrl); | ||
let txResp = await Dashsight.fetch(txUrl); | ||
@@ -161,3 +168,3 @@ /** @type {InsightTxResponse} */ | ||
for (let cursor = 1; cursor < pagesTotal; cursor += 1) { | ||
let nextResp = await dashfetch( | ||
let nextResp = await Dashsight.fetch( | ||
`${insightBaseUrl}/txs?address=${addr}&pageNum=${cursor}`); | ||
@@ -179,4 +186,8 @@ nextResp = await nextResp.json(); | ||
let instUrl = `${dashsightBaseUrl}/tx/sendix`; | ||
let txResp = await dashfetch(instUrl, { | ||
let txResp = await Dashsight.fetch(instUrl, { | ||
method: "POST", | ||
body: { | ||
// @ts-ignore | ||
rawtx: hexTx, | ||
} | ||
}); | ||
@@ -201,8 +212,9 @@ if (!txResp.ok) { | ||
/** @type {ToCoreUtxo} */ | ||
insight.toCoreUtxo = Dashsight.toCoreUtxo; | ||
/** @type {ToCoreUtxos} */ | ||
insight.toCoreUtxos = Dashsight.toCoreUtxos; | ||
insight.toCoreUtxos = function (insightUtxos) { | ||
let coreUtxos = insightUtxos.map(insight.toCoreUtxo); | ||
return coreUtxos; | ||
}; | ||
/** | ||
@@ -281,19 +293,24 @@ * Handles UTXOs that have NO MORE THAN ONE page of transactions | ||
/** @type {ToCoreUtxo} */ | ||
Dashsight.toCoreUtxo = function (utxo) { | ||
return { | ||
txId: utxo.txid, | ||
outputIndex: utxo.vout, | ||
address: utxo.address, | ||
script: utxo.scriptPubKey, | ||
satoshis: utxo.satoshis, | ||
}; | ||
}; | ||
/** | ||
* @param {String | URL | Request} url | ||
* @param {RequestInit} [opts] | ||
*/ | ||
Dashsight.fetch = async function dashfetch(url, opts) { | ||
opts = Object.assign({}, defaultOpts, opts) | ||
if (opts.body) { | ||
opts.body = JSON.stringify(opts.body) | ||
} | ||
/** @type {ToCoreUtxos} */ | ||
Dashsight.toCoreUtxos = function (insightUtxos) { | ||
let coreUtxos = insightUtxos.map(Dashsight.toCoreUtxo); | ||
let resp = await fetch(url, opts); | ||
if (resp.ok) { | ||
return resp; | ||
} | ||
return coreUtxos; | ||
}; | ||
let err = new Error( | ||
`http request was ${resp.status}, not ok. See err.response for details.`, | ||
); | ||
// @ts-ignore | ||
err.response = resp.json(); | ||
throw err; | ||
} | ||
@@ -303,5 +320,5 @@ if ("undefined" !== typeof module) { | ||
module.exports.create = Dashsight.create; | ||
module.exports.toCoreUtxo = Dashsight.toCoreUtxo; | ||
module.exports.toCoreUtxos = Dashsight.toCoreUtxos; | ||
module.exports.Dashfetch = Dashsight.fetch; | ||
} | ||
})(("undefined" !== typeof module && module.exports) || window); |
{ | ||
"name": "dashsight", | ||
"version": "1.4.0-1", | ||
"version": "1.4.0-2", | ||
"description": "SDK for Dash's flavor of the Insight API", | ||
"main": "index.js", | ||
"browser": { | ||
"./ws/index.js": "./dashsocket.js", | ||
"crypto": false | ||
"./ws/index.js": "./dashsocket.js" | ||
}, | ||
@@ -21,3 +20,3 @@ "bin": { | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"bump": "npm version -m \"chore(release): bump to v%s\"" | ||
"version": "npm version -m \"chore(release): bump to v%s\"" | ||
}, | ||
@@ -57,10 +56,11 @@ "files": [ | ||
"dependencies": { | ||
"dashtx": "^0.9.0-3" | ||
"@root/request": "^1.9.2" | ||
}, | ||
"devDependencies": { | ||
"@dashincubator/base58check": "^1.3.1", | ||
"@dashincubator/ripemd160": "^2.3.0", | ||
"@dashincubator/secp256k1": "^1.7.1-1", | ||
"@types/tough-cookie": "^4.0.2" | ||
"@dashevo/dashcore-lib": "^0.19.44", | ||
"@root/base58check": "^1.0.0", | ||
"@types/tough-cookie": "^4.0.2", | ||
"ripemd160": "^2.0.2", | ||
"secp256k1": "^4.0.3" | ||
} | ||
} |
@@ -21,4 +21,3 @@ # [dashsight.js](https://github.com/dashhive/dashsight.js) | ||
let dashsightBaseUrl = | ||
process.env.DASHSIGHT_BASE_URL || | ||
"https://dashsight.dashincubator.dev/insight-api"; | ||
process.env.DASHSIGHT_BASE_URL || "https://dashsight.dashincubator.dev/insight-api"; | ||
let dashsocketBaseUrl = | ||
@@ -43,4 +42,2 @@ process.env.DASHSOCKET_BASE_URL || "https://insight.dash.org/socket.io"; | ||
```html | ||
<script src="https://unpkg.com/@root/request@1.9.2/urequest.js"></script> | ||
<script src="https://unpkg.com/dashsight@1.2.0/dashrequest.js"></script> | ||
<script src="https://unpkg.com/dashsight@1.2.0/dashsight.js"></script> | ||
@@ -267,4 +264,3 @@ <script src="https://unpkg.com/dashsight@1.2.0/dashsocket.js"></script> | ||
Gets all unspent transaction outputs (the usable "coins") for the given address, | ||
including all information needed by `DashTx#hashAndSignAll()` (and | ||
`dashcore-lib.Transaction`). | ||
including all information needed by `dashcore-lib.Transaction`. | ||
@@ -307,41 +303,5 @@ ```js | ||
```js | ||
"use strict"; | ||
let Dashcore = require("@dashevo/dashcore-lib"); | ||
let Transaction = Dashcore.Transaction; | ||
let DashTx = require("dashtx"); | ||
let dashTx = DashTx.create({ | ||
version: 3, | ||
sign: signTx, | ||
toPublicKey: toPublicKey, | ||
addrToPubKeyHash: addrToPubKeyHash, | ||
}); | ||
async function signTx({ privateKey, hash }) { | ||
let sigOpts = { canonical: true }; | ||
let sigBuf = await Secp256k1.sign(hash, privateKey, sigOpts); | ||
return sigBuf; | ||
} | ||
async function toPublicKey(privKeyBuf) { | ||
let Secp256k1 = require("@dashincubator/secp256k1"); | ||
let isCompressed = true; | ||
let pubBuf = Secp256k1.getPublicKey(privKeyBuf, isCompressed); | ||
return pubBuf; | ||
} | ||
async function addrToPubKeyHash(addr) { | ||
let Base58Check = require("@dashincubator/base58check").Base58Check; | ||
let b58c = Base58Check.create({ | ||
pubKeyHashVersion: "4c", | ||
privateKeyVersion: "cc", | ||
}); | ||
let parts = await b58c.verify(addr); | ||
return parts.pubKeyHash; | ||
} | ||
// keys that correspond to the available utxos | ||
let privateKeys = { | ||
XmCyQ6qARLWXap74QubFMunngoiiA1QgCL: "YOUR_PRIVATE_KEY_HERE", | ||
}; | ||
let coreUtxos = [ | ||
@@ -361,15 +321,14 @@ { | ||
let txInfo = { | ||
inputs: coreUtxos, | ||
outputs: payments, | ||
}; | ||
let privateKeys = [ | ||
// keys that correspond to the available utxos | ||
"YOUR_KEY_HERE", | ||
]; | ||
let keys = coreUtxos.map(function (utxo) { | ||
let privHex = privateKeys[utxo.address]; | ||
let privBuf = Tx.utils.hexToU8(privHex); | ||
return privBuf; | ||
}); | ||
let tx = dashTx.hashAndSignAll(txInfo, keys); | ||
let tx = new Transaction(); | ||
tx.from(coreUtxos); | ||
tx.to(payments); | ||
tx.change(changeAddr); | ||
tx.sign(privateKeys); | ||
let txHex = tx.transaction; | ||
let txHex = tx.serialize(); | ||
@@ -376,0 +335,0 @@ let result = await dashsight.instantSend(txHex); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
67128
5
19
2003
352
4
+ Added@root/request@^1.9.2
+ Added@root/request@1.9.2(transitive)
- Removeddashtx@^0.9.0-3
- Removeddashtx@0.9.0(transitive)