@@ -7,77 +7,123 @@ import Plutarch.Api.V2
7
7
( PAddress
8
8
, PMaybeData (PDJust , PDNothing )
9
9
, PPubKeyHash
10
+ , PScriptHash
10
11
, PStakingCredential (PStakingHash , PStakingPtr )
11
12
)
13
+ import Plutarch.DataRepr (PDataFields )
12
14
import Plutarch.Extra.Maybe (pjust , pnothing )
13
15
import Plutarch.Monadic qualified as P
14
16
15
17
data PAddressConfiguration (s :: S )
16
18
= PAddressConfig'PaymentKeyHash'StakeKeyHash (Term s PPubKeyHash ) (Term s PPubKeyHash )
19
+ | PAddressConfig'PaymentKeyHash'ScriptHash (Term s PPubKeyHash ) (Term s PScriptHash )
17
20
| PAddressConfig'PaymentKeyHash (Term s PPubKeyHash )
18
21
deriving stock (Generic )
19
22
deriving anyclass (PlutusType , PShow , PEq )
20
23
21
24
instance DerivePlutusType PAddressConfiguration where
22
25
type DPTStrat _ = PlutusTypeScott
23
26
24
- pserializeAddress :: Term s (PAddress :--> PMaybe PByteString )
27
+ data PSerializedAddress (s :: S )
28
+ = PSerializedAddress
29
+ ( Term
30
+ s
31
+ ( PDataRecord
32
+ '[ " addrCbor" ':= PByteString
33
+ , " addrMapEntrySize" ':= PByteString
34
+ ]
35
+ )
36
+ )
37
+ deriving stock (Generic )
38
+ deriving anyclass (PlutusType , PIsData , PDataFields , PShow , PEq )
39
+
40
+ instance DerivePlutusType PSerializedAddress where
41
+ type DPTStrat _ = PlutusTypeData
42
+
43
+ pserializeAddress :: Term s (PAddress :--> PMaybe PSerializedAddress )
25
44
pserializeAddress = phoistAcyclic $
26
45
plam $ \ addr ->
27
46
pmatch (pmkAddrConfig # addr) $ \ case
28
47
PNothing -> pnothing
29
- PJust addrConfig ->
30
- pjust
31
- # mconcat
32
- [ phexByteStr " 58" -- byte string (one-byte uint8_t for n, and then n bytes follow)
33
- , paddrConfigAddrSize # addrConfig
34
- , paddrConfigAddrHeaderForTestnet # addrConfig
35
- , paddrConfigAddrBody # addrConfig
36
- ]
48
+ PJust addrConfig -> P. do
49
+ PPair addrSize addrMapEntrySize <- pmatch $ paddrConfigAddrSize # addrConfig
50
+ addrCbor <-
51
+ plet $
52
+ mconcat
53
+ [ phexByteStr " 58" -- byte string (one-byte uint8_t for n, and then n bytes follow)
54
+ , addrSize
55
+ , paddrConfigAddrHeaderForTestnet # addrConfig
56
+ , paddrConfigAddrBody # addrConfig
57
+ ]
58
+ pjust #$ pcon $
59
+ PSerializedAddress $
60
+ pdcons # pdata addrCbor #$ pdcons # pdata addrMapEntrySize # pdnil
37
61
38
62
pmkAddrConfig :: Term s (PAddress :--> PMaybe PAddressConfiguration )
39
63
pmkAddrConfig = phoistAcyclic $
40
64
plam $ \ addr -> P. do
41
65
creds <- pletFields @ [" credential" , " stakingCredential" ] addr
42
66
pmatch creds. credential $ \ case
43
67
PScriptCredential _ -> pnothing
44
- PPubKeyCredential rec -> P. do
45
- let pkh = pfield @ " _0" # rec
68
+ PPubKeyCredential pkhRec -> P. do
69
+ let pkh = pfield @ " _0" # pkhRec
46
70
pmatch creds. stakingCredential $ \ case
47
71
PDNothing _ -> pjust # pcon (PAddressConfig'PaymentKeyHash pkh)
48
- PDJust rec ->
49
- pmatch (pfield @ " _0" # rec ) $ \ case
50
- PStakingHash rec ->
51
- pmatch (pfield @ " _0" # rec ) $ \ case
52
- PScriptCredential _ -> pnothing
53
- PPubKeyCredential rec -> P. do
54
- let skh = pfield @ " _0" # rec
72
+ PDJust stakingCredRec ->
73
+ pmatch (pfield @ " _0" # stakingCredRec) $ \ case
74
+ PStakingHash stakingHashRec ->
75
+ pmatch (pfield @ " _0" # stakingHashRec) $ \ case
76
+ PScriptCredential shRec -> P. do
77
+ let sh = pfield @ " _0" # shRec
78
+ pjust # pcon (PAddressConfig'PaymentKeyHash'ScriptHash pkh sh)
79
+ PPubKeyCredential skhRec -> P. do
80
+ let skh = pfield @ " _0" # skhRec
55
81
pjust # pcon (PAddressConfig'PaymentKeyHash'StakeKeyHash pkh skh)
56
82
PStakingPtr _ -> pnothing
57
83
58
- paddrConfigAddrSize :: Term s (PAddressConfiguration :--> PByteString )
84
+ -- Get hex-encoded size for given address configuration.
85
+ --
86
+ -- PaymentKeyHash, StakeKeyHash, and ScriptHash are blake2b-224 hash
87
+ -- digests and all have size of 224 bits (28 bytes).
88
+ -- https://github.com/cardano-foundation/CIPs/blob/d66f7d0a0bcd06c425a6b7a41c6d18c922deff7e/CIP-0019/README.md?plain=1#L95-L97
89
+ paddrConfigAddrSize :: Term s (PAddressConfiguration :--> PPair PByteString PByteString )
59
90
paddrConfigAddrSize = phoistAcyclic $
60
91
plam $ \ addrConfig ->
61
92
pmatch addrConfig $ \ case
62
93
PAddressConfig'PaymentKeyHash'StakeKeyHash _ _ ->
63
- phexByteStr " 39" -- 57 = 1 (header) + 28 (pkh) + 28 (skh)
94
+ -- 0x39 = 57 = 1 (header) + 28 (pkh) + 28 (skh)
95
+ pcon $ PPair (phexByteStr " 39" ) (phexByteStr " 46" )
96
+ PAddressConfig'PaymentKeyHash'ScriptHash _ _ ->
97
+ -- 0x39 = 57 = 1 (header) + 28 (pkh) + 28 (sh)
98
+ pcon $ PPair (phexByteStr " 39" ) (phexByteStr " 46" )
64
99
PAddressConfig'PaymentKeyHash _ ->
65
- phexByteStr " 1D" -- 29 = 1 (header) + 28 (pkh)
100
+ -- 0x1D = 29 = 1 (header) + 28 (pkh)
101
+ pcon $ PPair (phexByteStr " 1D" ) (phexByteStr " 2A" )
66
102
103
+ -- Get hex-encoded network tag + header type for given address
104
+ -- configuration.
105
+ -- https://github.com/cardano-foundation/CIPs/blob/d66f7d0a0bcd06c425a6b7a41c6d18c922deff7e/CIP-0019/README.md?plain=1#L70-L93
67
106
paddrConfigAddrHeaderForTestnet :: Term s (PAddressConfiguration :--> PByteString )
68
107
paddrConfigAddrHeaderForTestnet = phoistAcyclic $
69
108
plam $ \ addrConfig ->
70
109
pmatch addrConfig $ \ case
71
110
PAddressConfig'PaymentKeyHash'StakeKeyHash _ _ ->
72
- phexByteStr " 00" -- 0b0000_0000
111
+ -- 0x00 = 0b0000_0000
112
+ phexByteStr " 00"
113
+ PAddressConfig'PaymentKeyHash'ScriptHash _ _ ->
114
+ -- 0x20 = 0b0010_0000
115
+ phexByteStr " 20"
73
116
PAddressConfig'PaymentKeyHash _ ->
74
- phexByteStr " 60" -- 0b0110_0000
117
+ -- 0x60 = 0b0110_0000
118
+ phexByteStr " 60"
75
119
76
120
paddrConfigAddrBody :: Term s (PAddressConfiguration :--> PByteString )
77
121
paddrConfigAddrBody = phoistAcyclic $
78
122
plam $ \ addrConfig ->
79
123
pmatch addrConfig $ \ case
80
124
PAddressConfig'PaymentKeyHash'StakeKeyHash pkh skh ->
81
125
pto pkh <> pto skh
126
+ PAddressConfig'PaymentKeyHash'ScriptHash pkh sh ->
127
+ pto pkh <> pto sh
82
128
PAddressConfig'PaymentKeyHash pkh ->
83
129
pto pkh
0 commit comments