diff --git a/bindings/go/examples/prepare_send_coins/main.go b/bindings/go/examples/prepare_send_coins/main.go new file mode 100644 index 000000000..45049ff1f --- /dev/null +++ b/bindings/go/examples/prepare_send_coins/main.go @@ -0,0 +1,50 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +package main + +import ( + "log" + + sdk "bindings/iota_sdk_ffi" +) + +func main() { + client := sdk.GraphQlClientNewDevnet() + + fromAddress, _ := sdk.AddressFromHex("0x611830d3641a68f94a690dcc25d1f4b0dac948325ac18f6dd32564371735f32c") + toAddress, _ := sdk.AddressFromHex("0x0000a4984bd495d4346fa208ddff4f5d5e5ad48c21dec631ddebc99809f16900") + + // This is a coin of type + // 0x3358bea865960fea2a1c6844b6fc365f662463dd1821f619838eb2e606a53b6a::cert::CERT + coinObjId, _ := sdk.ObjectIdFromHex("0x8ef4259fa2a3499826fa4b8aebeb1d8e478cf5397d05361c96438940b43d28c9") + amount := uint64(50000000000) + gasCoinObjId, _ := sdk.ObjectIdFromHex("0x0b0270ee9d27da0db09651e5f7338dfa32c7ee6441ccefa1f6e305735bcfc7ab") + + builder := sdk.TransactionBuilderInit(fromAddress, client) + builder.SendCoins([]*sdk.ObjectId{coinObjId}, toAddress, &amount) + builder.Gas(gasCoinObjId).GasBudget(1000000000) + + txn, err := builder.Finish() + if err.(*sdk.SdkFfiError) != nil { + log.Fatalf("Failed to create transaction: %v", err) + } + + txnBytes, err := txn.BcsSerialize() + if err != nil { + log.Fatalf("Failed to serialize transaction: %v", err) + } + log.Printf("Signing Digest: %v", sdk.HexEncode(txn.SigningDigest())) + log.Printf("Txn Bytes: %v", sdk.Base64Encode(txnBytes)) + + res, err := builder.DryRun(false) + if err.(*sdk.SdkFfiError) != nil { + log.Fatalf("Failed to send coins: %v", err) + } + + if res.Error != nil { + log.Fatalf("Failed to send coins: %v", *res.Error) + } + + log.Print("Send coins dry run was successful!") +} diff --git a/bindings/kotlin/examples/PrepareSendCoins.kt b/bindings/kotlin/examples/PrepareSendCoins.kt new file mode 100644 index 000000000..4befa5326 --- /dev/null +++ b/bindings/kotlin/examples/PrepareSendCoins.kt @@ -0,0 +1,51 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import iota_sdk.* +import kotlinx.coroutines.runBlocking + +fun main() = runBlocking { + try { + val client = GraphQlClient.newDevnet() + + val fromAddress = + Address.fromHex( + "0x611830d3641a68f94a690dcc25d1f4b0dac948325ac18f6dd32564371735f32c" + ) + val toAddress = + Address.fromHex( + "0x0000a4984bd495d4346fa208ddff4f5d5e5ad48c21dec631ddebc99809f16900" + ) + + // This is a coin of type + // 0x3358bea865960fea2a1c6844b6fc365f662463dd1821f619838eb2e606a53b6a::cert::CERT + val coinId = + ObjectId.fromHex( + "0x8ef4259fa2a3499826fa4b8aebeb1d8e478cf5397d05361c96438940b43d28c9" + ) + val gasCoinId = + ObjectId.fromHex( + "0x0b0270ee9d27da0db09651e5f7338dfa32c7ee6441ccefa1f6e305735bcfc7ab" + ) + + val builder = TransactionBuilder.init(fromAddress, client) + + builder.sendCoins(listOf(coinId), toAddress, 50000000000uL) + builder.gas(gasCoinId).gasBudget(1000000000uL) + + val txn = builder.finish() + + println("Signing Digest: ${hexEncode(txn.signingDigest())}") + println("Txn Bytes: ${base64Encode(txn.bcsSerialize())}") + + val res = builder.dryRun() + + if (res.error != null) { + throw Exception("Failed to send coins: ${res.error}") + } + + println("Send coins dry run was successful!") + } catch (e: Exception) { + e.printStackTrace() + } +} diff --git a/bindings/python/examples/prepare_send_coins.py b/bindings/python/examples/prepare_send_coins.py new file mode 100644 index 000000000..d4f20b2e5 --- /dev/null +++ b/bindings/python/examples/prepare_send_coins.py @@ -0,0 +1,53 @@ +# Copyright (c) 2025 IOTA Stiftung +# SPDX-License-Identifier: Apache-2.0 + +from lib.iota_sdk_ffi import * + +import asyncio + + +async def main(): + try: + client = GraphQlClient.new_devnet() + + from_address = Address.from_hex( + "0x611830d3641a68f94a690dcc25d1f4b0dac948325ac18f6dd32564371735f32c" + ) + to_address = Address.from_hex( + "0x0000a4984bd495d4346fa208ddff4f5d5e5ad48c21dec631ddebc99809f16900" + ) + + # This is a coin of type + # 0x3358bea865960fea2a1c6844b6fc365f662463dd1821f619838eb2e606a53b6a::cert::CERT + coin_id = ObjectId.from_hex( + "0x8ef4259fa2a3499826fa4b8aebeb1d8e478cf5397d05361c96438940b43d28c9" + ) + gas_coin_id = ObjectId.from_hex( + "0x0b0270ee9d27da0db09651e5f7338dfa32c7ee6441ccefa1f6e305735bcfc7ab" + ) + + builder = await TransactionBuilder.init(from_address, client) + builder.send_coins( + [coin_id], + to_address, + 50000000000, + ) + builder.gas(gas_coin_id).gas_budget(1000000000) + + txn = await builder.finish() + + print("Signing Digest:", hex_encode(txn.signing_digest())) + print("Txn Bytes:", base64_encode(txn.bcs_serialize())) + + res = await builder.dry_run() + if res.error is not None: + raise Exception("Failed to send coins:", res.error) + + print("Send coins dry run was successful!") + + except Exception as e: + print(f"Error: {e}") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/crates/iota-graphql-client/examples/prepare_send_coins.rs b/crates/iota-graphql-client/examples/prepare_send_coins.rs new file mode 100644 index 000000000..22c373d21 --- /dev/null +++ b/crates/iota-graphql-client/examples/prepare_send_coins.rs @@ -0,0 +1,52 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use std::str::FromStr; + +use base64ct::Encoding; +use eyre::Result; +use iota_graphql_client::Client; +use iota_transaction_builder::TransactionBuilder; +use iota_types::{Address, ObjectId}; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new_devnet(); + + let from_address = + Address::from_str("0x611830d3641a68f94a690dcc25d1f4b0dac948325ac18f6dd32564371735f32c")?; + let to_address = + Address::from_str("0x0000a4984bd495d4346fa208ddff4f5d5e5ad48c21dec631ddebc99809f16900")?; + + // This is a coin of type + // 0x3358bea865960fea2a1c6844b6fc365f662463dd1821f619838eb2e606a53b6a::cert::CERT + let coin = + ObjectId::from_str("0x8ef4259fa2a3499826fa4b8aebeb1d8e478cf5397d05361c96438940b43d28c9")?; + let gas_coin = + ObjectId::from_str("0x0b0270ee9d27da0db09651e5f7338dfa32c7ee6441ccefa1f6e305735bcfc7ab")?; + + let mut builder = TransactionBuilder::new(from_address).with_client(client.clone()); + + builder + .send_coins([coin], to_address, 50000000000) + .gas(gas_coin) + .gas_budget(1000000000); + + let txn = builder.finish().await?; + + println!("Signing Digest: {}", hex::encode(txn.signing_digest())); + println!( + "Txn Bytes: {}", + base64ct::Base64::encode_string(&bcs::to_bytes(&txn)?) + ); + + let res = client.dry_run_tx(&txn, false).await?; + + if let Some(err) = res.error { + eyre::bail!("Failed to send coins: {err}"); + } + + println!("Send coins dry run was successful!"); + + Ok(()) +}