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 how to consolidate to documentation #676

Merged
Merged
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
50 changes: 0 additions & 50 deletions bindings/nodejs/examples/client/consolidation.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright 2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { CommonOutput, Utils, Wallet, initLogger } from '@iota/sdk';

// This example uses secrets in environment variables for simplicity which should not be done in production.
require('dotenv').config({ path: '.env' });

// Run with command:
// yarn run-example ./how_tos/accounts_and_addresses/consolidate-outputs.ts

// In this example we will consolidate basic outputs from an account with only an AddressUnlockCondition by sending
// them to the same address again.
async function run() {
initLogger();
try {
if (!process.env.WALLET_DB_PATH) {
throw new Error(
'.env WALLET_DB_PATH is undefined, see .env.example',
);
}

if (!process.env.STRONGHOLD_PASSWORD) {
throw new Error(
'.env STRONGHOLD_PASSWORD is undefined, see .env.example',
);
}

if (!process.env.EXPLORER_URL) {
throw new Error('.env EXPLORER_URL is undefined, see .env.example');
}

const wallet = new Wallet({
storagePath: process.env.WALLET_DB_PATH,
});

const account = await wallet.getAccount('Alice');

// To create an address we need to unlock stronghold.
await wallet.setStrongholdPassword(process.env.STRONGHOLD_PASSWORD);

// Sync account to make sure account is updated with outputs from previous examples
account.sync();
console.log('Account synced');

// List unspent outputs before consolidation.
// The output we created with example `request_funds` and the basic output from `mint` have only one
// unlock condition and it is an `AddressUnlockCondition`, and so they are valid for consolidation. They have the
// same `AddressUnlockCondition`(the first address of the account), so they will be consolidated into one
// output.
const outputs = await account.unspentOutputs();
console.log('Outputs BEFORE consolidation:');

outputs.forEach(({ output, address }, i) => {
console.log(`OUTPUT #${i}`);
console.log(
'- address: %s\n- amount: %d\n- native tokens: %s',
Utils.hexToBech32(address.toString(), 'rms'),
output.getAmount(),
output instanceof CommonOutput ? output.getNativeTokens() : [],
);
});

console.log('Sending consolidation transaction...');

// Consolidate unspent outputs and print the consolidation transaction ID
// Set `force` to true to force the consolidation even though the `output_consolidation_threshold` isn't reached
const preparedTransaction = await account.prepareConsolidateOutputs(
true,
);
const transaction = await preparedTransaction.send();
console.log('Transaction sent: %s', transaction.transactionId);

// Wait for the consolidation transaction to get confirmed
const blockId = account.retryTransactionUntilIncluded(
transaction.transactionId,
);

console.log(
'Transaction included: %s/block/$s',
process.env.EXPLORER_URL,
blockId,
);

// Sync account
account.sync();
console.log('Account synced');

// Outputs after consolidation
console.log('Outputs AFTER consolidation:');
outputs.forEach(({ output, address }, i) => {
console.log(`OUTPUT #${i}`);
console.log(
'- address: %s\n- amount: %d\n- native tokens: %s',
Utils.hexToBech32(address.toString(), 'rms'),
output.getAmount(),
output instanceof CommonOutput
? output.getNativeTokens()
: undefined,
);
});
} catch (error) {
console.error('Error: ', error);
}
}

run().then(() => process.exit());
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from iota_sdk import Wallet, Utils
from dotenv import load_dotenv
import os

# In this example we will consolidate basic outputs from an account with only an AddressUnlockCondition by sending
# them to the same address again.

# This example uses secrets in environment variables for simplicity which should not be done in production.
load_dotenv()

if 'STRONGHOLD_PASSWORD' not in os.environ:
raise Exception('.env STRONGHOLD_PASSWORD is undefined, see .env.example')

wallet = Wallet('./alice-database')
wallet.set_stronghold_password(os.environ['STRONGHOLD_PASSWORD'])

account = wallet.get_account('Alice')

# Sync account to make sure account is updated with outputs from previous examples
account.sync()
print('Account synced')

