summaryrefslogtreecommitdiff
path: root/lib/metamask.hoon
diff options
context:
space:
mode:
Diffstat (limited to 'lib/metamask.hoon')
-rw-r--r--lib/metamask.hoon169
1 files changed, 169 insertions, 0 deletions
diff --git a/lib/metamask.hoon b/lib/metamask.hoon
new file mode 100644
index 0000000..4cb403b
--- /dev/null
+++ b/lib/metamask.hoon
@@ -0,0 +1,169 @@
+/+ naive, ethereum, server
+=>
+|%
++$ challenges (set secret)
++$ secret @uv
++$ authorization
+ $: who=@p
+ =secret
+ adr=tape
+ sig=tape
+ ==
++$ user-sessions (map comet=@p id=@p)
++$ sessions
+ $: =challenges
+ users=user-sessions
+ ==
+--
+|_ [=sessions =bowl:gall]
++$ sess ^sessions
+:: state field to keep track of users logged with metamask
+++ login ^- @p
+ =/ session (~(get by users.sessions) src.bowl)
+ ?~ session src.bowl
+ u.session
+
+ :: this goes on the router
+ ++ serve-metamask-challenge
+ |= eyre-id=@ta
+ :: special-case MetaMask auth handling
+ =/ new-challenge (sham [now eny]:bowl)
+ %+ weld (self-poke [%meta new-challenge])
+ %+ give-simple-payload:app:server
+ eyre-id
+ ^- simple-payload:http
+ :- :- 200
+ ~[['Content-Type' 'application/json']]
+ `(as-octs:mimes:html (en:json:html (enjs-challenge new-challenge)))
+ :: Modified from ~rabsef-bicrym's %mask by ~hanfel-dovned.
+ ++ process-metamask-auth
+ |= [order-id=@t octs=(unit octs)]
+ ^- (list card:agent:gall)
+ =/ challenges challenges.sessions
+ |^
+ ?~ octs ~|(%empty-auth-request !!)
+ :: ?. =('auth' (cut 3 [0 4] q.u.octs))
+ :: *(list card:agent:gall)
+ =/ jon (de:json:html q.u.octs)
+ ?~ jon ~|(%empty-auth-json !!)
+ =/ body=json u.jon
+ =/ axn (dejs-action body)
+ =/ is-valid (validate who.axn secret.axn adr.axn sig.axn)
+ ~& >> signature-valid=[is-valid who.axn secret.axn adr.axn sig.axn]
+ ?. is-valid ~|(%bad-metamask-signature !!)
+ %+ weld
+ (self-poke [%auth who.axn src.bowl secret.axn])
+ %+ give-simple-payload:app:server
+ order-id
+ ^- simple-payload:http
+ :- :- 200
+ ~[['Content-Type' 'application/json']]
+ =/ obj=json %- pairs:enjs:format :~([%login-ok [%b .y]])
+ `(as-octs:mimes:html (en:json:html obj))
+
+ ++ validate
+ |= [who=@p challenge=secret address=tape hancock=tape]
+ ^- ?
+ =/ addy (from-tape address)
+ =/ cock (from-tape hancock)
+ =/ owner (get-owner who) ?~ owner
+ ~& "no owner"
+ %.n
+ ?. =(addy u.owner)
+ ~& "wrong owner"
+ %.n
+ ?. (~(has in challenges) challenge)
+ ~& "bad challenge"
+ %.n
+ =/ note=@uvI
+ =+ octs=(as-octs:mimes:html (scot %uv challenge))
+ %- keccak-256:keccak:crypto
+ %- as-octs:mimes:html
+ ;: (cury cat 3)
+ '\19Ethereum Signed Message:\0a'
+ (crip (a-co:co p.octs))
+ q.octs
+ ==
+ ?. &(=(20 (met 3 addy)) =(65 (met 3 cock)))
+ ~& "addy != cock"
+ %.n
+ =/ r (cut 3 [33 32] cock)
+ =/ s (cut 3 [1 32] cock)
+ =/ v=@
+ =+ v=(cut 3 [0 1] cock)
+ ?+ v 99
+ %0 0
+ %1 1
+ %27 0
+ %28 1
+ ==
+ ?. |(=(0 v) =(1 v))
+ ~& "wrong v"
+ %.n
+ =/ xy
+ (ecdsa-raw-recover:secp256k1:secp:crypto note v r s)
+ =/ pub :((cury cat 3) y.xy x.xy 0x4)
+ =/ add (address-from-pub:key:ethereum pub)
+ =(addy add)
+ ::
+ ++ from-tape
+ |=(h=tape ^-(@ux (scan h ;~(pfix (jest '0x') hex))))
+ ::
+ ++ get-owner
+ |= who=@p
+ ^- (unit @ux)
+ =- ?~ pin=`(unit point:naive)`-
+ ~
+ ?. |(?=(%l1 dominion.u.pin) ?=(%l2 dominion.u.pin))
+ ~
+ `address.owner.own.u.pin
+ .^ (unit point:naive)
+ %gx
+ %+ en-beam
+ [our.bowl %azimuth [%da now.bowl]]
+ /point/(scot %p who)/noun
+ ==
+ ++ dejs-action
+ |= jon=json
+ ^- authorization
+ =, dejs:format
+ %. jon
+ %- ot
+ :~ [%who (se %p)]
+ [%secret (se %uv)]
+ [%address sa]
+ [%signature sa]
+ ==
+ --
+ ++ enjs-challenge
+ =, enjs:format
+ |= chal=@
+ ^- json
+ %- pairs
+ :~ [%challenge [%s (scot %uv chal)]]
+ ==
+ ++ self-poke
+ |= noun=*
+ ^- (list card:agent:gall)
+ :~ [%pass /gib %agent [our.bowl dap.bowl] %poke %noun !>(noun)]
+ ==
+
+ :: these are the poke handlers
+ ++ handle-meta
+ |= new-challenge=@ ^- ^sessions
+ =? users.sessions
+ !(~(has by users.sessions) src.bowl)
+ (~(put by users.sessions) [src.bowl src.bowl])
+ =? challenges.sessions
+ =(src.bowl (~(got by users.sessions) src.bowl))
+ (~(put in challenges.sessions) new-challenge)
+
+ sessions
+ ++ handle-auth
+ |= [who=@p src=@p =secret] ^- ^sessions
+ ~& > "%ustj: Successful authentication of {<src>} as {<who>}."
+ =. users.sessions (~(put by users.sessions) src who)
+ =. challenges.sessions (~(del in challenges.sessions) secret)
+ sessions
+
+--