Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
121 changes: 121 additions & 0 deletions bindings/go/examples/stake.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Copyright (c) 2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

package main

import (
"log"

sdk "bindings/iota_sdk_ffi"
)

func isNilError(err error) bool {
if sdkErr, ok := err.(*sdk.SdkFfiError); ok {
return sdkErr == nil
}
return false
}

func main() {
client := sdk.GraphQlClientNewDevnet()

myAddress, err := sdk.AddressFromHex("0x611830d3641a68f94a690dcc25d1f4b0dac948325ac18f6dd32564371735f32c")
if err != nil {
log.Fatalf("Failed to parse address: %v", err)
}

validators, err := client.ActiveValidators(nil, &sdk.PaginationFilter{Direction: sdk.DirectionForward})
if !isNilError(err) {
log.Fatalf("Failed to get active validators: %v", err)
}

if len(validators.Data) == 0 {
log.Fatal("No validators found")
}
validator := validators.Data[0]

var validatorName string
if validator.Name == nil {
validatorName = "with no name"
} else {
validatorName = *validator.Name
}
log.Printf("Staking to validator %v", validatorName)

coinObjId, err := sdk.ObjectIdFromHex("0xd04077fe3b6fad13b3d4ed0d535b7ca92afcac8f0f2a0e0925fb9f4f0b30c699")
if err != nil {
log.Fatalf("Failed to parse object ID: %v", err)
}
coin, err := client.Object(coinObjId, nil)
if !isNilError(err) {
log.Fatalf("Failed to get coin: %v", err)
}

gasCoinObjId, err := sdk.ObjectIdFromHex("0x0b0270ee9d27da0db09651e5f7338dfa32c7ee6441ccefa1f6e305735bcfc7ab")
if err != nil {
log.Fatalf("Failed to parse object ID: %v", err)
}
gasCoin, err := client.Object(gasCoinObjId, nil)
if !isNilError(err) {
log.Fatalf("Failed to get gas coin: %v", err)
}

iotaSystemAddress, err := sdk.AddressFromHex("0x3")
if err != nil {
log.Fatalf("Failed to parse address: %v", err)
}

iotaSystemId, err := sdk.ObjectIdFromHex("0x5")
if err != nil {
log.Fatalf("Failed to parse object ID: %v", err)
}

iotaSystemModule, err := sdk.NewIdentifier("iota_system")
if err != nil {
log.Fatalf("Failed to parse identifier: %v", err)
}

requestAddStakeFn, err := sdk.NewIdentifier("request_add_stake")
if err != nil {
log.Fatalf("Failed to parse identifier: %v", err)
}

builder := sdk.NewTransactionBuilder()
inputs := []*sdk.Argument{
builder.Input(sdk.UnresolvedInputNewShared(iotaSystemId, 1, true)),
builder.Input(sdk.UnresolvedInputFromObject(*coin).WithOwnedKind()),
builder.Input(sdk.UnresolvedInputNewPure(validator.Address.ToBytes())),
}
builder.MoveCall(
sdk.Function{
Package: iotaSystemAddress,
Module: iotaSystemModule,
Function: requestAddStakeFn,
},
inputs,
)
builder.SetSender(myAddress)
builder.SetGasBudget(50000000)
gasPrice, err := client.ReferenceGasPrice(nil)
if !isNilError(err) {
log.Fatalf("Failed to get gas price: %v", err)
}
builder.SetGasPrice(*gasPrice)
builder.AddGasObjects([]*sdk.UnresolvedInput{sdk.UnresolvedInputFromObject(*gasCoin).WithOwnedKind()})

txn, err := builder.Finish()
if err != nil {
log.Fatalf("Failed to create transaction: %v", err)
}

res, err := client.DryRunTx(txn, nil)
if !isNilError(err) {
log.Fatalf("Failed to get gas price: %v", err)
}

if res.Error != nil {
log.Fatalf("Failed to stake: %v", *res.Error)
}

log.Print("Stake dry run was successful!")
}
100 changes: 100 additions & 0 deletions bindings/go/examples/unstake.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) 2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

