Skip to content

Commit

Permalink
Allow conversion of object and objectid into unesolved::input, to mak…
Browse files Browse the repository at this point in the history
…e it nicer to pass in gas objects / objects as inputs
  • Loading branch information
stefan-mysten committed Nov 13, 2024
1 parent df96be5 commit 4c9c864
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 21 deletions.
2 changes: 1 addition & 1 deletion crates/sui-transaction-builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ description = "Transaction API for the Rust SDK for the Sui Blockchain"

[dependencies]
base64ct = "1.6"
sui-types = { package = "sui-sdk-types", path = "../sui-sdk-types", features = ["serde"] }
sui-types = { package = "sui-sdk-types", path = "../sui-sdk-types", features = ["serde", "hash"] }
sui-graphql-client = { package = "sui-graphql-client", path = "../sui-graphql-client" }
serde = { version = "1.0", features = ["derive"] }
bcs = "0.1.6"
Expand Down
62 changes: 42 additions & 20 deletions crates/sui-transaction-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-License-Identifier: Apache-2.0

mod error;
use base64ct::Encoding;

use error::ConversionError;
use error::Error;
Expand All @@ -19,6 +18,7 @@ use sui_types::types::Input;
use sui_types::types::MakeMoveVector;
use sui_types::types::MergeCoins;
use sui_types::types::MoveCall;
use sui_types::types::Object;
use sui_types::types::ObjectId;
use sui_types::types::ObjectReference;
use sui_types::types::Publish;
Expand All @@ -29,6 +29,7 @@ use sui_types::types::TransferObjects;
use sui_types::types::TypeTag;
use sui_types::types::Upgrade;

use base64ct::Encoding;
use serde::Serialize;

/// A builder for creating transactions. Use [`resolve`] to finalize the transaction data.
Expand Down Expand Up @@ -74,6 +75,14 @@ pub struct Function {
type_args: Vec<TypeTag>,
}

/// A trait to convert a type into an [`unresolved::Input`]. This is mostly used for gas objects,
/// to pass them either as literals, as an object id, as a reference to an object, or as a
/// [`unresolved::Input`] object.
pub trait IntoInput {
/// Convert the type into an [`unresolved::Input`].
fn into_input(self) -> unresolved::Input;
}

/// A transaction builder to build transactions.
impl TransactionBuilder {
/// Create a new transaction builder and initialize its elements to default.
Expand Down Expand Up @@ -101,8 +110,8 @@ impl TransactionBuilder {

/// Set the gas objects that will be used to pay for the transaction. Most commonly the gas
/// object can be either passed as literals and the builder will resolve it to the actual
/// object, or can created using one of the constructors of the [`unresolved::Input`] enum,
/// e.g., [`unresolved::Input::by_id`].
/// object, as a reference to an [`Object`], or can created using one of the constructors of the
/// [`unresolved::Input`] enum, e.g., [`unresolved::Input::by_id`].
///
/// Examples
/// ```rust,ignore
Expand All @@ -114,12 +123,13 @@ impl TransactionBuilder {
/// let gas_obj =
/// unresolved::Input::by_id("0x19406ea4d9609cd9422b85e6bf2486908f790b778c757aff805241f3f609f9b4".parse().unwrap());
/// tx.add_gas(vec![gas_obj]);
// Define a trait in your crate
pub fn add_gas<O, I>(&mut self, gas: I)
where
O: Into<unresolved::Input>,
O: IntoInput,
I: IntoIterator<Item = O>,
{
self.gas.extend(gas.into_iter().map(Into::into));
self.gas.extend(gas.into_iter().map(IntoInput::into_input));
}

/// Set the gas budget for the transaction.
Expand Down Expand Up @@ -416,6 +426,28 @@ impl<'a, T: Serialize> From<Serialized<'a, T>> for unresolved::Input {
}
}

impl IntoInput for unresolved::Input {
/// Pass the input as is.
fn into_input(self) -> unresolved::Input {
self
}
}

impl IntoInput for Object {
/// Convert the [`Object`] type into an [`unresolved::Input`] of kind immutable.
fn into_input(self) -> unresolved::Input {
unresolved::Input::immutable(self.object_id(), self.version(), self.digest())
}
}

impl IntoInput for ObjectId {
/// Convert the [`ObjectId`] type into an [`unresolved::Input`] with only object id as partial
/// information.
fn into_input(self) -> unresolved::Input {
unresolved::Input::by_id(self.clone())
}
}

/// Convert from an [`unresolved::Input`] to a [`unresolved::ObjectReference`]. This is used to
/// convert gas objects into unresolved object references.
fn try_from_gas_unresolved_input_to_unresolved_obj_ref(
Expand Down Expand Up @@ -571,16 +603,8 @@ mod tests {
.sent;
println!("Coins: {:?}", coins);
let gas = coins.last().unwrap().id;
let gas_obj = client
.object(*gas.as_address(), None)
.await
.unwrap()
.unwrap();
tx.add_gas(vec![unresolved::Input::immutable(
gas_obj.object_id(),
gas_obj.version(),
gas_obj.digest(),
)]);
let gas_obj = client.object(gas.into(), None).await.unwrap().unwrap();
tx.add_gas(vec![gas_obj]);
tx.add_gas_budget(500000000);
tx.add_gas_price(1000);
tx.set_sender(address);
Expand Down Expand Up @@ -1033,13 +1057,11 @@ mod tests {
vec![upgrade_cap.unwrap(), upgrade_receipt],
);

// we should be able to pass gas by obj id, but we need the resolution api for that so for
// now we need to pass the object or a reference.
let gas = coins.last().unwrap().id;
let gas_obj = client.object(gas.into(), None).await.unwrap().unwrap();
tx.add_gas(vec![unresolved::Input::immutable(
gas_obj.object_id(),
gas_obj.version(),
gas_obj.digest(),
)]);
tx.add_gas(vec![gas_obj]);
tx.add_gas_budget(500000000);
tx.add_gas_price(1000);
tx.set_sender(address);
Expand Down

0 comments on commit 4c9c864

Please sign in to comment.