diff options
author | polwex <polwex@sortug.com> | 2025-06-22 06:14:42 +0700 |
---|---|---|
committer | polwex <polwex@sortug.com> | 2025-06-22 06:14:42 +0700 |
commit | 6dccba9bb5100329209ad01732f9d63f4c4fb43b (patch) | |
tree | 140b33d2e25084174fce057056de9dea0e2dcbea /lib/metamask.hoon |
metamask login getting there
Diffstat (limited to 'lib/metamask.hoon')
-rw-r--r-- | lib/metamask.hoon | 169 |
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 + +-- |