@@ -11,6 +11,7 @@ module Functora.Bolt11
11
11
Bolt11HrpAmt (.. ),
12
12
inspectBolt11HrpAmt ,
13
13
Bolt11Hrp (.. ),
14
+ Bolt11Sig (.. ),
14
15
Bolt11 (.. ),
15
16
decodeBolt11 ,
16
17
)
@@ -33,7 +34,10 @@ import Prelude (Show (..), error, splitAt, take)
33
34
newtype Hex = Hex
34
35
{ unHex :: ByteString
35
36
}
36
- deriving stock (Eq , Ord , Show , Data , Generic )
37
+ deriving stock (Eq , Ord , Data , Generic )
38
+
39
+ instance Show Hex where
40
+ show = inspectHex
37
41
38
42
inspectHex :: forall a . (From String a ) => Hex -> a
39
43
inspectHex =
@@ -70,7 +74,7 @@ data Tag
70
74
| DescriptionHash Hex
71
75
| Expiry Int
72
76
| MinFinalCltvExpiry Int
73
- | OnchainFallback Hex -- TODO: address type
77
+ | OnchainFallback -- TODO: address type
74
78
| ExtraRouteInfo
75
79
| FeatureBits [Word5 ]
76
80
deriving stock (Eq , Ord , Show , Generic )
@@ -149,11 +153,17 @@ data Bolt11Hrp = Bolt11Hrp
149
153
}
150
154
deriving stock (Eq , Ord , Show , Data , Generic )
151
155
156
+ data Bolt11Sig = Bolt11Sig
157
+ { bolt11SigVal :: Hex ,
158
+ bolt11SigRecoveryFlag :: Int
159
+ }
160
+ deriving stock (Eq , Ord , Show , Data , Generic )
161
+
152
162
data Bolt11 = Bolt11
153
163
{ bolt11Hrp :: Bolt11Hrp ,
154
164
bolt11Timestamp :: Int , -- posix
155
165
bolt11Tags :: [Tag ], -- posix
156
- bolt11Signature :: Hex
166
+ bolt11Signature :: Bolt11Sig
157
167
}
158
168
deriving stock (Eq , Ord , Show , Generic )
159
169
@@ -200,13 +210,13 @@ w5bs = BS.pack . fromMaybe (error "what") . Bech32.toBase256
200
210
w5txt :: [Word5 ] -> Text
201
211
w5txt = decodeUtf8 . w5bs
202
212
203
- tagParser :: [Word5 ] -> (Maybe Tag , [Word5 ])
204
- tagParser [] = (Nothing , [] )
205
- tagParser ws@ [_] = (Nothing , ws)
206
- tagParser ws@ [_, _] = (Nothing , ws) -- appease the compiler warning gods
207
- tagParser ws
213
+ parseTag :: [Word5 ] -> (Maybe Tag , [Word5 ])
214
+ parseTag [] = (Nothing , [] )
215
+ parseTag ws@ [_] = (Nothing , ws)
216
+ parseTag ws@ [_, _] = (Nothing , ws) -- appease the compiler warning gods
217
+ parseTag ws
208
218
| length ws < 8 = (Nothing , ws)
209
- tagParser ws@ (typ : d1 : d2 : rest)
219
+ parseTag ws@ (typ : d1 : d2 : rest)
210
220
| length rest < 7 = (Nothing , ws)
211
221
| otherwise = (Just tag, leftovers)
212
222
where
@@ -222,7 +232,7 @@ tagParser ws@(typ : d1 : d2 : rest)
222
232
19 -> PayeePubkey datBs
223
233
6 -> Expiry (w5int dat)
224
234
24 -> MinFinalCltvExpiry (w5int dat)
225
- 9 -> OnchainFallback datBs
235
+ 9 -> OnchainFallback
226
236
3 -> ExtraRouteInfo
227
237
5 -> FeatureBits dat
228
238
n -> error (" unhandled typ " ++ show n)
@@ -232,24 +242,35 @@ data MSig
232
242
| Unk [Word5 ]
233
243
deriving stock (Eq , Ord , Show , Generic )
234
244
235
- tagsParser :: [Word5 ] -> ([Tag ], MSig )
236
- tagsParser ws
245
+ parseTags :: [Word5 ] -> ([Tag ], MSig )
246
+ parseTags ws
237
247
| length ws == 104 = ([] , Sig ws)
238
248
| otherwise =
239
- let (mtag, rest) = tagParser ws
249
+ let (mtag, rest) = parseTag ws
240
250
in maybe
241
251
([] , Unk rest)
242
- (\ tag -> first (tag : ) (tagsParser rest))
252
+ (\ tag -> first (tag : ) (parseTags rest))
243
253
mtag
244
254
245
255
decodeBolt11 :: Text -> Either String Bolt11
246
256
decodeBolt11 raw = do
247
257
(rawHrp, rawDp) <- first show $ Bech32. decodeLenient raw
248
- let (timestampBits, rest) = splitAt 7 $ Bech32. dataPartToWords rawDp
249
- timestamp = w5int timestampBits
250
- (tags, leftover) = tagsParser rest
251
- sig <- case leftover of
252
- Sig ws -> maybe (Left " corrupt" ) Right (Bech32. toBase256 ws)
253
- Unk left -> Left (" corrupt, leftover: " ++ show (Hex (w5bs left)))
254
258
hrp <- parseOnly parseHrp $ Bech32. humanReadablePartToText rawHrp
255
- Right (Bolt11 hrp timestamp tags (Hex (BS. pack sig)))
259
+ let (ts, rest) = splitAt 7 $ Bech32. dataPartToWords rawDp
260
+ let (tags, leftover) = parseTags rest
261
+ (rawSig, recFlag) <- case leftover of
262
+ Sig ws -> Right $ splitAt 103 ws
263
+ Unk left -> Left (" corrupt, leftover: " ++ show (Hex (w5bs left)))
264
+ sig <-
265
+ maybe (Left " corrupt" ) Right $ Bech32. toBase256 rawSig
266
+ Right
267
+ Bolt11
268
+ { bolt11Hrp = hrp,
269
+ bolt11Timestamp = w5int ts,
270
+ bolt11Tags = tags,
271
+ bolt11Signature =
272
+ Bolt11Sig
273
+ { bolt11SigVal = Hex $ BS. pack sig,
274
+ bolt11SigRecoveryFlag = w5int recFlag
275
+ }
276
+ }
0 commit comments