@@ -77,6 +77,86 @@ pub enum TransactionPayload {
77
77
New ( TransactionWrapper ) ,
78
78
}
79
79
80
+ impl TransactionPayload {
81
+ /// Creates a payload in either legacy or new format based on use_legacy flag
82
+ pub fn create (
83
+ transaction : & VersionedTransaction ,
84
+ config : RpcSendTransactionConfigWithBlockList ,
85
+ use_legacy : bool ,
86
+ ) -> Result < Self , PayloadError > {
87
+ if use_legacy {
88
+ Self :: to_legacy ( transaction, & config)
89
+ } else {
90
+ Self :: try_from ( ( transaction, config) )
91
+ }
92
+ }
93
+
94
+ /// Encodes a transaction using the specified encoding
95
+ fn encode_transaction (
96
+ tx : & VersionedTransaction ,
97
+ encoding : UiTransactionEncoding ,
98
+ ) -> Result < String , PayloadError > {
99
+ let tx_bytes = bincode:: serialize ( tx) ?;
100
+ Ok ( match encoding {
101
+ UiTransactionEncoding :: Base58 => bs58:: encode ( tx_bytes) . into_string ( ) ,
102
+ UiTransactionEncoding :: Base64 => BASE64_STANDARD . encode ( tx_bytes) ,
103
+ _ => return Err ( PayloadError :: UnsupportedEncoding ) ,
104
+ } )
105
+ }
106
+
107
+ /// Decodes a transaction string using the specified encoding
108
+ fn decode_transaction (
109
+ tx_string : & str ,
110
+ encoding : UiTransactionEncoding ,
111
+ ) -> Result < Vec < u8 > , PayloadError > {
112
+ Ok ( match encoding {
113
+ UiTransactionEncoding :: Base58 => bs58:: decode ( tx_string) . into_vec ( ) ?,
114
+ UiTransactionEncoding :: Base64 => BASE64_STANDARD . decode ( tx_string) ?,
115
+ _ => return Err ( PayloadError :: UnsupportedEncoding ) ,
116
+ } )
117
+ }
118
+
119
+ /// Creates a legacy payload from a transaction and configuration
120
+ pub fn to_legacy (
121
+ transaction : & VersionedTransaction ,
122
+ config_with_blocklist : & RpcSendTransactionConfigWithBlockList ,
123
+ ) -> Result < Self , PayloadError > {
124
+ let encoding = config_with_blocklist
125
+ . config
126
+ . as_ref ( )
127
+ . and_then ( |c| c. encoding )
128
+ . unwrap_or ( UiTransactionEncoding :: Base58 ) ;
129
+
130
+ match encoding {
131
+ UiTransactionEncoding :: Base64 | UiTransactionEncoding :: Base58 => ( ) ,
132
+ _ => return Err ( PayloadError :: UnsupportedEncoding ) ,
133
+ }
134
+
135
+ let tx_str = Self :: encode_transaction ( transaction, encoding) ?;
136
+
137
+ Ok ( Self :: Legacy ( LegacyPayload {
138
+ transaction : tx_str,
139
+ config : config_with_blocklist. config . unwrap_or_default ( ) ,
140
+ timestamp : Some ( ms_since_epoch ( ) ) ,
141
+ } ) )
142
+ }
143
+
144
+ /// Converts the payload to an appropriate protobuf message type
145
+ pub fn to_proto < T > ( & self ) -> T
146
+ where
147
+ T : From < TransactionWrapper > , // For the New Payload
148
+ T : From < Vec < u8 > > , // For the Legacy Payload
149
+ {
150
+ match self {
151
+ Self :: Legacy ( legacy) => {
152
+ let bytes = serde_json:: to_vec ( legacy) . expect ( "Failed to serialize legacy payload" ) ;
153
+ T :: from ( bytes)
154
+ }
155
+ Self :: New ( wrapper) => T :: from ( wrapper. clone ( ) ) ,
156
+ }
157
+ }
158
+ }
159
+
80
160
impl From < TransactionWrapper > for PublishTransaction {
81
161
fn from ( wrapper : TransactionWrapper ) -> Self {
82
162
Self {
@@ -116,6 +196,14 @@ impl From<Vec<u8>> for PublishTransaction {
116
196
}
117
197
}
118
198
199
+ impl From < Vec < u8 > > for SubscribeTransaction {
200
+ fn from ( bytes : Vec < u8 > ) -> Self {
201
+ Self {
202
+ payload : Some ( subscribe_transaction:: Payload :: LegacyPayload ( bytes) ) ,
203
+ }
204
+ }
205
+ }
206
+
119
207
impl TryFrom < ( & VersionedTransaction , RpcSendTransactionConfigWithBlockList ) >
120
208
for TransactionPayload
121
209
{
@@ -129,6 +217,7 @@ impl TryFrom<(&VersionedTransaction, RpcSendTransactionConfigWithBlockList)>
129
217
) -> Result < Self , Self :: Error > {
130
218
let tx_bytes = bincode:: serialize ( transaction) ?;
131
219
220
+ // Create new payload format with blocklist_pdas supported
132
221
Ok ( Self :: New ( TransactionWrapper {
133
222
transaction : tx_bytes,
134
223
config : Some ( TransactionConfig {
@@ -157,60 +246,6 @@ impl TryFrom<(&VersionedTransaction, RpcSendTransactionConfigWithBlockList)>
157
246
}
158
247
}
159
248
160
- impl TransactionPayload {
161
- pub fn to_legacy (
162
- transaction : & VersionedTransaction ,
163
- config_with_blocklist : & RpcSendTransactionConfigWithBlockList ,
164
- ) -> Result < Self , PayloadError > {
165
- let encoding = config_with_blocklist
166
- . config
167
- . as_ref ( )
168
- . and_then ( |c| c. encoding )
169
- . unwrap_or ( UiTransactionEncoding :: Base58 ) ;
170
-
171
- match encoding {
172
- UiTransactionEncoding :: Base64 | UiTransactionEncoding :: Base58 => ( ) ,
173
- _ => return Err ( PayloadError :: UnsupportedEncoding ) ,
174
- }
175
-
176
- let tx_bytes = bincode:: serialize ( transaction) ?;
177
- let tx_str = match encoding {
178
- UiTransactionEncoding :: Base58 => bs58:: encode ( tx_bytes) . into_string ( ) ,
179
- _ => BASE64_STANDARD . encode ( tx_bytes) ,
180
- } ;
181
-
182
- Ok ( Self :: Legacy ( LegacyPayload {
183
- transaction : tx_str,
184
- config : config_with_blocklist. config . unwrap_or_default ( ) ,
185
- timestamp : Some ( ms_since_epoch ( ) ) ,
186
- } ) )
187
- }
188
- }
189
-
190
- impl From < Vec < u8 > > for SubscribeTransaction {
191
- fn from ( bytes : Vec < u8 > ) -> Self {
192
- Self {
193
- payload : Some ( subscribe_transaction:: Payload :: LegacyPayload ( bytes) ) ,
194
- }
195
- }
196
- }
197
-
198
- impl TransactionPayload {
199
- pub fn to_proto < T > ( & self ) -> T
200
- where
201
- T : From < TransactionWrapper > , // For the New variant
202
- T : From < Vec < u8 > > , // For the Legacy variant
203
- {
204
- match self {
205
- Self :: Legacy ( legacy) => {
206
- let bytes = serde_json:: to_vec ( legacy) . expect ( "Failed to serialize legacy payload" ) ;
207
- T :: from ( bytes)
208
- }
209
- Self :: New ( wrapper) => T :: from ( wrapper. clone ( ) ) ,
210
- }
211
- }
212
- }
213
-
214
249
pub struct TransactionDecoder ;
215
250
216
251
impl TransactionDecoder {
@@ -225,23 +260,18 @@ impl TransactionDecoder {
225
260
> {
226
261
match payload {
227
262
TransactionPayload :: Legacy ( legacy) => {
228
- let tx_bytes = match legacy
263
+ let encoding = legacy
229
264
. config
230
265
. encoding
231
- . unwrap_or ( UiTransactionEncoding :: Base58 )
232
- {
233
- UiTransactionEncoding :: Base58 => {
234
- bs58:: decode ( & legacy. transaction ) . into_vec ( ) ?
235
- }
236
- UiTransactionEncoding :: Base64 => BASE64_STANDARD . decode ( & legacy. transaction ) ?,
237
- _ => return Err ( PayloadError :: UnsupportedEncoding ) ,
238
- } ;
266
+ . unwrap_or ( UiTransactionEncoding :: Base58 ) ;
267
+ let tx_bytes =
268
+ TransactionPayload :: decode_transaction ( & legacy. transaction , encoding) ?;
239
269
240
270
let tx = bincode:: deserialize ( & tx_bytes) ?;
241
271
Ok ( (
242
272
tx,
243
273
Some ( RpcSendTransactionConfigWithBlockList {
244
- config : Some ( legacy. config ) ,
274
+ config : Some ( legacy. config . clone ( ) ) ,
245
275
blocklist_pdas : vec ! [ ] , // Legacy format doesn't have blocklist
246
276
} ) ,
247
277
) )
0 commit comments