mirror of
https://github.com/urbit/shrub.git
synced 2025-01-05 11:09:30 +03:00
Merge pull request #5217 from urbit/lf/btc-test
btc-wallet, bitcoin: update for distribution
This commit is contained in:
commit
b518f30c17
@ -342,6 +342,7 @@
|
|||||||
:: helper core
|
:: helper core
|
||||||
~% %btc-provider-helper ..card ~
|
~% %btc-provider-helper ..card ~
|
||||||
|_ =bowl:gall
|
|_ =bowl:gall
|
||||||
|
+* grp ~(. groupl bowl)
|
||||||
++ send-status
|
++ send-status
|
||||||
|= [=status ship=(unit ship)]
|
|= [=status ship=(unit ship)]
|
||||||
^- card
|
^- card
|
||||||
@ -379,9 +380,10 @@
|
|||||||
::
|
::
|
||||||
++ in-group
|
++ in-group
|
||||||
=/ gs ~(tap in groups.whitelist)
|
=/ gs ~(tap in groups.whitelist)
|
||||||
|
?. is-running:grp %.n
|
||||||
|-
|
|-
|
||||||
?~ gs %.n
|
?~ gs %.n
|
||||||
?: (~(is-member groupl bowl) user i.gs)
|
?: (is-member:grp user i.gs)
|
||||||
%.y
|
%.y
|
||||||
$(gs t.gs)
|
$(gs t.gs)
|
||||||
--
|
--
|
||||||
|
@ -73,8 +73,8 @@
|
|||||||
^- (quip card _this)
|
^- (quip card _this)
|
||||||
~& > '%btc-wallet initialized'
|
~& > '%btc-wallet initialized'
|
||||||
::
|
::
|
||||||
=/ warning=event:settings [%put-entry %btc-wallet %warning %b %.y]
|
=/ warning=event:settings [%put-entry q.byk.bowl %btc-wallet %warning %b %.y]
|
||||||
=/ currency=event:settings [%put-entry %btc-wallet %currency %s 'USD']
|
=/ currency=event:settings [%put-entry q.byk.bowl %btc-wallet %currency %s 'USD']
|
||||||
=/ cards=(list card)
|
=/ cards=(list card)
|
||||||
:~ (poke-our:hc %settings-store %settings-event !>(warning))
|
:~ (poke-our:hc %settings-store %settings-event !>(warning))
|
||||||
(poke-our:hc %settings-store %settings-event !>(currency))
|
(poke-our:hc %settings-store %settings-event !>(currency))
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
:~ :- %apes
|
:~ :- %apes
|
||||||
:~ %btc-provider
|
:~ %btc-wallet
|
||||||
%btc-wallet
|
|
||||||
==
|
==
|
||||||
:- %fish ~
|
:- %fish ~
|
||||||
==
|
==
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
title+'Bitcoin'
|
title+'Bitcoin'
|
||||||
info+'BTC wallet for Urbit. Testing'
|
info+'BTC wallet for Urbit. Testing'
|
||||||
color+0xf9.8e40
|
color+0xf9.8e40
|
||||||
glob+'https://bootstrap.urbit.org/glob-0v2.3kv9h.9i6cv.vfu2o.roq7e.g983m.glob'
|
glob-http+'https://bootstrap.urbit.org/glob-0v2.sl9s6.ud2bs.l9ft0.mstja.5f8kt.glob'
|
||||||
image+'https://urbit.ewr1.vultrobjects.com/hastuc-dibtux/2021.8.24..02.57.38-bitcoin.svg'
|
image+'https://urbit.ewr1.vultrobjects.com/hastuc-dibtux/2021.8.24..02.57.38-bitcoin.svg'
|
||||||
base+'bitcoin'
|
base+'bitcoin'
|
||||||
version+[0 0 1]
|
version+[0 0 1]
|
||||||
|
1
pkg/bitcoin/lib/agentio.hoon
Symbolic link
1
pkg/bitcoin/lib/agentio.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/agentio.hoon
|
1
pkg/bitcoin/lib/azimuth.hoon
Symbolic link
1
pkg/bitcoin/lib/azimuth.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/azimuth.hoon
|
1
pkg/bitcoin/lib/azimuthio.hoon
Symbolic link
1
pkg/bitcoin/lib/azimuthio.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/azimuthio.hoon
|
@ -1,249 +0,0 @@
|
|||||||
/- bc=bitcoin
|
|
||||||
/+ bcu=bitcoin-utils
|
|
||||||
|%
|
|
||||||
++ params
|
|
||||||
|%
|
|
||||||
++ p 19
|
|
||||||
++ m 784.931
|
|
||||||
--
|
|
||||||
::
|
|
||||||
++ siphash
|
|
||||||
|= [k=byts m=byts]
|
|
||||||
^- byts
|
|
||||||
|^
|
|
||||||
?> =(wid.k 16)
|
|
||||||
?> (lte (met 3 dat.k) wid.k)
|
|
||||||
?> (lte (met 3 dat.m) wid.m)
|
|
||||||
=. k (flim:sha k)
|
|
||||||
=. m (flim:sha m)
|
|
||||||
(flim:sha (fin (comp m (init dat.k))))
|
|
||||||
:: Initialise internal state
|
|
||||||
::
|
|
||||||
++ init
|
|
||||||
|= k=@
|
|
||||||
^- [@ @ @ @]
|
|
||||||
=/ k0=@ (end [6 1] k)
|
|
||||||
=/ k1=@ (cut 6 [1 1] k)
|
|
||||||
:^ (mix k0 0x736f.6d65.7073.6575)
|
|
||||||
(mix k1 0x646f.7261.6e64.6f6d)
|
|
||||||
(mix k0 0x6c79.6765.6e65.7261)
|
|
||||||
(mix k1 0x7465.6462.7974.6573)
|
|
||||||
::
|
|
||||||
:: Compression rounds
|
|
||||||
++ comp
|
|
||||||
|= [m=byts v=[v0=@ v1=@ v2=@ v3=@]]
|
|
||||||
^- [@ @ @ @]
|
|
||||||
=/ len=@ud (div wid.m 8)
|
|
||||||
=/ last=@ (lsh [3 7] (mod wid.m 256))
|
|
||||||
=| i=@ud
|
|
||||||
=| w=@
|
|
||||||
|-
|
|
||||||
=. w (cut 6 [i 1] dat.m)
|
|
||||||
?: =(i len)
|
|
||||||
=. v3.v (mix v3.v (mix last w))
|
|
||||||
=. v (rnd (rnd v))
|
|
||||||
=. v0.v (mix v0.v (mix last w))
|
|
||||||
v
|
|
||||||
%= $
|
|
||||||
v =. v3.v (mix v3.v w)
|
|
||||||
=. v (rnd (rnd v))
|
|
||||||
=. v0.v (mix v0.v w)
|
|
||||||
v
|
|
||||||
i (add i 1)
|
|
||||||
==
|
|
||||||
::
|
|
||||||
:: Finalisation rounds
|
|
||||||
++ fin
|
|
||||||
|= v=[v0=@ v1=@ v2=@ v3=@]
|
|
||||||
^- byts
|
|
||||||
=. v2.v (mix v2.v 0xff)
|
|
||||||
=. v (rnd (rnd (rnd (rnd v))))
|
|
||||||
:- 8
|
|
||||||
:(mix v0.v v1.v v2.v v3.v)
|
|
||||||
::
|
|
||||||
:: Sipround
|
|
||||||
++ rnd
|
|
||||||
|= [v0=@ v1=@ v2=@ v3=@]
|
|
||||||
^- [@ @ @ @]
|
|
||||||
=. v0 (~(sum fe 6) v0 v1)
|
|
||||||
=. v2 (~(sum fe 6) v2 v3)
|
|
||||||
=. v1 (~(rol fe 6) 0 13 v1)
|
|
||||||
=. v3 (~(rol fe 6) 0 16 v3)
|
|
||||||
=. v1 (mix v1 v0)
|
|
||||||
=. v3 (mix v3 v2)
|
|
||||||
=. v0 (~(rol fe 6) 0 32 v0)
|
|
||||||
=. v2 (~(sum fe 6) v2 v1)
|
|
||||||
=. v0 (~(sum fe 6) v0 v3)
|
|
||||||
=. v1 (~(rol fe 6) 0 17 v1)
|
|
||||||
=. v3 (~(rol fe 6) 0 21 v3)
|
|
||||||
=. v1 (mix v1 v2)
|
|
||||||
=. v3 (mix v3 v0)
|
|
||||||
=. v2 (~(rol fe 6) 0 32 v2)
|
|
||||||
[v0 v1 v2 v3]
|
|
||||||
--
|
|
||||||
:: +str: bit streams
|
|
||||||
:: read is from the front
|
|
||||||
:: write appends to the back
|
|
||||||
::
|
|
||||||
++ str
|
|
||||||
|%
|
|
||||||
++ read-bit
|
|
||||||
|= s=bits:bc
|
|
||||||
^- [bit=@ub rest=bits:bc]
|
|
||||||
?> (gth wid.s 0)
|
|
||||||
:* ?:((gth wid.s (met 0 dat.s)) 0b0 0b1)
|
|
||||||
[(dec wid.s) (end [0 (dec wid.s)] dat.s)]
|
|
||||||
==
|
|
||||||
::
|
|
||||||
++ read-bits
|
|
||||||
|= [n=@ s=bits:bc]
|
|
||||||
^- [bits:bc rest=bits:bc]
|
|
||||||
=| bs=bits:bc
|
|
||||||
|-
|
|
||||||
?: =(n 0) [bs s]
|
|
||||||
=^ b s (read-bit s)
|
|
||||||
$(n (dec n), bs (write-bits bs [1 b]))
|
|
||||||
::
|
|
||||||
++ write-bits
|
|
||||||
|= [s1=bits:bc s2=bits:bc]
|
|
||||||
^- bits:bc
|
|
||||||
[(add wid.s1 wid.s2) (can 0 ~[s2 s1])]
|
|
||||||
--
|
|
||||||
:: +gol: Golomb-Rice encoding/decoding
|
|
||||||
::
|
|
||||||
++ gol
|
|
||||||
|%
|
|
||||||
:: +en: encode x and append to end of s
|
|
||||||
:: - s: bits stream
|
|
||||||
:: - x: number to add to the stream
|
|
||||||
:: - p: golomb-rice p param
|
|
||||||
::
|
|
||||||
++ en
|
|
||||||
|= [s=bits:bc x=@ p=@]
|
|
||||||
^- bits:bc
|
|
||||||
=+ q=(rsh [0 p] x)
|
|
||||||
=+ unary=[+(q) (lsh [0 1] (dec (bex q)))]
|
|
||||||
=+ r=[p (end [0 p] x)]
|
|
||||||
%+ write-bits:str s
|
|
||||||
(write-bits:str unary r)
|
|
||||||
::
|
|
||||||
++ de
|
|
||||||
|= [s=bits:bc p=@]
|
|
||||||
^- [delta=@ rest=bits:bc]
|
|
||||||
|^ ?> (gth wid.s 0)
|
|
||||||
=^ q s (get-q s)
|
|
||||||
=^ r s (read-bits:str p s)
|
|
||||||
[(add dat.r (lsh [0 p] q)) s]
|
|
||||||
::
|
|
||||||
++ get-q
|
|
||||||
|= s=bits:bc
|
|
||||||
=| q=@
|
|
||||||
=^ first-bit s (read-bit:str s)
|
|
||||||
|-
|
|
||||||
?: =(0 first-bit) [q s]
|
|
||||||
=^ b s (read-bit:str s)
|
|
||||||
$(first-bit b, q +(q))
|
|
||||||
--
|
|
||||||
--
|
|
||||||
:: +hsh
|
|
||||||
::
|
|
||||||
++ hsh
|
|
||||||
|%
|
|
||||||
:: +to-range
|
|
||||||
:: - item: scriptpubkey to hash
|
|
||||||
:: - f: N*M
|
|
||||||
:: - k: key for siphash (end of blockhash, reversed)
|
|
||||||
::
|
|
||||||
++ to-range
|
|
||||||
|= [item=byts f=@ k=byts]
|
|
||||||
^- @
|
|
||||||
(rsh [0 64] (mul f (swp 3 dat:(siphash k item))))
|
|
||||||
:: +set-construct: return sorted hashes of scriptpubkeys
|
|
||||||
::
|
|
||||||
++ set-construct
|
|
||||||
|= [items=(list byts) k=byts f=@]
|
|
||||||
^- (list @)
|
|
||||||
%+ sort
|
|
||||||
%+ turn items
|
|
||||||
|= item=byts
|
|
||||||
(to-range item f k)
|
|
||||||
lth
|
|
||||||
--
|
|
||||||
::
|
|
||||||
++ parse-filter
|
|
||||||
|= filter=hexb:bc
|
|
||||||
^- [n=@ux gcs-set=bits:bc]
|
|
||||||
=/ n n:(de:csiz:bcu filter)
|
|
||||||
=/ lead=@ ?:(=(1 wid.n) 1 +(wid.n))
|
|
||||||
:- dat.n
|
|
||||||
[(mul 8 (sub wid.filter lead)) `@ub`dat:(drop:byt:bcu lead filter)]
|
|
||||||
:: +to-key: blockhash (little endian) to key for siphash
|
|
||||||
::
|
|
||||||
++ to-key
|
|
||||||
|= blockhash=tape
|
|
||||||
^- byts
|
|
||||||
%+ take:byt:bcu 16
|
|
||||||
%- flip:byt:bcu
|
|
||||||
(from-cord:hxb:bcu (crip blockhash))
|
|
||||||
:: +match: whether block filter matches *any* target scriptpubkeys
|
|
||||||
:: - filter: full block filter, with leading N
|
|
||||||
:: - k: key for siphash (end of blockhash, reversed)
|
|
||||||
:: - targets: scriptpubkeys to match
|
|
||||||
::
|
|
||||||
++ match
|
|
||||||
|= [filter=hexb:bc k=byts targets=(list byts)]
|
|
||||||
^- ?
|
|
||||||
=/ [p=@ m=@] [p:params m:params]
|
|
||||||
=/ [n=@ux gcs-set=bits:bc] (parse-filter filter)
|
|
||||||
=+ target-hs=(set-construct:hsh targets k (mul n m))
|
|
||||||
=+ last-val=0
|
|
||||||
|-
|
|
||||||
?~ target-hs %.n
|
|
||||||
?: =(last-val i.target-hs)
|
|
||||||
%.y
|
|
||||||
?: (gth last-val i.target-hs)
|
|
||||||
$(target-hs t.target-hs)
|
|
||||||
:: last-val is less than target: check next val in GCS, if any
|
|
||||||
::
|
|
||||||
?: (lth wid.gcs-set p) %.n
|
|
||||||
=^ delta gcs-set
|
|
||||||
(de:gol gcs-set p)
|
|
||||||
$(last-val (add delta last-val))
|
|
||||||
:: +all-match: returns all target byts that match
|
|
||||||
:: - filter: full block filter, with leading N
|
|
||||||
:: - targets: scriptpubkeys to match
|
|
||||||
::
|
|
||||||
++ all-match
|
|
||||||
|= [filter=hexb:bc blockhash=hexb:bc targets=(list [address:bc byts])]
|
|
||||||
^- (set [address:bc hexb:bc])
|
|
||||||
=/ k (to-key (trip (to-cord:hxb:bcu blockhash)))
|
|
||||||
%- ~(gas in *(set [address:bc hexb:bc]))
|
|
||||||
=/ [p=@ m=@] [p:params m:params]
|
|
||||||
=/ [n=@ux gcs-set=bits:bc] (parse-filter filter)
|
|
||||||
=/ target-map=(map @ [address:bc hexb:bc])
|
|
||||||
%- ~(gas by *(map @ [address:bc hexb:bc]))
|
|
||||||
%+ turn targets
|
|
||||||
|= [a=address:bc t=hexb:bc]
|
|
||||||
[(to-range:hsh t (mul n m) k) a t]
|
|
||||||
=+ target-hs=(sort ~(tap in ~(key by target-map)) lth)
|
|
||||||
=+ last-val=0
|
|
||||||
=| matches=(list @)
|
|
||||||
|-
|
|
||||||
?~ target-hs
|
|
||||||
(murn matches ~(get by target-map))
|
|
||||||
?: =(last-val i.target-hs)
|
|
||||||
%= $
|
|
||||||
target-hs t.target-hs
|
|
||||||
matches [last-val matches]
|
|
||||||
==
|
|
||||||
?: (gth last-val i.target-hs)
|
|
||||||
$(target-hs t.target-hs)
|
|
||||||
:: last-val is less than target: get next val in GCS, if any
|
|
||||||
::
|
|
||||||
?: (lth wid.gcs-set p)
|
|
||||||
(murn matches ~(get by target-map))
|
|
||||||
=^ delta gcs-set
|
|
||||||
(de:gol gcs-set p)
|
|
||||||
$(last-val (add delta last-val))
|
|
||||||
::
|
|
||||||
--
|
|
1
pkg/bitcoin/lib/bip/b158.hoon
Symbolic link
1
pkg/bitcoin/lib/bip/b158.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../base-dev/lib/bip/b158.hoon
|
@ -1,144 +0,0 @@
|
|||||||
:: BIP173: Bech32 Addresses
|
|
||||||
:: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
|
|
||||||
::
|
|
||||||
:: Heavily copies:
|
|
||||||
:: https://github.com/bitcoinjs/bech32/blob/master/index.js
|
|
||||||
::
|
|
||||||
/- sur=bitcoin
|
|
||||||
/+ bcu=bitcoin-utils
|
|
||||||
=, sur
|
|
||||||
=, bcu
|
|
||||||
|%
|
|
||||||
++ prefixes
|
|
||||||
^- (map network tape)
|
|
||||||
(my [[%main "bc"] [%testnet "tb"] ~])
|
|
||||||
++ charset "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
|
|
||||||
+$ raw-decoded [hrp=tape data=(list @) checksum=(list @)]
|
|
||||||
:: below is a port of: https://github.com/bitcoinjs/bech32/blob/master/index.js
|
|
||||||
::
|
|
||||||
++ polymod
|
|
||||||
|= values=(list @)
|
|
||||||
|^ ^- @
|
|
||||||
=/ gen=(list @ux)
|
|
||||||
~[0x3b6a.57b2 0x2650.8e6d 0x1ea1.19fa 0x3d42.33dd 0x2a14.62b3]
|
|
||||||
=/ chk=@ 1
|
|
||||||
|- ?~ values chk
|
|
||||||
=/ top (rsh [0 25] chk)
|
|
||||||
=. chk
|
|
||||||
(mix i.values (lsh [0 5] (dis chk 0x1ff.ffff)))
|
|
||||||
$(values t.values, chk (update-chk chk top gen))
|
|
||||||
::
|
|
||||||
++ update-chk
|
|
||||||
|= [chk=@ top=@ gen=(list @ux)]
|
|
||||||
=/ is (gulf 0 4)
|
|
||||||
|- ?~ is chk
|
|
||||||
?: =(1 (dis 1 (rsh [0 i.is] top)))
|
|
||||||
$(is t.is, chk (mix chk (snag i.is gen)))
|
|
||||||
$(is t.is)
|
|
||||||
--
|
|
||||||
::
|
|
||||||
++ expand-hrp
|
|
||||||
|= hrp=tape
|
|
||||||
^- (list @)
|
|
||||||
=/ front (turn hrp |=(p=@tD (rsh [0 5] p)))
|
|
||||||
=/ back (turn hrp |=(p=@tD (dis 31 p)))
|
|
||||||
(zing ~[front ~[0] back])
|
|
||||||
::
|
|
||||||
++ verify-checksum
|
|
||||||
|= [hrp=tape data-and-checksum=(list @)]
|
|
||||||
^- ?
|
|
||||||
%- |=(a=@ =(1 a))
|
|
||||||
%- polymod
|
|
||||||
(weld (expand-hrp hrp) data-and-checksum)
|
|
||||||
::
|
|
||||||
++ checksum
|
|
||||||
|= [hrp=tape data=(list @)]
|
|
||||||
^- (list @)
|
|
||||||
:: xor 1 with the polymod
|
|
||||||
::
|
|
||||||
=/ pmod=@
|
|
||||||
%+ mix 1
|
|
||||||
%- polymod
|
|
||||||
(zing ~[(expand-hrp hrp) data (reap 6 0)])
|
|
||||||
%+ turn (gulf 0 5)
|
|
||||||
|=(i=@ (dis 31 (rsh [0 (mul 5 (sub 5 i))] pmod)))
|
|
||||||
::
|
|
||||||
++ charset-to-value
|
|
||||||
|= c=@tD
|
|
||||||
^- (unit @)
|
|
||||||
(find ~[c] charset)
|
|
||||||
++ value-to-charset
|
|
||||||
|= value=@
|
|
||||||
^- (unit @tD)
|
|
||||||
?: (gth value 31) ~
|
|
||||||
`(snag value charset)
|
|
||||||
::
|
|
||||||
++ is-valid
|
|
||||||
|= [bech=tape last-1-pos=@] ^- ?
|
|
||||||
?& ?|(=((cass bech) bech) =((cuss bech) bech)) :: to upper or to lower is same as bech
|
|
||||||
(gte last-1-pos 1)
|
|
||||||
(lte (add last-1-pos 7) (lent bech))
|
|
||||||
(lte (lent bech) 90)
|
|
||||||
(levy bech |=(c=@tD (gte c 33)))
|
|
||||||
(levy bech |=(c=@tD (lte c 126)))
|
|
||||||
==
|
|
||||||
:: data should be 5bit words
|
|
||||||
::
|
|
||||||
++ encode-raw
|
|
||||||
|= [hrp=tape data=(list @)]
|
|
||||||
^- cord
|
|
||||||
=/ combined=(list @)
|
|
||||||
(weld data (checksum hrp data))
|
|
||||||
%- crip
|
|
||||||
(zing ~[hrp "1" (tape (murn combined value-to-charset))])
|
|
||||||
++ decode-raw
|
|
||||||
|= body=cord
|
|
||||||
^- (unit raw-decoded)
|
|
||||||
=/ bech (cass (trip body)) :: to lowercase
|
|
||||||
=/ pos (flop (fand "1" bech))
|
|
||||||
?~ pos ~
|
|
||||||
=/ last-1=@ i.pos
|
|
||||||
?. (is-valid bech last-1) :: check bech32 validity (not segwit validity or checksum)
|
|
||||||
~
|
|
||||||
=/ hrp (scag last-1 bech)
|
|
||||||
=/ encoded-data-and-checksum=(list @)
|
|
||||||
(slag +(last-1) bech)
|
|
||||||
=/ data-and-checksum=(list @)
|
|
||||||
%+ murn encoded-data-and-checksum
|
|
||||||
charset-to-value
|
|
||||||
?. =((lent encoded-data-and-checksum) (lent data-and-checksum)) :: ensure all were in CHARSET
|
|
||||||
~
|
|
||||||
?. (verify-checksum hrp data-and-checksum)
|
|
||||||
~
|
|
||||||
=/ checksum-pos (sub (lent data-and-checksum) 6)
|
|
||||||
`[hrp (scag checksum-pos data-and-checksum) (slag checksum-pos data-and-checksum)]
|
|
||||||
:: +from-address: BIP173 bech32 address encoding to hex
|
|
||||||
:: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
|
|
||||||
:: expects to drop a leading 5-bit 0 (the witness version)
|
|
||||||
::
|
|
||||||
++ from-address
|
|
||||||
|= body=cord
|
|
||||||
^- hexb
|
|
||||||
~| "Invalid bech32 address"
|
|
||||||
=/ d=(unit raw-decoded) (decode-raw body)
|
|
||||||
?> ?=(^ d)
|
|
||||||
=/ bs=bits (from-atoms:bit 5 data.u.d)
|
|
||||||
=/ byt-len=@ (div (sub wid.bs 5) 8)
|
|
||||||
?> =(5^0b0 (take:bit 5 bs))
|
|
||||||
?> ?| =(20 byt-len)
|
|
||||||
=(32 byt-len)
|
|
||||||
==
|
|
||||||
[byt-len `@ux`dat:(take:bit (mul 8 byt-len) (drop:bit 5 bs))]
|
|
||||||
:: pubkey is the 33 byte ECC compressed public key
|
|
||||||
::
|
|
||||||
++ encode-pubkey
|
|
||||||
|= [=network pubkey=byts]
|
|
||||||
^- (unit cord)
|
|
||||||
?. =(33 wid.pubkey)
|
|
||||||
~|('pubkey must be a 33 byte ECC compressed public key' !!)
|
|
||||||
=/ prefix (~(get by prefixes) network)
|
|
||||||
?~ prefix ~
|
|
||||||
:- ~
|
|
||||||
%+ encode-raw u.prefix
|
|
||||||
[0v0 (to-atoms:bit 5 [160 `@ub`dat:(hash-160 pubkey)])]
|
|
||||||
--
|
|
1
pkg/bitcoin/lib/bip/b173.hoon
Symbolic link
1
pkg/bitcoin/lib/bip/b173.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../base-dev/lib/bip/b173.hoon
|
@ -1,182 +0,0 @@
|
|||||||
:: BIP174: PSBTs
|
|
||||||
:: https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
|
|
||||||
::
|
|
||||||
/- sur=bitcoin
|
|
||||||
/+ bcu=bitcoin-utils
|
|
||||||
=, sur
|
|
||||||
=, bcu
|
|
||||||
|%
|
|
||||||
++ en
|
|
||||||
|%
|
|
||||||
++ globals
|
|
||||||
|= rawtx=hexb
|
|
||||||
^- map:psbt
|
|
||||||
:~ [[1 0x0] rawtx]
|
|
||||||
==
|
|
||||||
::
|
|
||||||
++ input
|
|
||||||
|= [only-witness=? i=in:psbt]
|
|
||||||
^- map:psbt
|
|
||||||
%+ weld
|
|
||||||
?: only-witness ~
|
|
||||||
~[[1^0x0 rawtx.i]]
|
|
||||||
:~ (witness-tx i)
|
|
||||||
(hdkey %input hdkey.i)
|
|
||||||
==
|
|
||||||
::
|
|
||||||
++ output
|
|
||||||
|= =out:psbt
|
|
||||||
^- map:psbt
|
|
||||||
?~ hk.out ~
|
|
||||||
:~ (hdkey %output u.hk.out)
|
|
||||||
==
|
|
||||||
::
|
|
||||||
++ witness-tx
|
|
||||||
|= i=in:psbt
|
|
||||||
^- keyval:psbt
|
|
||||||
:- [1 0x1]
|
|
||||||
%- cat:byt
|
|
||||||
:~ (flip:byt 8^value.utxo.i)
|
|
||||||
1^0x16
|
|
||||||
2^0x14
|
|
||||||
(hash-160 pubkey.hdkey.i)
|
|
||||||
==
|
|
||||||
::
|
|
||||||
++ hdkey
|
|
||||||
|= [=target:psbt h=^hdkey]
|
|
||||||
^- keyval:psbt
|
|
||||||
=/ typ=@ux
|
|
||||||
?- target
|
|
||||||
%input 0x6
|
|
||||||
%output 0x2
|
|
||||||
==
|
|
||||||
=/ coin-type=hexb
|
|
||||||
?- network.h
|
|
||||||
%main
|
|
||||||
1^0x0
|
|
||||||
%testnet
|
|
||||||
1^0x1
|
|
||||||
==
|
|
||||||
:- (cat:byt ~[1^typ pubkey.h])
|
|
||||||
%- cat:byt
|
|
||||||
:~ fprint.h
|
|
||||||
1^`@ux`bipt.h 3^0x80
|
|
||||||
coin-type 3^0x80
|
|
||||||
4^0x80
|
|
||||||
1^`@ux`chyg.h 3^0x0
|
|
||||||
(flip:byt 4^idx.h)
|
|
||||||
==
|
|
||||||
::
|
|
||||||
++ keyval-byts
|
|
||||||
|= kv=keyval:psbt
|
|
||||||
^- hexb
|
|
||||||
%- cat:byt
|
|
||||||
:~ 1^wid.key.kv
|
|
||||||
key.kv
|
|
||||||
1^wid.val.kv
|
|
||||||
val.kv
|
|
||||||
==
|
|
||||||
::
|
|
||||||
++ map-byts
|
|
||||||
|= m=map:psbt
|
|
||||||
^- (unit hexb)
|
|
||||||
?~ m ~
|
|
||||||
:- ~
|
|
||||||
%- cat:byt
|
|
||||||
(turn m keyval-byts)
|
|
||||||
--
|
|
||||||
++ base64
|
|
||||||
|= b=hexb
|
|
||||||
^- base64:psbt
|
|
||||||
%- en:base64:mimes:html
|
|
||||||
(flip:byt b)
|
|
||||||
:: +encode: make base64 cord of PSBT
|
|
||||||
:: - only-witness: don't include non-witness UTXO
|
|
||||||
::
|
|
||||||
++ encode
|
|
||||||
|= $: only-witness=?
|
|
||||||
rawtx=hexb
|
|
||||||
txid=hexb
|
|
||||||
inputs=(list in:psbt)
|
|
||||||
outputs=(list out:psbt)
|
|
||||||
==
|
|
||||||
^- base64:psbt
|
|
||||||
=/ sep=(unit hexb) `1^0x0
|
|
||||||
=/ final=(list (unit hexb))
|
|
||||||
%+ join sep
|
|
||||||
%+ turn
|
|
||||||
%- zing
|
|
||||||
:~ ~[(globals:en rawtx)]
|
|
||||||
(turn inputs (cury input:en only-witness))
|
|
||||||
(turn outputs output:en)
|
|
||||||
==
|
|
||||||
map-byts:en
|
|
||||||
%- base64:en
|
|
||||||
^- byts
|
|
||||||
%- cat:byt
|
|
||||||
%+ weld ~[[5 0x70.7362.74ff]]
|
|
||||||
(murn (snoc final sep) same)
|
|
||||||
::
|
|
||||||
++ parse
|
|
||||||
|= psbt-base64=cord
|
|
||||||
^- (list map:psbt)
|
|
||||||
=/ todo=hexb
|
|
||||||
(drop:byt 5 (to-byts psbt-base64))
|
|
||||||
=| acc=(list map:psbt)
|
|
||||||
=| m=map:psbt
|
|
||||||
|-
|
|
||||||
?: =(wid.todo 0)
|
|
||||||
(snoc acc m)
|
|
||||||
:: 0x0: map separator
|
|
||||||
::
|
|
||||||
?: =(1^0x0 (take:byt 1 todo))
|
|
||||||
$(acc (snoc acc m), m *map:psbt, todo (drop:byt 1 todo))
|
|
||||||
=^ kv todo (next-keyval todo)
|
|
||||||
$(m (snoc m kv))
|
|
||||||
:: +get-txid: extract txid from a valid PSBT
|
|
||||||
::
|
|
||||||
++ get-txid
|
|
||||||
|= psbt-base64=cord
|
|
||||||
^- hexb
|
|
||||||
=/ tx=hexb
|
|
||||||
%- raw-tx
|
|
||||||
%+ drop:byt 5
|
|
||||||
(to-byts psbt-base64)
|
|
||||||
%- flip:byt
|
|
||||||
(dsha256 tx)
|
|
||||||
:: +raw-tx: extract hex transaction
|
|
||||||
:: looks for key 0x0 in global map
|
|
||||||
:: crashes if tx not in hex
|
|
||||||
::
|
|
||||||
++ raw-tx
|
|
||||||
|= b=hexb
|
|
||||||
^- hexb
|
|
||||||
|-
|
|
||||||
?: =(wid.b 0) !!
|
|
||||||
?: =(1^0x0 (take:byt 1 b)) !!
|
|
||||||
=/ nk (next-keyval b)
|
|
||||||
?: =(0x0 dat.key.kv.nk)
|
|
||||||
val.kv.nk
|
|
||||||
$(b rest.nk)
|
|
||||||
:: +next-keyval: returns next key-val in a PSBT map
|
|
||||||
:: input first byte must be a map key length
|
|
||||||
::
|
|
||||||
++ next-keyval
|
|
||||||
|= b=hexb
|
|
||||||
^- [kv=keyval:psbt rest=hexb]
|
|
||||||
=/ klen dat:(take:byt 1 b)
|
|
||||||
=/ k (take:byt klen (drop:byt 1 b))
|
|
||||||
=/ vlen dat:(take:byt 1 (drop:byt (add 1 klen) b))
|
|
||||||
=/ v (take:byt vlen (drop:byt (add 2 klen) b))
|
|
||||||
?> ?&((gth wid.k 0) (gth wid.v 0))
|
|
||||||
:- [k v]
|
|
||||||
(drop:byt ;:(add 2 klen vlen) b)
|
|
||||||
::
|
|
||||||
++ to-byts
|
|
||||||
|= psbt-base64=cord
|
|
||||||
^- hexb
|
|
||||||
~| "Invalid PSBT"
|
|
||||||
=+ p=(de:base64:mimes:html psbt-base64)
|
|
||||||
?~ p !!
|
|
||||||
(flip:byt u.p)
|
|
||||||
--
|
|
1
pkg/bitcoin/lib/bip/b174.hoon
Symbolic link
1
pkg/bitcoin/lib/bip/b174.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../base-dev/lib/bip/b174.hoon
|
@ -1,243 +0,0 @@
|
|||||||
:: bip32 implementation in hoon
|
|
||||||
::
|
|
||||||
:: to use, call one of the core initialization arms.
|
|
||||||
:: using the produced core, derive as needed and take out the data you want.
|
|
||||||
::
|
|
||||||
::NOTE tested to be correct against
|
|
||||||
:: https://en.bitcoin.it/wiki/BIP_0032_TestVectors
|
|
||||||
::
|
|
||||||
=, hmac:crypto
|
|
||||||
=, secp:crypto
|
|
||||||
=+ ecc=secp256k1
|
|
||||||
::
|
|
||||||
:: prv: private key
|
|
||||||
:: pub: public key
|
|
||||||
:: cad: chain code
|
|
||||||
:: dep: depth in chain
|
|
||||||
:: ind: index at depth
|
|
||||||
:: pif: parent fingerprint (4 bytes)
|
|
||||||
|_ [prv=@ pub=point.ecc cad=@ dep=@ud ind=@ud pif=@]
|
|
||||||
::
|
|
||||||
+$ keyc [key=@ cai=@] :: prv/pub key + chain code
|
|
||||||
::
|
|
||||||
:: elliptic curve operations and values
|
|
||||||
::
|
|
||||||
++ point priv-to-pub.ecc
|
|
||||||
::
|
|
||||||
++ ser-p compress-point.ecc
|
|
||||||
::
|
|
||||||
++ n n:t.ecc
|
|
||||||
::
|
|
||||||
:: core initialization
|
|
||||||
::
|
|
||||||
++ from-seed
|
|
||||||
|= byts
|
|
||||||
^+ +>
|
|
||||||
=+ der=(hmac-sha512l [12 'dees nioctiB'] [wid dat])
|
|
||||||
=+ pri=(cut 3 [32 32] der)
|
|
||||||
+>.$(prv pri, pub (point pri), cad (cut 3 [0 32] der))
|
|
||||||
::
|
|
||||||
++ from-private
|
|
||||||
|= keyc
|
|
||||||
+>(prv key, pub (point key), cad cai)
|
|
||||||
::
|
|
||||||
++ from-public
|
|
||||||
|= keyc
|
|
||||||
+>(pub (decompress-point.ecc key), cad cai)
|
|
||||||
::
|
|
||||||
++ from-public-point
|
|
||||||
|= [pon=point.ecc cai=@]
|
|
||||||
+>(pub pon, cad cai)
|
|
||||||
::
|
|
||||||
++ from-extended
|
|
||||||
|= t=tape
|
|
||||||
=+ x=(de-base58check 4 t)
|
|
||||||
=> |%
|
|
||||||
++ take
|
|
||||||
|= b=@ud
|
|
||||||
^- [v=@ x=@]
|
|
||||||
:- (end [3 b] x)
|
|
||||||
(rsh [3 b] x)
|
|
||||||
--
|
|
||||||
=^ k x (take 33)
|
|
||||||
=^ c x (take 32)
|
|
||||||
=^ i x (take 4)
|
|
||||||
=^ p x (take 4)
|
|
||||||
=^ d x (take 1)
|
|
||||||
?> =(0 x) :: sanity check
|
|
||||||
%. [d i p]
|
|
||||||
=< set-metadata
|
|
||||||
=+ v=(swag [1 3] t)
|
|
||||||
?: =("prv" v) (from-private k c)
|
|
||||||
?: =("pub" v) (from-public k c)
|
|
||||||
!!
|
|
||||||
::
|
|
||||||
++ set-metadata
|
|
||||||
|= [d=@ud i=@ud p=@]
|
|
||||||
+>(dep d, ind i, pif p)
|
|
||||||
::
|
|
||||||
:: derivation
|
|
||||||
::
|
|
||||||
++ derivation-path
|
|
||||||
;~ pfix
|
|
||||||
;~(pose (jest 'm/') (easy ~))
|
|
||||||
%+ most fas
|
|
||||||
;~ pose
|
|
||||||
%+ cook
|
|
||||||
|=(i=@ (add i (bex 31)))
|
|
||||||
;~(sfix dem soq)
|
|
||||||
::
|
|
||||||
dem
|
|
||||||
== ==
|
|
||||||
::
|
|
||||||
++ derive-path
|
|
||||||
|= t=tape
|
|
||||||
%- derive-sequence
|
|
||||||
(scan t derivation-path)
|
|
||||||
::
|
|
||||||
++ derive-sequence
|
|
||||||
|= j=(list @u)
|
|
||||||
?~ j +>
|
|
||||||
=. +> (derive i.j)
|
|
||||||
$(j t.j)
|
|
||||||
::
|
|
||||||
++ derive
|
|
||||||
?: =(0 prv)
|
|
||||||
derive-public
|
|
||||||
derive-private
|
|
||||||
::
|
|
||||||
++ derive-private
|
|
||||||
|= i=@u
|
|
||||||
^+ +>
|
|
||||||
:: we must have a private key to derive the next one
|
|
||||||
?: =(0 prv)
|
|
||||||
~| %know-no-private-key
|
|
||||||
!!
|
|
||||||
:: derive child at i
|
|
||||||
=/ [left=@ right=@]
|
|
||||||
=- [(cut 3 [32 32] -) (cut 3 [0 32] -)]
|
|
||||||
%+ hmac-sha512l [32 cad]
|
|
||||||
:- 37
|
|
||||||
?: (gte i (bex 31))
|
|
||||||
:: hardened child
|
|
||||||
(can 3 ~[4^i 32^prv 1^0])
|
|
||||||
:: normal child
|
|
||||||
(can 3 ~[4^i 33^(ser-p (point prv))])
|
|
||||||
=+ key=(mod (add left prv) n)
|
|
||||||
:: rare exception, invalid key, go to the next one
|
|
||||||
?: |(=(0 key) (gte left n)) $(i +(i))
|
|
||||||
%_ +>.$
|
|
||||||
prv key
|
|
||||||
pub (point key)
|
|
||||||
cad right
|
|
||||||
dep +(dep)
|
|
||||||
ind i
|
|
||||||
pif fingerprint
|
|
||||||
==
|
|
||||||
::
|
|
||||||
++ derive-public
|
|
||||||
|= i=@u
|
|
||||||
^+ +>
|
|
||||||
:: public keys can't be hardened
|
|
||||||
?: (gte i (bex 31))
|
|
||||||
~| %cant-derive-hardened-public-key
|
|
||||||
!!
|
|
||||||
:: derive child at i
|
|
||||||
=/ [left=@ right=@]
|
|
||||||
=- [(cut 3 [32 32] -) (cut 3 [0 32] -)]
|
|
||||||
%+ hmac-sha512l [32 cad]
|
|
||||||
37^(can 3 ~[4^i 33^(ser-p pub)])
|
|
||||||
:: rare exception, invalid key, go to the next one
|
|
||||||
?: (gte left n) $(i +(i)) ::TODO or child key is "point at infinity"
|
|
||||||
%_ +>.$
|
|
||||||
pub (add-points.ecc (point left) pub)
|
|
||||||
cad right
|
|
||||||
dep +(dep)
|
|
||||||
ind i
|
|
||||||
pif fingerprint
|
|
||||||
==
|
|
||||||
::
|
|
||||||
:: rendering
|
|
||||||
::
|
|
||||||
++ private-key ?.(=(0 prv) prv ~|(%know-no-private-key !!))
|
|
||||||
++ public-key (ser-p pub)
|
|
||||||
++ chain-code cad
|
|
||||||
++ private-chain [private-key cad]
|
|
||||||
++ public-chain [public-key cad]
|
|
||||||
::
|
|
||||||
++ identity (hash160 public-key)
|
|
||||||
++ fingerprint (cut 3 [16 4] identity)
|
|
||||||
::
|
|
||||||
++ address
|
|
||||||
|= network=?(%main %regtest %testnet)
|
|
||||||
^- @uc
|
|
||||||
:: removes checksum
|
|
||||||
::
|
|
||||||
%+ rsh [3 4]
|
|
||||||
%+ en-base58check
|
|
||||||
[4 (version-bytes network %pub %.n)]
|
|
||||||
[20 identity]
|
|
||||||
::
|
|
||||||
++ prv-extended
|
|
||||||
|= network=?(%main %regtest %testnet)
|
|
||||||
%+ en-b58c-bip32 (version-bytes network %prv %.y)
|
|
||||||
(build-extended private-key)
|
|
||||||
::
|
|
||||||
++ pub-extended
|
|
||||||
|= network=?(%main %regtest %testnet)
|
|
||||||
%+ en-b58c-bip32 (version-bytes network %pub %.y)
|
|
||||||
(build-extended public-key)
|
|
||||||
::
|
|
||||||
++ build-extended
|
|
||||||
|= key=@
|
|
||||||
%+ can 3
|
|
||||||
:~ 33^key
|
|
||||||
32^cad
|
|
||||||
4^ind
|
|
||||||
4^pif
|
|
||||||
1^dep
|
|
||||||
==
|
|
||||||
::
|
|
||||||
++ en-b58c-bip32
|
|
||||||
|= [v=@ k=@]
|
|
||||||
%- en-base58:mimes:html
|
|
||||||
(en-base58check [4 v] [74 k])
|
|
||||||
::
|
|
||||||
:: base58check
|
|
||||||
::
|
|
||||||
++ en-base58check
|
|
||||||
:: v: version bytes
|
|
||||||
:: d: data
|
|
||||||
|= [v=byts d=byts]
|
|
||||||
=+ p=[(add wid.v wid.d) (can 3 ~[d v])]
|
|
||||||
=- (can 3 ~[4^- p])
|
|
||||||
%+ rsh [3 28]
|
|
||||||
(sha-256l:sha 32 (sha-256l:sha p))
|
|
||||||
::
|
|
||||||
++ de-base58check
|
|
||||||
:: vw: amount of version bytes
|
|
||||||
|= [vw=@u t=tape]
|
|
||||||
=+ x=(de-base58:mimes:html t)
|
|
||||||
=+ hash=(sha-256l:sha 32 (sha-256:sha (rsh [3 4] x)))
|
|
||||||
?> =((end [3 4] x) (rsh [3 28] hash))
|
|
||||||
(cut 3 [vw (sub (met 3 x) (add 4 vw))] x)
|
|
||||||
::
|
|
||||||
++ hash160
|
|
||||||
|= d=@
|
|
||||||
(ripemd-160:ripemd:crypto 32 (sha-256:sha d))
|
|
||||||
::
|
|
||||||
++ version-bytes
|
|
||||||
|= [network=?(%main %regtest %testnet) type=?(%pub %prv) bip32=?]
|
|
||||||
^- @ux
|
|
||||||
|^
|
|
||||||
?- type
|
|
||||||
%pub ?:(bip32 xpub-key pay-to-pubkey)
|
|
||||||
%prv ?:(bip32 xprv-key private-key)
|
|
||||||
==
|
|
||||||
::
|
|
||||||
++ pay-to-pubkey ?:(=(network %main) 0x0 0x6f)
|
|
||||||
++ private-key ?:(=(network %main) 0x80 0xef)
|
|
||||||
++ xpub-key ?:(=(network %main) 0x488.b21e 0x435.87cf)
|
|
||||||
++ xprv-key ?:(=(network %main) 0x488.ade4 0x435.8394)
|
|
||||||
--
|
|
||||||
--
|
|
1
pkg/bitcoin/lib/bip32.hoon
Symbolic link
1
pkg/bitcoin/lib/bip32.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/bip32.hoon
|
@ -1,46 +0,0 @@
|
|||||||
:: bip39 implementation in hoon
|
|
||||||
::
|
|
||||||
/+ bip39-english
|
|
||||||
::
|
|
||||||
|%
|
|
||||||
++ from-entropy
|
|
||||||
|= byts
|
|
||||||
^- tape
|
|
||||||
=. wid (mul wid 8)
|
|
||||||
~| [%unsupported-entropy-bit-length wid]
|
|
||||||
?> &((gte wid 128) (lte wid 256))
|
|
||||||
::
|
|
||||||
=+ cs=(div wid 32)
|
|
||||||
=/ check=@
|
|
||||||
%+ rsh [0 (sub 256 cs)]
|
|
||||||
(sha-256l:sha (div wid 8) dat)
|
|
||||||
=/ bits=byts
|
|
||||||
:- (add wid cs)
|
|
||||||
%+ can 0
|
|
||||||
:~ cs^check
|
|
||||||
wid^dat
|
|
||||||
==
|
|
||||||
::
|
|
||||||
=/ pieces
|
|
||||||
|- ^- (list @)
|
|
||||||
:- (end [0 11] dat.bits)
|
|
||||||
?: (lte wid.bits 11) ~
|
|
||||||
$(bits [(sub wid.bits 11) (rsh [0 11] dat.bits)])
|
|
||||||
::
|
|
||||||
=/ words=(list tape)
|
|
||||||
%+ turn pieces
|
|
||||||
|= ind=@ud
|
|
||||||
(snag ind `(list tape)`bip39-english)
|
|
||||||
::
|
|
||||||
%+ roll (flop words)
|
|
||||||
|= [nex=tape all=tape]
|
|
||||||
?~ all nex
|
|
||||||
:(weld all " " nex)
|
|
||||||
::
|
|
||||||
::NOTE always produces a 512-bit result
|
|
||||||
++ to-seed
|
|
||||||
|= [mnem=tape pass=tape]
|
|
||||||
^- @
|
|
||||||
%- hmac-sha512t:pbkdf:crypto
|
|
||||||
[(crip mnem) (crip (weld "mnemonic" pass)) 2.048 64]
|
|
||||||
--
|
|
1
pkg/bitcoin/lib/bip39.hoon
Symbolic link
1
pkg/bitcoin/lib/bip39.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/bip39.hoon
|
File diff suppressed because it is too large
Load Diff
1
pkg/bitcoin/lib/bip39/english.hoon
Symbolic link
1
pkg/bitcoin/lib/bip39/english.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../base-dev/lib/bip39/english.hoon
|
1
pkg/bitcoin/lib/dbug.hoon
Symbolic link
1
pkg/bitcoin/lib/dbug.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/dbug.hoon
|
1
pkg/bitcoin/lib/default-agent.hoon
Symbolic link
1
pkg/bitcoin/lib/default-agent.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/default-agent.hoon
|
1
pkg/bitcoin/lib/docket.hoon
Symbolic link
1
pkg/bitcoin/lib/docket.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../garden-dev/lib/docket.hoon
|
1
pkg/bitcoin/lib/ethio.hoon
Symbolic link
1
pkg/bitcoin/lib/ethio.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/ethio.hoon
|
@ -4,6 +4,9 @@
|
|||||||
|_ =bowl:gall
|
|_ =bowl:gall
|
||||||
+$ card card:agent:gall
|
+$ card card:agent:gall
|
||||||
::
|
::
|
||||||
|
++ is-running
|
||||||
|
.^(? %gu /(scot %p our.bowl)/group-store/(scot %da now.bowl))
|
||||||
|
::
|
||||||
++ resource-for-update
|
++ resource-for-update
|
||||||
|= =vase
|
|= =vase
|
||||||
^- (list resource)
|
^- (list resource)
|
||||||
|
1
pkg/bitcoin/lib/language-server/build.hoon
Symbolic link
1
pkg/bitcoin/lib/language-server/build.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../base-dev/lib/language-server/build.hoon
|
1
pkg/bitcoin/lib/language-server/complete.hoon
Symbolic link
1
pkg/bitcoin/lib/language-server/complete.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../base-dev/lib/language-server/complete.hoon
|
1
pkg/bitcoin/lib/language-server/easy-print.hoon
Symbolic link
1
pkg/bitcoin/lib/language-server/easy-print.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../base-dev/lib/language-server/easy-print.hoon
|
1
pkg/bitcoin/lib/language-server/json.hoon
Symbolic link
1
pkg/bitcoin/lib/language-server/json.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../base-dev/lib/language-server/json.hoon
|
1
pkg/bitcoin/lib/language-server/parser.hoon
Symbolic link
1
pkg/bitcoin/lib/language-server/parser.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../base-dev/lib/language-server/parser.hoon
|
1
pkg/bitcoin/lib/language-server/rune-snippet.hoon
Symbolic link
1
pkg/bitcoin/lib/language-server/rune-snippet.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../base-dev/lib/language-server/rune-snippet.hoon
|
1
pkg/bitcoin/lib/mip.hoon
Symbolic link
1
pkg/bitcoin/lib/mip.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../garden-dev/lib/mip.hoon
|
1
pkg/bitcoin/lib/server.hoon
Symbolic link
1
pkg/bitcoin/lib/server.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/server.hoon
|
1
pkg/bitcoin/lib/shoe.hoon
Symbolic link
1
pkg/bitcoin/lib/shoe.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/shoe.hoon
|
1
pkg/bitcoin/lib/skeleton.hoon
Symbolic link
1
pkg/bitcoin/lib/skeleton.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/skeleton.hoon
|
1
pkg/bitcoin/lib/sole.hoon
Symbolic link
1
pkg/bitcoin/lib/sole.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/sole.hoon
|
1
pkg/bitcoin/lib/strand.hoon
Symbolic link
1
pkg/bitcoin/lib/strand.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/strand.hoon
|
1
pkg/bitcoin/lib/strandio.hoon
Symbolic link
1
pkg/bitcoin/lib/strandio.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/strandio.hoon
|
1
pkg/bitcoin/lib/treaty.hoon
Symbolic link
1
pkg/bitcoin/lib/treaty.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/treaty.hoon
|
1
pkg/bitcoin/lib/verb.hoon
Symbolic link
1
pkg/bitcoin/lib/verb.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/lib/verb.hoon
|
1
pkg/bitcoin/mar/belt.hoon
Symbolic link
1
pkg/bitcoin/mar/belt.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/belt.hoon
|
1
pkg/bitcoin/mar/bill.hoon
Symbolic link
1
pkg/bitcoin/mar/bill.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/bill.hoon
|
1
pkg/bitcoin/mar/blit.hoon
Symbolic link
1
pkg/bitcoin/mar/blit.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/blit.hoon
|
1
pkg/bitcoin/mar/docket.hoon
Symbolic link
1
pkg/bitcoin/mar/docket.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../garden-dev/mar/docket.hoon
|
1
pkg/bitcoin/mar/hoon.hoon
Symbolic link
1
pkg/bitcoin/mar/hoon.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/hoon.hoon
|
1
pkg/bitcoin/mar/htm.hoon
Symbolic link
1
pkg/bitcoin/mar/htm.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/htm.hoon
|
1
pkg/bitcoin/mar/html.hoon
Symbolic link
1
pkg/bitcoin/mar/html.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/html.hoon
|
1
pkg/bitcoin/mar/httr.hoon
Symbolic link
1
pkg/bitcoin/mar/httr.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/httr.hoon
|
1
pkg/bitcoin/mar/hymn.hoon
Symbolic link
1
pkg/bitcoin/mar/hymn.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/hymn.hoon
|
1
pkg/bitcoin/mar/js.hoon
Symbolic link
1
pkg/bitcoin/mar/js.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/js.hoon
|
1
pkg/bitcoin/mar/json.hoon
Symbolic link
1
pkg/bitcoin/mar/json.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/json.hoon
|
1
pkg/bitcoin/mar/json/rpc/response.hoon
Symbolic link
1
pkg/bitcoin/mar/json/rpc/response.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../base-dev/mar/json/rpc/response.hoon
|
1
pkg/bitcoin/mar/kelvin.hoon
Symbolic link
1
pkg/bitcoin/mar/kelvin.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/kelvin.hoon
|
1
pkg/bitcoin/mar/language-server/rpc/notification.hoon
Symbolic link
1
pkg/bitcoin/mar/language-server/rpc/notification.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../base-dev/mar/language-server/rpc/notification.hoon
|
1
pkg/bitcoin/mar/language-server/rpc/request.hoon
Symbolic link
1
pkg/bitcoin/mar/language-server/rpc/request.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../base-dev/mar/language-server/rpc/request.hoon
|
1
pkg/bitcoin/mar/language-server/rpc/response.hoon
Symbolic link
1
pkg/bitcoin/mar/language-server/rpc/response.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../base-dev/mar/language-server/rpc/response.hoon
|
1
pkg/bitcoin/mar/mime.hoon
Symbolic link
1
pkg/bitcoin/mar/mime.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/mime.hoon
|
1
pkg/bitcoin/mar/noun.hoon
Symbolic link
1
pkg/bitcoin/mar/noun.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/noun.hoon
|
1
pkg/bitcoin/mar/path.hoon
Symbolic link
1
pkg/bitcoin/mar/path.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/path.hoon
|
1
pkg/bitcoin/mar/png.hoon
Symbolic link
1
pkg/bitcoin/mar/png.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/png.hoon
|
1
pkg/bitcoin/mar/purl.hoon
Symbolic link
1
pkg/bitcoin/mar/purl.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/purl.hoon
|
1
pkg/bitcoin/mar/sole/action.hoon
Symbolic link
1
pkg/bitcoin/mar/sole/action.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../base-dev/mar/sole/action.hoon
|
1
pkg/bitcoin/mar/sole/effect.hoon
Symbolic link
1
pkg/bitcoin/mar/sole/effect.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../base-dev/mar/sole/effect.hoon
|
1
pkg/bitcoin/mar/svg.hoon
Symbolic link
1
pkg/bitcoin/mar/svg.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/svg.hoon
|
1
pkg/bitcoin/mar/tang.hoon
Symbolic link
1
pkg/bitcoin/mar/tang.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/tang.hoon
|
1
pkg/bitcoin/mar/tape.hoon
Symbolic link
1
pkg/bitcoin/mar/tape.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/tape.hoon
|
1
pkg/bitcoin/mar/txt-diff.hoon
Symbolic link
1
pkg/bitcoin/mar/txt-diff.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/txt-diff.hoon
|
1
pkg/bitcoin/mar/txt.hoon
Symbolic link
1
pkg/bitcoin/mar/txt.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/txt.hoon
|
1
pkg/bitcoin/mar/udon.hoon
Symbolic link
1
pkg/bitcoin/mar/udon.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/udon.hoon
|
1
pkg/bitcoin/mar/umd.hoon
Symbolic link
1
pkg/bitcoin/mar/umd.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/umd.hoon
|
1
pkg/bitcoin/mar/urb.hoon
Symbolic link
1
pkg/bitcoin/mar/urb.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/urb.hoon
|
1
pkg/bitcoin/mar/urbit.hoon
Symbolic link
1
pkg/bitcoin/mar/urbit.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/urbit.hoon
|
1
pkg/bitcoin/mar/woff2.hoon
Symbolic link
1
pkg/bitcoin/mar/woff2.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/woff2.hoon
|
1
pkg/bitcoin/mar/xml.hoon
Symbolic link
1
pkg/bitcoin/mar/xml.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/mar/xml.hoon
|
1
pkg/bitcoin/sur/bill.hoon
Symbolic link
1
pkg/bitcoin/sur/bill.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/sur/bill.hoon
|
1
pkg/bitcoin/sur/docket.hoon
Symbolic link
1
pkg/bitcoin/sur/docket.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../garden-dev/sur/docket.hoon
|
1
pkg/bitcoin/sur/hood.hoon
Symbolic link
1
pkg/bitcoin/sur/hood.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/sur/hood.hoon
|
@ -1,31 +0,0 @@
|
|||||||
|%
|
|
||||||
+$ settings-0 (map key bucket-0)
|
|
||||||
+$ bucket-0 (map key val-0)
|
|
||||||
+$ val-0
|
|
||||||
$% [%s p=@t]
|
|
||||||
[%b p=?]
|
|
||||||
[%n p=@]
|
|
||||||
==
|
|
||||||
::
|
|
||||||
+$ settings (map key bucket)
|
|
||||||
+$ bucket (map key val)
|
|
||||||
+$ key term
|
|
||||||
+$ val
|
|
||||||
$~ [%n 0]
|
|
||||||
$% [%s p=@t]
|
|
||||||
[%b p=?]
|
|
||||||
[%n p=@]
|
|
||||||
[%a p=(list val)]
|
|
||||||
==
|
|
||||||
+$ event
|
|
||||||
$% [%put-bucket =key =bucket]
|
|
||||||
[%del-bucket =key]
|
|
||||||
[%put-entry buc=key =key =val]
|
|
||||||
[%del-entry buc=key =key]
|
|
||||||
==
|
|
||||||
+$ data
|
|
||||||
$% [%all =settings]
|
|
||||||
[%bucket =bucket]
|
|
||||||
[%entry =val]
|
|
||||||
==
|
|
||||||
--
|
|
1
pkg/bitcoin/sur/settings.hoon
Symbolic link
1
pkg/bitcoin/sur/settings.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../garden-dev/sur/settings.hoon
|
1
pkg/bitcoin/sur/sole.hoon
Symbolic link
1
pkg/bitcoin/sur/sole.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/sur/sole.hoon
|
1
pkg/bitcoin/sur/spider.hoon
Symbolic link
1
pkg/bitcoin/sur/spider.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/sur/spider.hoon
|
1
pkg/bitcoin/sur/verb.hoon
Symbolic link
1
pkg/bitcoin/sur/verb.hoon
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../base-dev/sur/verb.hoon
|
@ -1,6 +1,6 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
// const HtmlWebpackPlugin = require('html-webpack-plugin');
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
// const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
// const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||||
const urbitrc = require('./urbitrc');
|
const urbitrc = require('./urbitrc');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
@ -33,6 +33,7 @@ let devServer = {
|
|||||||
host: '0.0.0.0',
|
host: '0.0.0.0',
|
||||||
disableHostCheck: true,
|
disableHostCheck: true,
|
||||||
historyApiFallback: true,
|
historyApiFallback: true,
|
||||||
|
publicPath: '/apps/bitcoin/',
|
||||||
};
|
};
|
||||||
|
|
||||||
const router = _.mapKeys(urbitrc.FLEET || {}, (value, key) => `${key}.localhost:9000`);
|
const router = _.mapKeys(urbitrc.FLEET || {}, (value, key) => `${key}.localhost:9000`);
|
||||||
@ -40,22 +41,19 @@ const router = _.mapKeys(urbitrc.FLEET || {}, (value, key) => `${key}.localhost:
|
|||||||
if(urbitrc.URL) {
|
if(urbitrc.URL) {
|
||||||
devServer = {
|
devServer = {
|
||||||
...devServer,
|
...devServer,
|
||||||
index: '',
|
index: 'index.html',
|
||||||
proxy: {
|
proxy: [{
|
||||||
'/~btc/js/bundle/index.*.js': {
|
target: 'http://localhost:9000',
|
||||||
target: 'http://localhost:9000',
|
changeOrigin: true,
|
||||||
pathRewrite: (req, path) => {
|
target: urbitrc.URL,
|
||||||
return '/index.js'
|
router,
|
||||||
|
context: path => {
|
||||||
|
if(path === '/apps/bitcoin/desk.js') {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
},
|
return !path.startsWith('/apps/bitcoin')
|
||||||
'**': {
|
|
||||||
changeOrigin: true,
|
|
||||||
target: urbitrc.URL,
|
|
||||||
router,
|
|
||||||
// ensure proxy doesn't timeout channels
|
|
||||||
proxyTimeout: 0
|
|
||||||
}
|
}
|
||||||
}
|
}]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +105,12 @@ module.exports = {
|
|||||||
devtool: 'inline-source-map',
|
devtool: 'inline-source-map',
|
||||||
devServer: devServer,
|
devServer: devServer,
|
||||||
plugins: [
|
plugins: [
|
||||||
new UrbitShipPlugin(urbitrc)
|
new UrbitShipPlugin(urbitrc),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
title: 'Bitcoin Wallet',
|
||||||
|
template: './public/index.html'
|
||||||
|
})
|
||||||
|
|
||||||
],
|
],
|
||||||
watch: true,
|
watch: true,
|
||||||
watchOptions: {
|
watchOptions: {
|
||||||
@ -118,7 +121,7 @@ module.exports = {
|
|||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
chunkFilename: 'index.js',
|
chunkFilename: 'index.js',
|
||||||
path: path.resolve(__dirname, '../dist'),
|
path: path.resolve(__dirname, '../dist'),
|
||||||
publicPath: '/',
|
publicPath: '/apps/bitcoin/',
|
||||||
globalObject: 'this'
|
globalObject: 'this'
|
||||||
},
|
},
|
||||||
optimization: {
|
optimization: {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
// const urbitrc = require('./urbitrc');
|
// const urbitrc = require('./urbitrc');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@ -44,14 +45,18 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
devtool: 'source-map',
|
devtool: 'source-map',
|
||||||
plugins: [
|
plugins: [
|
||||||
new CleanWebpackPlugin()
|
new CleanWebpackPlugin(),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
title: 'Bitcoin Wallet',
|
||||||
|
template: './public/index.html'
|
||||||
|
})
|
||||||
],
|
],
|
||||||
output: {
|
output: {
|
||||||
filename: (pathData) => {
|
filename: (pathData) => {
|
||||||
return pathData.chunk.name === 'app' ? 'index.[contenthash].js' : '[name].js';
|
return pathData.chunk.name === 'app' ? 'index.[contenthash].js' : '[name].js';
|
||||||
},
|
},
|
||||||
path: path.resolve(__dirname, `../../arvo/app/btc-wallet/js/bundle`),
|
path: path.resolve(__dirname, 'dist'),
|
||||||
publicPath: '/',
|
publicPath: '/apps/bitcoin/',
|
||||||
},
|
},
|
||||||
optimization: {
|
optimization: {
|
||||||
minimize: true,
|
minimize: true,
|
||||||
|
30
pkg/btc-wallet/public/index.html
Normal file
30
pkg/btc-wallet/public/index.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Wallet</title>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1, shrink-to-fit=no,maximum-scale=1"/>
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="apple-touch-fullscreen" content="yes" />
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
||||||
|
<!--
|
||||||
|
<link rel="apple-touch-icon" href="/~btc/img/touch_icon.png">
|
||||||
|
<link rel="icon" type="image/png" href="/~btc/img/Favicon.png">
|
||||||
|
-->
|
||||||
|
<link rel="manifest"
|
||||||
|
href='data:application/manifest+json,{
|
||||||
|
"name": "Wallet",
|
||||||
|
"short_name": "Wallet",
|
||||||
|
"description": "A%20bitcoin%20wallet%20for%20urbit",
|
||||||
|
"display": "standalone",
|
||||||
|
"background_color": "%23FFFFFF",
|
||||||
|
"theme_color": "%23000000"}' />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<div id="portal-root"></div>
|
||||||
|
<script src="/apps/bitcoin/desk.js"></script>
|
||||||
|
<script src="/session.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { Root } from './js/components/root.js';
|
import { Root } from './js/components/root.js';
|
||||||
import { api } from './js/api.js';
|
import { api } from './js/api.js';
|
||||||
import { subscription } from "./js/subscription.js";
|
import Channel from './js/channel';
|
||||||
|
|
||||||
import './css/indigo-static.css';
|
import './css/indigo-static.css';
|
||||||
import './css/fonts.css';
|
import './css/fonts.css';
|
||||||
@ -10,7 +10,7 @@ import './css/custom.css';
|
|||||||
|
|
||||||
// rebuild x3
|
// rebuild x3
|
||||||
|
|
||||||
const channel = new window.channel();
|
const channel = new Channel();
|
||||||
api.setChannel(window.ship, channel);
|
api.setChannel(window.ship, channel);
|
||||||
|
|
||||||
|
|
||||||
|
290
pkg/btc-wallet/src/js/channel.js
Normal file
290
pkg/btc-wallet/src/js/channel.js
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
export default class Channel {
|
||||||
|
constructor() {
|
||||||
|
this.init();
|
||||||
|
this.deleteOnUnload();
|
||||||
|
|
||||||
|
// a way to handle channel errors
|
||||||
|
//
|
||||||
|
//
|
||||||
|
this.onChannelError = (err) => {
|
||||||
|
console.error('event source error: ', err);
|
||||||
|
};
|
||||||
|
this.onChannelOpen = (e) => {
|
||||||
|
console.log('open', e);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.debounceInterval = 500;
|
||||||
|
// unique identifier: current time and random number
|
||||||
|
//
|
||||||
|
this.uid =
|
||||||
|
new Date().getTime().toString() +
|
||||||
|
"-" +
|
||||||
|
Math.random().toString(16).slice(-6);
|
||||||
|
|
||||||
|
this.requestId = 1;
|
||||||
|
|
||||||
|
// the currently connected EventSource
|
||||||
|
//
|
||||||
|
this.eventSource = null;
|
||||||
|
|
||||||
|
// the id of the last EventSource event we received
|
||||||
|
//
|
||||||
|
this.lastEventId = 0;
|
||||||
|
|
||||||
|
// this last event id acknowledgment sent to the server
|
||||||
|
//
|
||||||
|
this.lastAcknowledgedEventId = 0;
|
||||||
|
|
||||||
|
// a registry of requestId to successFunc/failureFunc
|
||||||
|
//
|
||||||
|
// These functions are registered during a +poke and are executed
|
||||||
|
// in the onServerEvent()/onServerError() callbacks. Only one of
|
||||||
|
// the functions will be called, and the outstanding poke will be
|
||||||
|
// removed after calling the success or failure function.
|
||||||
|
//
|
||||||
|
|
||||||
|
this.outstandingPokes = new Map();
|
||||||
|
|
||||||
|
// a registry of requestId to subscription functions.
|
||||||
|
//
|
||||||
|
// These functions are registered during a +subscribe and are
|
||||||
|
// executed in the onServerEvent()/onServerError() callbacks. The
|
||||||
|
// event function will be called whenever a new piece of data on this
|
||||||
|
// subscription is available, which may be 0, 1, or many times. The
|
||||||
|
// disconnect function may be called exactly once.
|
||||||
|
//
|
||||||
|
this.outstandingSubscriptions = new Map();
|
||||||
|
|
||||||
|
this.outstandingJSON = [];
|
||||||
|
|
||||||
|
this.debounceTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
resetDebounceTimer() {
|
||||||
|
if (this.debounceTimer) {
|
||||||
|
clearTimeout(this.debounceTimer);
|
||||||
|
this.debounceTimer = null;
|
||||||
|
}
|
||||||
|
this.debounceTimer = setTimeout(() => {
|
||||||
|
this.sendJSONToChannel();
|
||||||
|
}, this.debounceInterval)
|
||||||
|
}
|
||||||
|
|
||||||
|
setOnChannelError(onError = (err) => {}) {
|
||||||
|
this.onChannelError = onError;
|
||||||
|
}
|
||||||
|
|
||||||
|
setOnChannelOpen(onOpen = (e) => {}) {
|
||||||
|
this.onChannelOpen = onOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteOnUnload() {
|
||||||
|
window.addEventListener("beforeunload", (event) => {
|
||||||
|
this.delete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
clearQueue() {
|
||||||
|
clearTimeout(this.debounceTimer);
|
||||||
|
this.debounceTimer = null;
|
||||||
|
this.sendJSONToChannel();
|
||||||
|
}
|
||||||
|
|
||||||
|
// sends a poke to an app on an urbit ship
|
||||||
|
//
|
||||||
|
poke(ship, app, mark, json, successFunc, failureFunc) {
|
||||||
|
let id = this.nextId();
|
||||||
|
this.outstandingPokes.set(
|
||||||
|
id,
|
||||||
|
{
|
||||||
|
success: successFunc,
|
||||||
|
fail: failureFunc
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const j = {
|
||||||
|
id,
|
||||||
|
action: "poke",
|
||||||
|
ship,
|
||||||
|
app,
|
||||||
|
mark,
|
||||||
|
json
|
||||||
|
};
|
||||||
|
|
||||||
|
this.sendJSONToChannel(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
// subscribes to a path on an specific app and ship.
|
||||||
|
//
|
||||||
|
// Returns a subscription id, which is the same as the same internal id
|
||||||
|
// passed to your Urbit.
|
||||||
|
subscribe(
|
||||||
|
ship,
|
||||||
|
app,
|
||||||
|
path,
|
||||||
|
connectionErrFunc = () => {},
|
||||||
|
eventFunc = () => {},
|
||||||
|
quitFunc = () => {},
|
||||||
|
subAckFunc = () => {},
|
||||||
|
) {
|
||||||
|
let id = this.nextId();
|
||||||
|
this.outstandingSubscriptions.set(
|
||||||
|
id,
|
||||||
|
{
|
||||||
|
err: connectionErrFunc,
|
||||||
|
event: eventFunc,
|
||||||
|
quit: quitFunc,
|
||||||
|
subAck: subAckFunc
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const json = {
|
||||||
|
id,
|
||||||
|
action: "subscribe",
|
||||||
|
ship,
|
||||||
|
app,
|
||||||
|
path
|
||||||
|
}
|
||||||
|
|
||||||
|
this.resetDebounceTimer();
|
||||||
|
|
||||||
|
this.outstandingJSON.push(json);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// quit the channel
|
||||||
|
//
|
||||||
|
delete() {
|
||||||
|
let id = this.nextId();
|
||||||
|
clearInterval(this.ackTimer);
|
||||||
|
navigator.sendBeacon(this.channelURL(), JSON.stringify([{
|
||||||
|
id,
|
||||||
|
action: "delete"
|
||||||
|
}]));
|
||||||
|
if (this.eventSource) {
|
||||||
|
this.eventSource.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsubscribe to a specific subscription
|
||||||
|
//
|
||||||
|
unsubscribe(subscription) {
|
||||||
|
let id = this.nextId();
|
||||||
|
this.sendJSONToChannel({
|
||||||
|
id,
|
||||||
|
action: "unsubscribe",
|
||||||
|
subscription
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// sends a JSON command command to the server.
|
||||||
|
//
|
||||||
|
sendJSONToChannel(j) {
|
||||||
|
let req = new XMLHttpRequest();
|
||||||
|
req.open("PUT", this.channelURL());
|
||||||
|
req.setRequestHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
|
if (this.lastEventId == this.lastAcknowledgedEventId) {
|
||||||
|
if (j) {
|
||||||
|
this.outstandingJSON.push(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.outstandingJSON.length > 0) {
|
||||||
|
let x = JSON.stringify(this.outstandingJSON);
|
||||||
|
req.send(x);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we add an acknowledgment to clear the server side queue
|
||||||
|
//
|
||||||
|
// The server side puts messages it sends us in a queue until we
|
||||||
|
// acknowledge that we received it.
|
||||||
|
//
|
||||||
|
let payload = [
|
||||||
|
...this.outstandingJSON,
|
||||||
|
{action: "ack", "event-id": this.lastEventId}
|
||||||
|
];
|
||||||
|
if (j) {
|
||||||
|
payload.push(j)
|
||||||
|
}
|
||||||
|
let x = JSON.stringify(payload);
|
||||||
|
req.send(x);
|
||||||
|
|
||||||
|
this.lastAcknowledgedEventId = this.lastEventId;
|
||||||
|
}
|
||||||
|
this.outstandingJSON = [];
|
||||||
|
|
||||||
|
this.connectIfDisconnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
// connects to the EventSource if we are not currently connected
|
||||||
|
//
|
||||||
|
connectIfDisconnected() {
|
||||||
|
if (this.eventSource) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.eventSource = new EventSource(this.channelURL(), {withCredentials:true});
|
||||||
|
this.eventSource.onmessage = e => {
|
||||||
|
this.lastEventId = parseInt(e.lastEventId, 10);
|
||||||
|
|
||||||
|
let obj = JSON.parse(e.data);
|
||||||
|
let pokeFuncs = this.outstandingPokes.get(obj.id);
|
||||||
|
let subFuncs = this.outstandingSubscriptions.get(obj.id);
|
||||||
|
|
||||||
|
if (obj.response == "poke" && !!pokeFuncs) {
|
||||||
|
let funcs = pokeFuncs;
|
||||||
|
if (obj.hasOwnProperty("ok")) {
|
||||||
|
funcs["success"]();
|
||||||
|
} else if (obj.hasOwnProperty("err")) {
|
||||||
|
funcs["fail"](obj.err);
|
||||||
|
} else {
|
||||||
|
console.error("Invalid poke response: ", obj);
|
||||||
|
}
|
||||||
|
this.outstandingPokes.delete(obj.id);
|
||||||
|
|
||||||
|
} else if (obj.response == "subscribe" ||
|
||||||
|
(obj.response == "poke" && !!subFuncs)) {
|
||||||
|
let funcs = subFuncs;
|
||||||
|
|
||||||
|
if (obj.hasOwnProperty("err")) {
|
||||||
|
funcs["err"](obj.err);
|
||||||
|
this.outstandingSubscriptions.delete(obj.id);
|
||||||
|
} else if (obj.hasOwnProperty("ok")) {
|
||||||
|
funcs["subAck"](obj);
|
||||||
|
}
|
||||||
|
} else if (obj.response == "diff") {
|
||||||
|
// ensure we ack before channel clogs
|
||||||
|
if((this.lastEventId - this.lastAcknowledgedEventId) > 30) {
|
||||||
|
this.clearQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
let funcs = subFuncs;
|
||||||
|
funcs["event"](obj.json);
|
||||||
|
} else if (obj.response == "quit") {
|
||||||
|
let funcs = subFuncs;
|
||||||
|
funcs["quit"](obj);
|
||||||
|
this.outstandingSubscriptions.delete(obj.id);
|
||||||
|
} else {
|
||||||
|
console.log("Unrecognized response: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.eventSource.onopen = this.onChannelOpen;
|
||||||
|
|
||||||
|
this.eventSource.onerror = e => {
|
||||||
|
this.delete();
|
||||||
|
this.init();
|
||||||
|
this.onChannelError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
channelURL() {
|
||||||
|
return "/~/channel/" + this.uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextId() {
|
||||||
|
return this.requestId++;
|
||||||
|
}
|
||||||
|
}
|
@ -40,7 +40,7 @@ export default class Body extends Component {
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/~btc/settings">
|
<Route path="/settings">
|
||||||
<Col
|
<Col
|
||||||
display='flex'
|
display='flex'
|
||||||
flexDirection='column'
|
flexDirection='column'
|
||||||
@ -53,7 +53,7 @@ export default class Body extends Component {
|
|||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/~btc">
|
<Route path="/">
|
||||||
<Col
|
<Col
|
||||||
display='flex'
|
display='flex'
|
||||||
flexDirection='column'
|
flexDirection='column'
|
||||||
|
@ -30,6 +30,7 @@ export default class CurrencyPicker extends Component {
|
|||||||
}
|
}
|
||||||
let setCurrency = {
|
let setCurrency = {
|
||||||
"put-entry": {
|
"put-entry": {
|
||||||
|
desk: window.desk,
|
||||||
value: newCurrency,
|
value: newCurrency,
|
||||||
"entry-key": "currency",
|
"entry-key": "currency",
|
||||||
"bucket-key": "btc-wallet",
|
"bucket-key": "btc-wallet",
|
||||||
|
@ -16,7 +16,7 @@ export default class Header extends Component {
|
|||||||
render() {
|
render() {
|
||||||
let icon = this.props.settings ? "X" : "Adjust";
|
let icon = this.props.settings ? "X" : "Adjust";
|
||||||
let iconColor = this.props.settings ? "black" : "orange";
|
let iconColor = this.props.settings ? "black" : "orange";
|
||||||
let iconLink = this.props.settings ? "/~btc" : "/~btc/settings";
|
let iconLink = this.props.settings ? "/" : "/settings";
|
||||||
|
|
||||||
let connection = null;
|
let connection = null;
|
||||||
let badge = null;
|
let badge = null;
|
||||||
|
@ -24,6 +24,7 @@ export default class Warning extends Component {
|
|||||||
store.handleEvent({ data: { bucket: { warning: false}}});
|
store.handleEvent({ data: { bucket: { warning: false}}});
|
||||||
let removeWarning = {
|
let removeWarning = {
|
||||||
"put-entry": {
|
"put-entry": {
|
||||||
|
desk: window.desk,
|
||||||
value: false,
|
value: false,
|
||||||
"entry-key": "warning",
|
"entry-key": "warning",
|
||||||
"bucket-key": "btc-wallet",
|
"bucket-key": "btc-wallet",
|
||||||
|
@ -33,7 +33,7 @@ export class Root extends Component {
|
|||||||
const blur = !loaded ? false : !(this.state.wallet && this.state.provider);
|
const blur = !loaded ? false : !(this.state.wallet && this.state.provider);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BrowserRouter>
|
<BrowserRouter basename="/apps/bitcoin">
|
||||||
<ThemeProvider theme={light}>
|
<ThemeProvider theme={light}>
|
||||||
<Reset />
|
<Reset />
|
||||||
{loaded ? (
|
{loaded ? (
|
||||||
|
@ -7,7 +7,7 @@ class Store {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.state = {
|
this.state = {
|
||||||
loadedBtc: false,
|
loadedBtc: false,
|
||||||
loadedSettings: false,
|
loadedSettings: true,
|
||||||
loaded: false,
|
loaded: false,
|
||||||
providerPerms: {},
|
providerPerms: {},
|
||||||
shipWallets: {},
|
shipWallets: {},
|
||||||
@ -23,7 +23,7 @@ class Store {
|
|||||||
BTC: { last: 1, symbol: 'BTC' }
|
BTC: { last: 1, symbol: 'BTC' }
|
||||||
},
|
},
|
||||||
denomination: 'BTC',
|
denomination: 'BTC',
|
||||||
showWarning: true,
|
showWarning: false,
|
||||||
error: '',
|
error: '',
|
||||||
broadcastSuccess: false,
|
broadcastSuccess: false,
|
||||||
};
|
};
|
||||||
|
@ -20,7 +20,7 @@ export class Subscription {
|
|||||||
|
|
||||||
initializeSettings() {
|
initializeSettings() {
|
||||||
let app = 'settings-store';
|
let app = 'settings-store';
|
||||||
let path = '/bucket/btc-wallet';
|
let path = `/bucket/${window.desk}/btc-wallet`;
|
||||||
|
|
||||||
fetch(`/~/scry/${app}${path}.json`).then(res => res.json())
|
fetch(`/~/scry/${app}${path}.json`).then(res => res.json())
|
||||||
.then(n => {
|
.then(n => {
|
||||||
|
Loading…
Reference in New Issue
Block a user