Skip to content

Commit 8677c83

Browse files
committed
fix: use tuple enum syntax to make serde work
1 parent c27bd5a commit 8677c83

File tree

4 files changed

+55
-40
lines changed

4 files changed

+55
-40
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ aws-sdk-kms = "1.79.0"
3636
aws-credential-types = "1.2.4"
3737

3838
# Serialization
39-
serde = { version = "1.0.219", features = ["derive"] }
40-
serde_json = "1.0.140"
39+
serde = { version = "1.0.228", features = ["derive"] }
40+
serde_json = "1.0.145"
4141
serde_with = "3.14.0"
4242
serde-bool = "0.1.3"
4343
serde_repr = "0.1.20"

core/src/execution_options/solana.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ impl CommitmentLevel {
126126
}
127127
}
128128

129-
130129
#[derive(Serialize, Deserialize, Clone, Debug, utoipa::ToSchema)]
131130
#[schema(title = "Solana Transaction Options")]
132131
#[serde(rename_all = "camelCase")]
@@ -141,21 +140,24 @@ pub struct SolanaTransactionOptions {
141140

142141
/// Request to send a Solana transaction
143142
#[derive(Serialize, Deserialize, Clone, Debug, utoipa::ToSchema)]
144-
#[serde(rename_all = "camelCase")]
143+
// #[serde(rename_all = "camelCase")]
145144
pub struct SendSolanaTransactionRequest {
146145
/// Idempotency key for this transaction (defaults to random UUID)
147146
#[serde(default = "super::default_idempotency_key")]
147+
#[serde(rename = "idempotencyKey")]
148148
pub idempotency_key: String,
149149

150150
/// Transaction input (either instructions or serialized transaction)
151151
#[serde(flatten)]
152152
pub input: engine_solana_core::transaction::SolanaTransactionInput,
153153

154154
/// Solana execution options
155+
#[serde(rename = "executionOptions")]
155156
pub execution_options: SolanaExecutionOptions,
156157

157158
/// Webhook options for transaction status notifications
158159
#[serde(default)]
160+
#[serde(rename = "webhookOptions")]
159161
pub webhook_options: Vec<super::WebhookOptions>,
160162
}
161163

executors/src/solana_executor/worker.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,9 @@ impl SolanaExecutorJobHandler {
601601

602602
// For serialized transactions with existing signatures, we cannot retry with a new blockhash
603603
// because the signatures will become invalid. Check if there are any non-default signatures.
604-
if let engine_solana_core::transaction::SolanaTransactionInput::Serialized { transaction } = &job_data.transaction.input {
604+
if let engine_solana_core::transaction::SolanaTransactionInput::Serialized (t) = &job_data.transaction.input {
605605
// Deserialize the base64 transaction to check for signatures
606-
if let Ok(tx_bytes) = base64::engine::general_purpose::STANDARD.decode(transaction)
606+
if let Ok(tx_bytes) = base64::engine::general_purpose::STANDARD.decode(&t.transaction)
607607
&& let Ok((versioned_tx, _)) = bincode::serde::decode_from_slice::<solana_sdk::transaction::VersionedTransaction, _>(
608608
&tx_bytes,
609609
bincode::config::standard()
@@ -748,10 +748,10 @@ impl SolanaExecutorJobHandler {
748748

749749
// Build transaction - handle execution options differently for instructions vs serialized
750750
let versioned_tx = match &job_data.transaction.input {
751-
engine_solana_core::transaction::SolanaTransactionInput::Instructions { instructions } => {
751+
engine_solana_core::transaction::SolanaTransactionInput::Instructions(i) => {
752752
// For instruction-based transactions: calculate priority fees and apply execution options
753753
let compute_unit_price = if let Some(priority_fee) = &job_data.transaction.execution_options.priority_fee {
754-
Some(self.get_compute_unit_price(priority_fee, instructions, rpc_client, chain_id_str.as_str()).await?)
754+
Some(self.get_compute_unit_price(priority_fee, &i.instructions, rpc_client, chain_id_str.as_str()).await?)
755755
} else {
756756
None
757757
};
@@ -761,7 +761,7 @@ impl SolanaExecutorJobHandler {
761761
let memo_data = format!("thirdweb-engine:{}", transaction_id);
762762
let memo_ix = build_memo(&spl_memo_interface::v3::id(), memo_data.as_bytes(), &[]);
763763

764-
let mut instructions_with_memo = instructions.clone();
764+
let mut instructions_with_memo = i.instructions.clone();
765765
let memo_data_base64 = base64::engine::general_purpose::STANDARD.encode(memo_data.as_bytes());
766766
instructions_with_memo.push(SolanaInstructionData {
767767
program_id: memo_ix.program_id,
@@ -771,9 +771,7 @@ impl SolanaExecutorJobHandler {
771771
});
772772

773773
let solana_tx = SolanaTransaction {
774-
input: engine_solana_core::transaction::SolanaTransactionInput::Instructions {
775-
instructions: instructions_with_memo,
776-
},
774+
input: engine_solana_core::transaction::SolanaTransactionInput::new_with_instructions(instructions_with_memo),
777775
compute_unit_limit: job_data.transaction.execution_options.compute_unit_limit,
778776
compute_unit_price,
779777
};

solana-core/src/transaction.rs

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,32 @@ use solana_sdk::{
1111

1212
/// Input for Solana transaction - either build from instructions or use pre-built
1313
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
14-
#[serde(rename_all = "camelCase", untagged)]
14+
#[serde(untagged)]
1515
pub enum SolanaTransactionInput {
1616
/// Build transaction from instructions
17-
Instructions {
18-
instructions: Vec<SolanaInstructionData>,
19-
},
17+
Instructions(SolanaTransactionInputInstructions),
2018
/// Use pre-built serialized VersionedTransaction (base64)
21-
Serialized {
22-
transaction: String,
23-
},
19+
Serialized(SolanaTransactionInputSerialized),
20+
}
21+
22+
impl SolanaTransactionInput {
23+
pub fn new_with_instructions(instructions: Vec<SolanaInstructionData>) -> Self {
24+
Self::Instructions(SolanaTransactionInputInstructions { instructions })
25+
}
26+
27+
pub fn new_with_serialized(transaction: String) -> Self {
28+
Self::Serialized(SolanaTransactionInputSerialized { transaction })
29+
}
30+
}
31+
32+
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
33+
pub struct SolanaTransactionInputInstructions {
34+
pub instructions: Vec<SolanaInstructionData>,
35+
}
36+
37+
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
38+
pub struct SolanaTransactionInputSerialized {
39+
pub transaction: String,
2440
}
2541

2642
/// Solana instruction data provided by the user
@@ -142,11 +158,11 @@ impl SolanaTransaction {
142158
recent_blockhash: solana_sdk::hash::Hash,
143159
) -> Result<VersionedTransaction, SolanaTransactionError> {
144160
match &self.input {
145-
SolanaTransactionInput::Instructions { instructions } => {
146-
self.build_from_instructions(instructions, payer, recent_blockhash)
161+
SolanaTransactionInput::Instructions(i) => {
162+
self.build_from_instructions(&i.instructions, payer, recent_blockhash)
147163
}
148-
SolanaTransactionInput::Serialized { transaction } => {
149-
self.deserialize_transaction(transaction, payer)
164+
SolanaTransactionInput::Serialized(t) => {
165+
self.deserialize_transaction(&t.transaction, payer)
150166
}
151167
}
152168
}
@@ -175,15 +191,12 @@ impl SolanaTransaction {
175191
inst_list.push(inst.to_instruction()?);
176192
}
177193

178-
let message = v0::Message::try_compile(
179-
&payer,
180-
&inst_list,
181-
&[],
182-
recent_blockhash,
183-
)
184-
.map_err(|e| SolanaTransactionError::MessageCompilationFailed {
185-
error: e.to_string(),
186-
})?;
194+
let message =
195+
v0::Message::try_compile(&payer, &inst_list, &[], recent_blockhash).map_err(|e| {
196+
SolanaTransactionError::MessageCompilationFailed {
197+
error: e.to_string(),
198+
}
199+
})?;
187200

188201
let message = VersionedMessage::V0(message);
189202
let num_signatures = message.header().num_required_signatures as usize;
@@ -203,17 +216,19 @@ impl SolanaTransaction {
203216
tx_base64: &str,
204217
expected_payer: Pubkey,
205218
) -> Result<VersionedTransaction, SolanaTransactionError> {
206-
let tx_bytes = Base64Engine.decode(tx_base64)
207-
.map_err(|e| SolanaTransactionError::DeserializationFailed {
219+
let tx_bytes = Base64Engine.decode(tx_base64).map_err(|e| {
220+
SolanaTransactionError::DeserializationFailed {
208221
error: format!("Invalid base64: {}", e),
209-
})?;
222+
}
223+
})?;
210224

211225
// Deserialize from binary wire format using bincode
212226
let (transaction, _): (VersionedTransaction, _) =
213-
bincode::serde::decode_from_slice(&tx_bytes, bincode::config::standard())
214-
.map_err(|e| SolanaTransactionError::DeserializationFailed {
227+
bincode::serde::decode_from_slice(&tx_bytes, bincode::config::standard()).map_err(
228+
|e| SolanaTransactionError::DeserializationFailed {
215229
error: format!("Failed to deserialize VersionedTransaction: {}", e),
216-
})?;
230+
},
231+
)?;
217232

218233
// Verify fee payer
219234
let fee_payer = transaction.message.static_account_keys()[0];
@@ -245,10 +260,10 @@ pub enum SolanaTransactionError {
245260

246261
#[error("Invalid blockhash: {error}")]
247262
InvalidBlockhash { error: String },
248-
263+
249264
#[error("Failed to deserialize transaction: {error}")]
250265
DeserializationFailed { error: String },
251-
266+
252267
#[error("Fee payer mismatch: expected {expected}, got {got}")]
253268
FeePayerMismatch { expected: String, got: String },
254269
}

0 commit comments

Comments
 (0)