Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions component/sweep.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,26 @@
</v-ons-carousel>
</div>
<v-ons-list>
<template v-for="(item, idx) in queries">
<v-ons-list-item :modifier="getElementModifier(idx,0)">
<div class="center"><v-ons-input placeholder="秘密鍵 WIF" v-model="item.private"></v-ons-input></div>
<div class="right">
<v-ons-button v-show="queries.length&gt;1" @click="removePrivate(idx)" modifier="quiet"><v-ons-icon icon="ion-close"></v-ons-icon></v-ons-button>
</div>
</v-ons-list-item>
<v-ons-list-item :modifier="getElementModifier(idx,1)" v-show="details">
<div class="right">Loose<v-ons-switch v-model="item.loose"></v-ons-switch></div>
</v-ons-list-item>
<v-ons-list-item :modifier="getElementModifier(idx,2)" v-show="wifAddr(idx)" style="font-size:0.7em;color:#aaa;text-select:text">{{wifAddr(idx)}}</v-ons-list-item>
</template>
<v-ons-list-item>
<div class="center"><v-ons-input placeholder="秘密鍵 WIF" v-model="private"></v-ons-input></div>
<div class="right">Loose<v-ons-switch v-model="loose"></v-ons-switch></div>
<div class="left" @click="addPrivate()"><v-ons-icon icon="ion-plus"></v-ons-icon></div>
<div class="center" @click="addPrivate()">追加</div>
<div class="right">
Details<v-ons-switch v-model="details"></v-ons-switch>
</div>
</v-ons-list-item>
<v-ons-list-item modifier="small" v-show="wifAddr" style="font-size:0.7em;color:#aaa;text-select:text">{{wifAddr}}</v-ons-list-item>

<v-ons-list-item>
<div class="center">
<v-ons-input placeholder="吸い出し先アドレス" v-model="address"></v-ons-input>
Expand Down
69 changes: 51 additions & 18 deletions component/sweep.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,24 @@ module.exports = require("../js/lang.js")({
return {
currency: [],
currencyIndex: 0,
private: "",
address: "",
queries: [{ private: "", loose: false }],
feeRate: 0,
loose: false
details: false
};
},
store: require("../js/store.js"),
methods: {
send() {
if (!this.private || !this.address || !this.feeRate) {
if (this.queries.length === 0 || !this.feeRate) {
return;
}
const cur = currencyList.get(this.currency[this.currencyIndex].coinId);
const loose = this.queries.some(a => a.loose);
const keys = this.queries.map(a => a.private);
try {
cur
.sweep(this.private, this.address, this.feeRate, this.loose)
.sweep(keys, this.address, this.feeRate, loose)
.then(res => {
cur.saveTxLabel(res.txid, {
label: this.txLabel,
Expand All @@ -60,7 +62,8 @@ module.exports = require("../js/lang.js")({
page: require("./home.js"),
infoId: "sent",
payload: {
txId: res.txid
txId: res.txid,
coinId: this.currency[this.currencyIndex].coinId
}
});
this.$emit("replace", require("./finished.js"));
Expand All @@ -76,25 +79,22 @@ module.exports = require("../js/lang.js")({
this.address = currencyList
.get(this.currency[this.currencyIndex].coinId)
.getAddress(0, 0);
}
},
watch: {
currencyIndex() {
this.feeRate = currencyList.get(
this.currency[this.currencyIndex].coinId
).defaultFeeSatPerByte;
}
},
computed: {
wifAddr() {
let priv = this.private;
},
addPrivate() {
this.queries.push({ private: "", loose: false });
},
removePrivate(idx) {
this.queries.splice(idx, 1);
},
wifAddr(idx) {
let priv = this.queries[idx].private;
if (!priv) {
return "";
}
try {
const cur = currencyList.get(this.currency[this.currencyIndex].coinId);

if (this.loose) {
if (this.queries[idx].loose) {
const orig = bs58check.decode(priv);
const hash = orig.slice(1);
const version = cur.network.wif;
Expand All @@ -108,6 +108,39 @@ module.exports = require("../js/lang.js")({
} catch (e) {
return "";
}
},
getElementModifier(idx, element) {
/*
Priv Details Bottom
F F 0
T F 2
F T 1
T T 2
*/
switch (element) {
case 0:
if (!this.wifAddr(idx) && !this.details) {
return "";
}
return "nodivider";
case 1:
if (!this.wifAddr(idx) && this.details) {
return "small";
}
return "small nodivider";
case 2:
if (this.wifAddr(idx)) {
return "";
}
return "nodivider";
}
}
},
watch: {
currencyIndex() {
this.feeRate = currencyList.get(
this.currency[this.currencyIndex].coinId
).defaultFeeSatPerByte;
}
},
created() {
Expand Down
49 changes: 31 additions & 18 deletions js/currency.js
Original file line number Diff line number Diff line change
Expand Up @@ -804,26 +804,37 @@ module.exports = class {
});
}
sweep(priv, addr, feeRate, ignoreVersion = false) {
if (!Array.isArray(priv)) {
priv = [priv];
}
if (ignoreVersion) {
const orig = bs58check.decode(priv);
const hash = orig.slice(1);
const version = this.network.wif;
const payload = Buffer.allocUnsafe(orig.length);
payload.writeUInt8(version, 0);
hash.copy(payload, 1);
priv = bs58check.encode(payload);
}
let keyPair;
try {
keyPair = this.lib.ECPair.fromWIF(priv, this.network);
} catch (e) {
throw new errors.DecodeError("Failed to decode WIF");
for (const idx in priv) {
const orig = bs58check.decode(priv[idx]);
const hash = orig.slice(1);
const version = this.network.wif;
const payload = Buffer.allocUnsafe(orig.length);
payload.writeUInt8(version, 0);
hash.copy(payload, 1);
priv[idx] = bs58check.encode(payload);
}
}
return this.getUtxos([keyPair.getAddress()]).then(r => {
const txb = new this.lib.TransactionBuilder(
this.network,
this.maxFeeSatPerByte
);
// this achieves:
// - calculate an address only once for each KPs
// - lookup KP from address
// this replaces old keyPairs, as
// addresses can be obtained by `Object.keys(addressToKeyPair)`
// and keypairs by `Object.values(addressToKeyPair)`
const addressToKeyPair = {};
for (const item of priv) {
try {
const kp = this.lib.ECPair.fromWIF(item, this.network);
addressToKeyPair[kp.getAddress()] = kp;
} catch (e) {
throw new errors.DecodeError("Failed to decode WIF");
}
}
return this.getUtxos(Object.keys(addressToKeyPair)).then(r => {
const txb = new this.lib.TransactionBuilder(this.network);
const { outputs } = coinSelectSplit(r.utxos, [{}], +feeRate);
r.utxos.forEach((v, i) => {
txb.addInput(v.txId, v.vout);
Expand All @@ -833,6 +844,8 @@ module.exports = class {
}
txb.addOutput(addr, outputs[0].value);
r.utxos.forEach((v, i) => {
const address = v.address;
const keyPair = addressToKeyPair[address];
if (this.enableSegwit) {
const redeemScript = this.lib.script.witnessPubKeyHash.output.encode(
this.lib.crypto.hash160(keyPair.getPublicKeyBuffer())
Expand Down