package main

import (
"log"

sdk "bindings/iota_sdk_ffi"
)

func isNilError(err error) bool {
if sdkErr, ok := err.(*sdk.SdkFfiError); ok {
return sdkErr == nil
}
return false
}

func main() {
client := sdk.GraphQlClientNewDevnet()

stakedIotaType := "0x3::staking_pool::StakedIota"
stakedIotas, err := client.Objects(&sdk.PaginationFilter{Direction: sdk.DirectionForward}, &sdk.ObjectFilter{TypeTag: &stakedIotaType})
if !isNilError(err) {
log.Fatalf("Failed to get staked iota: %v", err)
}
if len(stakedIotas.Data) == 0 {
log.Fatal("No staked iota objects found")
}
stakedIota := stakedIotas.Data[0]

gasCoinType := sdk.StructTagGasCoin().String()
gasCoins, err := client.Objects(&sdk.PaginationFilter{Direction: sdk.DirectionForward}, &sdk.ObjectFilter{TypeTag: &gasCoinType, Owner: stakedIota.Owner().AsAddressOpt()})
if !isNilError(err) {
log.Fatalf("Failed to get gas coin: %v", err)
}
if len(gasCoins.Data) == 0 {
log.Fatal("No gas coins found")
}
gasCoin := gasCoins.Data[0]

iotaSystemAddress, err := sdk.AddressFromHex("0x3")
if err != nil {
log.Fatalf("Failed to parse address: %v", err)
}

iotaSystemId, err := sdk.ObjectIdFromHex("0x5")
if err != nil {
log.Fatalf("Failed to parse object ID: %v", err)
}

iotaSystemModule, err := sdk.NewIdentifier("iota_system")
if err != nil {
log.Fatalf("Failed to parse identifier: %v", err)
}

requestAddStakeFn, err := sdk.NewIdentifier("request_withdraw_stake")
if err != nil {
log.Fatalf("Failed to parse identifier: %v", err)
}

builder := sdk.NewTransactionBuilder()
inputs := []*sdk.Argument{
builder.Input(sdk.UnresolvedInputNewShared(iotaSystemId, 1, true)),
builder.Input(sdk.UnresolvedInputFromObject(stakedIota).WithOwnedKind()),
}
builder.MoveCall(
sdk.Function{
Package: iotaSystemAddress,
Module: iotaSystemModule,
Function: requestAddStakeFn,
TypeArgs: []*sdk.TypeTag{},
},
inputs,
)
builder.SetSender(gasCoin.Owner().AsAddress())
builder.SetGasBudget(50000000)
gasPrice, err := client.ReferenceGasPrice(nil)
if !isNilError(err) {
log.Fatalf("Failed to get gas price: %v", err)
}
builder.SetGasPrice(*gasPrice)
builder.AddGasObjects([]*sdk.UnresolvedInput{sdk.UnresolvedInputFromObject(gasCoin).WithOwnedKind()})

txn, err := builder.Finish()
if err != nil {
log.Fatalf("Failed to create transaction: %v", err)
}

res, err := client.DryRunTx(txn, nil)
if !isNilError(err) {
log.Fatalf("Failed to get gas price: %v", err)
}

if res.Error != nil {
log.Fatalf("Failed to unstake: %v", *res.Error)
}

log.Print("Unstake dry run was successful!")
}
15 changes: 15 additions & 0 deletions bindings/go/iota_sdk_ffi/iota_sdk_ffi.go
Original file line number Diff line number Diff line change
Expand Up @@ -5867,6 +5867,15 @@ func uniffiCheckChecksums() {
}
}
{
checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t {
return C.uniffi_iota_sdk_ffi_checksum_constructor_unresolvedinput_new_pure()
})
if checksum != 7951 {
// If this happens try cleaning and rebuilding your project
panic("iota_sdk_ffi: uniffi_iota_sdk_ffi_checksum_constructor_unresolvedinput_new_pure: UniFFI API checksum mismatch")
}
}
{
checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t {
return C.uniffi_iota_sdk_ffi_checksum_constructor_unresolvedinput_new_receiving()
})
Expand Down Expand Up @@ -20862,6 +20871,12 @@ func UnresolvedInputNewOwned(objectId *ObjectId, version uint64, digest *Digest)
}))
}

