aboutsummaryrefslogtreecommitdiff
path: root/src/Ssb/Peer.hs
blob: 41a49cb28345d631d88909e12e73b58c28e90b83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
-- | This module implements Scuttlebutt Peers
--
-- https://ssbc.github.io/scuttlebutt-protocol-guide/#peer-connections

module Ssb.Peer where

import           Protolude               hiding ( Identity )
import           Control.Arrow ((***))
import qualified Data.ByteString.Base64        as Base64
import qualified Network.Simple.TCP            as TCP
import qualified Data.Text as Text

import           Ssb.Identity
import           Ssb.Network
import qualified Ssb.Peer.SecretHandshake      as SH
import qualified Ssb.Peer.RPC                  as RPC

-- | TODO: Is there a standard way to re-export types?
type NetworkIdentifier = SH.NetworkIdentifier

-- | mainNet is the default Network where one will find most scuttlebutt
-- traffic.
mainNet :: NetworkIdentifier
mainNet = Base64.decodeLenient "1KHLiKZvAvjbY1ziZEHMXawbCEIM6qwjCDm3VYRan/s="

-- TODO: Perfect MultiAddress implementation

data MultiAddress = MultiAddress
    { protocol :: Text
    , host     :: Host
    , port     :: Port
    , key      :: PublicKey
    } deriving (Eq, Show)

id :: MultiAddress -> Identity
id ma = Identity Nothing (key ma)

parseMultiAddress :: Text -> Either Text MultiAddress
parseMultiAddress txt = do
    let (protocol, postProtocol) = split ":" txt
    let (addressPort, postAddress) = split "~" postProtocol
    let (address, port) = splitOnEnd ":" addressPort
    let (hashType, key) = split ":" postAddress
    return MultiAddress
      { protocol = protocol
      , host = address
      , port = port
      , key  = PublicKey $ Base64.decodeLenient $ encodeUtf8 key
      }
  where
    split c arg = (identity *** Text.drop 1) $ Text.breakOn c arg
    splitOnEnd c arg = (Text.dropEnd 1 *** identity) $ Text.breakOnEnd c arg

-- Example string "net:some.ho.st:8008~shs:SomeActuallyValidPubKey="
formatMultiAddress :: MultiAddress -> Text
formatMultiAddress addr =
    protocol addr <> ":"
    <> host addr <> ":" <> port addr
    <> "~shs:"
    <> formatPublicKey (key addr)