# List unspent outputs before consolidation.
# The output we created with example `request_funds` and the basic output from `mint` have only one
# unlock condition and it is an `AddressUnlockCondition`, and so they are valid for consolidation. They have the
# same `AddressUnlockCondition`(the first address of the account), so they will be consolidated into one
# output.
outputs = account.unspent_outputs()
print('Outputs BEFORE consolidation:')

for i, output_data in enumerate(outputs):
print(f'OUTPUT #{i}')
print(
'- address: {}\n- amount: {}\n- native tokens: {}'.format(
Utils.hex_to_bech32(output_data['address']['pubKeyHash'], 'rms'),
output_data['output']['amount'],
output_data['output'].get('nativeTokens'),
)
)

print('Sending consolidation transaction...')

# Consolidate unspent outputs and print the consolidation transaction ID
# Set `force` to true to force the consolidation even though the `output_consolidation_threshold` isn't reached
transaction = account.prepare_consolidate_outputs(True, None).send()
print('Transaction sent: {}'.format(transaction['transactionId']))

# Wait for the consolidation transaction to get confirmed
block_id = account.retry_transaction_until_included(transaction['transactionId'])

print(
'Transaction included: {}/block/{}'.format(
os.environ['EXPLORER_URL'],
block_id
)
)

# Sync account
account.sync()
print('Account synced')

