Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tx options param to prepare_claim_outputs() #2237

Merged
merged 5 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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)]
DaughterOfMars marked this conversation as resolved.
Show resolved Hide resolved
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-04-DD

### 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
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