massive refactors

This commit is contained in:
timlucmiptev 2021-02-18 14:13:06 +02:00 committed by ixv
parent 5134e4cd03
commit cde92cea10
10 changed files with 255 additions and 226 deletions

View File

@ -9,7 +9,7 @@
:: Scrys
:: x/is-whitelisted/SHIP: bool, whether ship is whitelisted
::
/- btc, json-rpc
/- *bitcoin, json-rpc
/+ *btc-provider, dbug, default-agent, groupl=group, resource
|%
+$ versioned-state
@ -195,7 +195,7 @@
^- (quip card _state)
~& >>> "dropping client {<client>}"
:- ~[[%give %kick ~[/clients] `client]]
state(clients.host-info (~(dif in clients.host-info) (sy ~[client])))
state(clients.host-info (~(dif in clients.host-info) (silt ~[client])))
::
:: Handles HTTP responses from RPC servers. Parses for errors, then handles response.
:: For actions that require collating multiple RPC calls, uses req-card to call out
@ -309,7 +309,7 @@
++ clean-client-list
^- (quip card _state)
=/ to-kick=(set ship)
%- sy
%- silt
%+ murn ~(tap in clients.host-info)
|= c=ship ^- (unit ship)
?:((is-whitelisted c) ~ `c)

View File

@ -1,10 +1,11 @@
:: btc-wallet
::
:: Scrys
:: x/scanned: (list xpub) of all scanned wallets
:: x/balance/xpub: balance (in sats) of wallet
/- *btc-wallet
/+ dbug, default-agent, *btc-wallet, bp=btc-provider, *btc, bip32
/+ dbug, default-agent, *btc-wallet, bp=btc-provider, *bitcoin, bip32
|%
++ defaults
|%
@ -26,7 +27,7 @@
+$ state-0
$: %0
prov=(unit provider)
walts=(map xpub:btc walt)
walts=(map xpub walt)
=btc-state
=history
curr-xpub=(unit xpub)
@ -58,7 +59,7 @@
state
:* %0
~
*(map xpub:btc walt)
*(map xpub walt)
*^btc-state
*^history
~
@ -82,10 +83,17 @@
^- (quip card _this)
=^ cards state
?+ mark (on-poke:def mark vase)
%btc-wallet-action
(handle-action:hc !<(action vase))
%btc-wallet-command
?> =(our.bowl src.bowl)
(handle-command:hc !<(command vase))
::
%btc-wallet-action
?< =(our.bowl src.bowl)
(handle-action:hc !<(action vase))
::
%btc-wallet-internal
?> =(our.bowl src.bowl)
(handle-internal:hc !<(internal vase))
==
[cards this]
++ on-peek
@ -96,7 +104,7 @@
``noun+!>(scanned-wallets)
::
[%x %balance @ ~]
``noun+!>((balance:hc (xpub:btc +>-.pax)))
``noun+!>((balance:hc (xpub +>-.pax)))
==
++ on-agent
|= [=wire =sign:agent:gall]
@ -132,7 +140,6 @@
++ handle-command
|= comm=command
^- (quip card _state)
?> =(our.bowl src.bowl)
?- -.comm
%set-provider
=* sub-card
@ -173,10 +180,9 @@
?< ?=(%pawn (clan:title payee.comm))
?< is-broadcasting
:_ state(poym ~, feybs (~(put by feybs) payee.comm feyb.comm))
~[(poke-us payee.comm [%gen-pay-address value.comm])]
~[(poke-peer payee.comm [%gen-pay-address value.comm])]
::
%broadcast-tx
?> =(src.bowl our.bowl)
?~ prov ~|("Provider not connected" !!)
=+ signed=(to-hexb txhex.comm)
=/ tx-match=?
@ -194,75 +200,25 @@
|= act=action
^- (quip card _state)
?- -.act
%add-poym-raw-txi
?> =(src.bowl our.bowl)
?~ poym `state
=. txis.u.poym
(update-poym-txis txis.u.poym +.act)
:_ state
=+ pb=~(to-psbt txb u.poym)
?~ pb ~
=+ vb=~(vbytes txb u.poym)
=+ fee=~(fee txb u.poym)
~& >> "{<vb>} vbytes, {<(div fee vb)>} sats/byte, {<fee>} sats fee"
%- (slog [%leaf "PSBT: {<u.pb>}"]~)
~
:: delete an incoming/outgoing payment when we see it included in a tx
::
%close-pym
?> =(src.bowl our.bowl)
=^ cards state
?. included.ti.act
`state
?: (~(has by pend.piym) txid.ti.act)
(piym-to-history ti.act)
?: (poym-has-txid txid.ti.act)
(poym-to-history ti.act)
`state
:- cards
(handle-tx-info ti.act)
::
%fail-broadcast-tx
?> =(src.bowl our.bowl)
~& >>> "%fail-broadcast-tx"
`state(poym ~)
::
%succeed-broadcast-tx
?> =(src.bowl our.bowl)
~& > "%succeed-broadcast-tx"
:_ state
?~ prov ~
:- (poke-provider [%tx-info txid.act])
?~ poym ~
?~ payee.u.poym ~
:_ ~
%- poke-us
:* u.payee.u.poym
%expect-payment
txid.act
value:(snag 0 txos.u.poym)
==
:: can't pay yourself; comets can't pay (could spam address requests)
:: must have curr-wallet set
:: comets can't pay (could spam address requests)
:: reuses payment address for ship if ship in piym already
::
%gen-pay-address
~| "Can't pay ourselves; no comets"
?< =(src.bowl our.bowl)
~| "no comets"
?< ?=(%pawn (clan:title src.bowl))
=^ cards state
(reuse-address src.bowl value.act)
?^ cards [cards state]
=+ f=(fam src.bowl)
?~ curr-xpub ~|("btc-wallet: no curr-xpub set" !!)
|^
=^ cards state reuse-address
?^ cards [cards state] :: if cards returned, means we already have an address
=+ f=(fam our.bowl now.bowl src.bowl)
=+ n=(~(gut by num-fam.piym) f 0)
?~ curr-xpub ~|("btc-walle: no curr-xpub set" !!)
?: (gte n fam-limit.params)
~|("More than {<fam-limit.params>} addresses for moons + planet" !!)
=. state state(num-fam.piym (~(put by num-fam.piym) f +(n)))
|^
=^ a=address state
(generate-address u.curr-xpub %0)
:- ~[(poke-us src.bowl [%recv-pay-address a value.act])]
:- ~[(poke-peer src.bowl [%recv-pay-address a value.act])]
state(ps.piym (~(put by ps.piym) src.bowl [~ u.curr-xpub a src.bowl value.act]))
::
++ generate-address
@ -273,6 +229,16 @@
=/ [addr=address =idx w=walt]
~(gen-address wad u.uw chyg)
[addr state(walts (~(put by walts) xpub w))]
::
++ reuse-address
^- (quip card _state)
=* payer src.bowl
=+ p=(~(get by ps.piym) payer)
?~ p `state
?^ pend.u.p ~|("%gen-address: {<payer>} already has pending payment to us" !!)
=+ newp=u.p(value value.act)
:_ state(ps.piym (~(put by ps.piym) payer newp))
~[(poke-peer payer [%recv-pay-address address.newp value.act])]
--
::
%recv-pay-address
@ -301,7 +267,7 @@
:: if no change, return txbu; else add change output to txbu
::
?~ chng [tb state]
=/ [addr=address:btc =idx w=walt]
=/ [addr=address =idx w=walt]
~(nixt-address wad u.uw %1)
:- `(~(add-output txb u.tb) addr u.chng `(~(hdkey wad w %1) idx))
state(walts (~(put by walts) xpub w))
@ -331,6 +297,60 @@
--
==
::
++ handle-internal
|= intr=internal
^- (quip card _state)
?- -.intr
%add-poym-raw-txi
?> =(src.bowl our.bowl)
?~ poym `state
=. txis.u.poym
(update-poym-txis txis.u.poym +.intr)
:_ state
=+ pb=~(to-psbt txb u.poym)
?~ pb ~
=+ vb=~(vbytes txb u.poym)
=+ fee=~(fee txb u.poym)
~& >> "{<vb>} vbytes, {<(div fee vb)>} sats/byte, {<fee>} sats fee"
%- (slog [%leaf "PSBT: {<u.pb>}"]~)
~
:: delete an incoming/outgoing payment when we see it included in a tx
::
%close-pym
?> =(src.bowl our.bowl)
=^ cards state
?. included.ti.intr
`state
?: (~(has by pend.piym) txid.ti.intr)
(piym-to-history ti.intr)
?: (poym-has-txid txid.ti.intr)
(poym-to-history ti.intr)
`state
:- cards
(handle-tx-info ti.intr)
::
%fail-broadcast-tx
?> =(src.bowl our.bowl)
~& >>> "%fail-broadcast-tx"
`state(poym ~)
::
%succeed-broadcast-tx
?> =(src.bowl our.bowl)
~& > "%succeed-broadcast-tx"
:_ state
?~ prov ~
:- (poke-provider [%tx-info txid.intr])
?~ poym ~
?~ payee.u.poym ~
:_ ~
%- poke-peer
:* u.payee.u.poym
%expect-payment
txid.intr
value:(snag 0 txos.u.poym)
==
==
::
:: +handle-provider-status: handle connectivity updates from provider
:: - retry pend.piym on any %connected event, since we're checking mempool
:: - if status is %connected, retry all pending address lookups
@ -375,8 +395,71 @@
(retry-txs network)
(retry-scans network)
==
(retry-pend-piym network)
--
(retry-pend-piym network)
::
++ retry-scans
|= =network
^- (list card)
%- zing
%+ murn ~(tap by scans)
|= [[=xpub =chyg] =batch]
?. =(network network:(~(got by walts) xpub)) ~
`-:(req-scan batch xpub chyg)
:: +retry-addrs: get info on addresses with unconfirmed UTXOs
::
++ retry-addrs
|= =network
^- (list card)
%- zing
%+ murn ~(val by walts)
|= w=walt
?. =(network network.w) ~
^- (unit (list card))
:- ~
%+ murn ~(tap by wach.w)
|= [a=address ad=addi]
?: %+ levy ~(tap in utxos.ad)
|=(u=utxo (gth height.u (sub block.btc-state confs.w)))
~
`(poke-provider [%address-info a])
:: +retry-txs: get info on txs without enough confirmations
::
++ retry-txs
|= =network
^- (list card)
%+ murn ~(tap by history)
|= [=txid =hest]
=/ w (~(get by walts) xpub.hest)
?~ w ~
?. =(network network.u.w) ~
?: (gte confs.hest confs.u.w) ~
`(poke-provider [%tx-info txid])
::
++ retry-poym
|= =network
^- (list card)
?~ poym ~
=/ w (~(get by walts) xpub.u.poym)
?~ w ~
?. =(network network.u.w) ~
%+ weld
?~ signed-tx.u.poym ~
~[(poke-provider [%broadcast-tx u.signed-tx.u.poym])]
%+ turn txis.u.poym
|= =txi
(poke-provider [%raw-tx ~(get-txid txb u.poym)])
:: +retry-pend-piym: check whether txids in pend-piym are in mempool
::
++ retry-pend-piym
|= =network
^- (list card)
%+ murn ~(tap by pend.piym)
|= [=txid p=payment]
=/ w (~(get by walts) xpub.p)
?~ w ~
?. =(network network.u.w) ~
`(poke-provider [%tx-info txid])
--
::
++ handle-provider-update
|= upd=update:bp
@ -389,12 +472,12 @@
(handle-address-info address.p.upd utxos.p.upd used.p.upd)
::
%tx-info
:- ~[(poke-us our.bowl [%close-pym info.p.upd])]
:- ~[(poke-internal [%close-pym info.p.upd])]
(handle-tx-info info.p.upd)
::
%raw-tx
:_ state
~[(poke-us our.bowl [%add-poym-raw-txi +.p.upd])]
~[(poke-internal [%add-poym-raw-txi +.p.upd])]
::
%broadcast-tx
?~ poym `state
@ -402,8 +485,8 @@
`state
:_ state
?: ?|(broadcast.p.upd included.p.upd)
~[(poke-us our.bowl [%succeed-broadcast-tx txid.p.upd])]
~[(poke-us our.bowl [%fail-broadcast-tx txid.p.upd])]
~[(poke-internal [%succeed-broadcast-tx txid.p.upd])]
~[(poke-internal [%fail-broadcast-tx txid.p.upd])]
==
::
++ handle-tx-info
@ -412,7 +495,7 @@
|^
=/ h (~(get by history) txid.ti)
=/ our-addrs=(set address) :: all our addresses in inputs/outputs of tx
%- sy
%- silt
%+ skim
%+ turn (weld inputs.ti outputs.ti)
|=(=val:tx address.val)
@ -446,7 +529,7 @@
==
::
++ is-our-ship
|= [as=(set address:btc) v=val:tx:btc]
|= [as=(set address) v=val:tx]
^- [=val:tx s=(unit ship)]
[v ?:((~(has in as) address.v) `our.bowl ~)]
::
@ -527,7 +610,7 @@
|= [=xpub endpoint=idx]
^- (quip card _state)
=/ b=batch
[(sy (gulf 0 endpoint)) endpoint %.n]
[(silt (gulf 0 endpoint)) endpoint %.n]
=^ cards0 state (req-scan b xpub %0)
=^ cards1 state (req-scan b xpub %1)
[(weld cards0 cards1) state]
@ -544,7 +627,7 @@
`state
=/ w=walt (~(got by walts) xpub)
=/ newb=batch
:* (sy (gulf +(endpoint.b) (add endpoint.b max-gap.w)))
:* (silt (gulf +(endpoint.b) (add endpoint.b max-gap.w)))
(add endpoint.b max-gap.w)
%.n
==
@ -588,20 +671,6 @@
:: Utilities for Incoming/Outgoing Payments
::
::
:: +reuse-address
:: - if piym already has address for payer, replace address and return to payer
:: - if payment is pending, crash. Shouldn't be getting an address request
::
++ reuse-address
|= [payer=ship value=sats]
^- (quip card _state)
=+ p=(~(get by ps.piym) payer)
?~ p `state
?^ pend.u.p ~|("%gen-address: {<payer>} already has pending payment to us" !!)
=+ newp=u.p(value value)
:_ state(ps.piym (~(put by ps.piym) payer newp))
~[(poke-us payer [%recv-pay-address address.newp value])]
::
++ poym-has-txid
|= txid=hexb
^- ?
@ -703,13 +772,6 @@
[o `payer]
==
(~(put by history) txid.hest hest)
:: +fam: planet parent if s is a moon
::
++ fam
|= s=ship
^- ship
?. =(%earl (clan:title s)) s
(sein:title our.bowl now.bowl s)
:: +update-pend.piym
:: - set pend.payment to txid (lock)
:: - add txid to pend.piym
@ -740,69 +802,6 @@
:: Card Builders and Pokers
::
::
++ retry-scans
|= =network
^- (list card)
%- zing
%+ murn ~(tap by scans)
|= [[=xpub =chyg] =batch]
?. =(network network:(~(got by walts) xpub)) ~
`-:(req-scan batch xpub chyg)
:: +retry-addrs: get info on addresses with unconfirmed UTXOs
::
++ retry-addrs
|= =network
^- (list card)
%- zing
%+ murn ~(val by walts)
|= w=walt
?. =(network network.w) ~
^- (unit (list card))
:- ~
%+ murn ~(tap by wach.w)
|= [a=address ad=addi]
?: %+ levy ~(tap in utxos.ad)
|=(u=utxo (gth height.u (sub block.btc-state confs.w)))
~
`(poke-provider [%address-info a])
:: +retry-txs: get info on txs without enough confirmations
::
++ retry-txs
|= =network
^- (list card)
%+ murn ~(tap by history)
|= [=txid =hest]
=/ w (~(get by walts) xpub.hest)
?~ w ~
?. =(network network.u.w) ~
?: (gte confs.hest confs.u.w) ~
`(poke-provider [%tx-info txid])
::
++ retry-poym
|= =network
^- (list card)
?~ poym ~
=/ w (~(get by walts) xpub.u.poym)
?~ w ~
?. =(network network.u.w) ~
%+ weld
?~ signed-tx.u.poym ~
~[(poke-provider [%broadcast-tx u.signed-tx.u.poym])]
%+ turn txis.u.poym
|= =txi
(poke-provider [%raw-tx ~(get-txid txb u.poym)])
:: +retry-pend-piym: check whether txids in pend-piym are in mempool
::
++ retry-pend-piym
|= =network
^- (list card)
%+ murn ~(tap by pend.piym)
|= [=txid p=payment]
=/ w (~(get by walts) xpub.p)
?~ w ~
?. =(network network.u.w) ~
`(poke-provider [%tx-info txid])
::
++ poke-provider
|= [act=action:bp]
^- card
@ -812,13 +811,20 @@
%poke %btc-provider-action !>([act])
==
::
++ poke-us
++ poke-peer
|= [target=ship act=action]
^- card
:* %pass /[(scot %da now.bowl)] %agent
[target %btc-wallet] %poke
%btc-wallet-action !>(act)
==
++ poke-internal
|= [intr=internal]
^- card
:* %pass /[(scot %da now.bowl)] %agent
[our.bowl %btc-wallet] %poke
%btc-wallet-internal !>(intr)
==
::
++ is-broadcasting
^- ?

View File

@ -1,7 +1,7 @@
:: lib/btc.hoon
:: Utilities for working with BTC data types and transactions
::
/- sur=btc
/- sur=bitcoin
^?
=< [sur .]
=, sur
@ -503,7 +503,6 @@
^- byts
:- (roll (turn bs |=(b=byts -.b)) add)
(can 3 (flop bs))
--
:: +flip:byt: flip endianness while preserving lead/trail zeroes
::
++ flip
@ -529,6 +528,7 @@
0^0x0
=+ n-take=(sub wid.b n)
[n-take (end [3 n-take] dat.b)]
--
::
++ bit
|%

View File

@ -1,5 +1,5 @@
/- sur=btc-provider, json-rpc
/+ *btc
/+ *bitcoin
^?
=< [sur .]
=, sur

View File

@ -1,7 +1,7 @@
::
::
/- *btc-wallet
/+ bip32, btc, bp=btc-provider
/+ bip32, bc=bitcoin, bp=btc-provider
=, secp:crypto
=+ ecc=secp256k1
|%
@ -10,21 +10,28 @@
++ max-gap 20
++ confs 6
--
:: +fam: planet parent if s is a moon
::
++ fam
|= [our=ship now=@da s=ship]
^- ship
?. =(%earl (clan:title s)) s
(sein:title our now s)
::
++ num-confs
|= [last-block=@ud =utxo:btc]
|= [last-block=@ud =utxo:bc]
?: =(0 height.utxo) 0
(add 1 (sub last-block height.utxo))
::
++ from-xpub
|= $: =xpub:btc
=fprint:btc
|= $: =xpub:bc
=fprint:bc
scan-to=(unit scon)
max-gap=(unit @ud)
confs=(unit @ud)
==
^- walt
=/ [=bipt =network] (xpub-type:btc xpub)
=/ [=bipt =network] (xpub-type:bc xpub)
:* xpub
network
fprint
@ -59,7 +66,7 @@
++ new-txbu
|= $: w=walt
payee=(unit ship)
=vbytes:btc
=vbytes:bc
is=(list insel)
txos=(list txo)
==
@ -86,23 +93,23 @@
(roll (turn txos.t |=(=txo value.txo)) add)
::
++ fee
^- sats:btc
^- sats:bc
=/ [in=sats out=sats] value
(sub in out)
::
++ vbytes
^- vbytes:btc
%+ add overhead-weight:btc
^- vbytes:bc
%+ add overhead-weight:bc
%+ add
%+ roll
(turn txis.t |=(t=txi (input-weight:btc bipt.hdkey.t)))
(turn txis.t |=(t=txi (input-weight:bc bipt.hdkey.t)))
add
%+ roll
(turn txos.t |=(t=txo (output-weight:btc (address-bipt:btc address.t))))
(turn txos.t |=(t=txo (output-weight:bc (address-bipt:bc address.t))))
add
++ tx-data
|^
^- data:tx:btc
^- data:tx:bc
:* (turn txis.t txi-data)
(turn txos.t txo-data)
0 1 `1
@ -115,16 +122,16 @@
==
++ txo-data
|= =txo
:- (script-pubkey:btc address.txo)
:- (script-pubkey:bc address.txo)
value.txo
--
::
++ get-txid
^- txid
(get-id:txu:btc tx-data)
(get-id:txu:bc tx-data)
::
++ get-rawtx
(basic-encode:txu:btc tx-data)
(basic-encode:txu:bc tx-data)
:: +add-output: append output (usually change) to txos
::
++ add-output
@ -136,18 +143,18 @@
:: - all inputs have an associated rawtx
::
++ to-psbt
^- (unit base64:psbt:btc)
=/ ins=(list in:psbt:btc)
^- (unit base64:psbt:bc)
=/ ins=(list in:psbt:bc)
%+ murn txis.t
|= =txi
?~ ur.txi ~
`[utxo.txi u.ur.txi hdkey.txi]
?: (lth (lent ins) (lent txis.t))
~
=/ outs=(list out:psbt:btc)
=/ outs=(list out:psbt:bc)
%+ turn txos.t
|=(=txo [address.txo hk.txo])
`(encode:pbt:btc %.y get-rawtx get-txid ins outs)
`(encode:pbt:bc %.y get-rawtx get-txid ins outs)
--
:: wad: door for processing walts (wallets)
:: parameterized on a walt and it's chyg account
@ -155,29 +162,29 @@
++ wad
|_ [w=walt =chyg]
++ pubkey
|= =idx:btc
^- hexb:btc
|= =idx:bc
^- hexb:bc
=/ pk=@ux
%- compress-point:ecc
pub:(derive-public:(derive-public:wilt.w (@ chyg)) idx)
[(met 3 pk) pk]
::
++ hdkey
|= =idx:btc
^- hdkey:btc
|= =idx:bc
^- hdkey:bc
[fprint.w (~(pubkey wad w chyg) idx) network.w bipt.w chyg idx]
::
++ mk-address
|= =idx:btc
^- address:btc
(pubkey-to-address:btc bipt.w network.w (pubkey idx))
|= =idx:bc
^- address:bc
(pubkey-to-address:bc bipt.w network.w (pubkey idx))
:: +nixt-address: used to get change addresses
:: - gets the current next available address
:: - doesn't bump nixt-address if it's unused
:: - if used, fall back to gen-address and make a new one
::
++ nixt-address
^- (trel address:btc idx:btc walt)
^- (trel address:bc idx:bc walt)
=/ addr (mk-address nixt-idx)
~| "lib/btc-wallet-store: get-next-address: nixt shouldn't be blank"
=/ =addi (~(got by wach.w) addr)
@ -190,12 +197,12 @@
:: - watches it (using update address)
::
++ gen-address
^- (trel address:btc idx:btc walt)
^- (trel address:bc idx:bc walt)
=/ addr (mk-address nixt-idx)
:* addr
nixt-idx
%+ update-address addr
[%.n chyg nixt-idx *(set utxo:btc)]
[%.n chyg nixt-idx *(set utxo:bc)]
==
:: +update-address
:: - insert a new address
@ -203,7 +210,7 @@
:: - watch address
::
++ update-address
|= [a=address:btc =addi]
|= [a=address:bc =addi]
^- walt
?> =(chyg chyg.addi)
?> =(a (mk-address idx.addi))
@ -225,12 +232,12 @@
::
++ bump-nixt
|^ ^- walt
=/ new-idx=idx:btc +(nixt-idx)
=/ new-idx=idx:bc +(nixt-idx)
|- ?> (lte new-idx max-index)
=+ addr=(mk-address new-idx)
=/ =addi
%+ ~(gut by wach.w) addr
[%.n chyg new-idx *(set utxo:btc)]
[%.n chyg new-idx *(set utxo:bc)]
?. used.addi
%= w
nixt (set-nixt new-idx)
@ -239,7 +246,7 @@
$(new-idx +(new-idx))
::
++ set-nixt
|= =idx:btc ^- nixt
|= =idx:bc ^- nixt
?:(?=(%0 chyg) [idx q.nixt.w] [p.nixt.w idx])
--
--
@ -249,9 +256,9 @@
|_ [w=walt eny=@uvJ last-block=@ud payee=(unit ship) =feyb txos=(list txo)]
++ dust-sats 3
++ dust-threshold
|= output-bipt=bipt:btc
|= output-bipt=bipt:bc
^- vbytes
(mul dust-sats (input-weight:btc output-bipt))
(mul dust-sats (input-weight:bc output-bipt))
::
++ target-value
^- sats
@ -260,31 +267,31 @@
::
++ base-weight
^- vbytes
%+ add overhead-weight:btc
%+ add overhead-weight:bc
%+ roll
%+ turn txos
|=(=txo (output-weight:btc (address-bipt:btc address.txo)))
|=(=txo (output-weight:bc (address-bipt:bc address.txo)))
add
::
++ total-vbytes
|= selected=(list insel)
^- vbytes
%+ add base-weight
(mul (input-weight:btc bipt.w) (lent selected))
(mul (input-weight:bc bipt.w) (lent selected))
:: value of an input after fee
:: 0 if net is <= 0
::
++ net-value
|= val=sats
^- sats
=/ cost (mul (input-weight:btc bipt.w) feyb)
=/ cost (mul (input-weight:bc bipt.w) feyb)
?: (lte val cost) 0
(sub val cost)
::
:: +spendable: whether utxo has enough confs to spend
::
++ spendable
|= =utxo:btc ^- ?
|= =utxo:bc ^- ?
(gte (num-confs last-block utxo) confs.w)
:: +with-change:
:: - choose UTXOs, if there are enough
@ -296,7 +303,7 @@
?~ tb [~ ~]
=+ excess=~(fee txb u.tb) :: (inputs - outputs)
=/ new-fee=sats :: cost of this tx + one more output
(mul feyb (add (output-weight:btc bipt.w) vbytes.u.tb))
(mul feyb (add (output-weight:bc bipt.w) vbytes.u.tb))
?. (gth excess new-fee)
[tb ~]
?. (gth (sub excess new-fee) (dust-threshold bipt.w))
@ -310,7 +317,7 @@
?. %+ levy txos
|= =txo
%+ gth value.txo
(dust-threshold (address-bipt:btc address.txo))
(dust-threshold (address-bipt:bc address.txo))
~|("One or more suggested outputs is dust." !!)
=/ is=(unit (list insel))
%- single-random-draw
@ -323,7 +330,7 @@
|= =addi
^- (list insel)
%+ turn ~(tap in utxos.addi)
|=(=utxo:btc [utxo chyg.addi idx.addi])
|=(=utxo:bc [utxo chyg.addi idx.addi])
--
:: single-random-draw
:: randomly choose utxos until target is hit
@ -334,7 +341,7 @@
^- (unit (list insel))
=/ rng ~(. og eny)
=/ target (add target-value (mul feyb base-weight)) :: add base fees to target
=| [select=(list insel) total=sats:btc]
=| [select=(list insel) total=sats:bc]
|-
?: =(~ is) ~
=^ n rng (rads:rng (lent is))

View File

@ -0,0 +1,12 @@
/- *btc-wallet
|_ intr=internal
++ grad %noun
++ grow
|%
++ noun intr
--
++ grab
|%
++ noun internal
--
--

View File

@ -1,4 +1,4 @@
/- *btc, *resource
/- *bitcoin, *resource
|%
+$ host-info
$: api-url=@t

View File

@ -1,4 +1,4 @@
/- *btc, bp=btc-provider
/- *bitcoin, bp=btc-provider
/+ bip32
|%
+$ params [batch-size=@ud fam-limit=@ud piym-limit=@ud]
@ -9,6 +9,8 @@
+$ piym [ps=(map ship payment) pend=(map txid payment) num-fam=(map ship @ud)]
+$ poym (unit txbu)
::
:: command: run from the CLI or as API calls by our ship
::
+$ command
$% [%set-provider provider=ship]
[%set-current-wallet =xpub]
@ -17,19 +19,21 @@
[%req-pay-address payee=ship value=sats feyb=sats]
[%broadcast-tx txhex=cord]
==
:: action: how peers poke us
::
+$ action
:: local-only actions
::
$% [%close-pym ti=info:tx]
[%add-poym-raw-txi =txid rawtx=hexb]
[%fail-broadcast-tx =txid]
[%succeed-broadcast-tx =txid]
:: peer actions
::
[%gen-pay-address value=sats]
$% [%gen-pay-address value=sats]
[%recv-pay-address =address value=sats]
[%expect-payment =txid value=sats]
==
:: internal: actions that simply make the state machine more explicit
::
+$ internal
$% [%add-poym-raw-txi =txid rawtx=hexb]
[%close-pym ti=info:tx]
[%fail-broadcast-tx =txid]
[%succeed-broadcast-tx =txid]
==
::
::
:: Wallet Types

View File

@ -1,4 +1,4 @@
/+ *test, *btc, bip32
/+ *test, *bitcoin, bip32
=, secp:crypto
=+ ecc=secp256k1
|%