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
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: 5 additions & 1 deletion bindings/core/src/method/wallet.rs
Original file line number Diff line number Diff line change
@@ -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 },
7 changes: 5 additions & 2 deletions bindings/core/src/method_handler/wallet.rs
Original file line number Diff line number Diff line change
@@ -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 } => {
6 changes: 6 additions & 0 deletions bindings/nodejs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions bindings/nodejs/lib/types/wallet/bridge/wallet.ts
Original file line number Diff line number Diff line change
@@ -153,6 +153,7 @@ export type __PrepareClaimOutputsMethod__ = {
name: 'prepareClaimOutputs';
data: {
outputIdsToClaim: OutputId[];
options?: TransactionOptions;
};
};

7 changes: 6 additions & 1 deletion bindings/nodejs/lib/wallet/wallet.ts
Original file line number Diff line number Diff line change
@@ -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();
}

/**
@@ -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(
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",
9 changes: 5 additions & 4 deletions bindings/python/iota_sdk/wallet/wallet.py
Original file line number Diff line number Diff line change
@@ -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
}
)))

4 changes: 2 additions & 2 deletions cli/src/wallet_cli/mod.rs
Original file line number Diff line number Diff line change
@@ -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{:?}",
@@ -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,
Original file line number Diff line number Diff line change
@@ -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
37 changes: 25 additions & 12 deletions sdk/src/wallet/operations/output_claiming.rs
Original file line number Diff line number Diff line change
@@ -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?;

@@ -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,
@@ -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();
@@ -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
2 changes: 1 addition & 1 deletion sdk/src/wallet/operations/transaction/prepare_output.rs
Original file line number Diff line number Diff line change
@@ -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> {
22 changes: 14 additions & 8 deletions sdk/tests/wallet/claim_outputs.rs
Original file line number Diff line number Diff line change
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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,
Loading