# Outputs after consolidation
outputs = account.unspent_outputs()
print('Outputs AFTER consolidation:')
for i, output_data in enumerate(outputs):
print(f'OUTPUT #{i}')
print(
'- address: {}\n- amount: {}\n- native tokens: {}'.format(
Utils.hex_to_bech32(output_data['address']['pubKeyHash'], 'rms'),
output_data['output']['amount'],
output_data['output'].get('nativeTokens'),
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
---
title: Consolidate Outputs
description: "How to consolidate outputs"
image: /img/logo/iota_mark_light.png
keywords:
- how to
- consolidate outputs
- nodejs
- python
- rust
---

import CodeBlock from "@theme/CodeBlock";
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import RustCode from "!!raw-loader!../../../../../sdk/examples/how_tos/accounts_and_addresses/consolidate_outputs.rs";
import NodejsCode from "!!raw-loader!../../../../../bindings/nodejs/examples/how_tos/accounts_and_addresses/consolidate-outputs.ts";
import PythonCode from "!!raw-loader!../../../../../bindings/python/examples/how_tos/accounts_and_addresses/consolidate_outputs.py";

This How-To will show you how to consolidate all outputs of an account.

## Code Example

<Tabs groupId="language">
<TabItem value="rust" label="Rust">
<CodeBlock className="language-rust">{RustCode}</CodeBlock>
</TabItem>
<TabItem value="nodejs" label="Nodejs">
<CodeBlock className="language-typescript">{NodejsCode}</CodeBlock>
</TabItem>
<TabItem value="python" label="Python">
<CodeBlock className="language-python">{PythonCode}</CodeBlock>
</TabItem>
</Tabs>

## Expected Output

<Tabs groupId="language">
<TabItem value="rust" label="Rust">

```plaintext
Account synced
Outputs BEFORE consolidation:
OUTPUT #0
- address: Bech32Address(rms1qr58umklvtqa4yxxwmskgzyhx2axfe5tfvunu5gauqu9sns7ava3u3kehwq)
- amount: 1000000
- native tokens: Some(NativeTokens([]))
OUTPUT #1
- address: Bech32Address(rms1qr58umklvtqa4yxxwmskgzyhx2axfe5tfvunu5gauqu9sns7ava3u3kehwq)
- amount: 998000000
- native tokens: Some(NativeTokens([]))
OUTPUT #2
- address: Bech32Address(rms1qz7652a7c7s9pcur04x7jlmmnyfq8mpxgahmz50tzqutmv6p72vus60pqsd)
- amount: 1000000
- native tokens: Some(NativeTokens([]))
Sending consolidation transaction...
Transaction sent: 0x245f75cb1b985304ceb022687e5c70ed6a936d667258015303e3f7f9ec285bbf
Transaction included: https://explorer.shimmer.network/testnet/block/0x5c06b0d2a16e22a54ca2f976a12d56515b58f8310c77de724b8d03dc4f862180
Account synced
Outputs AFTER consolidation:
OUTPUT #0
- address: Bech32Address(rms1qr58umklvtqa4yxxwmskgzyhx2axfe5tfvunu5gauqu9sns7ava3u3kehwq)
- amount: 1000000000
- native tokens: Some(NativeTokens([]))
```

</TabItem>
<TabItem value="nodejs" label="Nodejs">

```plaintext
Account synced
Outputs BEFORE consolidation:
OUTPUT #0
- address: rms1qr58umklvtqa4yxxwmskgzyhx2axfe5tfvunu5gauqu9sns7ava3u3kehwq
- amount: 1000000
- native tokens: undefined
OUTPUT #1
- address: rms1qr58umklvtqa4yxxwmskgzyhx2axfe5tfvunu5gauqu9sns7ava3u3kehwq
- amount: 998000000
- native tokens: undefined
OUTPUT #2
- address: rms1qz7652a7c7s9pcur04x7jlmmnyfq8mpxgahmz50tzqutmv6p72vus60pqsd
- amount: 1000000
- native tokens: undefined
Sending consolidation transaction...
Transaction sent: 0x245f75cb1b985304ceb022687e5c70ed6a936d667258015303e3f7f9ec285bbf
Transaction included: https://explorer.shimmer.network/testnet/block/0x5c06b0d2a16e22a54ca2f976a12d56515b58f8310c77de724b8d03dc4f862180
Account synced
Outputs AFTER consolidation:
OUTPUT #0
- address: rms1qr58umklvtqa4yxxwmskgzyhx2axfe5tfvunu5gauqu9sns7ava3u3kehwq
- amount: 1000000000
- native tokens: undefined
```

</TabItem>
<TabItem value="python" label="Python">

```plaintext
Account synced
Outputs BEFORE consolidation:
OUTPUT #0
- address: rms1qr58umklvtqa4yxxwmskgzyhx2axfe5tfvunu5gauqu9sns7ava3u3kehwq
- amount: 1000000
- native tokens: None
OUTPUT #1
- address: rms1qr58umklvtqa4yxxwmskgzyhx2axfe5tfvunu5gauqu9sns7ava3u3kehwq
- amount: 998000000
- native tokens: None
OUTPUT #2
- address: rms1qz7652a7c7s9pcur04x7jlmmnyfq8mpxgahmz50tzqutmv6p72vus60pqsd
- amount: 1000000
- native tokens: None
Sending consolidation transaction...
Transaction sent: 0x245f75cb1b985304ceb022687e5c70ed6a936d667258015303e3f7f9ec285bbf
Transaction included: https://explorer.shimmer.network/testnet/block/0x5c06b0d2a16e22a54ca2f976a12d56515b58f8310c77de724b8d03dc4f862180
Account synced
Outputs AFTER consolidation:
OUTPUT #0
- address: rms1qr58umklvtqa4yxxwmskgzyhx2axfe5tfvunu5gauqu9sns7ava3u3kehwq
- amount: 1000000000
- native tokens: None
```

</TabItem>
</Tabs>
1 change: 1 addition & 0 deletions documentation/sdk/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ module.exports = {
'how-tos/accounts-and-addresses/create-address',
'how-tos/accounts-and-addresses/list-transactions',
'how-tos/accounts-and-addresses/list-outputs',
'how-tos/accounts-and-addresses/consolidate-outputs',
]
},
{
Expand Down
10 changes: 5 additions & 5 deletions sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ name = "list_outputs"
path = "examples/how_tos/accounts_and_addresses/list_outputs.rs"
required-features = [ "rocksdb", "stronghold" ]

[[example]]
name = "consolidate_outputs"
path = "examples/how_tos/accounts_and_addresses/consolidate_outputs.rs"
required-features = [ "wallet", "stronghold" ]

# Simple Transaction Examples

[[example]]
Expand Down Expand Up @@ -656,11 +661,6 @@ name = "logger"
path = "examples/wallet/logger.rs"
required-features = [ "wallet" ]

[[example]]
name = "output_consolidation"
path = "examples/wallet/output_consolidation.rs"
required-features = [ "wallet", "stronghold" ]

[[example]]
name = "recover_accounts"
path = "examples/wallet/recover_accounts.rs"
Expand Down
Loading