web3-0.8.0.0: src/Network/Ethereum/Ens.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
-- |
-- Module : Network.Ethereum.Ens
-- Copyright : Alexander Krupenkin 2018
-- License : BSD3
--
-- Maintainer : mail@akru.me
-- Stability : experimental
-- Portability : unportable
--
-- ENS offers a secure & decentralised way to address resources both on
-- and off the blockchain using simple, human-readable names.
--
-- This module provide basic ENS resolvers.
--
module Network.Ethereum.Ens where
import Crypto.Hash (Digest, Keccak_256, hash)
import Data.ByteArray (convert, zero)
import Data.ByteArray.Sized (unsafeFromByteArrayAccess)
import Data.ByteString (ByteString)
import Data.ByteString.Char8 (split)
import Data.Monoid ((<>))
import Lens.Micro ((.~))
import Data.Solidity.Prim (Address, BytesN)
import Network.Ethereum.Account.Class (Account)
import Network.Ethereum.Account.Internal (AccountT, to, withParam)
import qualified Network.Ethereum.Ens.PublicResolver as Resolver
import qualified Network.Ethereum.Ens.Registry as Reg
import Network.JsonRpc.TinyClient (JsonRpc)
-- | Namehash algorithm
-- http://docs.ens.domains/en/latest/implementers.html#algorithm
namehash :: ByteString
-- ^ Domain name
-> BytesN 32
-- ^ Associated ENS node
namehash =
unsafeFromByteArrayAccess . foldr algo (zero 32) . split '.'
where
algo a b = sha3 (b <> sha3 a)
sha3 :: ByteString -> ByteString
sha3 bs = convert (hash bs :: Digest Keccak_256)
-- | Get address of ENS domain
resolve :: (JsonRpc m, Account p (AccountT p))
=> ByteString
-- ^ Domain name
-> AccountT p m Address
-- ^ Associated address
resolve name = do
r <- ensRegistry $ Reg.resolver node
withParam (to .~ r) $ Resolver.addr node
where
node = namehash name
ensRegistry = withParam $ to .~ "0x314159265dD8dbb310642f98f50C066173C1259b"