Transaction - 3

We are not done yet.

Setting up the stage

Here we are using the prelude import to import all the necessary type declarations.

use avail_rust::prelude::*;

#[tokio::main]
async fn main() -> Result<(), ClientError> {
    // Code goes here

    Ok(())
}

Connection

Both online_client and rpc_client can be grouped together and now we are using a wrapper to get the local node endpoint instead of writing it manually.
Together with local_endpoint we have the following other endpoints:

  • local_http_endpoint
  • turing_endpoint
  • turing_http_endpoint
  • mainnet_endpoint
  • mainnet_http_endpoint
	let sdk = SDK::new(SDK::local_endpoint()).await?;

new() method will use a reconnecting websocket rpc. If just HTTP is needed then new_http() will do the trick otherwise for custom clients new_custom(online_client: AOnlineClient, rpc_client: RpcClient) can be used.

Payload

Payload creation has been abstracted away and can now be accessed via sdk.tx.*.** path where * is pallet name and ** is call name. Not all transaction have been abstracted away and for some you will still need to use the following path avail_rust::avail::tx().*().**().

	let data = String::from("My Data").into_bytes();
	let tx = sdk.tx.data_availability.submit_data(data);

The object that is returned by the interface has many different helper functions attach to it. Make sure to check them out.

For some of them you will need to import either avail_rust::transaction::WebSocket or avail_rust::transaction::HTTP in order to get access to the desired execute_* call.
The prelude import automatically imports the WebSocket one and if that's not desired then you will need avoid prelude import and manually import all the type declarations.

Transaction Parameters, Signature, Submission, Watcher

The watcher is now combined with transaction submission. We can now choose if we want to wait for block inclusion, block finalization, and or fire and forget.
If we choose to wait, the system will automatically resubmit our transaction in case it didn't found it the next X blocks by using the same transaction parameters.
WebSocket and HTTP interface differ here in types and implementation:

  • WebSocket uses block subscription to fetch blocks.
  • HTTP cannot use block subscription because that's a websocket features thus we are forced to fetch headers every N (set to 3 by default) seconds in order to know if a new block has been produced.

The default 3 seconds (sleep_duration) for HTTP can be configured by calling execute_and_watch instead of execute_and_watch_inclusion or execute_and_watch_finalization.

	let tx_details = tx.execute_and_watch_inclusion(&account, None).await?;
	println!("Transaction was found.");
	println!("Block Hash: {:?}", tx_details.block_hash); // Block Hash: 0x61415b6012005665bac0cf8575a94e509d079a762be2ba6a71a04633efd01c1b
	println!("Block Number: {:?}", tx_details.block_number); // Block Number: 200
	println!("Tx Hash: {:?}", tx_details.tx_hash); // Tx Hash: 0x01651a93d55bde0f258504498d4f2164416df5331794d9c905d4c8711d9537ef
	println!("Tx Index: {:?}", tx_details.tx_index); // Tx Index: 1

	println!("Event count: {}", tx_details.events.iter().count()); // Event count: 7
	match tx_details.is_successful(&sdk.online_client) {
		Some(x) => x?,
		None => panic!("Failed to decode events."),
	};

Source Code

use avail_rust::prelude::*;

#[tokio::main]
async fn main() -> Result<(), ClientError> {
	// RPC Connection
	// ANCHOR: connection
	let sdk = SDK::new(SDK::local_endpoint()).await?;
	// ANCHOR_END: connection

	// Accounts
	let account = SDK::alice()?;

	// Payload
	// ANCHOR: payload
	let data = String::from("My Data").into_bytes();
	let tx = sdk.tx.data_availability.submit_data(data);
	// ANCHOR_END: payload

	// Transaction Params, Signature, Submission, Watcher
	// ANCHOR: signsend
	let tx_details = tx.execute_and_watch_inclusion(&account, None).await?;
	println!("Transaction was found.");
	println!("Block Hash: {:?}", tx_details.block_hash); // Block Hash: 0x61415b6012005665bac0cf8575a94e509d079a762be2ba6a71a04633efd01c1b
	println!("Block Number: {:?}", tx_details.block_number); // Block Number: 200
	println!("Tx Hash: {:?}", tx_details.tx_hash); // Tx Hash: 0x01651a93d55bde0f258504498d4f2164416df5331794d9c905d4c8711d9537ef
	println!("Tx Index: {:?}", tx_details.tx_index); // Tx Index: 1

	println!("Event count: {}", tx_details.events.iter().count()); // Event count: 7
	match tx_details.is_successful(&sdk.online_client) {
		Some(x) => x?,
		None => panic!("Failed to decode events."),
	};
	// ANCHOR_END: signsend

	Ok(())
}