Skip to content

Commit

Permalink
Adds ability to serialise Raw Sui Swap transactions (#4247)
Browse files Browse the repository at this point in the history
* Adds ability to serialise Raw Sui Swap transactions

* Adds sui compile test for raw json

* Addresses review comments

* Use serde::as_string instead of serde_with crate

* Use specified values for gas budget and gas price if provided

* Addresses review comment
  • Loading branch information
gupnik authored Feb 4, 2025
1 parent df1843f commit b4bed73
Show file tree
Hide file tree
Showing 14 changed files with 1,917 additions and 21 deletions.
35 changes: 20 additions & 15 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion rust/chains/tw_sui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ edition = "2021"
indexmap = "2.0"
move-core-types = { git = "https://github.com/move-language/move", rev = "ea70797099baea64f05194a918cebd69ed02b285", features = ["address32"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_repr = "0.1"
tw_coin_entry = { path = "../../tw_coin_entry" }
tw_encoding = { path = "../../tw_encoding" }
tw_hash = { path = "../../tw_hash" }
tw_keypair = { path = "../../tw_keypair" }
tw_memory = { path = "../../tw_memory" }
tw_misc = { path = "../../tw_misc" }
tw_misc = { path = "../../tw_misc", features = ["serde"] }
tw_proto = { path = "../../tw_proto" }
9 changes: 9 additions & 0 deletions rust/chains/tw_sui/src/modules/tx_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ impl<'a> TWTransactionBuilder<'a> {
TransactionType::transfer_object(ref transfer_obj) => {
self.transfer_object_from_proto(transfer_obj)
},
TransactionType::raw_json(ref raw_json) => self.raw_json_from_proto(raw_json),
TransactionType::None => SigningError::err(SigningErrorType::Error_invalid_params),
}?;
Ok(TWTransaction::Transaction(tx_data))
Expand Down Expand Up @@ -182,6 +183,14 @@ impl<'a> TWTransactionBuilder<'a> {
)
}

fn raw_json_from_proto(&self, raw_json: &str) -> SigningResult<TransactionData> {
TransactionBuilder::raw_json(
raw_json,
self.input.gas_budget,
self.input.reference_gas_price,
)
}

fn signer_address(&self) -> SigningResult<SuiAddress> {
if self.input.private_key.is_empty() {
SuiAddress::from_str(&self.input.signer)
Expand Down
1 change: 1 addition & 0 deletions rust/chains/tw_sui/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

pub mod command;
pub mod programmable_transaction;
pub mod raw_types;
pub mod sui_types;
pub mod transaction_builder;
pub mod transaction_data;
133 changes: 133 additions & 0 deletions rust/chains/tw_sui/src/transaction/raw_types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
use move_core_types::language_storage::TypeTag;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use tw_coin_entry::error::prelude::SigningError;
use tw_memory::Data;
use tw_misc::serde::as_string;

use crate::address::SuiAddress;

use super::{
command::Argument,
sui_types::{ObjectArg, ObjectID, SequenceNumber},
};

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PaymentConfig {
pub object_id: String,
#[serde(with = "as_string")]
pub version: u64,
pub digest: String,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct GasConfig {
#[serde(with = "as_string")]
pub budget: u64,
#[serde(with = "as_string")]
pub price: u64,
pub payment: Vec<PaymentConfig>,
}

#[derive(Debug, Deserialize, Serialize)]
pub enum InputObjectArg {
#[serde(rename_all = "camelCase")]
Shared {
mutable: bool,
#[serde(with = "as_string")]
initial_shared_version: u64,
object_id: String,
},
}

impl TryFrom<InputObjectArg> for ObjectArg {
type Error = SigningError;

fn try_from(arg: InputObjectArg) -> Result<Self, Self::Error> {
match arg {
InputObjectArg::Shared {
mutable,
initial_shared_version,
object_id,
} => Ok(ObjectArg::SharedObject {
id: ObjectID::from_str(&object_id)?,
initial_shared_version: SequenceNumber(initial_shared_version),
mutable,
}),
}
}
}

#[derive(Debug, Deserialize, Serialize)]
pub enum InputArg {
Pure(Data),
Object(InputObjectArg),
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Input {
pub kind: String,
pub index: u16,
#[serde(rename = "type")]
pub input_type: String,
pub value: InputArg,
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(tag = "kind")]
pub enum TransactionArg {
GasCoin,
Input { index: u16 },
Result { index: u16 },
}

impl From<TransactionArg> for Argument {
fn from(arg: TransactionArg) -> Self {
match arg {
TransactionArg::GasCoin => Argument::GasCoin,
TransactionArg::Input { index } => Argument::Input(index),
TransactionArg::Result { index } => Argument::Result(index),
}
}
}

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct TypeTagWrapper(#[serde(with = "as_string")] TypeTag);

impl From<TypeTagWrapper> for TypeTag {
fn from(value: TypeTagWrapper) -> Self {
value.0
}
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(tag = "kind")]
pub enum Transaction {
SplitCoins {
coin: TransactionArg,
amounts: Vec<TransactionArg>,
},
#[serde(rename_all = "camelCase")]
MoveCall {
target: String,
type_arguments: Vec<TypeTagWrapper>,
arguments: Vec<TransactionArg>,
},
TransferObjects {
objects: Vec<TransactionArg>,
address: TransactionArg,
},
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RawTransaction {
pub version: u8,
pub sender: SuiAddress,
pub expiration: Option<u64>,
pub gas_config: GasConfig,
pub inputs: Vec<Input>,
pub transactions: Vec<Transaction>,
}
Loading

0 comments on commit b4bed73

Please sign in to comment.