Skip to content
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
23 changes: 23 additions & 0 deletions .github/actions/start-local-network/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: "Start Local IOTA Network"
description: "Downloads and starts a local IOTA network for testing"

runs:
using: "composite"
steps:
- name: Get the IOTA testnet binary and start a local network
shell: bash
env:
IOTA_BINARY_VERSION: "v0.12.0-rc"
EPOCH_DURATION_MS: "10000"
run: |
ASSET_NAME="iota-$IOTA_BINARY_VERSION-linux-x86_64.tgz"
download_url="https://github.com/iotaledger/iota/releases/download/$IOTA_BINARY_VERSION/$ASSET_NAME"

echo "Downloading testnet binary from $download_url"
wget -q $download_url -O iota.tgz
tar -zxvf iota.tgz ./iota
chmod +x ./iota
echo "Starting local network with a faucet, an indexer (port 5432) and GraphQL. Epoch duration is set to $EPOCH_DURATION_MS ms"
echo "$(pwd)" >> $GITHUB_PATH
./iota start --force-regenesis --with-faucet --with-indexer --with-graphql --pg-port 5432 --pg-db-name iota_indexer_v2 --epoch-duration-ms $EPOCH_DURATION_MS &
sleep $((EPOCH_DURATION_MS / 1000)) # wait for the first epoch to end
48 changes: 48 additions & 0 deletions .github/workflows/bindings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@ concurrency:
jobs:
go:
runs-on: ubuntu-latest
services:
postgres:
image: postgres
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgrespw
POSTGRES_DB: iota_indexer_v2
POSTGRES_HOST_AUTH_METHOD: trust
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
Expand All @@ -26,10 +41,26 @@ jobs:
run: make go
- name: Checks for uncommitted changes
run: git diff --exit-code
- uses: ./.github/actions/start-local-network
- name: Run the examples
run: make go-examples
kotlin:
runs-on: ubuntu-latest
services:
postgres:
image: postgres
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgrespw
POSTGRES_DB: iota_indexer_v2
POSTGRES_HOST_AUTH_METHOD: trust
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
Expand All @@ -41,16 +72,33 @@ jobs:
with:
distribution: "oracle"
java-version: "21"
- uses: ./.github/actions/start-local-network
- name: Run the examples
run: make kotlin-examples
python:
runs-on: ubuntu-latest
services:
postgres:
image: postgres
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgrespw
POSTGRES_DB: iota_indexer_v2
POSTGRES_HOST_AUTH_METHOD: trust
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Build the bindings
run: make python
- name: Checks for uncommitted changes
run: git diff --exit-code
- uses: ./.github/actions/start-local-network
- name: Run the examples
run: make python-examples
24 changes: 3 additions & 21 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ jobs:

tests-with-network:
runs-on: ubuntu-latest
env:
EPOCH_DURATION_MS: 10000
services:
postgres: # we need this postgres instance for running a local network with indexer and graphql
image: postgres
Expand All @@ -66,28 +64,12 @@ jobs:

- uses: taiki-e/install-action@cargo-nextest

- name: Get the IOTA testnet binary and start a local network
shell: bash
env:
IOTA_BINARY_VERSION: "v0.12.0-rc" # used for downloading a specific IOTA binary version that matches the GraphQL schema for local network tests
run: |
ASSET_NAME="iota-$IOTA_BINARY_VERSION-linux-x86_64.tgz"
download_url="https://github.com/iotaledger/iota/releases/download/$IOTA_BINARY_VERSION/$ASSET_NAME"

echo "Downloading testnet binary from $download_url"
wget -q $download_url -O iota.tgz
tar -zxvf iota.tgz ./iota
chmod +x ./iota
echo "Starting local network with a faucet, an indexer (port 5432) and GraphQL. Epoch duration is set to $EPOCH_DURATION_MS ms"
echo "$(pwd)" >> $GITHUB_PATH # we need it on the path for calling iota move build for some tests
./iota start --force-regenesis --with-faucet --with-indexer --with-graphql --pg-port 5432 --pg-db-name iota_indexer_v2 --epoch-duration-ms $EPOCH_DURATION_MS &
- uses: ./.github/actions/start-local-network

