1
- using System . Text ;
2
- using System . Text . Json ;
3
- using NBitcoin . Secp256k1 ;
4
- using PeterO . Cbor ;
5
-
6
- namespace DotNut ;
1
+ namespace DotNut ;
7
2
8
3
public static class CashuTokenHelper
9
4
{
@@ -64,127 +59,4 @@ public static CashuToken Decode(string token, out string? version)
64
59
token = token . Substring ( 1 ) ;
65
60
return encoder . Decode ( token ) ;
66
61
}
67
- }
68
-
69
- public interface ICashuTokenEncoder
70
- {
71
- string Encode ( CashuToken token ) ;
72
- CashuToken Decode ( string token ) ;
73
- }
74
-
75
- public class CashuTokenV3Encoder : ICashuTokenEncoder
76
- {
77
- public string Encode ( CashuToken token )
78
- {
79
- var json = JsonSerializer . Serialize ( token ) ;
80
- return Base64UrlSafe . Encode ( Encoding . UTF8 . GetBytes ( json ) ) ;
81
- }
82
-
83
- public CashuToken Decode ( string token )
84
- {
85
- var json = Encoding . UTF8 . GetString ( Base64UrlSafe . Decode ( token ) ) ;
86
- return JsonSerializer . Deserialize < CashuToken > ( json ) ! ;
87
- }
88
- }
89
-
90
- public class CashuTokenV4Encoder : ICashuTokenEncoder , ICBORToFromConverter < CashuToken >
91
- {
92
- public string Encode ( CashuToken token )
93
- {
94
- var obj = ToCBORObject ( token ) ;
95
- return Base64UrlSafe . Encode ( obj . EncodeToBytes ( ) ) ;
96
- }
97
-
98
- public CashuToken Decode ( string token )
99
- {
100
- var obj = CBORObject . DecodeFromBytes ( Base64UrlSafe . Decode ( token ) ) ;
101
- return FromCBORObject ( obj ) ;
102
- }
103
-
104
- public CBORObject ToCBORObject ( CashuToken token )
105
- {
106
- //ensure that all token mints are the same
107
- var mints = token . Tokens . Select ( token1 => token1 . Mint ) . ToArray ( ) ;
108
- if ( mints . Distinct ( ) . Count ( ) != 1 )
109
- throw new FormatException ( "All proofs must have the same mint in v4 tokens" ) ;
110
- var proofSets = CBORObject . NewArray ( ) ;
111
- foreach ( var proofSet in token . Tokens . SelectMany ( token1 => token1 . Proofs ) . GroupBy ( proof => proof . Id ) )
112
- {
113
- var proofSetItem = CBORObject . NewOrderedMap ( ) ;
114
- proofSetItem . Add ( "i" , Convert . FromHexString ( proofSet . Key . ToString ( ) ) ) ;
115
- var proofSetItemArray = CBORObject . NewArray ( ) ;
116
- foreach ( var proof in proofSet )
117
- {
118
- var proofItem = CBORObject . NewOrderedMap ( )
119
- . Add ( "a" , proof . Amount )
120
- . Add ( "s" , Encoding . UTF8 . GetString ( proof . Secret . GetBytes ( ) ) )
121
- . Add ( "c" , proof . C . Key . ToBytes ( ) ) ;
122
- if ( proof . DLEQ is not null )
123
- {
124
- proofItem . Add ( "d" , CBORObject
125
- . NewOrderedMap ( )
126
- . Add ( "e" , proof . DLEQ . E . Key . ToBytes ( ) )
127
- . Add ( "s" , proof . DLEQ . S . Key . ToBytes ( ) )
128
- . Add ( "r" , proof . DLEQ . R . Key . ToBytes ( ) ) ) ;
129
- }
130
-
131
- if ( proof . Witness is not null )
132
- {
133
- proofItem . Add ( "w" , proof . Witness ) ;
134
- }
135
-
136
- proofSetItemArray . Add ( proofItem ) ;
137
- }
138
-
139
- proofSetItem . Add ( "p" , proofSetItemArray ) ;
140
- proofSets . Add ( proofSetItem ) ;
141
- }
142
-
143
- var cbor = CBORObject . NewOrderedMap ( ) ;
144
-
145
-
146
- if ( token . Memo is not null )
147
- cbor . Add ( "d" , token . Memo ) ;
148
- cbor . Add ( "t" , proofSets )
149
- . Add ( "m" , mints . First ( ) )
150
- . Add ( "u" , token . Unit ! ) ;
151
- return cbor ;
152
- }
153
-
154
- public CashuToken FromCBORObject ( CBORObject obj )
155
- {
156
- return new CashuToken
157
- {
158
- Unit = obj [ "u" ] . AsString ( ) ,
159
- Memo = obj . GetOrDefault ( "d" , null ) ? . AsString ( ) ,
160
- Tokens =
161
- [
162
- new CashuToken . Token ( )
163
- {
164
- Mint = obj [ "m" ] . AsString ( ) ,
165
- Proofs = obj [ "t" ] . Values . SelectMany ( proofSet =>
166
- {
167
- var id = new KeysetId ( Convert . ToHexString ( proofSet [ "i" ] . GetByteString ( ) ) . ToLowerInvariant ( ) ) ;
168
-
169
- return proofSet [ "p" ] . Values . Select ( proof => new Proof ( )
170
- {
171
- Amount = proof [ "a" ] . AsInt32 ( ) ,
172
- Secret = JsonSerializer . Deserialize < ISecret > ( proof [ "s" ] . ToJSONString ( ) ) ! ,
173
- C = ECPubKey . Create ( proof [ "c" ] . GetByteString ( ) ) ,
174
- Witness = proof . GetOrDefault ( "w" , null ) ? . AsString ( ) ,
175
- DLEQ = proof . GetOrDefault ( "d" , null ) is { } cborDLEQ
176
- ? new DLEQProof
177
- {
178
- E = ECPrivKey . Create ( cborDLEQ [ "e" ] . GetByteString ( ) ) ,
179
- S = ECPrivKey . Create ( cborDLEQ [ "s" ] . GetByteString ( ) ) ,
180
- R = ECPrivKey . Create ( cborDLEQ [ "r" ] . GetByteString ( ) )
181
- }
182
- : null ,
183
- Id = id
184
- } ) ;
185
- } ) . ToList ( )
186
- }
187
- ]
188
- } ;
189
- }
190
62
}
0 commit comments