melis-fork-claimer
Advanced tools
Comparing version 0.5.8 to 1.0.0
@@ -6,3 +6,3 @@ { | ||
"license": "ISC", | ||
"version": "0.5.8", | ||
"version": "1.0.0", | ||
"main": "src/index.js", | ||
@@ -26,4 +26,4 @@ "scripts": { | ||
"dependencies": { | ||
"melis-api-js": "^0.11.20" | ||
"melis-api-js": "^0.12.1" | ||
} | ||
} |
@@ -18,2 +18,4 @@ // | ||
const BSV_MIGRATED_ACCOUNT_NAME = "BSV Claimed Coins" | ||
const FORKS = { | ||
@@ -97,2 +99,10 @@ BCD: { | ||
}, | ||
BSV: { | ||
fork: 478558, | ||
name: "Bitcoin SV", | ||
bip143: true, | ||
signtype: 0x41, | ||
signid: 0x41, | ||
insightApi: "https://bchsvexplorer.com/api/" | ||
} | ||
/* | ||
@@ -227,3 +237,3 @@ B2X: { | ||
const aa = u.aa | ||
u.key = melis.deriveMyHdAccount(account.num, aa.chain, aa.hdindex, account.coin) | ||
u.key = melis.deriveAddressKey(account.num, aa.chain, aa.hdindex) | ||
}) | ||
@@ -433,5 +443,15 @@ } | ||
static getCoins() { | ||
return Object.keys(FORKS) | ||
return Object.keys(FORKS).filter(c => c !== 'BSV') | ||
} | ||
static accountsForPrinting(accounts) { | ||
let res = "#Accounts: " + Object.keys(accounts).length | ||
Object.keys(accounts).forEach(pubId => { | ||
const a = accounts[pubId] | ||
const name = a.meta ? a.meta.name : "[no name]" | ||
res += "\n" + pubId + " " + a.coin + " " + a.type + " " + name | ||
}) | ||
return res | ||
} | ||
getCoin() { | ||
@@ -590,6 +610,2 @@ return this.claimedCoin | ||
hashForSignature_legacy(ins, inIndex, inScript, outs, hashType) { | ||
if (ins.length !== 1) | ||
throw ("Only one input supported in hashForSignature_legacy") | ||
const txIn = ins[0] | ||
const buffer = Buffer.allocUnsafe(2000) | ||
@@ -637,8 +653,12 @@ let offset = 0 | ||
// Number of inputs | ||
writeVarInt(1) | ||
writeVarInt(ins.length) | ||
writeSlice(txIn.hash) | ||
writeUInt32(txIn.index) | ||
writeVarSlice(inScript) | ||
writeUInt32(Bitcoin.Transaction.DEFAULT_SEQUENCE) | ||
for (let i = 0; i < ins.length; i++) { | ||
const txIn = ins[i] | ||
writeSlice(txIn.hash) | ||
writeUInt32(txIn.index) | ||
if (i == inIndex) | ||
writeVarSlice(inScript) | ||
writeUInt32(Bitcoin.Transaction.DEFAULT_SEQUENCE) | ||
} | ||
@@ -707,3 +727,3 @@ // ins.forEach(function (txIn) { | ||
toffset = 0 | ||
ins.forEach(function (txIn) { | ||
ins.forEach(txIn => { | ||
writeSlice(txIn.hash) | ||
@@ -717,18 +737,18 @@ writeUInt32(txIn.index) | ||
toffset = 0 | ||
ins.forEach(function (txIn) { | ||
writeUInt32(txIn.sequence) | ||
}) | ||
ins.forEach(txIn => writeUInt32(txIn.sequence)) | ||
const hashSequence = bcrypto.hash256(tbuffer) | ||
// hashOutputs | ||
const txOutsSize = outs.reduce(function (sum, output) { | ||
return sum + 8 + varSliceSize(output.script) | ||
const txOutsSize = outs.reduce(function (sum, out) { | ||
return sum + 8 + varSliceSize(out.script) | ||
}, 0) | ||
tbuffer = Buffer.allocUnsafe(txOutsSize) | ||
toffset = 0 | ||
outs.forEach(function (out) { | ||
outs.forEach(out => { | ||
writeUInt64(out.value) | ||
writeVarSlice(out.script) | ||
//console.log("[REMOVEME] out amount: " + out.value + " script: " + out.script.toString('hex')); | ||
}) | ||
//console.log("[REMOVEME] outputsToHash: " + tbuffer.toString('hex')); | ||
const hashOutputs = bcrypto.hash256(tbuffer) | ||
@@ -741,9 +761,14 @@ | ||
writeSlice(hashPrevouts) | ||
//console.log("[REMOVEME] getPrevoutHash: " + hashPrevouts.toString('hex')); | ||
writeSlice(hashSequence) | ||
//console.log("[REMOVEME] getSequenceHash: " + hashSequence.toString('hex')); | ||
writeSlice(input.hash) | ||
writeUInt32(input.index) | ||
//console.log("[REMOVEME] serializedInput: " + input.hash.toString('hex') + " " + input.index); | ||
writeVarSlice(inScript) | ||
//console.log("[REMOVEME] inputScriptBytes: " + inScript.toString('hex')); | ||
writeUInt64(input.value) | ||
writeUInt32(input.sequence) | ||
writeSlice(hashOutputs) | ||
//console.log("[REMOVEME] getOutputsHash: " + hashOutputs.toString('hex')); | ||
writeUInt32(lockTime) | ||
@@ -753,3 +778,3 @@ writeUInt32(this.forkInfo.signid) | ||
console.log("BIP143 hash buffer: " + tbuffer.toString('hex')) | ||
console.log("input #" + inputToSign + "BIP143 hashForSig: " + tbuffer.toString('hex')) | ||
return bcrypto.hash256(tbuffer) | ||
@@ -765,2 +790,3 @@ } | ||
// TODO: Needs to check a lot more things now | ||
verifyClaimProposal(claim, unspent, targetAddress) { | ||
@@ -773,2 +799,5 @@ const unspents = claim.unspents | ||
}, 0) | ||
console.log("[analyze] unspent:", unspent) | ||
console.log("[analyze] unspents:", unspents) | ||
console.log("[analyze] recipient:", recipients) | ||
const networkFees = inputAmount - outputAmount | ||
@@ -788,2 +817,3 @@ const hasTargetAddress = recipients.some(out => out.address === targetAddress) | ||
//console.log("[prepareSignaturesForClaim] unspents:", unspents) | ||
let inputAmount = 0 | ||
@@ -795,5 +825,8 @@ unspents.forEach(u => { | ||
/console.log("[prepareSignaturesForClaim] recipients:", recipients) | ||
let outputAmount = 0 | ||
recipients.forEach(recipient => { | ||
tx.addOutput(Buffer.from(recipient.outScript, 'base64'), recipient.amount) | ||
const script = Buffer.from(recipient.outScript, 'base64') | ||
//console.log("[REMOVEME] base64 " + recipient.outScript + " -> " + script.toString('hex')) | ||
tx.addOutput(script, recipient.amount) | ||
outputAmount += recipient.amount | ||
@@ -805,25 +838,28 @@ }) | ||
const ins = [] | ||
unspents.forEach(u => ins.push({ | ||
hash: Buffer.from(u.hash, 'hex').reverse(), | ||
index: u.n, | ||
value: u.amount, | ||
sequence: Bitcoin.Transaction.DEFAULT_SEQUENCE | ||
})) | ||
const signatures = [] | ||
for (let i = 0; i < unspents.length; i++) { | ||
const u = unspents[i] | ||
console.log("Preparing signature for:", u) | ||
const inputScript = Buffer.from(u.inputScript, 'base64') | ||
console.log("Input Script: " + inputScript.toString('hex')) | ||
const aa = u.aa | ||
if (aa) { | ||
console.log("Preparing signature for input#:" + i, u) | ||
const inputScript = Buffer.from(u.inputScript, 'base64') | ||
//console.log("Input Script: " + inputScript.toString('hex')) | ||
const ins = [{ | ||
hash: Buffer.from(u.hash, 'hex').reverse(), | ||
index: u.n, | ||
value: u.amount, | ||
sequence: Bitcoin.Transaction.DEFAULT_SEQUENCE | ||
}] | ||
const hashForSignature = this.hashForSignature(ins, 0, inputScript, tx.outs, Bitcoin.Transaction.SIGHASH_ALL) | ||
console.log("hash for sig: ", hashForSignature.toString('hex')) | ||
const account = claim.account | ||
const aa = u.aa | ||
const key = melis.deriveMyHdAccount(account.num, aa.chain, aa.hdindex) | ||
const signature = key.sign(hashForSignature) | ||
signatures.push(signature.toDER().toString('hex')) | ||
const hashForSignature = this.hashForSignature(ins, i, inputScript, tx.outs, Bitcoin.Transaction.SIGHASH_ALL) | ||
//console.log("input #" + i + " hashForSig: ", hashForSignature.toString('hex')) | ||
const account = claim.account | ||
const key = melis.deriveAddressKey(account.num, aa.chain, aa.hdindex) | ||
const signature = key.sign(hashForSignature) | ||
signatures.push(signature.toDER().toString('hex')) | ||
} | ||
} | ||
console.log("TX:", tx) | ||
//console.log("TX:", tx) | ||
return { | ||
@@ -897,10 +933,9 @@ id: claim.id, | ||
console.log("Claim proposal: ", claimProposal) | ||
if (unspents.length !== 1) | ||
throw "Unexpected number of unspents (should be 1): " + unspents.length | ||
const unspent = unspents[0] | ||
const verified = this.verifyClaimProposal(claimProposal, unspent, targetAddress) | ||
if (!verified) | ||
throw "Claim does not meet minimum sanity checks" | ||
//if (!params.ignoreVerification) | ||
// doExit() | ||
// TODO: Riabilitare il controllo? | ||
// const unspent = unspents[0] | ||
// const verified = this.verifyClaimProposal(claimProposal, unspent, targetAddress) | ||
// if (!verified) | ||
// throw "Claim does not meet minimum sanity checks" | ||
// //if (!params.ignoreVerification) | ||
// // doExit() | ||
const claimSignatures = this.prepareSignaturesForClaim(melis, claimProposal) | ||
@@ -913,4 +948,106 @@ const broadcastResult = await melis.submitForkClaim(claimSignatures.id, claimSignatures.signatures) | ||
async findExistingBSVAccount(melis) { | ||
const accounts = melis.peekAccounts() | ||
//console.log("PEEKED ACCOUNTS:\n", ForkClaimer.accountsForPrinting(accounts)) | ||
const pubId = Object.keys(accounts).find(pubId => accounts[pubId].coin === "BSV" && accounts[pubId].meta && accounts[pubId].meta.migrationInfo === BSV_MIGRATED_ACCOUNT_NAME) | ||
//const filtered = accounts.filter(a => a.coin === "BSV" && a.meta && a.meta.migrationInfo === BSV_MIGRATED_ACCOUNT_NAME) | ||
console.log("[findExistingBSVAccount] existing BSV account: ", pubId) | ||
if (pubId) | ||
return pubId | ||
const creationOptions = { | ||
coin: 'BSV', | ||
type: MELIS.C.TYPE_PLAIN_HD, | ||
meta: { | ||
name: "Claimed BSV", | ||
migrationInfo: BSV_MIGRATED_ACCOUNT_NAME | ||
} | ||
} | ||
console.log("Creating account with options:", creationOptions) | ||
const res = await melis.accountCreate(creationOptions) | ||
console.log("Created BSV account: ", res) | ||
return res.account.pubId | ||
} | ||
async bsvScan(melis, accounts, doDebug) { | ||
try { | ||
const bchDriver = melis.getCoinDriver('BCH') | ||
const res = {} | ||
for (let i = 0; i < accounts.length; i++) { | ||
const account = accounts[i] | ||
if (account.type !== '2' && account.type !== 'H') { | ||
console.log("Skipping account " + account.pubId + " of unsupported type " + account.type) | ||
continue | ||
} | ||
console.log("scanning account " + account.pubId + " type: " + account.type + " meta: " + JSON.stringify(account.meta)) | ||
const slice = await melis.addressesGet(account) | ||
//console.log("slice result: " + slice) | ||
if (!slice.list) { | ||
console.log("No addresses on melis for account " + account.pubId) | ||
continue | ||
} | ||
const addrs = slice.list.map(aa => bchDriver.toLegacyAddress(aa.address)) | ||
if (doDebug) | ||
console.log("#Addresses: " + addrs.length + "\n", addrs) | ||
const utxos = await this.queryUtxos(addrs, { | ||
doDebug | ||
}) | ||
if (doDebug) | ||
console.log("utxos:", utxos) | ||
if (utxos.length) | ||
res[account.pubId] = { | ||
utxos, | ||
account | ||
} | ||
} | ||
return res | ||
} catch (err) { | ||
console.log("bsvScan Ex:", err) | ||
} | ||
} | ||
async bsvRedeem(melis, params) { | ||
try { | ||
const account = params.account | ||
const utxos = params.utxos | ||
let targetAddress = params.targetAddress | ||
if (params && params.doDebug) | ||
console.log("[BSV CLAIM] utxos: ", utxos) | ||
if (!account) | ||
throw ("Missing account in parameters") | ||
if (!utxos || !utxos.length) | ||
throw ("Missing utxos in parameters") | ||
if (!targetAddress) { | ||
const pubId = await this.findExistingBSVAccount(melis) | ||
const aa = await melis.getPaymentAddressViaRest(pubId, { | ||
info: 'BSV Redeemed coins' | ||
}) | ||
if (params && params.doDebug) | ||
console.log("Created new aa: ", aa) | ||
targetAddress = aa.address | ||
} | ||
console.log("Target BSV address: ", targetAddress) | ||
const unspents = utxos.map(u => ({ | ||
hash: u.txid, | ||
n: u.vout, | ||
address: u.address | ||
})) | ||
const res = await this.redeem(melis, { | ||
account, | ||
targetCoin: 'BSV', | ||
targetAddress, | ||
unspents | ||
}) | ||
return res | ||
} catch (err) { | ||
console.log("bsvRedeem Ex:", err) | ||
} | ||
} | ||
} | ||
module.exports = ForkClaimer |
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
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
31518
942
1
+ Addedbig-integer@1.6.36(transitive)
+ Addedcashaddrjs@0.3.12(transitive)
+ Addedmelis-api-js@0.12.5(transitive)
+ Addedws@7.5.10(transitive)
- Removedasync-limiter@1.0.1(transitive)
- Removedbig-integer@1.6.52(transitive)
- Removedcashaddrjs@0.2.9(transitive)
- Removedmelis-api-js@0.11.20(transitive)
- Removedws@6.2.3(transitive)
Updatedmelis-api-js@^0.12.1