diff --git a/BTC.scratch.md b/BTC.scratch.md index 7e127c358e..9060db63fa 100644 --- a/BTC.scratch.md +++ b/BTC.scratch.md @@ -4,11 +4,15 @@ The below requires norsyr's fix to `decompress-point` in order to work. ## Set Credentials and Ping Servers (don't need password if all run on localhost) ``` -=rpc-pass '57a6662a8ddb792a557e9fe6d1a731f954db6c35e75a91e823ab20ea7a33585b' -:btc-provider|command [%set-credentials [rpc-url='http://localhost:8332' rpc-user='__cookie__' rpc-pass] [rpc-url='http://localhost:50002']]=rpc-pass '57a6662a8ddb792a557e9fe6d1a731f954db6c35e75a91e823ab20ea7a33585b' +=rpc-pass 'c7dc0698a2e3a5d66096152b34c273b8fbcc821e9d49f2ac706e38307d3441c5' :btc-provider|command [%set-credentials [rpc-url='http://localhost:8332' rpc-user='__cookie__' rpc-pass] [rpc-url='http://localhost:50002']] -:btc-provider|action [%watch-address [%bech32 'bc1q59u5epktervh6fxqay2dlph0wxu9hjnx6v8n66'']] +:btc-provider|action [%address-info [%bech32 'bc1q59u5epktervh6fxqay2dlph0wxu9hjnx6v8n66']] +:btc-provider|action [%address-info [%bech32 'bc1qlwd7mw33uea5m8r2lsnsrkc7gp2qynrxsfxpfm']] +:btc-provider|action [%address-info [%bech32 'bc1qglkc9zfcn04vcc88nn0ljtxcpu5uxfznc3829k']] +:: first is an address w balance +:: second has no balance but is used +:: third is unused ``` ## Transactions diff --git a/app/btc-provider.hoon b/app/btc-provider.hoon index 731536f97d..c5d42b72d8 100644 --- a/app/btc-provider.hoon +++ b/app/btc-provider.hoon @@ -6,7 +6,8 @@ :: current connection state :: results/errors of RPC calls :: -/+ *btc-provider, dbug, default-agent +/- btc +/+ *btc-provider, dbug, default-agent, elib=electrum-rpc |% +$ versioned-state $% state-0 @@ -105,44 +106,44 @@ ++ start-ping-timer |= interval=@dr ^- card [%pass /ping-timer %arvo %b %wait (add now.bowl interval)] -:: only %ping works if we're not connected +:: if not connected, only %ping action works :: ++ handle-action |= act=action - |^ ^- (quip card _state) - ?: ?&(?!(connected.host-info) ?!(=(-.act %ping))) + ^- (quip card _state) + ?. ?|(connected.host-info =(-.act %ping)) ~& >>> "Not connected to RPC" [~[(send-update [%| [%not-connected 500]])] state] =/ ract=action:rpc ?- -.act - %watch-address + %address-info [%erpc %get-address-utxos address.act] :: %ping [%brpc %get-block-count ~] == - [~[(req-card ract)] state] - ++ req-card - |= ract=action:rpc - =| out=outbound-config:iris - =/ req=request:http - (gen-request host-info ract) - [%pass /[-.act]/[-.ract]/[(scot %da now.bowl)] %arvo %i %request req out] - -- -:: wire structure -:: /action-tas/rpc-action-tas/timestamp + [~[(req-card act ract)] state] +++ req-card + |= [act=action ract=action:rpc] + =| out=outbound-config:iris + =/ req=request:http + (gen-request host-info ract) + [%pass (mk-wire act ract) %arvo %i %request req out] +:: Wire structure: /action-tas/rpc-action-tas/(address, if %erpc action)/now +:: +++ mk-wire + |= [act=action ract=action:rpc] + ^- wire + =/ addr=path + ?:(?=(%erpc -.ract) /(address-to-cord:elib address.ract) /) + %- zing ~[/[-.act]/[-.ract] addr /[(scot %da now.bowl)]] :: -:: TODO use the 2 below to handle responses -:: ~& > (parse-response:btc-rpc:blib rpc-resp) -:: ~& >> (to-response (rpc-response [%erpc (parse-response:electrum-rpc:elib rpc-resp)])) ++ handle-rpc-response |= [=wire response=client-response:iris] ^- (quip card _state) ?. ?=(%finished -.response) `state =* status status-code.response-header.response - :: handle error types, in order: - :: - connection errors - :: - RPC errors + :: handle error types: connection errors, RPC errors (in order) :: =^ conn-err state (connection-error status) @@ -153,14 +154,28 @@ (get-rpc-response response) ?. ?=([%result *] rpc-resp) [~[(send-update [%| [%rpc-error ~]])] state] - :: no error, so handle returned RPC data + :: no error, switch on wire to handle RPC data :: ?+ wire ~|("Unexpected HTTP response" !!) - [%watch-address %erpc *] - :: use the %erpc parser here - ~& >> +<.wire :: %brpc/%erpc - ~& > rpc-resp - `state + [%address-info %erpc @ *] + =/ addr=address:btc (address-from-cord:elib +>-.wire) + =/ eresp (parse-response:electrum-rpc:elib rpc-resp) + :_ state + ^- (list card) + :~ ?- -.eresp + %get-address-utxos + ?: =(0 ~(wyt in utxos.eresp)) + (req-card [%address-info addr] [%erpc %get-address-history addr]) + (send-update [%& %address-info addr utxos.eresp %.y]) + :: + %get-address-history + %- send-update + :* %& %address-info addr *(set utxo:btc) + ?:(=(0 ~(wyt in txs.eresp)) %.n %.y) + == + == + == + :: [%ping %brpc *] `state(connected.host-info %.y) == @@ -183,6 +198,7 @@ :: ++ send-update |= =update ^- card + ~& >> "send-update: {}" [%give %fact [/clients]~ %btc-provider-update !>(update)] :: ++ is-whitelisted diff --git a/lib/electrum-rpc.hoon b/lib/electrum-rpc.hoon index 9aaa81f4f9..a353498040 100644 --- a/lib/electrum-rpc.hoon +++ b/lib/electrum-rpc.hoon @@ -5,6 +5,14 @@ ?: ?=([%legacy *] address) (scot %uc +.address) +.address +:: +++ address-from-cord + |= addrc=@t ^- address + ?. ?| =("bc1" (scag 3 (trip addrc))) + =("tb1" (scag 3 (trip addrc))) + == + ~|("legacy addresses not yet supported" !!) + [%bech32 addrc] ++ to-hex |= h=@t ^- @ux @@ -39,6 +47,9 @@ ?+ id.res ~|([%unsupported-response id.res] !!) %get-address-utxos [id.res ((as:dejs:format utxo) res.res)] + :: + %get-address-history + [id.res ((as:dejs:format history) res.res)] == ++ utxo %- ot:dejs:format @@ -47,22 +58,29 @@ [%height ni:dejs:format] [%value ni:dejs:format] == + ++ history + %- ot:dejs:format + :~ ['tx_hash' (cu:dejs:format to-hash256 so:dejs:format)] + [%height ni:dejs:format] + == -- :: ++ request-to-http |= [endpoint=@t req=request:electrum:rpc] - ^- request:http + |^ ^- request:http %- http-request - ?- -.req - %get-address-balance - %^ cat 3 - (cat 3 endpoint '/addresses/balance/') - (address-to-cord address.req) - :: + ?- method.req %get-address-utxos - %^ cat 3 - (cat 3 endpoint '/addresses/utxos/') - (address-to-cord address.req) + (mk-url '/addresses/utxos/' address.req) + :: + %get-address-history + (mk-url '/addresses/history/' address.req) == + ++ mk-url + |= [base=@t addr=address] + %^ cat 3 + (cat 3 endpoint base) + (address-to-cord addr) + -- -- -- diff --git a/sur/btc-provider.hoon b/sur/btc-provider.hoon index 48ae2126c1..543c73ee23 100644 --- a/sur/btc-provider.hoon +++ b/sur/btc-provider.hoon @@ -5,11 +5,11 @@ +$ credentials [bc=btc-credentials ec=electrum-credentials] +$ host-info [creds=credentials connected=? clients=(set ship)] +$ action - $% [%watch-address =address] + $% [%address-info =address] [%ping ~] == +$ result - $% [%watch-address a=address utxos=(set utxo) used=?] + $% [%address-info a=address utxos=(set utxo) used=?] == +$ error $% [%not-connected status=@ud] @@ -45,5 +45,4 @@ +$ response btc-node-hook-response:brpc -- -- - -- diff --git a/sur/btc.hoon b/sur/btc.hoon index b8b9055d88..0336a1fe7e 100644 --- a/sur/btc.hoon +++ b/sur/btc.hoon @@ -10,7 +10,7 @@ +$ hash160 [wid=%20 dat=@ux] +$ hash ?(hash256 hash160) +$ buffer (list @ux) -+$ utxo [pos=@ tx-hash=hash256 block-height=@ value=sats] ++$ utxo [pos=@ tx-hash=hash256 height=@ value=sats] ++ address-info $: =address confirmed-value=sats diff --git a/sur/electrum-rpc.hoon b/sur/electrum-rpc.hoon index 9a48bdd0f2..6a37bc91d1 100644 --- a/sur/electrum-rpc.hoon +++ b/sur/electrum-rpc.hoon @@ -1,10 +1,12 @@ /- *btc |% -+$ request - $% [%get-address-balance =address] - [%get-address-utxos =address] ++$ method + $? %get-address-utxos + %get-address-history == ++$ request [=method =address] +$ response $% [%get-address-utxos utxos=(set utxo)] -== + [%get-address-history txs=(set [tx=hash256 height=@])] + == --