- name: Run tests that require local network (GraphQL Client and Tx Builder)
env:
NETWORK: "local" # other expected options are mainnet, testnet, or devnet, or an actual URL to a GraphQL server: http://localhost:port
run: |
sleep $((EPOCH_DURATION_MS / 1000)) # wait for the network to get to epoch #2
make test-with-localnet
NETWORK: "local"
run: make test-with-localnet

doctests:
runs-on: ubuntu-latest
Expand Down
36 changes: 36 additions & 0 deletions bindings/go/examples/faucet/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

package main

import (
"fmt"
"log"

sdk "bindings/iota_sdk_ffi"
)

func main() {
address, err := sdk.AddressFromHex("0x0000a4984bd495d4346fa208ddff4f5d5e5ad48c21dec631ddebc99809f16900")
if err != nil {
log.Fatalf("Failed to create address: %v", err)
}

faucetClient := sdk.FaucetClientNewLocal()

faucetReceipt, err := faucetClient.RequestAndWait(address)
if err.(*sdk.SdkFfiError) != nil {
log.Fatalf("Failed to request faucet: %v", err)
}

if err.(*sdk.SdkFfiError) == nil {
fmt.Println("Faucet receipt:")
for _, coin := range faucetReceipt.Sent {
coinIdHex := coin.Id.ToHex()
digestBase58 := coin.TransferTxDigest.ToBase58()
fmt.Printf(" Coin ID: %s, Amount: %d, Digest: %s\n", coinIdHex, coin.Amount, digestBase58)
}
} else {
fmt.Println("Faucet receipt: nil")
}
}
29 changes: 29 additions & 0 deletions bindings/kotlin/examples/Faucet.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import iota_sdk.Address
import iota_sdk.FaucetClient
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
try {
val address =
Address.fromHex(
"0x0000a4984bd495d4346fa208ddff4f5d5e5ad48c21dec631ddebc99809f16900"
)
val faucetClient = FaucetClient.newLocal()
val faucetReceipt = faucetClient.requestAndWait(address)
if (faucetReceipt != null) {
println("Faucet receipt:")
for (coin in faucetReceipt.sent) {
println(
" Coin ID: ${coin.id.toHex()}, Amount: ${coin.amount}, Digest: ${coin.transferTxDigest.toBase58()}"
)
}
} else {
println("Faucet receipt: null")
}
} catch (e: Exception) {
e.printStackTrace()
}
}
22 changes: 22 additions & 0 deletions bindings/python/examples/faucet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright (c) 2025 IOTA Stiftung
# SPDX-License-Identifier: Apache-2.0

from lib.iota_sdk_ffi import *

import asyncio


async def main():
address = Address.from_hex("0x0000a4984bd495d4346fa208ddff4f5d5e5ad48c21dec631ddebc99809f16900")
faucet_client = FaucetClient.new_local()
faucet_receipt = await faucet_client.request_and_wait(address)
if faucet_receipt:
print("Faucet receipt:")
for coin in faucet_receipt.sent:
print(f" Coin ID: {coin.id.to_hex()}, Amount: {coin.amount}, Digest: {coin.transfer_tx_digest.to_base58()}")
else:
print("Faucet receipt: None")


if __name__ == "__main__":
asyncio.run(main())
26 changes: 26 additions & 0 deletions crates/iota-graphql-client/examples/faucet.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use anyhow::Result;
use iota_graphql_client::faucet::FaucetClient;
use iota_types::Address;

#[tokio::main]
async fn main() -> Result<()> {
let address =
Address::from_hex("0x0000a4984bd495d4346fa208ddff4f5d5e5ad48c21dec631ddebc99809f16900")?;
let faucet_receipt = FaucetClient::local().request_and_wait(address).await?;
if let Some(receipt) = faucet_receipt {
println!("Faucet receipt:");
for coin in &receipt.sent {
println!(
" Coin ID: {}, Amount: {}, Digest: {}",
coin.id, coin.amount, coin.transfer_tx_digest
);
}
} else {
println!("Faucet receipt: None");
}

Ok(())
}
Loading