func UnresolvedInputNewPure(bytes []byte) *UnresolvedInput {
return FfiConverterUnresolvedInputINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer {
return C.uniffi_iota_sdk_ffi_fn_constructor_unresolvedinput_new_pure(FfiConverterBytesINSTANCE.Lower(bytes),_uniffiStatus)
}))
}

// Return a receiving kind of object with all required fields.
func UnresolvedInputNewReceiving(objectId *ObjectId, version uint64, digest *Digest) *UnresolvedInput {
return FfiConverterUnresolvedInputINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer {
Expand Down
11 changes: 11 additions & 0 deletions bindings/go/iota_sdk_ffi/iota_sdk_ffi.h
Original file line number Diff line number Diff line change
Expand Up @@ -4021,6 +4021,11 @@ void* uniffi_iota_sdk_ffi_fn_constructor_unresolvedinput_new_immutable(void* obj
void* uniffi_iota_sdk_ffi_fn_constructor_unresolvedinput_new_owned(void* object_id, uint64_t version, void* digest, RustCallStatus *out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IOTA_SDK_FFI_FN_CONSTRUCTOR_UNRESOLVEDINPUT_NEW_PURE
#define UNIFFI_FFIDEF_UNIFFI_IOTA_SDK_FFI_FN_CONSTRUCTOR_UNRESOLVEDINPUT_NEW_PURE
void* uniffi_iota_sdk_ffi_fn_constructor_unresolvedinput_new_pure(RustBuffer bytes, RustCallStatus *out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IOTA_SDK_FFI_FN_CONSTRUCTOR_UNRESOLVEDINPUT_NEW_RECEIVING
#define UNIFFI_FFIDEF_UNIFFI_IOTA_SDK_FFI_FN_CONSTRUCTOR_UNRESOLVEDINPUT_NEW_RECEIVING
void* uniffi_iota_sdk_ffi_fn_constructor_unresolvedinput_new_receiving(void* object_id, uint64_t version, void* digest, RustCallStatus *out_status
Expand Down Expand Up @@ -8574,6 +8579,12 @@ uint16_t uniffi_iota_sdk_ffi_checksum_constructor_unresolvedinput_new_immutable(
#define UNIFFI_FFIDEF_UNIFFI_IOTA_SDK_FFI_CHECKSUM_CONSTRUCTOR_UNRESOLVEDINPUT_NEW_OWNED
uint16_t uniffi_iota_sdk_ffi_checksum_constructor_unresolvedinput_new_owned(void

);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IOTA_SDK_FFI_CHECKSUM_CONSTRUCTOR_UNRESOLVEDINPUT_NEW_PURE
#define UNIFFI_FFIDEF_UNIFFI_IOTA_SDK_FFI_CHECKSUM_CONSTRUCTOR_UNRESOLVEDINPUT_NEW_PURE
uint16_t uniffi_iota_sdk_ffi_checksum_constructor_unresolvedinput_new_pure(void

);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IOTA_SDK_FFI_CHECKSUM_CONSTRUCTOR_UNRESOLVEDINPUT_NEW_RECEIVING
Expand Down
1 change: 0 additions & 1 deletion bindings/kotlin/examples/ChainId.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ fun main() = runBlocking {
val client = GraphQlClient.newDevnet()
val chainId = client.chainId()
println("Chain ID: $chainId")

} catch (e: Exception) {
e.printStackTrace()
}
Expand Down
2 changes: 0 additions & 2 deletions bindings/kotlin/examples/Example.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
// SPDX-License-Identifier: Apache-2.0

import iota_sdk.Address
import iota_sdk.Direction
import iota_sdk.EventFilter
import iota_sdk.GraphQlClient
import iota_sdk.ObjectId
import iota_sdk.PaginationFilter
import iota_sdk.TransactionsFilter
import kotlinx.coroutines.runBlocking

Expand Down
39 changes: 21 additions & 18 deletions bindings/kotlin/examples/GetObject.kt
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
// Copyright (c) 2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import iota_sdk.Address
import iota_sdk.Direction
import iota_sdk.EventFilter
import iota_sdk.GraphQlClient
import iota_sdk.ObjectId
import iota_sdk.PaginationFilter
import iota_sdk.TransactionsFilter
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
try {
val client = GraphQlClient.newDevnet()

val objectId = ObjectId.fromHex("0x20c056090c3dd1604fcfd7ea759781de650aa45323738e799365d0c28bebeb1e")
val objectId =
ObjectId.fromHex(
"0x20c056090c3dd1604fcfd7ea759781de650aa45323738e799365d0c28bebeb1e"
)

val obj = client.`object`(objectId)!!

val objType = if (obj.objectType().isPackage()) { "Package"} else { obj.objectType().asStruct().toString() };

val objOwner = if (obj.owner().isAddress()) {
"Address(${obj.owner().asAddress().toHex()})"
} else if (obj.owner().isObject()) {
"Object(${obj.owner().asObject().toHex()})"
} else if (obj.owner().isShared()) {
"Shared(${obj.owner().asShared()})"
} else {
"Immutable"
};
val objType =
if (obj.objectType().isPackage()) {
"Package"
} else {
obj.objectType().asStruct().toString()
}

val objOwner =
if (obj.owner().isAddress()) {
"Address(${obj.owner().asAddress().toHex()})"
} else if (obj.owner().isObject()) {
"Object(${obj.owner().asObject().toHex()})"
} else if (obj.owner().isShared()) {
"Shared(${obj.owner().asShared()})"
} else {
"Immutable"
}

println("Object ID: ${obj.objectId().toHex()}")
println("Version: ${obj.version()}")
Expand All @@ -38,7 +42,6 @@ fun main() = runBlocking {
println("Type: $objType")
@OptIn(kotlin.ExperimentalStdlibApi::class)
println("BCS bytes: ${obj.asStruct().contents.toHexString()}")

} catch (e: Exception) {
e.printStackTrace()
}
Expand Down
15 changes: 9 additions & 6 deletions bindings/kotlin/examples/MoveFunctions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ fun main() = runBlocking {
try {
val client = GraphQlClient.newDevnet()

val packageAddress = Address.fromHex("0x3ec4826f1d6e0d9f00680b2e9a7a41f03788ee610b3d11c24f41ab0ae71da39f")
val packageAddress =
Address.fromHex(
"0x3ec4826f1d6e0d9f00680b2e9a7a41f03788ee610b3d11c24f41ab0ae71da39f"
)

val pkg = client.`package`(packageAddress, null)
if (pkg == null) {
Expand All @@ -18,10 +21,11 @@ fun main() = runBlocking {
}

for ((moduleId, _) in pkg.modules()) {
var module = client.normalizedMoveModule(
packageAddress,
moduleId.asStr(),
)
var module =
client.normalizedMoveModule(
packageAddress,
moduleId.asStr(),
)
if (module == null) {
println("module `${moduleId.asStr()}` not found")
return@runBlocking
Expand All @@ -35,7 +39,6 @@ fun main() = runBlocking {
println()
}
}

} catch (e: Exception) {
e.printStackTrace()
}
Expand Down
Loading