Skip to content

Commit 49bf89b

Browse files
authored
chore(examples): add generic move function example (#199)
* add rs example * add py example * add go example * add kotlin example * fix typo * raise exception
1 parent c2849de commit 49bf89b

File tree

11 files changed

+377
-19
lines changed

11 files changed

+377
-19
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright (c) 2025 IOTA Stiftung
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package main
5+
6+
import (
7+
"encoding/binary"
8+
"fmt"
9+
"log"
10+
11+
sdk "bindings/iota_sdk_ffi"
12+
)
13+
14+
func main() {
15+
client := sdk.GraphQlClientNewDevnet()
16+
17+
sender, _ := sdk.AddressFromHex("0x71b4b4f171b4355ff691b7c470579cf1a926f96f724e5f9a30efc4b5f75d085e")
18+
gas_coin_id, _ := sdk.ObjectIdFromHex("0xa1d009e8dafe20b1cba05e08aea488aafae1f89d892c3eaef6c0994e155e441a")
19+
20+
gas_coin_obj, err := client.Object(gas_coin_id, nil)
21+
if err.(*sdk.SdkFfiError) != nil {
22+
log.Fatalf("Failed to fetch gas coin object: %v", err)
23+
}
24+
gas_coin := sdk.UnresolvedInputFromObject(*gas_coin_obj).WithOwnedKind()
25+
26+
reference_gas_price, err := client.ReferenceGasPrice(nil)
27+
if err.(*sdk.SdkFfiError) != nil {
28+
log.Fatalf("Failed to fetch reference gas price: %v", err)
29+
}
30+
31+
builder := sdk.NewTransactionBuilder()
32+
33+
addr1, _ := sdk.AddressFromHex("0xde49ea53fbadee67d3e35a097cdbea210b659676fc680a0b0c5f11d0763d375e")
34+
addr2, _ := sdk.AddressFromHex("0xe512234aa4ef6184c52663f09612b68f040dd0c45de037d96190a071ca5525b3")
35+
36+
addr1_arg := builder.Input(sdk.UnresolvedInputNewPure(addr1.ToBytes()))
37+
addr2_arg := builder.Input(sdk.UnresolvedInputNewPure(addr2.ToBytes()))
38+
39+
address_type_tag := sdk.TypeTagNewAddress()
40+
balance_type_tag := sdk.TypeTagNewU64()
41+
42+
buf := make([]byte, 8)
43+
binary.LittleEndian.PutUint64(buf, 10_000_000)
44+
bal1_arg := builder.Input(sdk.UnresolvedInputNewPure(buf))
45+
binary.LittleEndian.PutUint64(buf, 20_000_000)
46+
bal2_arg := builder.Input(sdk.UnresolvedInputNewPure(buf))
47+
48+
arg1 := builder.MakeMoveVec(&address_type_tag, []*sdk.Argument{addr1_arg, addr2_arg})
49+
arg2 := builder.MakeMoveVec(&balance_type_tag, []*sdk.Argument{bal1_arg, bal2_arg})
50+
51+
package_name, _ := sdk.AddressFromHex("0x2")
52+
module_name, _ := sdk.NewIdentifier("vec_map")
53+
function_name, _ := sdk.NewIdentifier("from_keys_values")
54+
55+
function := sdk.Function{Package: package_name,
56+
Module: module_name,
57+
Function: function_name,
58+
TypeArgs: []*sdk.TypeTag{address_type_tag, balance_type_tag},
59+
}
60+
61+
builder.MoveCall(function, []*sdk.Argument{arg1, arg2})
62+
63+
builder.SetGasBudget(50_000_000)
64+
builder.SetGasPrice(*reference_gas_price)
65+
builder.SetSender(sender)
66+
builder.AddGasObjects([]*sdk.UnresolvedInput{gas_coin})
67+
68+
txn, err := builder.Finish()
69+
if err != nil {
70+
log.Fatalf("Failed to create transaction: %v", err)
71+
}
72+
73+
skipChecks := false
74+
res, err := client.DryRunTx(txn, &skipChecks)
75+
76+
if res.Error != nil {
77+
log.Fatalf("Failed to call generic Move function: %v", err)
78+
}
79+
80+
fmt.Print("Successfully called generic Move function")
81+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright (c) 2025 IOTA Stiftung
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import iota_sdk.Address
5+
import iota_sdk.Function
6+
import iota_sdk.GraphQlClient
7+
import iota_sdk.Identifier
8+
import iota_sdk.ObjectId
9+
import iota_sdk.TransactionBuilder
10+
import iota_sdk.TypeTag
11+
import iota_sdk.UnresolvedInput
12+
import java.nio.ByteBuffer
13+
import java.nio.ByteOrder
14+
import kotlinx.coroutines.runBlocking
15+
16+
fun main() = runBlocking {
17+
try {
18+
val client = GraphQlClient.newDevnet()
19+
20+
val sender =
21+
Address.fromHex(
22+
"0x71b4b4f171b4355ff691b7c470579cf1a926f96f724e5f9a30efc4b5f75d085e"
23+
)
24+
25+
val gasCoin =
26+
client.`object`(
27+
ObjectId.fromHex(
28+
"0xa1d009e8dafe20b1cba05e08aea488aafae1f89d892c3eaef6c0994e155e441a"
29+
)
30+
)
31+
?: error("Missing gas coin")
32+
33+
val builder = TransactionBuilder()
34+
35+
val address1 =
36+
builder.input(
37+
UnresolvedInput.newPure(
38+
Address.fromHex(
39+
"0xde49ea53fbadee67d3e35a097cdbea210b659676fc680a0b0c5f11d0763d375e"
40+
)
41+
.toBytes()
42+
)
43+
)
44+
val address2 =
45+
builder.input(
46+
UnresolvedInput.newPure(
47+
Address.fromHex(
48+
"0xe512234aa4ef6184c52663f09612b68f040dd0c45de037d96190a071ca5525b3"
49+
)
50+
.toBytes()
51+
)
52+
)
53+
54+
val balance1 = builder.input(UnresolvedInput.newPure(uLongToBytes(10_000_000uL)))
55+
val balance2 = builder.input(UnresolvedInput.newPure(uLongToBytes(20_000_000uL)))
56+
57+
val addresses = builder.makeMoveVec(TypeTag.newAddress(), listOf(address1, address2))
58+
val balances = builder.makeMoveVec(TypeTag.newU64(), listOf(balance1, balance2))
59+
60+
val package_addr = Address.fromHex("0x2")
61+
val module_name = Identifier("vec_map")
62+
val function_name = Identifier("from_keys_values")
63+
64+
val function =
65+
Function(
66+
package_addr,
67+
module_name,
68+
function_name,
69+
listOf(TypeTag.newAddress(), TypeTag.newU64())
70+
)
71+
builder.moveCall(function, listOf(addresses, balances))
72+
73+
builder.setSender(sender)
74+
builder.setGasBudget(50_000_000uL)
75+
builder.setGasPrice(
76+
client.referenceGasPrice(null) ?: error("Failed to fetch reference gas price")
77+
)
78+
builder.addGasObjects(listOf(UnresolvedInput.fromObject(gasCoin).withOwnedKind()))
79+
80+
val txn = builder.finish()
81+
val res = client.dryRunTx(txn, false)
82+
83+
if (res.error != null) {
84+
println("Failed to call generic Move function: $res.error")
85+
}
86+
87+
println("Successfully called generic Move function!")
88+
} catch (e: Exception) {
89+
e.printStackTrace()
90+
}
91+
}
92+
93+
fun uLongToBytes(num: ULong): ByteArray {
94+
return ByteBuffer.allocate(ULong.SIZE_BYTES)
95+
.order(ByteOrder.LITTLE_ENDIAN)
96+
.putLong(num.toLong())
97+
.array()
98+
}

bindings/python/examples/coin_balances.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import asyncio
77

8+
89
async def main():
910
client = GraphQlClient.new_devnet()
1011

bindings/python/examples/epoch.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ async def main():
1313
# Get current epoch
1414
current_epoch = await client.epoch()
1515
if current_epoch is None:
16-
print("Current epoch is None")
17-
return
16+
raise Exception("missing current epoch")
1817

1918
print(f"Current epoch: {current_epoch.epoch_id}")
2019
print(f"Current epoch start time: {current_epoch.start_timestamp}")
@@ -23,8 +22,7 @@ async def main():
2322
previous_epoch_id = current_epoch.epoch_id - 1
2423
previous_epoch = await client.epoch(previous_epoch_id)
2524
if previous_epoch is None:
26-
print("Previous epoch is None")
27-
return
25+
raise Exception("missing previous epoch")
2826

2927
print(f"Previous epoch: {previous_epoch.epoch_id}")
3028
if previous_epoch.total_stake_rewards is not None:
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Copyright (c) 2025 IOTA Stiftung
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
import asyncio
5+
6+
from lib.iota_sdk_ffi import *
7+
8+
9+
async def main():
10+
client = GraphQlClient.new_devnet()
11+
12+
sender = Address.from_hex(
13+
"0x71b4b4f171b4355ff691b7c470579cf1a926f96f724e5f9a30efc4b5f75d085e"
14+
)
15+
gas_coin = await client.object(
16+
ObjectId.from_hex(
17+
"0xa1d009e8dafe20b1cba05e08aea488aafae1f89d892c3eaef6c0994e155e441a"
18+
)
19+
)
20+
if gas_coin is None:
21+
raise Exception("missing gas coin")
22+
23+
builder = TransactionBuilder()
24+
25+
addresses = builder.make_move_vec(
26+
TypeTag.new_address(),
27+
[
28+
builder.input(
29+
UnresolvedInput.new_pure(
30+
Address.from_hex(
31+
"0xde49ea53fbadee67d3e35a097cdbea210b659676fc680a0b0c5f11d0763d375e"
32+
).to_bytes(),
33+
)
34+
),
35+
builder.input(
36+
UnresolvedInput.new_pure(
37+
Address.from_hex(
38+
"0xe512234aa4ef6184c52663f09612b68f040dd0c45de037d96190a071ca5525b3"
39+
).to_bytes()
40+
)
41+
),
42+
],
43+
)
44+
balances = builder.make_move_vec(
45+
TypeTag.new_u64(),
46+
[
47+
builder.input(
48+
UnresolvedInput.new_pure(
49+
(10_000_000).to_bytes(8, "little", signed=False)
50+
)
51+
),
52+
builder.input(
53+
UnresolvedInput.new_pure(
54+
(20_000_000).to_bytes(8, "little", signed=False)
55+
)
56+
),
57+
],
58+
)
59+
60+
builder.move_call(
61+
Function(
62+
package=Address.from_hex("0x2"),
63+
module=Identifier("vec_map"),
64+
function=Identifier("from_keys_values"),
65+
type_args=[TypeTag.new_address(), TypeTag.new_u64()],
66+
),
67+
[addresses, balances],
68+
)
69+
builder.set_sender(sender)
70+
builder.set_gas_budget(50_000_000)
71+
builder.set_gas_price(await client.reference_gas_price())
72+
builder.add_gas_objects([UnresolvedInput.from_object(gas_coin).with_owned_kind()])
73+
74+
txn = builder.finish()
75+
res = await client.dry_run_tx(txn, False)
76+
77+
if res.error is not None:
78+
raise Exception(f"Failed to call generic Move function: {res.error}")
79+
80+
print("Successfully called generic Move function!")
81+
82+
83+
if __name__ == "__main__":
84+
asyncio.run(main())

bindings/python/examples/get_object.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ async def main():
1515

1616
obj = await client.object(object_id)
1717
if obj is None:
18-
return
18+
raise Exception("missing object")
1919

2020
print("Object ID:", obj.object_id().to_hex())
2121
print("Version:", obj.version())

bindings/python/examples/move_functions.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ async def main():
1515

1616
package = await client.package(package_address)
1717
if package is None:
18-
print("no package found")
19-
return
18+
raise Exception("missing package")
2019

2120
for module_id in package.modules():
2221
module = await client.normalized_move_module(

bindings/python/examples/owned_objects.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
from lib.iota_sdk_ffi import *
55
import asyncio
66

7+
78
async def main():
89
client = GraphQlClient.new_devnet()
910
address = Address.from_hex("0x0")
10-
objects_page = await client.objects(
11-
ObjectFilter(owner=address)
12-
)
11+
objects_page = await client.objects(ObjectFilter(owner=address))
1312
print(f"Owned objects({len(objects_page.data)}):")
1413
for obj in objects_page.data:
1514
print(obj.object_id().to_hex())
1615

16+
1717
if __name__ == "__main__":
1818
asyncio.run(main())

bindings/python/examples/pagination.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,20 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
import asyncio
5-
from lib.iota_sdk_ffi import Address, Direction, GraphQlClient, ObjectFilter, PaginationFilter
5+
from lib.iota_sdk_ffi import (
6+
Address,
7+
Direction,
8+
GraphQlClient,
9+
ObjectFilter,
10+
PaginationFilter,
11+
)
12+
613

714
async def main():
815
client = GraphQlClient.new_devnet()
9-
address = Address.from_hex("0x611830d3641a68f94a690dcc25d1f4b0dac948325ac18f6dd32564371735f32c")
16+
address = Address.from_hex(
17+
"0x611830d3641a68f94a690dcc25d1f4b0dac948325ac18f6dd32564371735f32c"
18+
)
1019

1120
all_objects = []
1221
next_cursor = None
@@ -15,7 +24,7 @@ async def main():
1524
page = await client.objects(
1625
ObjectFilter(owner=address),
1726
# Limit to 1 to demonstrate pagination
18-
PaginationFilter(direction=Direction.FORWARD, cursor=next_cursor, limit=1)
27+
PaginationFilter(direction=Direction.FORWARD, cursor=next_cursor, limit=1),
1928
)
2029
all_objects.extend(page.data)
2130
if page.page_info.has_next_page:
@@ -26,5 +35,6 @@ async def main():
2635
for obj_id in all_objects:
2736
print(obj_id.object_id().to_hex())
2837

38+
2939
if __name__ == "__main__":
3040
asyncio.run(main())

0 commit comments

Comments
 (0)