From ec6b540483e3fcd5c1ff20029985e58e744380b7 Mon Sep 17 00:00:00 2001 From: timlucmiptev Date: Fri, 2 Oct 2020 08:48:58 +0300 Subject: [PATCH] w btc-node --- app/btc-node-hook.hoon | 358 ++++ app/btc-node-store.hoon | 156 ++ gen/btc-node-hook/action.hoon | 9 + gen/btc-node-hook/command.hoon | 16 + gen/btc-node-store/command.hoon | 16 + lib/btc-node-json.hoon | 2821 +++++++++++++++++++++++++++++++ sur/btc-node-hook.hoon | 2028 ++++++++++++++++++++++ sur/btc-node-store.hoon | 155 ++ 8 files changed, 5559 insertions(+) create mode 100644 app/btc-node-hook.hoon create mode 100644 app/btc-node-store.hoon create mode 100644 gen/btc-node-hook/action.hoon create mode 100644 gen/btc-node-hook/command.hoon create mode 100644 gen/btc-node-store/command.hoon create mode 100644 lib/btc-node-json.hoon create mode 100644 sur/btc-node-hook.hoon create mode 100644 sur/btc-node-store.hoon diff --git a/app/btc-node-hook.hoon b/app/btc-node-hook.hoon new file mode 100644 index 0000000000..67a84c726f --- /dev/null +++ b/app/btc-node-hook.hoon @@ -0,0 +1,358 @@ +:: btc-node-hook: send JSON rpc requests to bitcoin full node +:: and poke the responses into the btc-node-store +:: +/- *btc-node-hook, *btc-node-store, sole +/+ default-agent, sole, base64, lib=btc-node-json, verb +:: +=> |% + +$ card card:agent:gall + +$ versioned-state + $% [%0 state-zero] + == + :: + +$ state-zero + $: user=@t + pass=@t + endpoint=@t + == + -- +:: +=| state-zero +=* state - +:: Main +:: +%+ verb | +^- agent:gall +=< |_ =bowl:gall + +* this . + btc-core +> + bc ~(. btc-core bowl) + def ~(. (default-agent this %|) bowl) + :: + ++ on-init + ^- (quip card _this) + [~ this(user '', pass '', endpoint '')] + :: + ++ on-save !>(state) + ++ on-load + |= old=vase + `this(state !<(state-zero old)) + :: + ++ on-poke + |= [=mark =vase] + ^- (quip card _this) + =^ cards state + ?+ mark (on-poke:def mark vase) + %btc-node-hook-action + (handle-action:bc !<(btc-node-hook-action vase)) + :: + %btc-node-hook-command + (handle-command:bc !<(btc-node-hook-command vase)) + == + [cards this] + :: + ++ on-watch on-watch:def + ++ on-leave on-leave:def + ++ on-peek on-peek:def + ++ on-agent on-agent:def + ++ on-arvo + |= [=wire =sign-arvo] + ^- (quip card _this) + =* response client-response.sign-arvo + =^ cards state + ?+ +<.sign-arvo (on-arvo:def wire sign-arvo) + %http-response (http-response:bc wire response) + == + [cards this] + :: + ++ on-fail on-fail:def + -- +:: +|_ =bowl:gall +:: +++ handle-action + |= act=btc-node-hook-action + ^- (quip card _state) + =/ body=request:rpc:jstd + (request-to-rpc:btc-rpc:lib act) + =/ =header-list:http + :~ ['Content-Type' 'application/json'] + :- 'Authorization' + ;: (cury cat 3) + 'Basic ' + %- ~(en base64 | &) + (as-octs:mimes:html :((cury cat 3) user ':' pass)) + == == + =/ req=request:http + :* %'POST' + (endpoint-url act) + header-list + =, html + %- some + %- as-octt:mimes + (en-json (request-to-json:rpc:jstd body)) + == + =/ out *outbound-config:iris + :_ state + [%pass /[(scot %da now.bowl)] %arvo %i %request req out]~ +:: +++ handle-command + |= comm=btc-node-hook-command + ^- (quip card _state) + ?+ -.comm ~| [%unsupported-hook-command -.comm] !! + %credentials + :_ state(endpoint url.comm, user user.comm, pass pass.comm) + [%pass / %arvo %d %flog [%text "credentials updated..."]]~ + == +:: +++ httr-to-rpc-response + |= hit=httr:eyre + ^- response:rpc:jstd + ~| hit + =/ jon=json (need (de-json:html q:(need r.hit))) + ?. =(%2 (div p.hit 100)) + (parse-error jon) + =, dejs-soft:format + ^- response:rpc:jstd + =; dere + =+ res=((ar dere) jon) + ?~ res (need (dere jon)) + [%batch u.res] + |= jon=json + ^- (unit response:rpc:jstd) + =/ res=[id=(unit @t) res=(unit json) err=(unit json)] + %. jon + =, dejs:format + =- (ou -) + :~ ['id' (uf ~ (mu so))] + ['result' (uf ~ (mu same))] + ['error' (uf ~ (mu same))] + == + ?: ?=([^ * ~] res) + `[%result [u.id.res ?~(res.res ~ u.res.res)]] + ~| jon + `(parse-error jon) +:: +++ parse-error + |= =json + ^- response:rpc:jstd + :- %error + ?~ json ['' '' ''] + %. json + =, dejs:format + =- (ou -) + :~ =- ['id' (uf '' (cu - (mu so)))] + |*(a=(unit) ?~(a '' u.a)) + :- 'error' + =- (uf ['' ''] -) + =- (cu |*(a=(unit) ?~(a ['' ''] u.a)) (mu (ou -))) + :~ ['code' (uf '' no)] + ['message' (uf '' so)] + == == +:: +++ http-response + |= [=wire response=client-response:iris] + ^- (quip card _state) + ?. ?=(%finished -.response) + [~ state] + =* status status-code.response-header.response + =/ rpc-resp=response:rpc:jstd + %- httr-to-rpc-response + %+ to-httr:iris + response-header.response + full-file.response + ?. ?=([%result *] rpc-resp) + ~& [%error +.rpc-resp] + [~ state] + %- handle-btc-response + (parse-response:btc-rpc:lib rpc-resp) +:: +++ handle-btc-response + |= btc-resp=btc-node-hook-response + ^- (quip card _state) + :_ state + ^- (list card) + ?+ -.btc-resp + :: By default we just print all RPC responses that are not + :: considered here explicitly for proper format printing or + :: for being passed on to the store app. + :: + ~&(btc-resp ~) + :: + :: %abandon-transaction + :: %abort-rescan + :: %add-multisig-address + :: %backup-wallet + :: %bump-fee + %create-wallet + =/ btc-store-req=btc-node-store-action + :+ %add-wallet name.btc-resp + ?:(=('' warning.btc-resp) ~ (some warning.btc-resp)) + [(btc-node-store-poke /store btc-store-req)]~ + :: + :: %dump-privkey + :: %dump-wallet + :: %encrypt-wallet + :: %get-addresses-by-label + :: + %get-address-info + ~&([%address-info +.btc-resp] ~) + :: + %get-balance + ~&([%amount (trip +.btc-resp)] ~) + :: + :: %get-balance + :: %get-new-address + :: %get-raw-change-address + :: %get-received-by-address + :: %get-received-by-label + :: %get-transaction + :: %get-unconfirmed-balance + :: + %get-wallet-info + ^- (list card) + =/ btc-store-req=btc-node-store-action + [%update-wallet wallet-name.btc-resp +>:btc-resp] + [(btc-node-store-poke /update btc-store-req)]~ + :: + :: %import-address + :: %import-multi + :: %import-privkey + :: %import-pruned-funds + :: %import-pubkey + :: %import-wallet + :: %key-pool-refill + :: %list-address-groupings + :: %list-labels + :: %list-lock-unspent + :: %list-received-by-address + :: %list-received-by-label + :: %lists-in-ceblock + :: + %list-transactions + ~&([%transactions +.btc-resp] ~) + :: + :: %list-unspent + :: %list-wallet-dir + :: + %list-wallets + ^- (list card) + :~ (btc-node-store-poke /list-wallets [%list-wallets ~]) + :* %pass / %arvo %d %flog + %text "remote-wallets={<`wain`wallets.btc-resp>}" + == == + :: + %load-wallet + [(btc-node-store-poke /load [%load-wallet name.btc-resp])]~ + :: + :: %lock-unspent + :: %remove-pruned-funds + :: %rescan-blockchain + :: %send-many + :: %send-to-address + :: %set-hd-seed + :: %set-label + :: %set-tx-fee + :: %sign-message + :: %sign-raw-transaction-with-wallet + :: %unload-wallet + :: %wallet-create-fundedpsbt + :: %wallet-lock + :: %wallet-passphrase + :: %wallet-passphrase-change + :: %wallet-process-psbt + == +:: +++ btc-node-store-poke + |= [=wire act=btc-node-store-action] + ^- card + :* %pass + wire + %agent + [our.bowl %btc-node-store] + %poke + [%btc-node-store-action !>(act)] + == +:: +++ default-wallet + .^ @t + %gx + (scot %p our.bowl) + %btc-node-store + (scot %da now.bowl) + /default-wallet/noun + == +:: +++ n-wallets + .^ @ud + %gx + (scot %p our.bowl) + %btc-node-store + (scot %da now.bowl) + /n-wallets/noun + == +:: +++ endpoint-url + |= [act=btc-node-hook-action] + ^- @t + ?. ?| ?=(%abandon-transaction -.act) + ?=(%abort-rescan -.act) + ?=(%add-multisig-address -.act) + ?=(%backup-wallet -.act) + ?=(%bump-fee -.act) + ?=(%dump-privkey -.act) + ?=(%dump-wallet -.act) + ?=(%encrypt-wallet -.act) + ?=(%fund-raw-transaction -.act) + ?=(%get-balance -.act) + ?=(%get-balances -.act) + ?=(%get-addresses-by-label -.act) + ?=(%get-address-info -.act) + ?=(%get-new-address -.act) + ?=(%get-raw-change-address -.act) + ?=(%get-received-by-address -.act) + ?=(%get-received-by-label -.act) + ?=(%get-transaction -.act) + ?=(%get-unconfirmed-balance -.act) + ?=(%get-wallet-info -.act) + ?=(%import-address -.act) + ?=(%import-multi -.act) + ?=(%import-privkey -.act) + ?=(%import-pruned-funds -.act) + ?=(%import-pubkey -.act) + ?=(%import-wallet -.act) + ?=(%key-pool-refill -.act) + ?=(%list-address-groupings -.act) + ?=(%list-labels -.act) + ?=(%list-lock-unspent -.act) + ?=(%list-received-by-address -.act) + ?=(%list-received-by-label -.act) + ?=(%lists-in-ceblock -.act) + ?=(%list-transactions -.act) + ?=(%list-unspent -.act) + ?=(%lock-unspent -.act) + ?=(%remove-pruned-funds -.act) + ?=(%rescan-blockchain -.act) + ?=(%send-many -.act) + ?=(%send-to-address -.act) + ?=(%set-hd-seed -.act) + ?=(%set-label -.act) + ?=(%set-tx-fee -.act) + ?=(%sign-message -.act) + ?=(%sign-raw-transaction-with-wallet -.act) + ?=(%wallet-create-fundedpsbt -.act) + ?=(%wallet-lock -.act) + ?=(%wallet-passphrase -.act) + ?=(%wallet-passphrase-change -.act) + ?=(%wallet-process-psbt -.act) + == + endpoint + ;: (cury cat 3) + endpoint + 'wallet/' + :: + ?: ?=([?(%dump-wallet %import-wallet) filename=@t] act) + filename.act + default-wallet + == +-- diff --git a/app/btc-node-store.hoon b/app/btc-node-store.hoon new file mode 100644 index 0000000000..6488538f72 --- /dev/null +++ b/app/btc-node-store.hoon @@ -0,0 +1,156 @@ +:: btc-node-store: data store for state received from a bitcoin full node +:: +:: data: scry command: +:: +:: default-wallet .^(@t %gx /=btc-node-store=/default-wallet/noun) +:: n-wallets .^(@ud %gx /=btc-node-store=/n-wallets/noun) +:: [def-wallet attr] .^((unit wallet) %gx /=btc-node-store=/wallet/noun) +:: [name attr] .^((unit wallet) %gx /=btc-node-store=/wallet//noun) +:: +:: +/- *btc-node-store +/+ *btc-node-json, default-agent, verb +:: +=> |% + :: + +$ card card:agent:gall + :: + +$ state + $% [%0 state-zero] + == + :: + +$ state-zero + $: =wallets + default-wallet=@t + == + -- +:: +=| state-zero +=* state - +:: Main +:: +%+ verb | +^- agent:gall +=< |_ =bowl:gall + +* this . + btc-core +> + bc ~(. btc-core bowl) + def ~(. (default-agent this %|) bowl) + :: + ++ on-init + ^- (quip card _this) + :- ~ + %_ this + wallets (~(put by wallets) [*@t *wallet]) + == + :: + ++ on-save !>(state) + ++ on-load + |= old=vase + `this(state !<(state-zero old)) + :: + ++ on-poke + |= [=mark =vase] + ^- (quip card _this) + |^ + ?+ mark (on-poke:def mark vase) + %btc-node-store-action + (store-action !<(btc-node-store-action vase)) + :: + %btc-node-store-command + (store-command !<(btc-node-store-command vase)) + == + :: + ++ store-action + |= action=btc-node-store-action + ^- (quip card _this) + =^ cards state + ?+ -.action ~|([%unsupported-action -.action] !!) + %add-wallet (handle-add:bc +.action) + %load-wallet (handle-switch:bc +.action) + %list-wallets handle-list-wallet:bc + %update-wallet (handle-update-wallet:bc +.action) + == + [cards this] + :: + ++ store-command + |= command=btc-node-store-command + ^- (quip card _this) + =^ cards state + ?+ -.command ~|([%unsupported-command -.command] !!) + %switch-wallet (handle-switch:bc +.command) + == + [cards this] + -- + ++ on-watch on-watch:def + ++ on-leave on-leave:def + :: +on-peek: read from app state + :: + ++ on-peek + |= =path + ^- (unit (unit cage)) + ?+ path (on-peek:def path) + [%x %default-wallet ~] ``noun+!>(default-wallet) + [%x %n-wallets ~] ``noun+!>(~(wyt by wallets)) + [%x %wallet @t ~] ``noun+!>((~(get by wallets) i.t.t.path)) + [%x %wallet ~] ``noun+!>((~(get by wallets) default-wallet)) + == + :: + ++ on-agent on-agent:def + ++ on-arvo on-arvo:def + ++ on-fail on-fail:def + -- +:: +|_ =bowl:gall +:: +++ handle-add + |= [name=@t warning=(unit @t)] + ^- (quip card _state) + ?: (~(has by wallets) name) + ~& "This wallet already exists..." + [~ state] + :- ~ + ~& "Wallet {} added succesfully..." + %_ state + wallets (~(put by wallets) [name name ~]) + == +:: +++ handle-list-wallet + ^- (quip card _state) + =/ wallet-names=(list @t) + (turn ~(tap by wallets) |=([n=@t *] n)) + :_ state + :_ ~ + :* %pass / %arvo %d %flog + %text "local-wallets={<`wain`wallet-names>}" + == +:: +++ handle-update-wallet + |= [name=@t attrs=wallet-attr] + ^- (quip card _state) + =/ w=wallet [name (some attrs)] + :- ~ + %_ state + wallets + ?: (~(has by wallets) name.w) + ~& "The wallet exists. Updating..." + (~(put by wallets) name.w w) + :: + ~& "The wallet doesn't exist. Creating..." + (~(put by wallets) [name.w w]) + == +:: +++ handle-switch + |= name=@t + ^- (quip card _state) + :_ state(default-wallet name) + :_ ~ + :* %pass / %arvo %d %flog + %text + %+ weld + "New default-wallet: {}" + ?: (~(has by wallets) name) + "" + " (wallet is not local)" + == +-- diff --git a/gen/btc-node-hook/action.hoon b/gen/btc-node-hook/action.hoon new file mode 100644 index 0000000000..092b91aa11 --- /dev/null +++ b/gen/btc-node-hook/action.hoon @@ -0,0 +1,9 @@ +:: Sends an action to the BTC hook app +:: +/- *btc-node-hook +:: +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[act=btc-node-hook-action ~] ~] + == +[%btc-node-hook-action act] diff --git a/gen/btc-node-hook/command.hoon b/gen/btc-node-hook/command.hoon new file mode 100644 index 0000000000..84035a8265 --- /dev/null +++ b/gen/btc-node-hook/command.hoon @@ -0,0 +1,16 @@ +:: Sends a command to the BTC hook app +:: +:: Commands: +:: +:: [%credentials 'http://127.0.0.1:18443/' 'user' 'password'] +:: +/- *btc-node-hook +:: +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[comm=btc-node-hook-command ~] ~] + == +:- %btc-node-hook-command +?+ -.comm ~| [%unsupported-command -.comm] !! + %credentials comm +== diff --git a/gen/btc-node-store/command.hoon b/gen/btc-node-store/command.hoon new file mode 100644 index 0000000000..fe0b3eb0b1 --- /dev/null +++ b/gen/btc-node-store/command.hoon @@ -0,0 +1,16 @@ +:: Sends a command to the BTC store app +:: +:: Commands: +:: +:: > :btc-node-store|command [%switch-wallet 'local'] +:: +/- *btc-node-store +:: +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[comm=btc-node-store-command ~] ~] + == +:- %btc-node-store-command +?+ -.comm ~|([%unsupported-command -.comm] !!) + %switch-wallet comm +== diff --git a/lib/btc-node-json.hoon b/lib/btc-node-json.hoon new file mode 100644 index 0000000000..40b86deed8 --- /dev/null +++ b/lib/btc-node-json.hoon @@ -0,0 +1,2821 @@ +/- *btc-node-hook +/+ base64 +=, format +=> =, dejs + |% + :: %ferm: Checks the unit for ~ and returns a json e.g. [%s @ta] + :: + ++ ferm |*([a=(unit) t=term] ?~(a ~ t^u.a)) + :: %feud: Checks the unit for ~ and returns a [%n @ud] json + :: + ++ feud |=(a=(unit @u) ?~(a ~ (numb:enjs u.a))) + :: %method: Removes 'hep' (-) from a %tas producing the RPC method + :: + :: (e.g. %add-multisig-address -> 'addmultisigaddress') + :: + ++ method + |= t=@t + ^- @t + %+ scan (scow %tas t) + ((slug |=(a=[@ @t] (cat 3 a))) (star hep) alp) + :: %groups: used in %list-address-groupings + :: + ++ groups + |= l=(list @t) + ^- (list [?(@uc [%bech32 @t]) @t (unit @t)]) + ?> ?=([@t @t *] l) + :_ ~ + :* (addr-type-validator i.l) + :: + i.t.l + :: + ?~ t.t.l + ~ + (some i.t.t.l) + == + :: %base58-to-cord: parses @uc to BTC addresses (legacy and p2sh) + :: + ++ base58-to-cord + |= b=@uc + ^- @t + :: Removes leading 0c + :: + (rsh 3 2 (scot %uc b)) + :: %hex-to-cord: parses hexadecimal to cords without dots and 0x + :: + ++ hex-to-cord + |= h=@ux + ^- @t + %- crip + =- ((x-co:co (mul 2 p)) q) + (as-octs:mimes:html h) + :: + ++ hash-to-cord + |= h=@ux + ^- @t + %- crip + :: extend with zeros up to 64 bytes + :: + ((x-co:co 64) h) + :: %addr-type-validator: parses BTC addresses (legacy and p2sh) to @uc + :: + :: bech32/segwit addressed are tagged separately. + :: + ++ addr-type-validator + |= addr=@t + ^- ?(@uc [%bech32 @t]) + =, dejs + =/ res=(unit @u) (rush addr fim:ag) + ?~ res + :: TODO: fim:ag doesn't parse %bech32 addresses + :: + bech32+addr + `@uc`u.res + :: %to-hex: parses hexadecimal to @ux with separator dots and 0x + :: + ++ to-hex + |= h=@t + ^- @ux + ?: =('' h) 0x0 + :: Add leading 00 + :: + =+ (lsh 3 2 h) + :: Group by 4-size block + :: + =+ (rsh 3 2 -) + :: Parse hex to atom + :: + `@ux`(rash - hex) + :: + ++ ip-port-to-cord + |= [ip=@if port=@ud] + %- crip + :(weld (slag 1 (scow %if ip)) ":" ((d-co:co 1) port)) + :: + ++ to-wall + |= =tape + ^- wall + %+ roll (flop tape) + |= [char=@tD =wall] + ?~ wall + [[char ~] ~] + ?: =('\0a' char) + [~ wall] + [[char i.wall] t.wall] + :: + ++ json-parser + |% + :: %vin:json-parser + :: + :: Used in: + :: - $raw-transaction:json-parser + :: - %decode-psbt + :: - %decode-raw-transaction + :: + ++ vin + =- (ar (ou -)) + :~ ['txid' (uf ~ (mu (cu to-hex so)))] + ['vout' (uf ~ (mu ni))] + :: + :- 'scriptSig' + =- (uf ~ (mu (ot -))) + :~ ['asm' so] + :: + ['hex' (cu to-hex so)] + == + :: + :- 'txinwitness' + =- (uf ~ (mu -)) + (ar (cu to-hex so)) + :: + ['sequence' (un ni)] + == + :: %vout:json-parser + :: + :: Used in: + :: - $raw-transaction:json-parser + :: - %decode-psbt + :: - %decode-raw-transaction + :: + ++ vout + =- (ar (ot -)) + :~ ['value' no] + ['n' ni] + :: + :- 'scriptPubKey' + %- ou + :~ ['asm' (un so)] + ['hex' (un (cu to-hex so))] + ['reqSigs' (uf ~ (mu ni))] + ['type' (un so)] + :: + :- 'addresses' + =- (uf ~ (mu -)) + (ar (cu addr-type-validator so)) + == == + :: %script:json-parser + :: + :: Used in: + :: - %decode-psbt + :: + ++ script + =- (uf ~ (mu (ot -))) + :~ ['asm' so] + ['hex' (cu to-hex so)] + ['type' so] + == + :: %utxo:json-parser + :: + :: Used in: + :: - %decode-psbt + :: + ++ utxo + =- (uf ~ (mu (ot -))) + :~ ['amount' no] + :: + :- 'scriptPubKey' + %- ot + :~ ['asm' so] + ['hex' (cu to-hex so)] + ['type' so] + ['address' (cu addr-type-validator so)] + == == + :: %raw-transaction:json-parser + :: + :: Used in: + :: - %get-block + :: - %get-raw-transaction + :: - %import-pruned-funds + :: + ++ raw-transaction + %- ou + =, json-parser + :~ ['in_active_chain' (uf ~ (mu bo))] + ['hex' (un (cu to-hex so))] + ['txid' (un (cu to-hex so))] + ['hash' (un (cu to-hex so))] + ['size' (un ni)] + ['vsize' (un ni)] + ['weight' (un ni)] + ['version' (un no)] + ['locktime' (un ni)] + ['vin' (un vin)] + ['vout' (un vout)] + ['blockhash' (uf ~ (mu (cu to-hex so)))] + ['confirmations' (uf ~ (mu ni))] + ['blocktime' (uf ~ (mu ni))] + ['time' (uf ~ (mu ni))] + == + :: %mem-pool:json-parser + :: + :: Used in: + :: - %get-raw-mempool + :: - %get-mempool-ancestors + :: - %get-mempool-descendants + :: - %get-mempool-entry + :: + ++ mem-pool + %- ou + :~ ['size' (uf ~ (mu ni))] + ['vsize' (un ni)] + ['weight' (un ni)] + ['fee' (un no)] + ['modifiedfee' (un no)] + ['time' (un ni)] + ['height' (un ni)] + ['descendantcount' (un ni)] + ['descendantsize' (un ni)] + ['descendantfees' (un no)] + ['ancestorcount' (un ni)] + ['ancestorsize' (un ni)] + ['ancestorfees' (un no)] + ['wtxid' (un (cu to-hex so))] + :: + :- 'fees' + %- un + %- ot + :~ ['base' no] + ['modified' no] + ['ancestor' no] + ['descendant' no] + == + :: + ['depends' (un (ar (cu to-hex so)))] + ['spentby' (un (ar (cu to-hex so)))] + ['bip125-replaceable' (un bo)] + == + :: %tx-in-block:json-parser + :: + :: Used in: + :: - %get-block + :: - %get-raw-transaction + :: + ++ tx-in-block + =- (ar (ou -)) + :~ ['address' (uf ~ (mu (cu addr-type-validator so)))] + ['category' (un (cu category so))] + ['amount' (un no)] + ['label' (uf ~ (mu so))] + ['vout' (un ni)] + ['fee' (uf ~ (mu no))] + ['confirmations' (un ni)] + ['blockhash' (uf ~ (mu (cu to-hex so)))] + ['blockindex' (uf ~ (mu ni))] + ['blocktime' (uf ~ (mu ni))] + ['txid' (un (cu to-hex so))] + ['time' (un ni)] + ['timereceived' (uf ~ (mu ni))] + :: + :- 'walletconflicts' + =- (uf ~ (mu -)) + (ar (cu to-hex so)) + :: + ['bip125-replaceable' (un (cu bip125-replaceable so))] + ['abandoned' (uf ~ (mu bo))] + ['comment' (uf ~ (mu so))] + ['to' (uf ~ (mu so))] + == + :: %prev-txs:json-parser + :: + :: Used in: + :: - %sign-raw-transaction-with-key + :: - %sign-raw-transaction-with-wallet + :: + ++ prev-txs + |= t=prev-tx + ^- (list (pair @t json)) + :~ ['txid' s+(hash-to-cord txid.t)] + ['vout' (numb:enjs:format vout.t)] + ['scriptPubKey' s+(hex-to-cord script-pubkey.t)] + :: + :- 'redeemScript' + ?~ redeem-script.t + ~ + s+(hex-to-cord u.redeem-script.t) + :: + :- 'witnessScript' + ?~ witness-script.t + ~ + s+(hex-to-cord u.witness-script.t) + :: + ['amount' n+amount.t] + == + -- + -- +|% +++ btc-rpc + =, ^btc-rpc + |% + ++ request-to-rpc + =, enjs:format + |= req=request + ^- request:rpc:jstd + :^ -.req (method -.req) %list + ^- (list json) + ?- -.req + :: Blockchain + :: + %get-best-block-hash + ~ + :: + %get-block + ~[s+(hash-to-cord blockhash.req) (feud verbosity.req)] + :: + %get-blockchain-info + ~ + :: + %get-block-count + ~ + :: + %get-block-filter + ~[s+(hash-to-cord block-hash.req) (ferm filter-type.req %s)] + :: + %get-block-hash + ~[(numb height.req)] + :: + %get-block-header + ~[s+(hash-to-cord blockhash.req) (ferm verbose.req %b)] + :: + %get-block-stats + :~ =* h hash-or-height.req + ?- -.h + %num (numb +.h) + %hex s+(hash-to-cord +.h) + == + :: + ?~ stats.req ~ + a+(turn u.stats.req |=(a=@t s+a)) + == + :: + %get-chain-tips + ~ + :: + %get-chain-tx-stats + :~ (feud n-blocks.req) + :: + ?~ blockhash.req + ~ + s+(hash-to-cord u.blockhash.req) + == + :: + %get-difficulty + ~ + :: + %get-mempool-ancestors + ~[s+(hash-to-cord txid.req) (ferm verbose.req %b)] + :: + %get-mempool-descendants + ~[s+(hash-to-cord txid.req) (ferm verbose.req %b)] + :: + %get-mempool-entry + ~[s+(hash-to-cord txid.req)] + :: + %get-mempool-info + ~ + :: + %get-raw-mempool + ~[(ferm verbose.req %b)] + :: + %get-tx-out + :~ s+(hash-to-cord txid.req) + :: + (numb n.req) + :: + (ferm include-mempool.req %b) + == + :: + %get-tx-out-proof + :~ :- %a + %+ turn tx-ids.req + |= a=@ux + s+(hex-to-cord a) + :: + ?~ blockhash.req + ~ + s+(hex-to-cord u.blockhash.req) + == + :: + %get-tx-outset-info + ~ + :: + %precious-block + ~[s+(hash-to-cord blockhash.req)] + :: + %prune-blockchain + ~[(numb height.req)] + :: + %save-mempool + ~ + :: + %scan-tx-outset + :~ s+action.req + :: + :- %a + %+ turn scan-objects.req + |= s-o=scan-object + ^- json + ?@ s-o + s+s-o + ?> ?=([@t (unit range)] s-o) + %- pairs + :~ ['desc' s+desc.object.s-o] + :: + :- 'range' + ^- json + ?~ range.object.s-o + ~ + =* r u.range.object.s-o + ?@ r + (numb r) + a+~[(numb -.r) (numb +.r)] + == == + :: + %verify-chain + ~[(feud check-level.req) (feud n-blocks.req)] + :: + %verify-tx-out-proof + ~[s+proof.req] + :: Control + :: + %get-memory-info + ~ + :: + %get-rpc-info + ~ + :: + %help + ?~ command.req ~ + [%s u.command.req]~ + :: + %logging + :~ ?+ include.req [%a (turn include.req |=(s=logging-category [%s s]))] + %all [%a [%s 'all']~] + %none [%a [%s 'none']~] + == + ?+ exclude.req [%a (turn exclude.req |=(s=logging-category [%s s]))] + %all [%a [%s 'all']~] + %none [%a [%s 'none']~] + == == + :: + %stop + ~ + :: + %uptime + ~ + :: Generating + :: + %generate + :- (numb blocks.req) + ?~ max-tries.req + ~ + [(numb u.max-tries.req) ~] + :: + %generate-to-address + :- (numb n-blocks.req) + :- [%s ?^(address.req +.address.req (base58-to-cord address.req))] + ?~ max-tries.req + ~ + [(numb u.max-tries.req) ~] + :: Mining + :: + %get-block-template + :_ ~ + :- %o + %- molt + ^- (list (pair @t json)) + :- ['rules' [%a (turn rules.req |=(s=rule [%s s]))]] + :- ['capabilities' [%a (turn capabilities.req |=(s=capability [%s s]))]] + ?~ mode.req ~ + ?+ u.mode.req :- ['mode' %s mode.u.mode.req] ~ + [%proposal *] + ?~ workid.u.mode.req + :+ ['mode' %s mode.u.mode.req] + ['data' %s (hex-to-cord data.u.mode.req)] ~ + :^ ['mode' %s mode.u.mode.req] + ['data' %s (hex-to-cord data.u.mode.req)] + ['workid' %s u.workid.u.mode.req] ~ + == + :: + %get-mining-info + ~ + :: + %get-network-hash-ps + :~ ?~ n-blocks.req ~ + (numb u.n-blocks.req) + ?~ height.req ~ + (numb u.height.req) + == + :: + %prioritise-transaction + :~ [%s (hash-to-cord txid.req)] + :: dummy null argument, could be omitted by using named + :: instead of positional json rpc arguments + :: see https://bitcoincore.org/en/doc/0.18.0/rpc/mining/prioritisetransaction/ + ~ + (numb fee-delta.req) + == + :: + %submit-block + [%s (hex-to-cord hex-data.req)]~ + :: + %submit-header + [%s (hex-to-cord hex-data.req)]~ + :: Network + :: + %add-node + :- [%s (ip-port-to-cord node.req port.req)] + :- [%s command.req] + ~ + :: + %clear-banned + ~ + :: + %disconnect-node + ?@ node.req + :_ ~ + [%n node-id.node.req] + :_ ~ + [%s (ip-port-to-cord address.node.req port.node.req)] + :: + %get-added-node-info + ?~ node.req ~ + :_ ~ + =/ ip=cord + =/ a (scow %if u.node.req) + ?~ a '' + (crip t.a) + [%s ip] + :: + %get-connection-count + ~ + :: + %get-net-totals + ~ + :: + %get-network-info + ~ + :: + %get-node-addresses + ?~ count.req ~ + :_ ~ + (numb u.count.req) + :: + %get-peer-info + ~ + :: + %list-banned + ~ + :: + %ping + ~ + :: + %set-ban + :- [%s subnet.req] + :- [%s command.req] + ?~ ban-time.req ~ + ?- -.u.ban-time.req + %dr [(numb (div +.u.ban-time.req ~s1)) ~] + %da [(numb (unt:chrono:userlib +.u.ban-time.req)) [%b %.y] ~] + == + :: + %set-network-active + :_ ~ + [%b state.req] + :: Raw Transactions + :: + %analyze-psbt + :_ ~ + :- %s + ?^ (de:base64 psbt.req) + psbt.req + (en:base64 (as-octs:mimes:html psbt.req)) + :: + %combine-psbt + :_ ~ + :- %a + %+ turn txs.req + |= a=@t + :- %s + ?^ (de:base64 a) + a + (en:base64 (as-octs:mimes:html a)) + :: + %combine-raw-transaction + ~[a+(turn txs.req |=(a=@ux s+(hex-to-cord a)))] + :: + %convert-to-psbt + :~ s+(hex-to-cord hex-string.req) + (ferm permit-sig-data.req %b) + (ferm is-witness.req %b) + == + :: + %create-psbt + :~ :- %a + %+ turn inputs.req + |= a=input + ^- json + %- pairs ^- (list (pair @t json)) + :~ ['txid' s+(hash-to-cord txid.a)] + ['vout' (numb vout.a)] + ['sequence' (numb sequence.a)] + == + :: + =* out outputs.req + :- %a + %+ weld + :_ ~ + (pairs [-.data.out s+(hex-to-cord +.data.out)]~) + :: + %+ turn addresses.out + |= [address=?(address [%bech32 @t]) amount=@t] + ^- json + %- pairs + :~ :- 'address' + :- %s + ?^ address + +.address + (base58-to-cord address) + :: + ['amount' n+amount] + == + :: + (feud locktime.req) + (ferm replaceable.req %b) + == + :: + %create-raw-transaction + :~ :- %a + ^- (list json) + %+ turn inputs.req + |= a=input + ^- json + %- pairs + ^- (list (pair @t json)) + :~ ['txid' s+(hash-to-cord txid.a)] + ['vout' (numb vout.a)] + ['sequence' (numb sequence.a)] + == + :: + =* out outputs.req + :- %a + %+ weld + :_ ~ + (pairs [-.data.out s+(hex-to-cord +.data.out)]~) + :: + %+ turn addresses.out + |= [address=?(address [%bech32 @t]) amount=@t] + ^- json + %- pairs + :_ ~ + :_ n+amount + ?^ address + +.address + (base58-to-cord address) + :: + (feud locktime.req) + (ferm replaceable.req %b) + == + :: + %decode-psbt + :_ ~ + :- %s + ?^ (de:base64 psbt.req) + psbt.req + (en:base64 (as-octs:mimes:html psbt.req)) + :: + %decode-raw-transaction + :~ s+(hex-to-cord hex-string.req) + b+is-witness.req + == + :: + %decode-script + ~[s+(hex-to-cord hex-string.req)] + :: + %finalize-psbt + :~ :- %s + ?^ (de:base64 psbt.req) + psbt.req + (en:base64 (as-octs:mimes:html psbt.req)) + :: + (ferm extract.req %b) + == + :: + %fund-raw-transaction + :~ s+(hex-to-cord hex-string.req) + :: + %- pairs + ?~ options.req + ~ + =* opts u.options.req + :: Excludes ~ elements + :: + =- (skip - |=([@t a=json] =(a ~))) + ^- (list (pair @t json)) + :~ :- 'changeAddress' + ?~ change-address.opts + ~ + =* a u.change-address.opts + [%s ?^(a +.a (base58-to-cord a))] + :: + ['changePosition' (feud change-position.opts)] + ['change_type' (ferm change-type.opts %s)] + ['includeWatching' (ferm include-watching.opts %b)] + ['lockUnspents' (ferm lock-unspents.opts %b)] + ['feeRate' (ferm fee-rate.opts %s)] + :: + :- 'subtractFeeFromOutputs' + ?~ subtract-fee-from-outputs.opts + ~ + :- %a ^- (list json) + (turn u.subtract-fee-from-outputs.opts numb) + :: + ['replaceable' (ferm replaceable.opts %b)] + ['conf_target' (feud conf-target.opts)] + ['estimate_mode' (ferm mode.opts %s)] + == + :: + b+is-witness.req + == + :: + %get-raw-transaction + :~ s+(hash-to-cord txid.req) + (ferm verbose.req %b) + :: + ?~ blockhash.req + ~ + s+(hash-to-cord u.blockhash.req) + == + :: + %join-psbts + ~[a+(turn txs.req |=(a=@t s+a))] + :: + %send-raw-transaction + :~ s+(hex-to-cord hex-string.req) + (ferm max-fee-rate.req %s) + == + :: + %sign-raw-transaction-with-key + :~ s+(hex-to-cord hex-string.req) + :: + :- %a ^- (list json) + %+ turn priv-keys.req + |= a=@t + :- %s + ?^ (de:base64 a) + a + (en:base64 (as-octs:mimes:html a)) + :: + ?~ prev-txs.req + ~ + =* txs u.prev-txs.req + :- %a ^- (list json) + %+ turn txs + |= a=prev-tx + (pairs (prev-txs:json-parser a)) + :: + (ferm sig-hash-type.req %s) + == + :: + %test-mempool-accept + :~ :- %a ^- (list json) + %+ turn raw-txs.req + |=(a=@ux s+(hex-to-cord a)) + :: + (ferm max-fee-rate.req %s) + == + :: + %utxo-update-psbt + :~ :- %s + ?^ (de:base64 psbt.req) + psbt.req + (en:base64 (as-octs:mimes:html psbt.req)) + :: + :- %a ^- (list json) + ?~ descriptors.req ~ + %+ turn u.descriptors.req + |= =descriptor + ?@ descriptor + s+descriptor + ?~ range.descriptor + ~ + =* range u.range.descriptor + ?@ range + (numb range) + a+~[(numb -.range) (numb +.range)] + == + :: Util + :: + %create-multi-sig + :~ (numb n-required.req) + :: + :- %a + %+ turn keys.req + |=(a=@ux s+(hex-to-cord a)) + :: + (ferm address-type.req %s) + == + :: + %derive-addresses + :: Sending a (unit range), resulting in a "null" parameter, + :: returns this from the RPC node + :: "Range should not be specified for an un-ranged descriptor" + :: + =- (skip - |=(a=json =(a ~))) + ^- (list json) + :~ s+descriptor.req + :: + ?~ range.req + ~ + =* range u.range.req + ?@ range + (numb range) + a+~[(numb -.range) (numb +.range)] + == + :: + %estimate-smart-fee + =- (skip - |=(a=json =(a ~))) + ^- (list json) + :~ (numb conf-target.req) + (ferm mode.req %s) + == + :: + %get-descriptor-info + ~[s+descriptor.req] + :: + %sign-message-with-privkey + ~[s+privkey.req s+message.req] + :: + %validate-address + :_ ~ + :- %s + ?^ address.req + +.address.req + (base58-to-cord address.req) + :: + %verify-message + :~ :- %s + ?^ address.req + +.address.req + (base58-to-cord address.req) + :: + s+signature.req + s+message.req + == + :: Wallet + :: + %abandon-transaction + ~[s+(hash-to-cord txid.req)] + :: + %abort-rescan + ~ + :: + %add-multisig-address + :~ (numb n-required.req) + :: + :- %a + %+ turn keys.req + |= a=?(address [%bech32 @t]) + :- %s + ?^ a + +.a + (base58-to-cord a) + :: + (ferm label.req %s) + s+address-type.req + == + :: + %backup-wallet + ~[s+destination.req] + :: + %bump-fee + :~ s+(hash-to-cord txid.req) + :: + %- pairs + ?~ options.req + ~ + =* opts u.options.req + :: Excludes ~ elements + :: + =- (skip - |=([@t a=json] =(a ~))) + ^- (list (pair @t json)) + :~ ['confTarget' (feud conf-target.opts)] + ['totalFee' (ferm total-fee.opts %n)] + ['fee_rate' (ferm total-fee.opts %n)] + ['replaceable' (ferm replaceable.opts %b)] + ['estimate_mode' (ferm mode.opts %s)] + == == + :: + %create-wallet + :~ s+name.req + (ferm disable-private-keys.req %b) + (ferm blank.req %b) + (ferm passphrase.req %s) + (ferm avoid-reuse.req %b) + == + :: + %dump-privkey + :_ ~ + :- %s + ?^ address.req + +.address.req + (base58-to-cord address.req) + :: + %dump-wallet + ~[s+filename.req] + :: + %encrypt-wallet + ~[s+passphrase.req] + :: + %get-addresses-by-label + ~[s+label.req] + :: + %get-address-info + :_ ~ + :- %s + ?^ address.req + +.address.req + (base58-to-cord address.req) + :: + %get-balance + ?~ +.req + ~ + =/ req u.+.req + :~ (ferm dummy.req %s) + (feud minconf.req) + (ferm include-watch-only.req %b) + (ferm avoid-reuse.req %b) + == + :: + %get-balances + ~ + :: + %get-new-address + :~ (ferm label.req %s) + :: + (ferm address-type.req %s) + == + :: + %get-raw-change-address + ~[(ferm address-type.req %s)] + :: + %get-received-by-address + :~ :- %s + ?^ address.req + +.address.req + (base58-to-cord address.req) + :: + (numb minconf.req) + == + :: + %get-received-by-label + ~[s+label.req (feud minconf.req)] + :: + %get-transaction + :~ s+(hash-to-cord txid.req) + (ferm include-watch-only.req %b) + (ferm verbose.req %b) + == + :: + %get-unconfirmed-balance + ~ + :: + %get-wallet-info + ~ + :: + %import-address + :~ :- %s + ?- -.address.req + %addr + (base58-to-cord +.address.req) + :: + %bech32 + +.address.req + :: + %script + (hex-to-cord +.address.req) + == + :: + (ferm label.req %s) + (ferm rescan.req %b) + (ferm p2sh.req %b) + == + :: + %import-multi + :~ ?~ requests.req + ~ + =* reqs requests.req + :- %a + %+ turn reqs + |= r=import-request + %- pairs + :: Exclude nulls + :: + =- (skip - |=([@t a=json] =(a ~))) + ^- (list (pair @t json)) + :~ ['desc' (ferm desc.r %s)] + :: + :- 'scriptPubKey' + =* scri script-pubkey.r + ?- -.scri + %script + [%s s.scri] + :: + %address + %- pairs + :_ ~ + :- 'address' + :- %s + =* a a.script-pubkey.r + ?^ a + +.a + (base58-to-cord a) + == + :: + :- 'timestamp' + :- %s + ?: ?=(%now timestamp.r) + %now + (scot %da timestamp.r) + :: + ['redeemScript' (ferm redeem-script.r %s)] + :: + ['witnessScript' (ferm witness-script.r %s)] + :: + :- 'pubkeys' + ?~ pubkeys.r + ~ + a+(turn u.pubkeys.r |=(a=@t s+a)) + :: + :- 'keys' + ?~ keys.r + ~ + a+(turn u.keys.r |=(a=@t s+a)) + :: + :- 'range' + ?~ range.r + ~ + =+ u.range.r + ?@ - + (numb -) + a+~[(numb -<) (numb ->)] + :: + ['internal' (ferm internal.r %b)] + ['watchonly' (ferm watchonly.r %b)] + ['label' (ferm label.r %s)] + ['keypool' (ferm keypool.r %b)] + == + :: + ?~ options.req + ~ + (pairs ['rescan' b+u.options.req]~) + == + :: + %import-privkey + :~ s+privkey.req + (ferm label.req %s) + (ferm rescan.req %b) + == + :: + %import-pruned-funds + :~ s+(hex-to-cord raw-transaction.req) + s+tx-out-proof.req + == + :: + %import-pubkey + :~ s+(hex-to-cord pubkey.req) + (ferm label.req %s) + (ferm rescan.req %b) + == + :: + %import-wallet + ~[s+filename.req] + :: + %key-pool-refill + ~[(feud new-size.req)] + :: + %list-address-groupings + ~ + :: + %list-labels + ~[(ferm purpose.req %s)] + :: + %list-lock-unspent + ~ + :: + %list-received-by-address + ?~ +.req + ~ + =/ req u.+.req + :: BTC node can't take a null as the address + :: "JSON value is not a string as expected" + :: so we remove it from the parameters + :: + =- (skip - |=(a=json =(a s+'null'))) + ^- (list json) + :~ (feud minconf.req) + (ferm include-empty.req %b) + (ferm include-watch-only.req %b) + :: + =* addr address-filter.req + :- %s + ?~ addr 'null' + ?^ u.addr + +.u.addr + (base58-to-cord u.addr) + == + :: + %list-received-by-label + ?~ +.req + ~ + =/ req u.+.req + :~ (feud minconf.req) + (ferm include-empty.req %b) + (ferm include-watch-only.req %b) + == + :: + %lists-in-ceblock + ?~ +.req + ~ + =/ req u.+.req + :~ ?~ blockhash.req + ~ + s+(hash-to-cord u.blockhash.req) + :: + (feud target-confirmations.req) + (ferm include-watch-only.req %b) + (ferm include-removed.req %b) + == + :: + %list-transactions + ?~ +.req + ~ + =/ req u.+.req + :~ (ferm label.req %s) + (feud count.req) + (feud skip.req) + (ferm include-watch-only.req %b) + == + :: + %list-unspent + ?~ +.req + ~ + =/ req u.+.req + :~ (feud minconf.req) + (feud maxconf.req) + :: + ?~ addresses.req ~ + =* addrs u.addresses.req + :- %a + %+ turn addrs + |= a=?(address [%bech32 @t]) + ^- json + :- %s + ?^ a + +.a + (base58-to-cord a) + :: + (ferm include-unsafe.req %b) + :: + ?~ query-options.req ~ + =* opts u.query-options.req + :: Remove if all query-options are ~ + :: + =- ?~(- ~ (pairs -)) + ^- (list (pair @t json)) + :: Excludes ~ elements + :: + =- (skip - |=([@t a=json] =(a ~))) + ^- (list (pair @t json)) + :~ ['minimumAmount' (feud minimum-amount.opts)] + ['maximumAmount' (feud maximum-amount.opts)] + ['minimumCount' (feud maximum-count.opts)] + ['minimumSumAmount' (feud minimum-sum-amount.opts)] + == == + :: + %list-wallet-dir + ~ + :: + %list-wallets + ~ + :: + %load-wallet + ~[s+filename.req] + :: + %lock-unspent + :~ b+unlock.req + :: + =- ?~(- ~ %a^-) + ?~ transactions.req + ~ + =* opts u.transactions.req + %+ turn opts + |= [t=@ux v=@ud] + =- ?~(- ~ (pairs -)) + ^- (list (pair @t json)) + ~[['txid' s+(hash-to-cord t)] ['vout' (numb v)]] + == + :: + %remove-pruned-funds + ~[s+(hash-to-cord txid.req)] + :: + %rescan-blockchain + :~ (feud start-height.req) + (feud stop-height.req) + == + :: + %send-many + :~ s+dummy.req + :: + ?~ amounts.req ~ + :- %o + %- molt + %+ turn amounts.req + |= [addr=?(address [%bech32 @t]) amount=@t] + ^- [@t json] + :_ n+amount + ?^ addr + +.addr + (base58-to-cord addr) + :: + (feud minconf.req) + (ferm comment.req %s) + :: + ?~ subtract-fee-from.req ~ + =* addrs u.subtract-fee-from.req + :- %a + %+ turn addrs + |= a=?(address [%bech32 @t]) + ^- json + :- %s + ?^ a + +.a + (base58-to-cord a) + :: + (ferm replaceable.req %b) + (feud conf-target.req) + (ferm mode.req %s) + == + :: + %send-to-address + :~ :- %s + ?^ address.req + +.address.req + (base58-to-cord address.req) + :: + n+amount.req + (ferm comment.req %s) + (ferm comment-to.req %s) + (ferm subtract-fee-from-amount.req %b) + (ferm replaceable.req %b) + (feud conf-target.req) + (ferm mode.req %s) + (ferm avoid-reuse.req %b) + == + :: + %set-hd-seed + ~ + :: + %set-label + :~ :- %s + =* a address.req + ?^ a + +.a + (base58-to-cord a) + :: + s+label.req + == + :: + %set-tx-fee + ~[n+amount.req] + :: + %set-wallet-flag + ~[s+flag.req (ferm value.req %b)] + :: + %sign-message + :~ :- %s + =* a address.req + ?^ a + +.a + (base58-to-cord a) + :: + s+message.req + == + :: + %sign-raw-transaction-with-wallet + :~ s+(hex-to-cord hex-string.req) + :: + ?~ prev-txs.req + ~ + =* txs u.prev-txs.req + :- %a + %+ turn ^- (list prev-tx) txs + |= a=prev-tx + ^- json + (pairs (prev-txs:json-parser a)) + :: + (ferm sig-hash-type.req %s) + == + :: + %unload-wallet + ~[(ferm wallet-name.req %s)] + :: + %wallet-create-fundedpsbt + :~ :- %a + %+ turn inputs.req + |= a=input + ^- json + %- pairs + :~ ['txid' s+(hash-to-cord txid.a)] + ['vout' (numb vout.a)] + ['sequence' (numb sequence.a)] + == + :: + =* out outputs.req + :- %a + %+ weld + :_ ~ + (pairs [-.data.out s+(hex-to-cord +.data.out)]~) + %+ turn addresses.out + |= [address=?(@uc [%bech32 @t]) amount=@t] + ^- json + %- pairs + :_ ~ + :_ n+amount + ?^ address + +.address + (base58-to-cord address) + :: + (feud locktime.req) + :: + ?~ options.req + ~ + =* opts u.options.req + =- (pairs -) + =- (skip - |=([@t a=json] =(a ~))) + ^- (list (pair @t json)) + :~ :- 'changeAddress' + ?~ change-address.opts + ~ + =* a u.change-address.opts + [%s ?^(a +.a (base58-to-cord a))] + :: + ['changePosition' (feud change-position.opts)] + ['change_type' (ferm change-type.opts %s)] + ['includeWatching' (ferm include-watching.opts %b)] + ['lockUnspents' (ferm lock-unspents.opts %b)] + ['feeRate' (ferm fee-rate.opts %n)] + :: + :- 'subtractFeeFromOutputs' + ?~ subtract-fee-from-outputs.opts + ~ + a+(turn u.subtract-fee-from-outputs.opts numb) + :: + ['replaceable' (ferm replaceable.opts %b)] + ['conf_target' (feud conf-target.opts)] + ['estimate_mode' (ferm mode.opts %s)] + == + :: + (ferm bip32-derivs.req %b) + == + :: + %wallet-lock + ~ + :: + %wallet-passphrase + ~[s+passphrase.req (numb timeout.req)] + :: + %wallet-passphrase-change + :~ (ferm old-passphrase.req %s) + (ferm new-passphrase.req %s) + == + :: + %wallet-process-psbt + :~ :- %s + ?^ (de:base64 psbt.req) + psbt.req + (en:base64 (as-octs:mimes:html psbt.req)) + :: + b+sign.req + s+sig-hash.req + (ferm bip32-derivs.req %b) + == + :: ZMQ + :: + %get-zmq-notifications + ~ + == + :: + ++ parse-response + =, dejs:format + |= res=response:rpc:jstd + ^- response + ~| -.res + :: only deals with successful requests + :: ignores (%error, %fails and %batch) + :: + ?> ?=(%result -.res) + ?+ id.res ~| [%unsupported-response id.res] !! + :: Blockchain + :: + %get-best-block-hash + [id.res ((cu to-hex so) res.res)] + :: + %get-block + :- id.res + %. res.res + ?+ -.res.res ~|([%format-not-valid -.res.res] !!) + %s + (cu to-hex so) + :: + %o + %- ou + :~ ['hash' (un (cu to-hex so))] + ['confirmations' (un ni)] + ['size' (un ni)] + ['strippedsize' (un ni)] + ['weight' (un ni)] + ['height' (un ni)] + ['version' (un no)] + ['versionHex' (un (cu to-hex so))] + ['merkleroot' (un (cu to-hex so))] + :: + :- 'tx' + =- (un (ar -)) + |= =json + %. json + :: verbosity = 1 + :: + ?: =(%s -.json) + (cu to-hex so) + ?. =(%o -.json) + !! + :: verbosity = 2 + :: + raw-transaction:json-parser + :: + ['time' (un ni)] + ['mediantime' (un ni)] + ['nonce' (un ni)] + ['bits' (un (cu to-hex so))] + ['difficulty' (un no)] + ['chainwork' (un (cu to-hex so))] + ['nTx' (un ni)] + ['previousblockhash' (un (cu to-hex so))] + ['nextblockhash' (uf ~ (mu (cu to-hex so)))] + == == + :: + %get-blockchain-info + :- id.res + %. res.res + %- ou + :~ ['chain' (un (cu network-name so))] + ['blocks' (un ni)] + ['headers' (un ni)] + ['bestblockhash' (un (cu to-hex so))] + ['difficulty' (un no)] + ['mediantime' (un ni)] + ['verificationprogress' (un no)] + ['initialblockdownload' (un bo)] + ['chainwork' (un (cu to-hex so))] + ['size_on_disk' (un ni)] + ['pruned' (un bo)] + ['pruneheight' (uf ~ (mu ni))] + ['automatic_pruning' (uf ~ (mu bo))] + ['prune_target_size' (uf ~ (mu ni))] + :: + :- 'softforks' + =; softforks + (un (om (ou softforks))) + :~ ['type' (un (cu soft-fork-types so))] + :: + :- 'bip9' + =; bip9 + (uf ~ (mu bip9)) + %- ou + :~ ['status' (uf ~ (mu (cu soft-fork-status so)))] + ['bit' (uf ~ (mu ni))] + :: + :- 'start_time' + =- (un (cu - no)) + |= a=@t + ^- ?(@ud %'-1') + ?: =(a '-1') + %'-1' + (rash a dem) + :: + ['timeout' (un ni)] + ['since' (un ni)] + :: + :- 'statistics' + =- (uf ~ (mu (ot -))) + :~ ['period' ni] + ['threshold' ni] + ['elapsed' ni] + ['count' ni] + ['possible' bo] + == == + :: + ['height' (uf ~ (mu ni))] + ['active' (un bo)] + == == + :: + %get-block-count + [id.res (ni res.res)] + :: + %get-block-filter + :- id.res + %. res.res + %- ot + :~ ['filter' (cu to-hex so)] + ['header' (cu to-hex so)] + == + :: + %get-block-hash + [id.res ((cu to-hex so) res.res)] + :: + %get-block-header + :- id.res + ?: =(%s -.res.res) + ((cu to-hex so) res.res) + ?. =(%o -.res.res) !! + %. res.res + %- ou + :~ ['hash' (un (cu to-hex so))] + ['confirmations' (un ni)] + ['height' (un ni)] + ['version' (un no)] + ['versionHex' (un (cu to-hex so))] + ['merkleroot' (un (cu to-hex so))] + ['time' (un ni)] + ['mediantime' (un ni)] + ['nonce' (un ni)] + ['bits' (un (cu to-hex so))] + ['difficulty' (un no)] + ['chainwork' (un (cu to-hex so))] + ['nTx' (un ni)] + ['previousblockhash' (un (cu to-hex so))] + ['nextblockhash' (uf ~ (mu (cu to-hex so)))] + == + :: + %get-block-stats + :- id.res + %. res.res + %- ot + :~ ['avgfee' no] + ['avgfeerate' ni] + ['avgtxsize' ni] + ['blockhash' (cu to-hex so)] + :: + :- 'feerate_percentiles' + =- (cu - (ar no)) + |= p=(list @t) + ?> ?=([@t @t @t @t @t *] p) + :* i.p + i.t.p + i.t.t.p + i.t.t.t.p + i.t.t.t.t.p + == + :: + ['height' ni] + ['ins' ni] + ['maxfee' no] + ['maxfeerate' no] + ['maxtxsize' ni] + ['medianfee' no] + ['mediantime' ni] + ['mediantxsize' ni] + ['minfee' no] + ['minfeerate' no] + ['mintxsize' ni] + ['outs' ni] + ['subsidy' no] + ['swtotal_size' ni] + ['swtotal_weight' ni] + ['swtxs' ni] + ['time' ni] + ['total_out' no] + ['total_size' ni] + ['total_weight' no] + ['totalfee' no] + ['txs' ni] + ['utxo_increase' no] + ['utxo_size_inc' no] + == + :: + %get-chain-tips + :- id.res + %. res.res + =- (ar (ot -)) + :~ ['height' ni] + ['hash' (cu to-hex so)] + ['branchlen' ni] + ['status' (cu chain-status so)] + == + :: + %get-chain-tx-stats + :- id.res + %. res.res + %- ou + :~ ['time' (un ni)] + ['txcount' (un ni)] + ['window_final_block_hash' (un (cu to-hex so))] + ['window_final_block_height' (un ni)] + ['window_block_count' (un ni)] + ['window_tx_count' (uf ~ (mu ni))] + ['window_interval' (uf ~ (mu ni))] + ['txrate' (uf ~ (mu no))] + == + :: + %get-difficulty + [id.res (no res.res)] + :: + %get-mempool-ancestors + :- id.res + ?: =(%a -.res.res) + %. res.res + (ar (cu to-hex so)) + ?. =(%o -.res.res) !! + :: The parsing rule +hex used in +om + :: will give a raw atom so we reparse + :: the keys to get a @ux + :: + =- (turn ~(tap by -) |*([a=@ b=*] [`@ux`a b])) + %. res.res + (op hex mem-pool:json-parser) + :: + %get-mempool-descendants + :- id.res + ?: =(%a -.res.res) + %. res.res + (ar (cu to-hex so)) + ?. =(%o -.res.res) !! + :: The parsing rule +hex used in +om + :: will give a raw atom so we reparse + :: the keys to get a @ux + :: + =- (turn ~(tap by -) |*([a=@ b=*] [`@ux`a b])) + %. res.res + (op hex mem-pool:json-parser) + :: + %get-mempool-entry + [id.res (mem-pool:json-parser res.res)] + :: + %get-mempool-info + :- id.res + %. res.res + %- ot + :~ ['size' ni] + ['bytes' ni] + ['usage' ni] + ['maxmempool' ni] + ['mempoolminfee' no] + ['minrelaytxfee' no] + == + :: + %get-raw-mempool + :- id.res + ?: =(%a -.res.res) + %. res.res + (ar (cu to-hex so)) + ?. =(%o -.res.res) !! + :: The parsing rule +hex used in +om + :: will give a raw atom so we reparse + :: the keys to get a @ux + :: + =- (turn ~(tap by -) |*([a=@ b=*] [`@ux`a b])) + %. res.res + (op hex mem-pool:json-parser) + :: + %get-tx-out + :- id.res + ?~ res.res + ~ + %- some + %. res.res + %- ot + :~ ['bestblock' (cu to-hex so)] + ['confirmations' ni] + ['value' no] + :: + :- 'scriptPubKey' + %- ou + :~ ['asm' (un so)] + ['hex' (un (cu to-hex so))] + ['reqSigs' (uf ~ (mu ni))] + ['type' (un so)] + ['addresses' (uf ~ (mu (ar (cu addr-type-validator so))))] + == + :: + ['coinbase' bo] + == + :: + %get-tx-out-proof + [id.res (so res.res)] + :: + %get-tx-outset-info + :- id.res + %. res.res + %- ot + :~ ['height' ni] + ['bestblock' (cu to-hex so)] + ['transactions' ni] + ['txouts' ni] + ['bogosize' ni] + ['hash_serialized_2' (cu to-hex so)] + ['disk_size' ni] + ['total_amount' no] + == + :: + %precious-block + [id.res ~] + :: + %prune-blockchain + [id.res (ni res.res)] + :: + %save-mempool + [id.res ~] + :: + %scan-tx-outset + :- id.res + %. res.res + %- ou + :~ ['success' (uf ~ (mu bo))] + ['searched_items' (uf ~ (mu ni))] + ['txouts' (uf ~ (mu ni))] + ['height' (uf ~ (mu ni))] + ['best-blocks' (uf ~ (mu (cu to-hex so)))] + :: + :- 'unspents' + =- (un (ar (ot -))) + :~ ['txid' (cu to-hex so)] + ['vout' ni] + ['scriptPubKey' (cu to-hex so)] + ['desc' so] + ['amount' no] + ['height' ni] + == + :: + ['total_amount' (un no)] + == + :: + %verify-chain + [id.res (bo res.res)] + :: + %verify-tx-out-proof + :- id.res + %. res.res + (ar (cu to-hex so)) + :: Control + :: + %get-memory-info + :- id.res + %. res.res + %- ot + :_ ~ + :- 'locked' + %- ot + :~ ['used' ni] + ['free' ni] + ['total' ni] + ['locked' ni] + ['chunks_free' ni] + ['chunks_used' ni] + == + :: + %get-rpc-info + :- id.res + %. res.res + %- ot + :_ ~ + :- 'active_commands' + %- ar + %- ot + :~ ['method' so] + :- 'duration' + %+ cu + |= a/@u + (mul (div ~s1 1.000) a) + ni + == + :: + %help + :- id.res + %. res.res + (cu to-wall sa) + :: + %logging + :- id.res + %. res.res + (om bo) + :: + %stop + :- id.res + (so res.res) + :: + %uptime + :- id.res + %+ mul ~s1 + (ni res.res) + :: Generating + :: + %generate + :- id.res + %. res.res + (ar (cu to-hex so)) + :: + %generate-to-address + :- id.res + %. res.res + (ar (su hex)) + :: Mining + :: + %get-block-template + :- id.res + %. res.res + %- ot + :~ ['version' ni] + ['rules' (ar (cu ^rule so))] + ['vbavailable' (om ni)] + ['vbrequired' ni] + ['previousblockhash' (su hex)] + :- 'transactions' + %- ar + %- ot + :~ ['data' (su hex)] + ['txid' (su hex)] + ['hash' (su hex)] + ['depends' (ar ni)] + ['fee' ni] + ['sigops' ni] + ['weight' ni] + == + ['coinbaseaux' (ot ~[flags+so])] + ['coinbasevalue' ni] + ['target' (su hex)] + ['mintime' (cu from-unix:chrono:userlib ni)] + ['mutable' (ar (cu mutable so))] + ['noncerange' so] + ['sigoplimit' ni] + ['sizelimit' ni] + ['weightlimit' ni] + ['curtime' (cu from-unix:chrono:userlib ni)] + ['bits' (su hex)] + ['height' ni] + ['default_witness_commitment' (su hex)] + == + :: + %get-mining-info + :- id.res + %. res.res + %- ot + :~ ['blocks' ni] + ['currentblockweight' ni] + ['currentblocktx' ni] + ['difficulty' ne] + ['networkhashps' ne] + ['pooledtx' ni] + ['chain' (cu network-name so)] + ['warnings' so] + == + :: + %get-network-hash-ps + :- id.res + (ne res.res) + :: + %prioritise-transaction + :- id.res + (bo res.res) + :: + %submit-block + :- id.res + (so res.res) + :: + %submit-header + :- id.res + (so res.res) + :: Network + :: + %add-node + :- id.res + (ul res.res) + :: + %clear-banned + :- id.res + (ul res.res) + :: + %disconnect-node + :- id.res + (ul res.res) + :: + %get-added-node-info + :- id.res + %. res.res + %- ar + %- ot + :~ ['addednode' so] + ['connected' bo] + :- 'addresses' + %- ar + %- ot + :~ ['address' so] + ['connected' (cu ?(%inbound %outbound) so)] + == == + :: + %get-connection-count + :- id.res + (ni res.res) + :: + %get-net-totals + :- id.res + %. res.res + %- ot + :~ ['totalbytesrecv' ni] + ['totalbytessent' ni] + ['timemillis' (cu |=(a=@u (from-unix:chrono:userlib (div a 1.000))) ni)] + :- 'uploadtarget' + %- ot + :~ ['timeframe' (cu |=(a=@u (mul a ~s1)) ni)] + ['target' ni] + ['target_reached' bo] + ['serve_historical_blocks' bo] + ['bytes_left_in_cycle' ni] + ['time_left_in_cycle' (cu |=(a=@u (mul a ~s1)) ni)] + == == + :: + %get-network-info + :- id.res + %. res.res + %- ot + :~ ['version' ni] + ['subversion' so] + ['protocolversion' ni] + ['localservices' so] + ['localservicesnames' (ar so)] + ['localrelay' bo] + ['timeoffset' no] + ['connections' ni] + ['networkactive' bo] + :- 'networks' + %- ar + %- ot + :~ ['name' (cu ?(%ipv4 %ipv6 %onion) so)] + ['limited' bo] + ['reachable' bo] + ['proxy' so] + ['proxy_randomize_credentials' bo] + == + ['relayfee' ne] + ['incrementalfee' ne] + :- 'localaddresses' + %- ar + %- ot + :~ ['address' so] + ['port' ni] + ['score' ni] + == + ['warnings' so] + == + :: + %get-node-addresses + :- id.res + %. res.res + %- ar + %- ot + :~ ['time' (cu from-unix:chrono:userlib ni)] + ['services' ni] + ['address' so] + ['port' ni] + == + :: + %get-peer-info + :- id.res + %. res.res + %- ar + %- ou + :~ ['id' (un ni)] + ['addr' (un so)] + ['addrbind' (un so)] + ['addrlocal' (uf ~ (mu so))] + ['services' (un so)] + ['servicesnames' (un (ar so))] + ['relaytxes' (un bo)] + ['lastsend' (un (cu from-unix:chrono:userlib ni))] + ['lastrecv' (un (cu from-unix:chrono:userlib ni))] + ['bytessent' (un ni)] + ['bytesrecv' (un ni)] + ['conntime' (un (cu from-unix:chrono:userlib ni))] + ['timeoffset' (un no)] + ['pingtime' (un ne)] + ['minping' (un ne)] + ['pingwait' (uf ~ (mu ni))] + ['version' (un ni)] + ['subver' (un so)] + ['inbound' (un bo)] + ['addnode' (un bo)] + ['startingheight' (un ni)] + ['banscore' (un ni)] + ['synced_headers' (un ni)] + ['synced_blocks' (un ni)] + ['inflight' (un (ar ni))] + ['whitelisted' (un bo)] + ['minfeefilter' (un ne)] + ['bytessent_per_msg' (un (om ni))] + ['bytesrecv_per_msg' (un (om ni))] + == + :: + %list-banned + :- id.res + %. res.res + %- ar + %- ot + :~ ['address' so] + ['banned_until' (cu from-unix:chrono:userlib ni)] + ['ban_created' (cu from-unix:chrono:userlib ni)] + ['ban_reason' so] + == + :: + %ping + :- id.res + (ul res.res) + :: + %set-ban + :- id.res + (ul res.res) + :: + %set-network-active + :- id.res + (bo res.res) + :: Raw Transactions + :: + %analyze-psbt + :- id.res + %. res.res + %- ou + :~ :- 'inputs' + =- (un (ar (ou -))) + :~ ['has_utxo' (un bo)] + ['is_final' (un bo)] + :: + :- 'missing' + =- (uf ~ (mu (ou -))) + :~ :- 'pubkeys' + =- (uf ~ (mu -)) + (ar (cu to-hex so)) + :: + :- 'signatures' + =- (uf ~ (mu -)) + (ar (cu to-hex so)) + :: + ['redeemscript' (uf ~ (mu (cu to-hex so)))] + ['witnessscript' (uf ~ (mu (cu to-hex so)))] + == + :: + ['next' (uf ~ (mu so))] + == + :: + ['estimated_vsize' (uf ~ (mu no))] + ['estimated_feerate' (uf ~ (mu no))] + ['fee' (uf ~ (mu no))] + ['next' (un so)] + == + :: + %combine-psbt + [id.res (so res.res)] + :: + %combine-raw-transaction + [id.res ((cu to-hex so) res.res)] + :: + %convert-to-psbt + [id.res (so res.res)] + :: + %create-psbt + [id.res (so res.res)] + :: + %create-raw-transaction + [id.res ((cu to-hex so) res.res)] + :: + %decode-psbt + :- id.res + %. res.res + %- ou + :~ :- 'tx' + =- (un (ot -)) + =, json-parser + :~ ['txid' (cu to-hex so)] + ['hash' (cu to-hex so)] + ['size' ni] + ['vsize' ni] + ['weight' ni] + ['version' ni] + ['locktime' ni] + ['vin' vin] + ['vout' vout] + == + :: + ['unknown' (un (om so))] + :: + :- 'inputs' + =- (un (ar (ou -))) + =, json-parser + :~ ['non_witness_utxo' utxo] + ['witness_utxo' utxo] + :: + :- 'partial_signatures' + =- (uf ~ (mu -)) + (op hex (cu to-hex so)) + :: + ['sighash' (uf ~ (mu (cu sig-hash so)))] + ['redeem_script' script] + ['witness_script' script] + :: + :- 'bip32_derivs' + =- (uf ~ (mu -)) + =- (op hex (ot -)) + :~ ['master_fingerprint' so] + ['path' so] + == + :: + :- 'final_scriptsig' + =- (uf ~ (mu (ot -))) + :~ ['asm' so] + ['hex' (cu to-hex so)] + == + :: + :- 'final_scriptwitness' + =- (uf ~ (mu -)) + (ar (cu to-hex so)) + :: + ['unknown' (uf ~ (mu (om so)))] + == + :: + :- 'outputs' + =- (un (ar (ou -))) + =, json-parser + :~ ['redeem_script' script] + ['witness_script' script] + :: + :- 'bip32_derivs' + =- (uf ~ (mu -)) + =- (op hex (ot -)) + :~ ['master_fingerprint' so] + ['path' so] + == + :: + ['unknown' (uf ~ (mu (om so)))] + == + :: + ['fee' (uf ~ (mu no))] + == + :: + %decode-raw-transaction + :- id.res + %. res.res + %- ot + =, json-parser + :~ ['txid' (cu to-hex so)] + ['hash' (cu to-hex so)] + ['size' ni] + ['vsize' ni] + ['weight' ni] + ['version' ni] + ['locktime' ni] + ['vin' vin] + ['vout' vout] + == + :: + %decode-script + :- id.res + %. res.res + %- ou + :~ ['asm' (un so)] + ['hex' (uf ~ (mu (cu to-hex so)))] + ['type' (un so)] + ['reqSigs' (uf ~ (mu ni))] + :: + :- 'addresses' + =- (uf ~ (mu (ar -))) + (cu addr-type-validator so) + :: + :- 'p2sh' + (uf ~ (mu (cu @uc so))) + :: + :- 'segwit' + =- (uf ~ (mu (ou -))) + :~ ['asm' (un so)] + ['hex' (uf ~ (mu (cu to-hex so)))] + ['type' (un so)] + ['reqSigs' (uf ~ (mu ni))] + :: + :- 'addresses' + =- (un (ar -)) + (cu |=(a=@t bech32+a) so) + :: + :- 'p2sh-segwit' + =- (uf ~ (mu -)) + (cu @uc (su fim:ag)) + == == + :: + %finalize-psbt + :- id.res + %. res.res + %- ou + :~ :- 'psbt' + =- (uf ~ (mu (cu - so))) + |=(a=@t ?>(?=(^ (de:base64 a)) a)) + :: + ['hex' (uf ~ (mu (cu to-hex so)))] + ['complete' (un bo)] + == + :: + %fund-raw-transaction + :- id.res + %. res.res + %- ot + :~ ['hex' (cu to-hex so)] + ['fee' no] + :: + :- 'changepos' + =- (cu - no) + |= a=@t + ^- ?(@ud %'-1') + ?: =(a '-1') + %'-1' + (rash a dem) + == + :: + %get-raw-transaction + :- id.res + %. res.res + ?: =(%s -.res.res) + (cu to-hex so) + ?. =(%o -.res.res) + !! + raw-transaction:json-parser + :: + %join-psbts + :- id.res + %. res.res + =- (cu - so) + |=(a=@t ?>(?=(^ (de:base64 a)) a)) + :: + %send-raw-transaction + [id.res ((cu to-hex so) res.res)] + :: + %sign-raw-transaction-with-key + :- id.res + %. res.res + %- ou + :~ ['hex' (un (cu to-hex so))] + ['complete' (un bo)] + :: + :- 'errors' + =- (uf ~ (mu -)) + =- (ar (ot -)) + :~ ['txid' (cu to-hex so)] + ['vout' ni] + ['scriptSig' (cu to-hex so)] + ['sequence' ni] + ['error' so] + == == + :: + %test-mempool-accept + :- id.res + %. res.res + =- (ar (ou -)) + :~ ['txid' (un (cu to-hex so))] + ['allowed' (un bo)] + ['reject-reason' (uf ~ (mu so))] + == + :: + %utxo-update-psbt + :- id.res + %. res.res + =- (cu - so) + |=(a=@t ?>(?=(^ (de:base64 a)) a)) + :: Util + :: + %create-multi-sig + :- id.res + %. res.res + %- ot + :~ ['address' (cu addr-type-validator so)] + ['redeemScript' so] + == + :: + %derive-addresses + :- id.res + %. res.res + (ar (cu addr-type-validator so)) + :: + %estimate-smart-fee + :- id.res + %. res.res + %- ou + :~ ['feerate' (uf ~ (mu no))] + ['errors' (uf ~ (mu (ar so)))] + ['blocks' (un ni)] + == + :: + %get-descriptor-info + :- id.res + %. res.res + %- ot + :~ ['descriptor' so] + ['checksum' so] + ['isrange' bo] + ['issolvable' bo] + ['hasprivatekeys' bo] + == + :: + %sign-message-with-privkey + [id.res (so res.res)] + :: + %validate-address + :- id.res + %. res.res + %- ou + :~ ['isvalid' (un bo)] + ['address' (uf ~ (mu (cu addr-type-validator so)))] + ['scriptPubKey' (uf ~ (mu (cu to-hex so)))] + ['isscript' (uf ~ (mu bo))] + ['iswitness' (uf ~ (mu bo))] + ['witness_version' (uf ~ (mu so))] + ['witness_program' (uf ~ (mu (cu to-hex so)))] + == + :: + %verify-message + [id.res (bo res.res)] + :: Wallet + :: + %abandon-transaction + [id.res ~] + :: + %abort-rescan + [id.res ~] + :: + %add-multisig-address + :- id.res + %. res.res + %- ot + :~ ['address' (cu addr-type-validator so)] + :: + ['redeemScript' so] + == + :: + %backup-wallet + [id.res ~] + :: + %bump-fee + :- id.res + %. res.res + %- ot + :~ ['txid' (cu to-hex so)] + ['origfee' no] + ['fee' no] + ['errors' (ar so)] + == + :: + %create-wallet + :- id.res + %. res.res + (ot ~[name+so warning+so]) + :: + %dump-privkey + [id.res (so res.res)] + :: + %dump-wallet + :- id.res + %. res.res + (ot [filename+so]~) + :: + %encrypt-wallet + [id.res ~] + :: + %get-addresses-by-label + :- id.res + :: Transforms the keys encoded as tapes to ?(@uc [%bech32 @t]) + :: + =- %+ turn ~(tap by -) + |* [k=tape v=*] + :_ v + ^- ?(@uc [%bech32 @t]) + (addr-type-validator (crip k)) + %. res.res + =- (op (star aln) -) + (ot ['purpose' (cu purpose so)]~) + :: + %get-address-info + :- id.res + %. res.res + %- ou + :~ ['address' (un (cu addr-type-validator so))] + ['scriptPubKey' (un (cu to-hex so))] + ['ismine' (un bo)] + ['iswatchonly' (un bo)] + ['solvable' (un bo)] + ['desc' (uf ~ (mu so))] + ['isscript' (un bo)] + ['ischange' (un bo)] + ['iswitness' (un bo)] + ['witness_version' (uf ~ (mu no))] + ['witness_program' (uf ~ (mu (cu to-hex so)))] + ['script' (uf ~ (mu so))] + ['hex' (uf ~ (mu (cu to-hex so)))] + :: + :- 'pubkeys' + =- (uf ~ (mu -)) + (ar (cu to-hex so)) + :: + ['sigsrequired' (uf ~ (mu ni))] + ['pubkey' (uf ~ (mu (cu to-hex so)))] + :: + :- 'embedded' + =- (uf ~ (mu -)) + %- ou + :~ ['scriptPubKey' (un (cu to-hex so))] + ['solvable' (uf ~ (mu bo))] + ['desc' (uf ~ (mu so))] + ['isscript' (un bo)] + ['ischange' (uf ~ (mu bo))] + ['iswitness' (un bo)] + ['witness_version' (uf ~ (mu no))] + ['witness_program' (uf ~ (mu (cu to-hex so)))] + ['script' (uf ~ (mu (cu to-hex so)))] + ['hex' (uf ~ (mu (cu to-hex so)))] + :: + :- 'pubkeys' + =- (uf ~ (mu -)) + (ar (cu to-hex so)) + :: + ['sigsrequired' (uf ~ (mu ni))] + ['pubkey' (uf ~ (mu (cu to-hex so)))] + ['iscompressed' (uf ~ (mu bo))] + ['label' (uf ~ (mu so))] + ['hdmasterfingerprint' (uf ~ (mu (cu to-hex so)))] + :: + :- 'labels' + =- (uf ~ (mu -)) + =- (ar (ot -)) + :~ ['name' so] + ['purpose' (cu purpose so)] + == == + :: + ['iscompressed' (uf ~ (mu bo))] + ['label' (uf ~ (mu so))] + ['timestamp' (uf ~ (mu ni))] + ['hdkeypath' (uf ~ (mu so))] + ['hdseedid' (uf ~ (mu (cu to-hex so)))] + ['hdmasterfingerprint' (uf ~ (mu (cu to-hex so)))] + :: + :- 'labels' + =- (un (ar (ot -))) + :~ ['name' so] + ['purpose' (cu purpose so)] + == == + :: + %get-balance + [id.res (no res.res)] + :: + %get-balances + :- id.res + %. res.res + %- ou + :~ :- 'mine' + =; mine + (un (ou mine)) + :~ ['trusted' (uf ~ (mu no))] + ['untrusted_pending' (un no)] + ['immature' (un no)] + ['used' (uf ~ (mu no))] + == + :: + :- 'watchonly' + =; watchonly + (uf ~ (mu (ot watchonly))) + :~ ['trusted' no] + ['untrusted_pending' no] + ['immature' no] + == == + :: + %get-new-address + :- id.res + ^- ?(@uc [%bech32 @t]) + %. res.res + (cu addr-type-validator so) + :: + %get-raw-change-address + :- id.res + %. res.res + (cu addr-type-validator so) + :: + %get-received-by-address + [id.res (no res.res)] + :: + %get-received-by-label + [id.res (no res.res)] + :: + %get-transaction + :- id.res + %. res.res + %- ou + :~ ['amount' (un no)] + ['fee' (uf ~ (mu no))] + ['confirmations' (un ni)] + ['blockhash' (uf ~ (mu (cu to-hex so)))] + ['blockindex' (uf ~ (mu ni))] + ['blocktime' (uf ~ (mu ni))] + ['txid' (un (cu to-hex so))] + ['time' (un ni)] + ['timereceived' (un ni)] + ['bip125-replaceable' (un (cu bip125-replaceable so))] + :: + :- 'details' + =- (un (ar (ou -))) + :~ ['address' (uf ~ (mu (cu addr-type-validator so)))] + ['category' (un (cu category so))] + ['amount' (un no)] + ['label' (uf ~ (mu so))] + ['vout' (un ni)] + ['fee' (uf ~ (mu no))] + ['abandoned' (uf ~ (mu bo))] + == + :: + ['hex' (un (cu to-hex so))] + ['decoded' (uf ~ (mu raw-transaction:json-parser))] + == + :: + %get-unconfirmed-balance + [id.res (no res.res)] + :: + %get-wallet-info + :- id.res + %. res.res + %- ou + :~ ['walletname' (un so)] + ['walletversion' (un ni)] + ['balance' (un no)] + ['unconfirmed_balance' (un no)] + ['immature_balance' (un no)] + ['txcount' (un ni)] + ['keypoololdest' (un ni)] + ['keypoolsize' (un ni)] + ['keypool_size_hd_internal' (uf ~ (mu ni))] + ['unlocked_until' (uf ~ (mu ni))] + ['paytxfee' (un no)] + ['hdseedid' (uf ~ (mu (cu to-hex so)))] + ['private_keys_enabled' (un bo)] + ['avoid_reuse' (un bo)] + :- 'scanning' + %- un + |= =json + %. json + ?: =(%b -.json) + bo + ?. =(%o -.json) + !! + (ot ~[['duration' no] ['progress' no]]) + == + :: + %list-wallets + [id.res ((ar so) res.res)] + :: + %import-address + [id.res ~] + :: + %import-multi + :- id.res + %. res.res + =- (ar (ou -)) + :~ ['success' (un bo)] + ['warnings' (uf ~ (mu (ar so)))] + :: + :- 'errors' + =- (uf ~ (mu -)) + (ot ~[['error' so] ['message' so]]) + == + :: + %import-privkey + [id.res ~] + :: + %import-pruned-funds + [id.res ~] + :: + %import-pubkey + [id.res ~] + :: + %import-wallet + [id.res ~] + :: + %key-pool-refill + [id.res ~] + :: + %list-address-groupings + :- id.res + %. res.res + =- (ar (ar -)) + =- (cu groups (ar -)) + |= =json + %. json + ?: =(%s -.json) + so + ?. =(%n -.json) + !! + no + :: + %list-labels + [id.res ((ar so) res.res)] + :: + %list-lock-unspent + :- id.res + %. res.res + %- ar + (ot ~[['txid' (cu to-hex so)] ['vout' ni]]) + :: + %list-received-by-address + :- id.res + %. res.res + =- (ar (ou -)) + :~ :- 'involvesWatchonly' + =- (uf ~ (cu - (mu bo))) + |= b=(unit ?) + ?~ b ~ + ?>(=(u.b &) (some %&)) + :: + ['address' (un (cu addr-type-validator so))] + ['amount' (un no)] + ['confirmations' (un ni)] + ['label' (un so)] + ['txids' (un (ar (cu to-hex so)))] + == + :: + %list-received-by-label + :- id.res + %. res.res + =- (ar (ou -)) + :~ :- 'involvesWatchonly' + =- (uf ~ (cu - (mu bo))) + |= b=(unit ?) + ?~ b ~ + ?>(=(u.b &) (some %&)) + :: + ['amount' (un no)] + ['confirmations' (un ni)] + ['label' (un so)] + == + :: + %lists-in-ceblock + :- id.res + %. res.res + %- ou + =, json-parser + :~ ['transactions' (un tx-in-block)] + ['removed' (uf ~ (mu tx-in-block))] + ['lastblock' (un (cu to-hex so))] + == + :: + %list-transactions + [id.res (tx-in-block:json-parser res.res)] + :: + %list-unspent + :- id.res + %. res.res + =- (ar (ou -)) + :~ ['txid' (un (cu to-hex so))] + ['vout' (un ni)] + ['address' (un (cu addr-type-validator so))] + ['label' (un so)] + ['scriptPubKey' (un (cu to-hex so))] + ['amount' (un no)] + ['confirmations' (un ni)] + ['redeemScript' (un (cu to-hex so))] + ['witnessScript' (uf ~ (mu (cu to-hex so)))] + ['spendable' (un bo)] + ['solvable' (un bo)] + ['reused' (uf ~ (mu bo))] + ['desc' (uf ~ (mu so))] + ['safe' (un bo)] + == + :: + %list-wallet-dir + :- id.res + %. res.res + =- (ot ['wallets' -]~) + (ar (ot [name+so]~)) + :: + %list-wallets + [id.res ((ar so) res.res)] + :: + %load-wallet + :- id.res + %. res.res + (ot ~[name+so warning+so]) + :: + %lock-unspent + [id.res (bo res.res)] + :: + %remove-pruned-funds + [id.res ~] + :: + %rescan-blockchain + :- id.res + %. res.res + %- ot + :~ ['start_height' ni] + ['stop_height' ni] + == + :: + %send-many + :- id.res + %. res.res + (cu to-hex so) + :: + %send-to-address + :- id.res + %. res.res + (cu to-hex so) + :: + %set-hd-seed + [id.res ~] + :: + %set-label + [id.res ~] + :: + %set-tx-fee + [id.res (bo res.res)] + :: + %set-wallet-flag + :- id.res + %. res.res + %- ot + :~ ['flag_name' so] + ['flag_state' bo] + ['warnings' so] + == + :: + %sign-message + [id.res (so res.res)] + :: + %sign-raw-transaction-with-wallet + :- id.res + %. res.res + %- ou + :~ ['hex' (un (cu to-hex so))] + ['complete' (un bo)] + :: + :- 'errors' + =- (uf ~ (mu (ar (ot -)))) + :~ ['txid' (cu to-hex so)] + ['vout' ni] + ['scriptSig' (cu to-hex so)] + ['sequence' ni] + ['error' so] + == == + :: + %unload-wallet + [id.res ~] + :: + %wallet-create-fundedpsbt + :- id.res + %. res.res + %- ot + :~ ['psbt' so] + ['fee' no] + :: + =- ['changepos' (cu - no)] + |= a=@t + ^- ?(@ud %'-1') + ?: =(a '-1') + %'-1' + (rash a dem) + == + :: + %wallet-lock + [id.res ~] + :: + %wallet-passphrase + [id.res ~] + :: + %wallet-passphrase-change + [id.res ~] + :: + %wallet-process-psbt + :- id.res + %. res.res + %- ot + :~ ['psbt' so] + ['complete' bo] + == + :: ZMQ + :: + %get-zmq-notifications + :- id.res + %. res.res + =- (ar (ot -)) + :~ ['type' so] + ['address' (cu addr-type-validator so)] + ['hwm' ni] + == + == + -- +-- diff --git a/sur/btc-node-hook.hoon b/sur/btc-node-hook.hoon new file mode 100644 index 0000000000..5b6275b5b5 --- /dev/null +++ b/sur/btc-node-hook.hoon @@ -0,0 +1,2028 @@ +=> :: Helper types + :: + |% + :: +address: base58check encoded public key (20 bytes) + :: + :: FIXME: %bech32 is not parsed by fim:ag + :: + +$ address ?(@uc [%bech32 @t]) + ++ blockhash @ux + :: $estimate-mode + :: + :: Used in: + :: - %fund-raw-transaction + :: - %estimate-smart-fee + :: - %bump-fee + :: - %wallet-create-fundedpsbt + :: - %send-to-address + :: - %send-many + :: + +$ estimate-mode ?(%'UNSET' %'ECONOMICAL' %'CONSERVATIVE') + :: $category: + :: + :: Used in: + :: - $tx-in-block + :: - %get-transaction + :: - %list-transactions + :: + +$ category ?(%send %receive %generate %immature %orphan) + :: $rule: + :: + :: Used in: + :: - %get-block-template + :: + :: + +$ rule %segwit + :: $capability: + :: + :: Used in: + :: - %get-block-template + :: + +$ capability + $? %longpoll + %coinbasetxn + %coinbasevalue + %proposal + %serverlist + %workid + == + :: $block-template-mode: + :: + :: Used in: + :: - %get-block-template + :: + +$ block-template-mode + $? mode=%template + [mode=%proposal data=@ux workid=(unit @t)] + == + :: $logging-category: + :: + :: Used in: + :: - %logging + :: + +$ logging-category + $? %net + %tor + %mempool + %http + %bench + %zmq + %db + %rpc + %estimatefee + %addrman + %selectcoins + %reindex + %cmpctblock + %rand + %prune + %proxy + %mempoolrej + %libevent + %coindb + %qt + %leveldb + == + :: $rpc-command: + :: + :: Used in: + :: - %get-rpc-info + :: + +$ rpc-command [method=@t duration=@dr] + :: $transaction: + :: + :: Used in: + :: - %get-block-template + :: + +$ transaction + $: data=@ux + txid=@ux + hash=@ux + depends=(list @ud) + fee=@ud + sigops=@ud + weight=@ud + == + :: $mutable: + :: + :: Used in: + :: - %get-block-template + :: + +$ mutable ?(%value %time %transactions %prevblock) + :: $node-address: + :: + :: Used in: + :: - $node-info + :: + +$ node-address [address=@t connected=?(%inbound %outbound)] + :: $node-info: + :: + :: Used in: + :: - %get-added-node-info + :: + +$ node-info [added-node=@t connected=? addresses=(list node-address)] + :: $upload-target: + :: + :: Used in: + :: - %get-net-totals + :: + +$ upload-target + $: timeframe=@dr + target=@ud + target-reached=? + serve-historical-blocks=? + bytes-left-in-cycle=@ud + time-left-in-cycle=@dr + == + :: $network-info: + :: + :: Used in: + :: - %get-network-info + :: + +$ network-info + $: name=?(%ipv4 %ipv6 %onion) + limited=? + reachable=? + proxy=@t + proxy-randomize-credentials=? + == + :: $local-address: + :: + :: Used in: + :: - %get-network-info + :: + +$ local-address [address=@t port=@ud score=@ud] + :: $node-address-info: + :: + :: Used in: + :: - %get-node-addresses + :: + +$ node-address-info [time=@da services=@ud address=@t port=@ud] + :: $peer-info: + :: + :: Used in: + :: - %get-peer-info + :: + +$ peer-info + $: id=@ud + addr=@t + addr-bind=@t + addr-local=(unit @t) + services=@t + services-names=(list @t) + relay-txes=? + last-send=@da + last-recv=@da + bytes-sent=@ud + bytes-recv=@ud + conn-time=@da + time-offset=@t + ping-time=@rd + min-ping=@rd + ping-wait=(unit @ud) + version=@ud + subver=@t + inbound=? + addnode=? + starting-height=@ud + ban-score=@ud + synced-headers=@ud + synced-blocks=@ud + inflight=(list @ud) + whitelisted=? + min-fee-filter=@rd + bytes-sent-per-msg=(map @t @ud) + bytes-recv-per-msg=(map @t @ud) + == + :: $banned: + :: + :: Used in: + :: - %list-banned + :: + +$ banned [address=@t banned-until=@da ban-created=@da ban-reason=@t] + :: $chain-status: + :: + :: Used in: + :: - %get-chain-tips + :: + +$ chain-status + $? %invalid + %headers-only + %valid-headers + %valid-fork + %active + == + :: $soft-fork-types: + :: + :: Used in: + :: - %get-blockchain-info/$softforks + :: + +$ soft-fork-types ?(%buried %bip9) + :: $soft-fork-status: + :: + :: Used in: + :: - %get-blockchain-info/$softforks + :: + +$ soft-fork-status ?(%defined %started %'locked_in' %active %failed) + :: $purpose: + :: + :: Used in: + :: - %get-addresses-by-label + :: - %get-address-info + :: + +$ purpose ?(%send %receive) + :: $address-type: + :: + :: Used in: + :: - %add-multisig-address + :: + +$ address-type ?(%legacy %p2sh-segwit %bech32) + :: $bip125-replaceable: + :: + :: Used in: + :: - %get-transaction + :: - %list-transactions + :: - $tx-in-block + :: + +$ bip125-replaceable ?(%yes %no %unknown) + :: $network-name: + :: + :: Used in: + :: - %get-blockchain-info + :: + +$ network-name ?(%main %test %regtest) + :: $sig-hash: + :: + :: Used in: + :: - %wallet-process-psbt + :: - %sign-raw-transaction-with-wallet + :: - %sign-raw-transaction-with-key + :: - %decode-psbt + :: + +$ sig-hash + $? %'NONE' + %'SINGLE' + %'ALL|ANYONECANPAY' + %'NONE|ANYONECANPAY' + %'SINGLE|ANYONECANPAY' + %'ALL' + == + :: $script: + :: + :: Used in: + :: - %decode-psbt: $redeem-script/$witness-script + :: + +$ script [asm=@t hex=@ux type=@t] + :: $script-pubkey: + :: + :: Used in: + :: - $utxo + :: + +$ script-pubkey + $: asm=@t + hex=@ux + type=@t + =address + == + :: $range: + :: + :: Used in: + :: - %derive-addresses + :: - $scan-object + :: + +$ range ?(@ud [@ud @ud]) + :: $vin: + :: + :: Used in: + :: - $serialized-tx + :: - $raw-transaction-rpc-out + :: + +$ vin + $: txid=(unit @ux) + vout=(unit @ud) + script-sig=(unit [asm=@t hex=@ux]) + tx-in-witness=(unit (list @ux)) + sequence=@ud + == + :: $vout: + :: + :: Used in: + :: - $serialized-tx + :: - $raw-transaction-rpc-out + :: + +$ vout + $: value=@t + n=@ud + :: + $= script-pubkey + $: asm=@t + hex=@ux + req-sigs=(unit @ud) + type=@t + addresses=(unit (list address)) + == == + :: $input: + :: + :: Used in: + :: - %wallet-create-fundedpsbt + :: - $partially-signed-transaction + :: + +$ input + $: txid=@ux + vout=@ud + sequence=@ud + == + :: $output: + :: + :: Used in: + :: - %wallet-create-fundedpsbt + :: - $partially-signed-transaction + :: + +$ output + $: data=[%data @ux] + addresses=(list [=address amount=@t]) + == + :: $scan-object: + :: + :: Used in: + :: - %scan-tx-outset + :: + +$ scan-object + $? descriptor=@t + :: + $= object + $: desc=@t + range=(unit range) + == == + :: $utxo: + :: + :: Used in: + :: - %decode-psbt + :: + +$ utxo + (unit [amount=@t =script-pubkey]) + :: $segwit-script: + :: + :: Used in: + :: - %decode-script + :: + +$ segwit-script + $: asm=@t + hex=(unit @ux) + type=@t + req-sigs=(unit @ud) + addresses=(list [%bech32 @t]) + p2sh-segwit=(unit @uc) + == + :: $partially-signed-transaction: + :: + :: Used in: + :: - %create-psbt + :: - %create-raw-transaction + :: + +$ partially-signed-transaction + $: inputs=(list input) + outputs=output + locktime=(unit @ud) + replaceable=(unit ?) + == + :: $import-request: + :: + :: Used in: + :: - %import-multi + :: + +$ import-request + $: desc=(unit @t) + :: + $= script-pubkey + $% [%script s=@t] + [%address a=address] + == + :: + timestamp=?(@da %now) + redeem-script=(unit @t) + witness-script=(unit @t) + pubkeys=(unit (list @t)) + keys=(unit (list @t)) + range=(unit ?(@ud [@ud @ud])) + internal=(unit ?) + watchonly=(unit ?) + label=(unit @t) + keypool=(unit ?) + == + :: $serialized-tx: + :: + :: Used in: + :: - %decode-psbt + :: - %decode-raw-transaction + :: + +$ serialized-tx + $: txid=@ux + hash=@ux + size=@ud + vsize=@ud + weight=@ud + version=@ud + locktime=@ud + vin=(list vin) + vout=(list vout) + == + :: $prev-tx: + :: + :: Used in: + :: - %sign-raw-transaction-with-wallet + :: - %sign-raw-transaction-with-key + :: + +$ prev-tx + $: txid=@ux + vout=@ud + script-pubkey=@ux + redeem-script=(unit @ux) + witness-script=(unit @ux) + amount=@t + == + :: $raw-transaction-rpc-out: + :: + :: Used in: + :: - %get-block + :: - %get-raw-transaction + :: + +$ raw-transaction-rpc-out + $: in-active-chain=(unit ?) + hex=@ux + txid=@ux + hash=@ux + size=@ud + vsize=@ud + weight=@ud + version=@t + locktime=@ud + vin=(list vin) + vout=(list vout) + blockhash=(unit @ux) + confirmations=(unit @ud) + blocktime=(unit @ud) + time=(unit @ud) + == + :: $tx-in-block: + :: + :: Used in: + :: - %lists-in-ceblock + :: - %list-transactions + :: + +$ tx-in-block + $: address=(unit address) + =category + amount=@t + label=(unit @t) + vout=@ud + fee=(unit @t) + confirmations=@ud + blockhash=(unit @ux) + blockindex=(unit @ud) + blocktime=(unit @ud) + txid=@ux + time=@ud + time-received=(unit @ud) + wallet-conflicts=(unit (list @ux)) + =bip125-replaceable + abandoned=(unit ?) + comment=(unit @t) + to=(unit @t) + == + :: $errors: + :: + :: Used in: + :: - %sign-raw-transaction-with-key + :: - %sign-raw-transaction-with-wallet + :: + +$ errors + %- list + $: txid=@ + vout=@ + script-sig=@ + sequence=@ + error=@t + == + :: $mem-pool: + :: + :: Used in: + :: - $mem-pool-response + :: - %get-mempool-entry + :: + +$ mem-pool + $: size=(unit @ud) + vsize=@ud + weight=@ud + fee=@t + modified-fee=@t + time=@ud + height=@ud + descendant-count=@ud + descendant-size=@ud + descendant-fees=@t + ancestor-count=@ud + ancestor-size=@ud + ancestor-fees=@t + w-txid=@ux + :: + $= fees + $: base=@t + modified=@t + ancestor=@t + descendant=@t + == + :: + depends=(list @ux) + spent-by=(list @ux) + bip125-replaceable=? + == + :: $mem-pool-response: + :: + :: Used in: + :: - %get-raw-mempool + :: - %get-mempool-entry + :: - %get-mempool-ancestors + :: - %get-mempool-descendants + :: - %get-raw-mempool + :: + +$ mem-pool-response + %- list + $@ :: (for verbose = false) + :: + @ux + :: + :: (for verbose = true) + :: + [id=@ux =mem-pool] + :: + :: $descriptor + :: + :: Used in: + :: - %utxo-update-psbt + :: + +$ descriptor + $? @t + :: + $: desc=@t + range=(unit range) + == == + -- +|% +:: ++$ btc-node-hook-action request:btc-rpc ++$ btc-node-hook-response response:btc-rpc ++$ btc-node-hook-command command:btc-rpc +:: +++ btc-rpc + |% + +$ request + $% + :: Blockchain + :: + :: %get-best-block-hash: Returns the hash of the + :: best (tip) block in the longest blockchain. + :: + [%get-best-block-hash ~] + :: %get-block: Returns an Object/string with information about block + :: + [%get-block blockhash=@ux verbosity=(unit ?(%0 %1 %2))] + :: %get-blockchain-info: Returns info regarding blockchain processing. + :: + [%get-blockchain-info ~] + :: %get-block-count: Returns number of blocks in the longest blockchain + :: + [%get-block-count ~] + :: %get-block-filter: Retrieve a BIP 157 content filter for a block. + :: + [%get-block-filter block-hash=@ux filter-type=(unit @t)] + :: %get-block-hash: Returns hash of block in best-block-chain at height + :: + [%get-block-hash height=@ud] + :: %get-block-header: If verbose is false, returns a string that is + :: serialized, hex-encoded data for blockheader 'hash'. If verbose is + :: true, returns an Object + :: + [%get-block-header blockhash=@ux verbose=(unit ?)] + :: %get-block-stats: Compute per block statistics for a given window. + :: + $: %get-block-stats + $= hash-or-height + $% [%hex @ux] + [%num @ud] + == + :: + stats=(unit (list @t)) + == + :: %get-chain-tips: Return information about tips in the block tree. + :: + [%get-chain-tips ~] + :: %get-chain-tx-stats: Compute statistics about total number rate + :: of transactions in the chain. + :: + [%get-chain-tx-stats n-blocks=(unit @ud) blockhash=(unit @ux)] + :: %get-difficulty: Returns the proof-of-work difficulty as a multiple + :: of the minimum difficulty. + :: + [%get-difficulty ~] + :: %get-mempool-ancestors: If txid is in the mempool, returns + :: all in-mempool ancestors. + :: + [%get-mempool-ancestors txid=@ux verbose=(unit ?)] + :: %get-mempool-descendants: If txid is in the mempool, returns + :: all in-mempool descendants. + :: + [%get-mempool-descendants txid=@ux verbose=(unit ?)] + :: %get-mempool-entry: Returns mempool data for given transaction + :: + [%get-mempool-entry txid=@ux] + :: %get-mempool-info: Returns details on the active state of the + :: TX memory pool. + :: + [%get-mempool-info ~] + :: %get-raw-mempool: Returns all transaction ids in memory pool as a + :: json array of string transaction ids. + :: + [%get-raw-mempool verbose=(unit ?)] + :: %get-tx-out: Returns details about an unspent transaction output. + :: + [%get-tx-out txid=@ux n=@ud include-mempool=(unit ?)] + :: %get-tx-out-proof: Returns a hex-encoded proof that "txid" was + :: included in a block. + :: + [%get-tx-out-proof tx-ids=(list @ux) blockhash=(unit @ux)] + :: %get-tx-outset-info: Returns statistics about the unspent + :: transaction output set. + :: + [%get-tx-outset-info ~] + :: %precious-block: Treats a block as if it were received before + :: others with the same work. + :: + [%precious-block blockhash=@ux] + :: %prune-blockchain: + :: + [%prune-blockchain height=@ud] + :: %save-mempool: Dumps the mempool to disk. + :: It will fail until the previous dump is fully loaded. + :: + [%save-mempool ~] + :: %scan-tx-outset: Scans the unspent transaction output set for + :: entries that match certain output descriptors. + :: + $: %scan-tx-outset + action=?(%start %abort %status) + scan-objects=(list scan-object) + == + :: %verify-chain: Verifies blockchain database. + :: + [%verify-chain check-level=(unit @ud) n-blocks=(unit @ud)] + :: %verify-tx-out-proof: Verifies that a proof points to a transaction + :: in a block, returning the transaction it commits to + :: and throwing an RPC error if the block is not in our best chain + :: + [%verify-tx-out-proof proof=@t] + :: Control + :: + :: %getmemoryinfo: Returns an object containing information about memory + :: usage. + :: + [%get-memory-info ~] + :: %getrpcinfo: Returns details of the RPC server. + :: + [%get-rpc-info ~] + :: %help: List all commands, or get help for a specified command. + :: + [%help command=(unit @t)] + :: %logging: Gets and sets the logging configuration. + :: + $: %logging + include=?(%all %none (list logging-category)) + exclude=?(%all %none (list logging-category)) + == + :: %stop: Stop Bitcoin server. + :: + [%stop ~] + :: %uptime: Returns the total uptime of the server. + :: + [%uptime ~] + :: Generating + :: + [%generate blocks=@ud max-tries=(unit @ud)] + :: %generatetoaddress: Mine blocks immediately to a specified address + :: (before the RPC call returns) + :: + [%generate-to-address n-blocks=@ud =address max-tries=(unit @ud)] + :: Mining + :: + :: %getblocktemplate: It returns data needed to construct a block + :: to work on. + :: + $: %get-block-template + rules=(list rule) + capabilities=(list capability) + mode=(unit block-template-mode) + == + :: %getmininginfo: Returns a json object containing mining-related + :: information. + :: + [%get-mining-info ~] + :: %getnetworkhashps: Returns the estimated network hashes per second + :: based on the last n blocks. + :: + [%get-network-hash-ps n-blocks=(unit @ud) height=(unit @ud)] + :: %prioritisetransaction: Accepts the transaction into mined blocks + :: at a higher (or lower) priority + :: + [%prioritise-transaction txid=@ux fee-delta=@ud] + :: %submitblock: Attempts to submit new block to network. + :: + [%submit-block hex-data=@ux] + :: %submitheader: Decode the given hexdata as a header and submit it + :: as a candidate chain tip if valid. Throws when the header is + :: invalid. + :: + [%submit-header hex-data=@ux] + :: Mining + :: + :: %addnode: Attempts to add or remove a node from the addnode list. + :: Or try a connection to a node once. + :: + [%add-node node=@if port=@ud command=?(%add %remove %onetry)] + :: %clearbanned: Clear all banned IPs. + :: + [%clear-banned ~] + :: %disconnectnode: Immediately disconnects from the specified peer node. + :: + [%disconnect-node node=?(node-id=@t [address=@if port=@ud])] + :: %getaddednodeinfo: Returns information about the given added node, + :: or all added nodes (note that onetry addnodes are not listed here) + :: + [%get-added-node-info node=(unit @if)] + :: %getconnectioncount: Returns the number of connections to other + :: nodes. + :: + [%get-connection-count ~] + :: %getnettotals: Returns information about network traffic, + :: including bytes in, bytes out, and current time. + :: + [%get-net-totals ~] + :: %getnetworkinfo: Returns an object containing various state info + :: regarding P2P networking. + :: + [%get-network-info ~] + :: %getnodeaddresses: Return known addresses which can potentially be + :: used to find new nodes in the network + [%get-node-addresses count=(unit @ud)] + :: %getpeerinfo: Returns data about each connected network node as a + :: json array of objects. + :: + [%get-peer-info ~] + :: %listbanned: List all banned IPs/Subnets. + :: + [%list-banned ~] + :: %ping: Requests that a ping be sent to all other nodes, to measure + :: ping time. Results provided in getpeerinfo, pingtime and pingwait + :: fields are decimal seconds. Ping command is handled in queue with all + :: other commands, so it measures processing backlog, not just network + :: ping. + :: + [%ping ~] + :: %setban: Attempts to add or remove an IP/Subnet from the banned list. + :: + $: %set-ban + subnet=@t + command=?(%add %remove) + ban-time=(unit ?([%dr @dr] [%da @da])) + == + :: %setnetworkactive: Disable/enable all p2p network activity. + :: + [%set-network-active state=?] + :: Raw Transactions + :: + :: %analyze-psbt: Analyzes and provides information about + :: the current status of a PSBT and its inputs + :: + [%analyze-psbt psbt=@t] + :: %combine-psbt: Combine multiple partially signed Bitcoin + :: transactions into one transaction. + :: + [%combine-psbt txs=(list @t)] + :: %combine-raw-transaction: Combine multiple partially signed t + :: ransactions into one transaction. + :: + [%combine-raw-transaction txs=(list @ux)] + :: %convert-to-psbt: Converts a network serialized transaction to a + :: PSBT. + :: + $: %convert-to-psbt + hex-string=@ux + permit-sig-data=(unit ?) + is-witness=(unit ?) + == + :: %create-psbt: Creates a transaction in the Partially Signed + :: Transaction format. + :: + [%create-psbt partially-signed-transaction] + :: %create-raw-transaction: Create a transaction spending the given + :: inputs and creating new outputs. + :: + [%create-raw-transaction partially-signed-transaction] + :: %decode-psbt: Return a JSON object representing the serialized, + :: base64-encoded partially signed Bitcoin transaction. + :: + [%decode-psbt psbt=@t] + :: %decode-raw-transaction: Return a JSON object representing the + :: serialized, hex-encoded transaction. + :: + [%decode-raw-transaction hex-string=@ux is-witness=?] + :: %decode-script: Decode a hex-encoded script. + :: + [%decode-script hex-string=@ux] + :: %finalize-psbt: Finalize the inputs of a PSBT. + :: + [%finalize-psbt psbt=@t extract=(unit ?)] + :: %fund-raw-transaction: Add inputs to a transaction until it has + :: enough in value to meet its out value. + :: + $: %fund-raw-transaction + hex-string=@ux + :: + $= options + %- unit + $: change-address=(unit address) + change-position=(unit @ud) + change-type=(unit address-type) + include-watching=(unit ?) + lock-unspents=(unit ?) + fee-rate=(unit @t) + subtract-fee-from-outputs=(unit (list @ud)) + replaceable=(unit ?) + conf-target=(unit @ud) + mode=(unit estimate-mode) + == + :: + is-witness=? + == + :: %get-raw-transaction: Return the raw transaction data. + :: + [%get-raw-transaction txid=@ux verbose=(unit ?) blockhash=(unit @ux)] + :: %join-psbts: Joins multiple distinct PSBTs with different inputs + :: and outputs into one PSBT with inputs and outputs from all of + :: the PSBTs + :: + [%join-psbts txs=(list @t)] + :: %send-raw-transaction: Submits raw transaction + :: (serialized, hex-encoded) to local node and network. + :: + [%send-raw-transaction hex-string=@ux max-fee-rate=(unit @t)] + :: %sign-raw-transaction-with-key: Sign inputs for raw transaction + :: (serialized, hex-encoded). + :: + $: %sign-raw-transaction-with-key + hex-string=@ux + priv-keys=(list @t) + prev-txs=(unit (list prev-tx)) + sig-hash-type=(unit sig-hash) + == + :: %test-mempool-accept: Returns result of mempool acceptance tests + :: indicating if raw transaction (serialized, hex-encoded) would be + :: accepted by mempool. + :: + [%test-mempool-accept raw-txs=(list @ux) max-fee-rate=(unit @t)] + :: %utxo-update-psbt: Updates a PSBT with witness UTXOs retrieved from + :: the UTXO set or the mempool. + :: + $: %utxo-update-psbt + psbt=@t + descriptors=(unit (list descriptor)) + == + :: Util + :: + :: %create-multi-sig: Creates a multi-signature address with n + :: signature of m keys required. It returns a json object with the + :: address and redeemScript. + :: + $: %create-multi-sig + n-required=@ud + keys=(list @ux) + address-type=(unit address-type) + == + :: %derive-addresses: Derives one or more addresses corresponding to + :: an output descriptor. + :: + [%derive-addresses descriptor=@t range=(unit range)] + :: %estimate-smart-fee: Estimates the approximate fee per kilobyte + :: needed for a transaction to begin confirmation within conf_target + :: blocks if possible and return the number of blocks for which the + :: estimate is valid. + :: + [%estimate-smart-fee conf-target=@ud mode=(unit estimate-mode)] + :: %get-descriptor-info: Analyses a descriptor. + :: + [%get-descriptor-info descriptor=@t] + :: %sign-message-with-privkey: Sign a message with the private key of + :: an address + :: + [%sign-message-with-privkey privkey=@t message=@t] + :: %validate-address: Return information about the given + :: bitcoin address. + :: + [%validate-address =address] + :: %verify-message: Verify a signed message + :: + [%verify-message =address signature=@t message=@t] + :: Wallet + :: + :: %abandon-transaction: Mark in-wallet transaction as abandoned. + :: + [%abandon-transaction txid=@ux] + :: %abort-rescan: Stops current wallet rescan triggered by an + :: RPC call, e.g. by an importprivkey call. + :: + [%abort-rescan ~] + :: %add-multisig-address: Add a nrequired-to-sign multisignature + :: address to the wallet. + :: + $: %add-multisig-address + n-required=@ud + keys=(list address) + label=(unit @t) + =address-type + == + :: %backupwallet: Safely copies current wallet file to destination. + :: + [%backup-wallet destination=@t] + :: %bump-fee: Bumps the fee of an opt-in-RBF transaction T, replacing + :: it with a new transaction B. + :: + $: %bump-fee + txid=@ux + :: + $= options + %- unit + $: conf-target=(unit @ud) + total-fee=(unit @t) + fee-rate=(unit @t) + replaceable=(unit ?) + mode=(unit estimate-mode) + == == + :: %create-wallet: Creates and loads a new wallet. + :: + :: - %name: The name for the new wallet. + :: - %disable-private-keys: Disable the possibility of private keys + :: (only watchonlys are possible in this mode). + :: - %blank: Create a blank wallet. + :: A blank wallet has no keys or HD seed. + :: One can be set using sethdseed. + :: + $: %create-wallet + name=@t + disable-private-keys=(unit ?) + blank=(unit ?) + passphrase=(unit @t) + avoid-reuse=(unit ?) + == + :: %dump-privkey: Reveals the private key corresponding to 'address'. + :: + [%dump-privkey =address] + :: %dump-wallet: Dumps all wallet keys in a human-readable format to + :: a server-side file. + :: + [%dump-wallet filename=@t] + :: %encrypt-wallet: Encrypts the wallet with 'passphrase'. + :: + [%encrypt-wallet passphrase=@t] + :: %get-addresses-by-label: Returns the list of addresses assigned the + :: specified label. + :: + [%get-addresses-by-label label=@t] + :: %get-address-info: Return information about the given bitcoin + :: address. + :: + [%get-address-info =address] + :: %get-balance: Returns the total available balance. + :: + $: %get-balance + %- unit + $: dummy=(unit %'*') + minconf=(unit @ud) + include-watch-only=(unit ?) + avoid-reuse=(unit ?) + == == + :: %get-balances: Returns an object with all balances in BTC. + :: + [%get-balances ~] + :: %get-new-address: Returns a new Bitcoin address for receiving + :: payments. + :: + [%get-new-address label=(unit @t) address-type=(unit address-type)] + :: %get-raw-change-address: Returns a new Bitcoin address, + :: for receiving change. + :: + [%get-raw-change-address address-type=(unit address-type)] + :: %get-received-by-address: Returns the total amount received by the + :: given address in transactions with at least minconf confirmations. + :: + [%get-received-by-address =address minconf=@ud] + :: %get-received-by-label: Returns the total amount received by + :: addresses with