Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions bindings/go/examples/tx_command_results/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ func main() {

builder.SplitCoins(
iota_sdk.PtbArgumentGas(),
// Use the named results of previous commands to use as arguments
// Use the assigned results of previous commands to use as arguments
[]*iota_sdk.PtbArgument{iota_sdk.PtbArgumentRes("res0"), iota_sdk.PtbArgumentRes("res1")},
// For nested results, a tuple or vec can be used to name them
// For nested results, a tuple or vec can be used to assign them
[]string{"coin0", "coin1"},
)

// Use named results as arguments
// Use assigned results as arguments
builder.TransferObjects(sender, []*iota_sdk.PtbArgument{iota_sdk.PtbArgumentRes("coin0"), iota_sdk.PtbArgumentRes("coin1")})

txn, err := builder.Finish()
Expand Down
6 changes: 3 additions & 3 deletions bindings/kotlin/examples/TxCommandResults.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ fun main() = runBlocking {

builder.splitCoins(
PtbArgument.gas(),
// Use the named results of previous commands to use as arguments
// Use the assigned results of previous commands to use as arguments
listOf(PtbArgument.res("res0"), PtbArgument.res("res1")),
// For nested results, a tuple or vec can be used to name them
// For nested results, a tuple or vec can be used to assign them
listOf("coin0", "coin1"),
)

// Use named results as arguments
// Use assigned results as arguments
builder.transferObjects(sender, listOf(PtbArgument.res("coin0"), PtbArgument.res("coin1")))

val txn = builder.finish()
Expand Down
6 changes: 3 additions & 3 deletions bindings/python/examples/tx_command_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ async def main():

builder.split_coins(
PtbArgument.gas(),
# Use the named results of previous commands as arguments
# Use the assigned results of previous commands as arguments
[PtbArgument.res("res0"),
PtbArgument.res("res1")],
# For nested results, a tuple or vec can be used to name them
# For nested results, a tuple or vec can be used to assign them
["coin0", "coin1"],
)

# Use named results as arguments
# Use assigned results as arguments
builder.transfer_objects(
sender, [PtbArgument.res("coin0"),
PtbArgument.res("coin1")])
Expand Down
2 changes: 1 addition & 1 deletion crates/iota-sdk-ffi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ The following methods are available:

#### Commands

Each command method adds one or more commands to the final transaction. Some commands have optional follow-up methods. Most command results can be named, which allows them to be used later in the transaction via the `PTBArgument::Res` variant. When a single name is provided, the result will be named, and when a list of names is provided, the names will be used for the individual nested results.
Each command method adds one or more commands to the final transaction. Some commands have optional follow-up methods. Most command results can be assigned a name, which allows them to be used later in the transaction via the `PTBArgument::Res` variant. When a single name is provided, the result will be assigned, and when a list of names is provided, the names will be used for the individual nested results.

- `move_call`: Call a move function.
- `send_iota`: Send IOTA coins to a recipient address.
Expand Down
8 changes: 4 additions & 4 deletions crates/iota-sdk-ffi/src/transaction_builder/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl TransactionBuilder {
.move_call(**package, &module.as_str(), &function.as_str())
.arguments(arguments)
.type_tags(type_args.into_iter().map(|v| v.0.clone()))
.name(names);
.assign(names);
});
self
}
Expand Down Expand Up @@ -218,7 +218,7 @@ impl TransactionBuilder {
names: Vec<String>,
) -> Arc<Self> {
self.write(|builder| {
builder.split_coins(coin, amounts).name(names);
builder.split_coins(coin, amounts).assign(names);
});
self
}
Expand Down Expand Up @@ -257,7 +257,7 @@ impl TransactionBuilder {
.map(|e| builder.apply_argument(e.as_ref()))
.collect(),
});
builder.named_command(cmd, name);
builder.assigned_command(cmd, name);
});
self
}
Expand Down Expand Up @@ -310,7 +310,7 @@ impl TransactionBuilder {
self.write(|builder| {
builder
.upgrade(**package_id, package_data.0.clone(), upgrade_ticket)
.name(name);
.assign(name);
});
self
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl ClientTransactionBuilder {
.move_call(**package, &module.as_str(), &function.as_str())
.arguments(arguments)
.type_tags(type_args.into_iter().map(|v| v.0.clone()))
.name(names);
.assign(names);
});
self
}
Expand Down Expand Up @@ -206,7 +206,7 @@ impl ClientTransactionBuilder {
names: Vec<String>,
) -> Arc<Self> {
self.write(|builder| {
builder.split_coins(coin, amounts).name(names);
builder.split_coins(coin, amounts).assign(names);
});
self
}
Expand Down Expand Up @@ -245,7 +245,7 @@ impl ClientTransactionBuilder {
.map(|e| builder.apply_argument(e.as_ref()))
.collect(),
});
builder.named_command(cmd, name);
builder.assigned_command(cmd, name);
});
self
}
Expand Down Expand Up @@ -298,7 +298,7 @@ impl ClientTransactionBuilder {
self.write(|builder| {
builder
.upgrade(**package_id, package_data.0.clone(), upgrade_ticket)
.name(name);
.assign(name);
});
self
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use crate::{builder::TransactionBuildData, unresolved::Argument};

/// A trait that defines an assigned result, either a string or nothing.
pub trait AssignedResult {
/// Get the assigned result argument.
fn assigned_result(&self, ptb: &mut TransactionBuildData) -> Argument {
Argument::Result((ptb.commands.len() - 1) as _)
}

/// Push the assigned result to the PTB.
fn push_assigned_result(self, arg: Argument, ptb: &mut TransactionBuildData);
}

impl AssignedResult for () {
fn push_assigned_result(self, _: Argument, _: &mut TransactionBuildData) {}
}

impl AssignedResult for &str {
fn push_assigned_result(self, arg: Argument, ptb: &mut TransactionBuildData) {
ptb.assigned_results.insert(self.to_owned(), arg);
}
}

impl AssignedResult for String {
fn push_assigned_result(self, arg: Argument, ptb: &mut TransactionBuildData) {
ptb.assigned_results.insert(self.to_owned(), arg);
}
}

impl<T: AssignedResult> AssignedResult for Option<T> {
fn push_assigned_result(self, arg: Argument, ptb: &mut TransactionBuildData) {
if let Some(s) = self {
s.push_assigned_result(arg, ptb)
}
}
}

/// A trait that allows tuples to be used to bind nested assigned results.
pub trait AssignedResults {
/// Push the assigned results to the PTB.
fn push_assigned_results(self, ptb: &mut TransactionBuildData);
}

impl<T: AssignedResult> AssignedResults for T {
fn push_assigned_results(self, ptb: &mut TransactionBuildData) {
let arg = Argument::Result((ptb.commands.len() - 1) as _);
self.push_assigned_result(arg, ptb)
}
}

impl<T: AssignedResult> AssignedResults for Vec<T> {
fn push_assigned_results(self, ptb: &mut TransactionBuildData) {
for (i, v) in self.into_iter().enumerate() {
let arg = Argument::NestedResult((ptb.commands.len() - 1) as _, i as _);
v.push_assigned_result(arg, ptb);
}
}
}

macro_rules! impl_assigned_result_tuple {
($(($n:tt, $T:ident)),*) => {
impl<$($T),+> AssignedResults for ($($T),+)
where $($T: AssignedResult),+
{
fn push_assigned_results(self, ptb: &mut TransactionBuildData) {
$(
let arg = Argument::NestedResult((ptb.commands.len() - 1) as _, $n);
self.$n.push_assigned_result(arg, ptb);
)+
}
}
};
}

variadics_please::all_tuples_enumerated!(impl_assigned_result_tuple, 2, 10, T);
52 changes: 26 additions & 26 deletions crates/iota-sdk-transaction-builder/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ use serde::Serialize;
use crate::{
ClientMethods, PTBArgument, SharedMut, WaitForTx,
builder::{
assigned_results::{AssignedResult, AssignedResults},
gas_station::GasStationData,
named_results::{NamedResult, NamedResults},
ptb_arguments::PTBArgumentList,
signer::TransactionSigner,
},
Expand All @@ -34,9 +34,9 @@ use crate::{
},
};

mod assigned_results;
pub(crate) mod client_methods;
pub(crate) mod gas_station;
mod named_results;
/// Argument types for PTBs
pub mod ptb_arguments;
pub mod signer;
Expand Down Expand Up @@ -75,7 +75,7 @@ pub struct TransactionBuildData {
/// expiration.
expiration: TransactionExpiration,
/// The map of user-defined names that map to a particular command's result.
named_results: HashMap<String, Argument>,
assigned_results: HashMap<String, Argument>,
/// The data used for gas station sponsorship.
gas_station_data: Option<GasStationData>,
}
Expand Down Expand Up @@ -174,14 +174,14 @@ impl TransactionBuildData {
}

/// Manually set a command with an optional name
pub fn named_command(&mut self, cmd: Command, name: impl NamedResults) {
pub fn assigned_command(&mut self, cmd: Command, name: impl AssignedResults) {
self.command(cmd);
name.push_named_results(self);
name.push_assigned_results(self);
}

/// Get the value for the given string in the named results map
pub fn get_named_result(&self, name: &str) -> Option<Argument> {
self.named_results.get(name).copied()
/// Get the value for the given string in the assigned results map
pub fn get_assigned_result(&self, name: &str) -> Option<Argument> {
self.assigned_results.get(name).copied()
}
}

Expand All @@ -197,7 +197,7 @@ impl TransactionBuilder {
sender,
sponsor: Default::default(),
expiration: Default::default(),
named_results: Default::default(),
assigned_results: Default::default(),
gas_station_data: Default::default(),
},
client: (),
Expand Down Expand Up @@ -303,13 +303,13 @@ impl<C, L> TransactionBuilder<C, L> {
}

/// Manually set a command with an optional name
pub fn named_command(&mut self, cmd: Command, name: impl NamedResults) {
self.data.named_command(cmd, name);
pub fn assigned_command(&mut self, cmd: Command, name: impl AssignedResults) {
self.data.assigned_command(cmd, name);
}

/// Get the value for the given string in the named results map
pub fn get_named_result(&self, name: &str) -> Option<Argument> {
self.data.get_named_result(name)
/// Get the value for the given string in the assigned results map
pub fn get_assigned_result(&self, name: &str) -> Option<Argument> {
self.data.get_assigned_result(name)
}

/// Begin building a move call.
Expand Down Expand Up @@ -356,7 +356,7 @@ impl<C, L> TransactionBuilder<C, L> {
/// # )?,
/// # [1000u64],
/// # )
/// # .name(("coin"));
/// # .assign(("coin"));
///
/// builder.transfer_objects(
/// Address::from_str("0x0000a4984bd495d4346fa208ddff4f5d5e5ad48c21dec631ddebc99809f16900")?,
Expand Down Expand Up @@ -591,7 +591,7 @@ impl<C, L> TransactionBuilder<C, L> {
/// let mut builder = TransactionBuilder::new(sender).with_client(client);
/// builder
/// .split_coins(coin, [1000u64, 2000, 3000])
/// .name(("coin1", "coin2", "coin3"))
/// .assign(("coin1", "coin2", "coin3"))
/// .transfer_objects(sender, (res("coin1"), res("coin2"), res("coin3")));
/// let txn = builder.finish().await?;
/// # Ok(())
Expand Down Expand Up @@ -740,7 +740,7 @@ impl<C, L> TransactionBuilder<C, L> {
///
/// builder
/// .make_move_vec([address1, address2])
/// .name("addresses")
/// .assign("addresses")
/// .move_call(Address::FRAMEWORK, "vec_map", "from_keys_values")
/// .generics::<(Address, u64)>()
/// .arguments((res("addresses"), [10000000u64, 20000000u64]));
Expand Down Expand Up @@ -1239,40 +1239,40 @@ impl<C> TransactionBuilder<C, MoveCall> {
impl TransactionBuilder<(), Publish> {
/// Get the package ID from the UpgradeCap so that it can be used for future
/// commands.
pub fn package_id(&mut self, name: impl NamedResult) -> &mut TransactionBuilder {
pub fn package_id(&mut self, name: impl AssignedResult) -> &mut TransactionBuilder {
let cap = self.arg();
self.move_call(Address::FRAMEWORK, "package", "upgrade_package")
.arguments([cap])
.name(name)
.assign(name)
.reset()
}
}

impl<C: ClientMethods> TransactionBuilder<C, Publish> {
/// Get the package ID from the UpgradeCap so that it can be used for future
/// commands.
pub fn package_id(&mut self, name: impl NamedResult) -> &mut TransactionBuilder<C> {
pub fn package_id(&mut self, name: impl AssignedResult) -> &mut TransactionBuilder<C> {
let cap = self.arg();
self.move_call(Address::FRAMEWORK, "package", "upgrade_package")
.arguments([cap])
.name(name)
.assign(name)
.reset()
}
}

impl<C> TransactionBuilder<C, Publish> {
/// Finish the publish call and return the UpgradeCap.
pub fn upgrade_cap(&mut self, name: impl NamedResult) -> &mut TransactionBuilder<C> {
name.push_named_results(&mut self.data);
pub fn upgrade_cap(&mut self, name: impl AssignedResult) -> &mut TransactionBuilder<C> {
name.push_assigned_results(&mut self.data);

self.reset()
}
}

impl<C, L: Into<Command>> TransactionBuilder<C, L> {
/// Set the name for the last command.
pub fn name(&mut self, name: impl NamedResults) -> &mut Self {
name.push_named_results(&mut self.data);
/// Assign a name to the last command's result.
pub fn assign(&mut self, name: impl AssignedResults) -> &mut Self {
name.push_assigned_results(&mut self.data);
self
}

Expand Down
Loading