diff --git a/DEMO.md b/DEMO.md index 2e707521c..f99b03878 100644 --- a/DEMO.md +++ b/DEMO.md @@ -59,7 +59,7 @@ On both `~zod`/`dopzod`, choose depending on whether you're on test or main `~dopzod` ``` -:btc-wallet-hook|action [%req-pay-address ~zod 3.000 feyb=[~ 30]] +:btc-wallet-hook|action [%req-pay-address ~zod 30.000 feyb=[~ 10]] ``` ### Check State on ~zod/~dopzod @@ -83,6 +83,11 @@ Or can change amount: :btc-wallet-hook|action [%req-pay-address ~zod 3.000 feyb=[~ 100]] ``` +### Broadcast the Signed TX +``` +:btc-wallet-hook|action [%broadcast-tx tx] +``` + ## Scan a Real Xpub ``` diff --git a/app/btc-provider.hoon b/app/btc-provider.hoon index 8db23927c..153d71149 100644 --- a/app/btc-provider.hoon +++ b/app/btc-provider.hoon @@ -206,6 +206,9 @@ :: ++ send-status |= =status ^- card + %- ?: ?=(%new-block -.status) + ~&(>> "%new-block: {}" same) + same [%give %fact ~[/clients] %btc-provider-status !>(status)] :: ++ send-update @@ -213,7 +216,7 @@ ^- card =+ c=[%give %fact ~[/clients] %btc-provider-update !>(update)] ?: ?=(%.y -.update) - ~& >> "prov. update: {}" +:: ~& >> "prov. update: {}" c ~& >> "prov. err: {}" c diff --git a/app/btc-wallet-hook.hoon b/app/btc-wallet-hook.hoon index 4dacfa01a..4b1597f25 100644 --- a/app/btc-wallet-hook.hoon +++ b/app/btc-wallet-hook.hoon @@ -200,7 +200,10 @@ :_ state =+ pb=~(to-psbt txb:bwsl u.poym) ?~ pb ~ - ~& >> "PSBT: {}" + =+ vb=~(vbytes txb:bwsl u.poym) + =+ fee=~(fee txb:bwsl u.poym) + ~& >> "{} vbytes, {<(div fee vb)>} sats/byte, {} sats fee" + %- (slog [%leaf "PSBT: {}"]~) ~[(send-update [%sign-tx u.poym])] :: %close-pym diff --git a/lib/btc-wallet-store.hoon b/lib/btc-wallet-store.hoon index 4442647cd..439edb585 100644 --- a/lib/btc-wallet-store.hoon +++ b/lib/btc-wallet-store.hoon @@ -68,9 +68,20 @@ (roll (turn txos.t |=(=txo value.txo)) add) :: ++ fee + ^- sats:btc =/ [in=sats out=sats] value (sub in out) :: + ++ vbytes + ^- vbytes:btc + %+ add overhead-weight:btc + %+ add + %+ roll + (turn txis.t |=(t=txi (input-weight:btc bipt.hdkey.t))) + add + %+ roll + (turn txos.t |=(t=txo (output-weight:btc (address-bipt:btc address.t)))) + add ++ tx-data |^ ^- data:tx:btc @@ -101,6 +112,7 @@ ++ add-output |= =txo ^- txbu + :: todo update vbytes t(txos (snoc [txos.t] txo)) :: +to-psbt: returns a based 64 PSBT if :: - all inputs have an associated rawtx @@ -135,7 +147,7 @@ ++ hdkey |= =idx:btc ^- hdkey:btc - [fprint.w (~(pubkey wad w chyg) idx) bipt.w chyg idx] + [fprint.w (~(pubkey wad w chyg) idx) network.w bipt.w chyg idx] :: ++ mk-address |= =idx:btc @@ -221,25 +233,7 @@ ++ dust-threshold |= output-bipt=bipt:btc ^- vbytes - (mul dust-sats (input-weight output-bipt)) - ++ meta-weight 11 - ++ output-weight - |= b=bipt:btc - ^- vbytes - ?- b - %44 34 - %49 32 - %84 31 - == - :: - ++ input-weight - |= b=bipt:btc - ^- vbytes - ?- b - %44 148 - %49 91 - %84 68 - == + (mul dust-sats (input-weight:btc output-bipt)) :: ++ target-value ^- sats @@ -248,24 +242,24 @@ :: ++ base-weight ^- vbytes - %+ add meta-weight + %+ add overhead-weight:btc %+ roll %+ turn txos - |=(=txo (output-weight (address-bipt:btc address.txo))) + |=(=txo (output-weight:btc (address-bipt:btc address.txo))) add :: ++ total-vbytes |= selected=(list insel) ^- vbytes %+ add base-weight - (mul (input-weight bipt.w) (lent selected)) + (mul (input-weight:btc bipt.w) (lent selected)) :: value of an input after fee :: 0 if net is <= 0 :: ++ net-value |= val=sats ^- sats - =/ cost (mul (input-weight bipt.w) feyb) + =/ cost (mul (input-weight:btc bipt.w) feyb) ?: (lte val cost) 0 (sub val cost) :: @@ -284,7 +278,7 @@ ?~ tb [~ ~] =+ excess=~(fee txb u.tb) :: (inputs - outputs) =/ new-fee=sats :: cost of this tx + one more output - (mul feyb (add (output-weight bipt.w) vbytes.u.tb)) + (mul feyb (add (output-weight:btc bipt.w) vbytes.u.tb)) ?. (gth excess new-fee) [tb ~] ?. (gth (sub excess new-fee) (dust-threshold bipt.w)) diff --git a/lib/btc.hoon b/lib/btc.hoon index c5feb9d14..8c1f5bbeb 100644 --- a/lib/btc.hoon +++ b/lib/btc.hoon @@ -20,6 +20,25 @@ :: :- (div (lent (trip h)) 2) `@ux`(rash - hex) +:: +++ overhead-weight ^-(vbytes 11) +++ input-weight + |= =bipt + ^- vbytes + ?- bipt + %44 148 + %49 91 + %84 68 + == +++ output-weight + |= =bipt + ^- vbytes + ?- bipt + %44 34 + %49 32 + %84 31 + == +:: ++ xpub-type |= =xpub ^- [=bipt =network] @@ -310,7 +329,7 @@ :~ fprint.h %- to-byts:buf :~ `@ux`bipt.h 0x0 0x0 0x80 - 0x0 0x0 0x0 0x80 + ?:(?=(%main network.h) 0x0 0x1) 0x0 0x0 0x80 0x0 0x0 0x0 0x80 `@ux`chyg.h 0x0 0x0 0x0 == diff --git a/psbt_sign.js b/psbt_sign.js index 070a4ae51..e186f85bf 100644 --- a/psbt_sign.js +++ b/psbt_sign.js @@ -1,20 +1,21 @@ -/* -Usage: -var p = require("./psbt_sign.js") -const psbt = PSBT_STRING_BASE64 -const mnemonics = MNEMONICS_STRING -const [psbt, mnemonics] = [] -p.run(mnemonics, psbt) - */ - const bitcoin = require('bitcoinjs-lib'); const ecpair = bitcoin.ECPair; const crypto = bitcoin.crypto; const bscript = bitcoin.script; const bip39 = require('bip39'); -const NETWORK = bitcoin.networks.bitcoin; const LOCK_TIME = 0; const SIGHASH_ALL = 1; +let NETWORK; + +/* +Usage: +var p = require("./psbt_sign.js") +var psbt = PSBT_STRING_BASE64 +const mnemonics = MNEMONICS_STRING + +p.run("TESTNET", mnemonics, psbt) +p.run("MAIN", mnemonics, psbt) + */ const isSegwitTx = (rawTx) => { return rawTx.substring(8, 12) === '0001'; @@ -22,7 +23,15 @@ const isSegwitTx = (rawTx) => { // const PATHS = ["m/84'/0'/0'/0/0", "m/84'/0'/0'/1/0"]; -const run = async(mnemonics, psbtStr) => { +const run = async(network, mnemonics, psbtStr) => { + let NETWORK; + if (network === "MAIN") { + NETWORK = bitcoin.networks.bitcoin; + } + else if (network = "TESTNET") { + NETWORK = bitcoin.networks.testnet; + } + const psbt = bitcoin.Psbt.fromBase64(psbtStr); const is = psbt.data.inputs; const seed = await bip39.mnemonicToSeed(mnemonics); diff --git a/sur/btc-wallet-store.hoon b/sur/btc-wallet-store.hoon index 02fe33ccd..2ac6087b0 100644 --- a/sur/btc-wallet-store.hoon +++ b/sur/btc-wallet-store.hoon @@ -74,11 +74,11 @@ outputs=(list [=val:tx s=(unit ship)]) == +$ history (map hexb hest) -:: state/watch variables: +:: state/watch variables: :: scanning addresses and monitoring generated addresses :: batch: indexes to scan for a given chyg :: scans: all scans underway (batches) -:: piym-watch: any address we've been told has an incoming payment promised +:: piym-watch: any address we've been told has an incoming payment promised :: +$ batch [todo=(set idx) endpoint=idx has-used=?] +$ scans (map [xpub chyg] batch) @@ -87,7 +87,6 @@ :: %address-info: give new data about an address. :: - used: address has been seen on the BTC blockchain? :: - block: the most recent block at the time of this information being retrieved -:: TODO: document :: +$ action $% [%add-wallet =xpub =fprint scan-to=(unit scon) max-gap=(unit @ud) confs=(unit @ud)] diff --git a/sur/btc.hoon b/sur/btc.hoon index df618f562..d67b01411 100644 --- a/sur/btc.hoon +++ b/sur/btc.hoon @@ -16,7 +16,7 @@ +$ bipt $?(%44 %49 %84) +$ chyg $?(%0 %1) +$ idx @ud -+$ hdkey [=fprint pubkey=hexb =bipt =chyg =idx] ++$ hdkey [=fprint pubkey=hexb =network =bipt =chyg =idx] +$ sats @ud +$ vbytes @ud +$ buffer (list @ux)