Skip to content

Commit

Permalink
Add tx options param to prepare_claim_outputs() (#2237)
Browse files Browse the repository at this point in the history
* Add tx options param to prepare_claim_outputs()

* Add new param

* Bump version and set release data
  • Loading branch information
Thoralf-M authored May 2, 2024
1 parent 3e44c80 commit 6696bfd
Show file tree
Hide file tree
Showing 12 changed files with 72 additions and 33 deletions.
6 changes: 5 additions & 1 deletion bindings/core/src/method/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,11 @@ pub enum WalletMethod {
/// Claim outputs.
/// Expected response: [`PreparedTransaction`](crate::Response::PreparedTransaction)
#[serde(rename_all = "camelCase")]
PrepareClaimOutputs { output_ids_to_claim: Vec<OutputId> },
PrepareClaimOutputs {
output_ids_to_claim: Vec<OutputId>,
#[serde(default)]
options: Option<TransactionOptions>,
},
/// Consolidate outputs.
/// Expected response: [`PreparedTransaction`](crate::Response::PreparedTransaction)
PrepareConsolidateOutputs { params: ConsolidationParams },
Expand Down
7 changes: 5 additions & 2 deletions bindings/core/src/method_handler/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,11 @@ pub(crate) async fn call_wallet_method_internal(
let data = wallet.prepare_burn(burn, options).await?;
Response::PreparedTransaction(data)
}
WalletMethod::PrepareClaimOutputs { output_ids_to_claim } => {
let data = wallet.prepare_claim_outputs(output_ids_to_claim).await?;
WalletMethod::PrepareClaimOutputs {
output_ids_to_claim,
options,
} => {
let data = wallet.prepare_claim_outputs(output_ids_to_claim, options).await?;
Response::PreparedTransaction(data)
}
WalletMethod::PrepareConsolidateOutputs { params } => {
Expand Down
6 changes: 6 additions & 0 deletions bindings/nodejs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Security -->

## 2.0.0-alpha.9 - 2024-05-02

### Added

- `Wallet::prepareClaimOutputs()` optional transactionOptions parameter;

## 2.0.0-alpha.8 - 2024-04-22

### Fixed
Expand Down
1 change: 1 addition & 0 deletions bindings/nodejs/lib/types/wallet/bridge/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export type __PrepareClaimOutputsMethod__ = {
name: 'prepareClaimOutputs';
data: {
outputIdsToClaim: OutputId[];
options?: TransactionOptions;
};
};

Expand Down
7 changes: 6 additions & 1 deletion bindings/nodejs/lib/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,11 @@ export class Wallet {
*/
async claimOutputs(
outputIds: OutputId[],
transactionOptions?: TransactionOptions,
): Promise<TransactionWithMetadata> {
return (await this.prepareClaimOutputs(outputIds)).send();
return (
await this.prepareClaimOutputs(outputIds, transactionOptions)
).send();
}

/**
Expand All @@ -431,11 +434,13 @@ export class Wallet {
*/
async prepareClaimOutputs(
outputIds: OutputId[],
transactionOptions?: TransactionOptions,
): Promise<PreparedTransaction> {
const response = await this.methodHandler.callMethod({
name: 'prepareClaimOutputs',
data: {
outputIdsToClaim: outputIds,
options: transactionOptions,
},
});
const parsed = JSON.parse(
Expand Down
2 changes: 1 addition & 1 deletion bindings/nodejs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@iota/sdk",
"version": "2.0.0-alpha.8",
"version": "2.0.0-alpha.9",
"description": "Node.js binding to the IOTA SDK library",
"main": "out/index.js",
"types": "out/index.d.ts",
Expand Down
9 changes: 5 additions & 4 deletions bindings/python/iota_sdk/wallet/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,18 +286,19 @@ def prepare_burn_nft(self,
return PreparedTransaction(self, prepared)

def claim_outputs(
self, output_ids_to_claim: List[OutputId]) -> TransactionWithMetadata:
self, output_ids_to_claim: List[OutputId], options: Optional[TransactionOptions] = None) -> TransactionWithMetadata:
"""Claim outputs.
"""
return self.prepare_claim_outputs(output_ids_to_claim).send()
return self.prepare_claim_outputs(output_ids_to_claim, options).send()

def prepare_claim_outputs(
self, output_ids_to_claim: List[OutputId]) -> PreparedTransaction:
self, output_ids_to_claim: List[OutputId], options: Optional[TransactionOptions] = None) -> PreparedTransaction:
"""Claim outputs.
"""
return PreparedTransaction(self, PreparedTransactionData.from_dict(self._call_method(
'prepareClaimOutputs', {
'outputIdsToClaim': output_ids_to_claim
'outputIdsToClaim': output_ids_to_claim,
'options': options
}
)))

Expand Down
4 changes: 2 additions & 2 deletions cli/src/wallet_cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ pub async fn claim_command(wallet: &Wallet, output_id: Option<OutputId>) -> Resu
if let Some(output_id) = output_id {
println_log_info!("Claiming output {output_id}");

let transaction = wallet.claim_outputs([output_id]).await?;
let transaction = wallet.claim_outputs([output_id], None).await?;

println_log_info!(
"Claiming transaction sent:\n{:?}\n{:?}",
Expand All @@ -587,7 +587,7 @@ pub async fn claim_command(wallet: &Wallet, output_id: Option<OutputId>) -> Resu
// Doing chunks of only 60, because we might need to create the double amount of outputs, because of potential
// storage deposit return unlock conditions and also consider the remainder output.
for output_ids_chunk in output_ids.chunks(60) {
let transaction = wallet.claim_outputs(output_ids_chunk.to_vec()).await?;
let transaction = wallet.claim_outputs(output_ids_chunk.to_vec(), None).await?;
println_log_info!(
"Claiming transaction sent:\n{:?}\n{:?}",
transaction.transaction_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("{}", output_id);
}

let transaction = wallet.claim_outputs(output_ids).await?;
let transaction = wallet.claim_outputs(output_ids, None).await?;
println!("Transaction sent: {}", transaction.transaction_id);

wallet
Expand Down
37 changes: 25 additions & 12 deletions sdk/src/wallet/operations/output_claiming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,12 +230,15 @@ where
pub async fn claim_outputs<I: IntoIterator<Item = OutputId> + Send>(
&self,
output_ids_to_claim: I,
transaction_options: impl Into<Option<TransactionOptions>> + Send,
) -> Result<TransactionWithMetadata, WalletError>
where
I::IntoIter: Send,
{
log::debug!("[OUTPUT_CLAIMING] claim_outputs");
let prepared_transaction = self.prepare_claim_outputs(output_ids_to_claim).await?;
let prepared_transaction = self
.prepare_claim_outputs(output_ids_to_claim, transaction_options)
.await?;

let claim_tx = self.sign_and_submit_transaction(prepared_transaction, None).await?;

Expand All @@ -251,6 +254,7 @@ where
pub async fn prepare_claim_outputs<I: IntoIterator<Item = OutputId> + Send>(
&self,
output_ids_to_claim: I,
transaction_options: impl Into<Option<TransactionOptions>> + Send,
) -> Result<PreparedTransactionData, WalletError>
where
I::IntoIter: Send,
Expand Down Expand Up @@ -278,7 +282,8 @@ where
));
}

let wallet_address = self.address().await;
let transaction_options = transaction_options.into();
let remainder_address = self.get_remainder_address(transaction_options.clone()).await?;
drop(wallet_ledger);

let mut nft_outputs_to_send = Vec::new();
Expand All @@ -301,31 +306,39 @@ where
// deposit for the remaining amount and possible native tokens
NftOutputBuilder::from(nft_output)
.with_nft_id(nft_output.nft_id_non_null(&output_data.output_id))
.with_unlock_conditions([AddressUnlockCondition::new(&wallet_address)])
.with_unlock_conditions([AddressUnlockCondition::new(remainder_address.clone())])
.finish_output()?
} else {
NftOutputBuilder::from(nft_output)
.with_minimum_amount(storage_score_params)
.with_nft_id(nft_output.nft_id_non_null(&output_data.output_id))
.with_unlock_conditions([AddressUnlockCondition::new(&wallet_address)])
.with_unlock_conditions([AddressUnlockCondition::new(remainder_address.clone())])
.finish_output()?
};

nft_outputs_to_send.push(nft_output);
}
}

let required_inputs = outputs_to_claim
.iter()
.map(|o| o.output_id)
// add additional inputs
.chain(possible_additional_inputs.iter().map(|o| o.output_id))
.collect();

self.prepare_send_outputs(
// We only need to provide the NFT outputs, ISA automatically creates basic outputs as remainder outputs
nft_outputs_to_send,
TransactionOptions {
required_inputs: outputs_to_claim
.iter()
.map(|o| o.output_id)
// add additional inputs
.chain(possible_additional_inputs.iter().map(|o| o.output_id))
.collect(),
..Default::default()
match transaction_options {
Some(mut tx_options) => {
tx_options.required_inputs = required_inputs;
tx_options
}
None => TransactionOptions {
required_inputs,
..Default::default()
},
},
)
.await
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/wallet/operations/transaction/prepare_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ impl<S: 'static + SecretManage> Wallet<S> {
}

// Get a remainder address based on transaction_options or use the first account address
async fn get_remainder_address(
pub(crate) async fn get_remainder_address(
&self,
transaction_options: impl Into<Option<TransactionOptions>> + Send,
) -> Result<Address, WalletError> {
Expand Down
22 changes: 14 additions & 8 deletions sdk/tests/wallet/claim_outputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ async fn claim_2_basic_micro_outputs() -> Result<(), Box<dyn std::error::Error>>
let base_coin_amount_before_claiming = balance.base_coin().available();

let tx = wallet_0
.claim_outputs(wallet_0.claimable_outputs(OutputsToClaim::MicroTransactions).await?)
.claim_outputs(
wallet_0.claimable_outputs(OutputsToClaim::MicroTransactions).await?,
None,
)
.await?;
wallet_0
.wait_for_transaction_acceptance(&tx.transaction_id, None, None)
Expand Down Expand Up @@ -113,7 +116,7 @@ async fn claim_1_of_2_basic_outputs() -> Result<(), Box<dyn std::error::Error>>
let base_coin_amount_before_claiming = balance.base_coin().available();

let tx = wallet_0
.claim_outputs(wallet_0.claimable_outputs(OutputsToClaim::Amount).await?)
.claim_outputs(wallet_0.claimable_outputs(OutputsToClaim::Amount).await?, None)
.await?;
wallet_0
.wait_for_transaction_acceptance(&tx.transaction_id, None, None)
Expand Down Expand Up @@ -193,7 +196,7 @@ async fn claim_2_basic_outputs_no_available_in_claim_account() -> Result<(), Box
let base_coin_amount_before_claiming = balance.base_coin().available();

let tx = wallet_1
.claim_outputs(wallet_1.claimable_outputs(OutputsToClaim::All).await?)
.claim_outputs(wallet_1.claimable_outputs(OutputsToClaim::All).await?, None)
.await?;
wallet_1
.wait_for_transaction_acceptance(&tx.transaction_id, None, None)
Expand Down Expand Up @@ -281,7 +284,7 @@ async fn claim_2_native_tokens() -> Result<(), Box<dyn std::error::Error>> {
assert_eq!(balance.potentially_locked_outputs().len(), 2);

let tx = wallet_0
.claim_outputs(wallet_0.claimable_outputs(OutputsToClaim::NativeTokens).await?)
.claim_outputs(wallet_0.claimable_outputs(OutputsToClaim::NativeTokens).await?, None)
.await?;
wallet_0
.wait_for_transaction_acceptance(&tx.transaction_id, None, None)
Expand Down Expand Up @@ -404,7 +407,7 @@ async fn claim_2_native_tokens_no_available_balance_in_claim_account() -> Result
assert_eq!(balance.potentially_locked_outputs().len(), 2);

let tx = wallet_1
.claim_outputs(wallet_1.claimable_outputs(OutputsToClaim::NativeTokens).await?)
.claim_outputs(wallet_1.claimable_outputs(OutputsToClaim::NativeTokens).await?, None)
.await?;
wallet_1
.wait_for_transaction_acceptance(&tx.transaction_id, None, None)
Expand Down Expand Up @@ -470,7 +473,7 @@ async fn claim_2_nft_outputs() -> Result<(), Box<dyn std::error::Error>> {
assert_eq!(balance.potentially_locked_outputs().len(), 2);

let tx = wallet_0
.claim_outputs(wallet_0.claimable_outputs(OutputsToClaim::Nfts).await?)
.claim_outputs(wallet_0.claimable_outputs(OutputsToClaim::Nfts).await?, None)
.await?;
wallet_0
.wait_for_transaction_acceptance(&tx.transaction_id, None, None)
Expand Down Expand Up @@ -547,7 +550,7 @@ async fn claim_2_nft_outputs_no_available_in_claim_account() -> Result<(), Box<d
assert_eq!(balance.potentially_locked_outputs().len(), 2);

let tx = wallet_1
.claim_outputs(wallet_1.claimable_outputs(OutputsToClaim::Nfts).await?)
.claim_outputs(wallet_1.claimable_outputs(OutputsToClaim::Nfts).await?, None)
.await?;
wallet_1
.wait_for_transaction_acceptance(&tx.transaction_id, None, None)
Expand Down Expand Up @@ -612,7 +615,10 @@ async fn claim_basic_micro_output_error() -> Result<(), Box<dyn std::error::Erro
assert_eq!(balance.potentially_locked_outputs().len(), 1);

let result = wallet_1
.claim_outputs(wallet_1.claimable_outputs(OutputsToClaim::MicroTransactions).await?)
.claim_outputs(
wallet_1.claimable_outputs(OutputsToClaim::MicroTransactions).await?,
None,
)
.await;
assert!(matches!(
result,
Expand Down

0 comments on commit 6696bfd

Please sign in to comment.