Skip to content

DevNet Types

Type definitions and structures used in the DevNet package.

DevNet

Main structure representing a connection to a Starknet DevNet instance.

Type Definition

type DevNet struct {
	// contains filtered or unexported fields
}

Description

DevNet encapsulates the connection to a running starknet-devnet instance. It maintains the base URL and HTTP client for communication with the DevNet server.

The struct contains unexported fields that manage:

  • Base URL of the DevNet instance
  • HTTP client for API requests
  • Request configuration

Creating a DevNet Instance

// Default connection (http://localhost:5050)
devNet := devnet.NewDevNet()
 
// Custom URL
devNet := devnet.NewDevNet("http://localhost:5051")
 
// Remote DevNet
devNet := devnet.NewDevNet("http://192.168.1.100:5050")

Available Methods

DevNet provides the following methods:

  • Accounts() - Retrieve pre-funded test accounts
  • FeeToken() - Get fee token information
  • IsAlive() - Check if DevNet is running
  • Mint() - Mint tokens to an address

See DevNet Methods for detailed documentation.

Usage Example

package main
 
import (
	"fmt"
	"log"
	"math/big"
 
	"github.com/NethermindEth/starknet.go/devnet"
	"github.com/NethermindEth/starknet.go/utils"
)
 
func main() {
	// Create DevNet instance
	devNet := devnet.NewDevNet()
 
	// Verify connection
	if !devNet.IsAlive() {
		log.Fatal("DevNet is not running")
	}
 
	// Use DevNet methods
	accounts, err := devNet.Accounts()
	if err != nil {
		log.Fatal(err)
	}
 
	fmt.Printf("Connected to DevNet with %d accounts\n", len(accounts))
 
	// Mint tokens
	address, _ := utils.HexToFelt(accounts[0].Address)
	amount := big.NewInt(1000000000000000000)
 
	mintResp, err := devNet.Mint(address, amount)
	if err != nil {
		log.Fatal(err)
	}
 
	fmt.Printf("Minted %s %s\n", mintResp.NewBalance, mintResp.Unit)
}

Related Functions


TestAccount

Represents a pre-funded test account provided by DevNet.

Type Definition

type TestAccount struct {
	PrivateKey string
	PublicKey  string
	Address    string
}

Fields

PrivateKey

PrivateKey string

Private key of the test account as a hex string with 0x prefix. Used for signing transactions and messages.

Format: 0x followed by 64 hexadecimal characters

Example: 0x00c1cf1490de1352865301bb8705143f3ef938f97fdf892f1090dcb5ac7bcd1d

PublicKey

PublicKey string

Public key derived from the private key as a hex string with 0x prefix. Used for account identification and verification.

Format: 0x followed by 64 hexadecimal characters

Example: 0x02b191c2f3ecf685a91af7cf72a43e7b90e2e41220175de5c4f7498981b10053

Address

Address string

Deployed account contract address on the DevNet network as a hex string with 0x prefix. This is where the account exists on-chain.

Format: 0x followed by up to 64 hexadecimal characters

Example: 0x0691c5c4fa7e87894f08fcb2f9eb5f1e8db0b2f3e3c1c4e8d7b5c9f3e7d2b1a0

Usage Example

package main
 
import (
	"fmt"
	"log"
 
	"github.com/NethermindEth/starknet.go/devnet"
)
 
func main() {
	devNet := devnet.NewDevNet()
 
	// Get test accounts
	accounts, err := devNet.Accounts()
	if err != nil {
		log.Fatal(err)
	}
 
	// Access first account
	testAccount := accounts[0]
 
	fmt.Printf("Test Account Details:\n")
	fmt.Printf("  Private Key: %s\n", testAccount.PrivateKey)
	fmt.Printf("  Public Key:  %s\n", testAccount.PublicKey)
	fmt.Printf("  Address:     %s\n", testAccount.Address)
 
	// Iterate through all accounts
	for i, acc := range accounts {
		fmt.Printf("\nAccount %d:\n", i)
		fmt.Printf("  Address: %s\n", acc.Address)
	}
}

Usage Example with Account Package

package main
 
import (
	"context"
	"fmt"
	"log"
 
	"github.com/NethermindEth/starknet.go/account"
	"github.com/NethermindEth/starknet.go/devnet"
	"github.com/NethermindEth/starknet.go/rpc"
	"github.com/NethermindEth/starknet.go/utils"
)
 
func createAccountFromTestAccount(
	testAccount devnet.TestAccount,
	provider rpc.RPCProvider,
) (*account.Account, error) {
	// Convert string keys to felt
	privateKey, err := utils.HexToFelt(testAccount.PrivateKey)
	if err != nil {
		return nil, fmt.Errorf("invalid private key: %w", err)
	}
 
	publicKey, err := utils.HexToFelt(testAccount.PublicKey)
	if err != nil {
		return nil, fmt.Errorf("invalid public key: %w", err)
	}
 
	address, err := utils.HexToFelt(testAccount.Address)
	if err != nil {
		return nil, fmt.Errorf("invalid address: %w", err)
	}
 
	// Create keystore
	ks := account.NewMemKeystore()
	ks.Put(publicKey.String(), privateKey)
 
	// Create account
	acc, err := account.NewAccount(
		provider,
		address,
		publicKey.String(),
		ks,
		account.CairoV2,
	)
	if err != nil {
		return nil, fmt.Errorf("failed to create account: %w", err)
	}
 
	return acc, nil
}
 
func main() {
	// Get DevNet test account
	devNet := devnet.NewDevNet()
	accounts, err := devNet.Accounts()
	if err != nil {
		log.Fatal(err)
	}
 
	// Create RPC provider
	provider, err := rpc.NewProvider("http://localhost:5050/rpc")
	if err != nil {
		log.Fatal(err)
	}
 
	// Convert to account.Account
	acc, err := createAccountFromTestAccount(accounts[0], provider)
	if err != nil {
		log.Fatal(err)
	}
 
	// Use account for transactions
	nonce, err := acc.Nonce(context.Background())
	if err != nil {
		log.Fatal(err)
	}
 
	fmt.Printf("Account nonce: %s\n", nonce.String())
}

Usage Example with Multiple Accounts

package main
 
import (
	"fmt"
	"log"
 
	"github.com/NethermindEth/starknet.go/devnet"
)
 
func main() {
	devNet := devnet.NewDevNet()
 
	accounts, err := devNet.Accounts()
	if err != nil {
		log.Fatal(err)
	}
 
	// Use different accounts for different roles
	deployer := accounts[0]
	user1 := accounts[1]
	user2 := accounts[2]
 
	fmt.Printf("Deployer address: %s\n", deployer.Address)
	fmt.Printf("User 1 address: %s\n", user1.Address)
	fmt.Printf("User 2 address: %s\n", user2.Address)
 
	// In tests, you might use:
	// - deployer: Deploy contracts
	// - user1: Interact with contracts
	// - user2: Test multi-user scenarios
}

Description

TestAccount represents a pre-funded account provided by DevNet for testing purposes. These accounts are:

  • Pre-deployed: Account contracts already exist on-chain
  • Pre-funded: Contain initial balance for gas fees
  • Deterministic: Same accounts generated on each DevNet restart (with same seed)
  • Ready to use: No setup or deployment required

Each DevNet instance typically provides 10 test accounts, though this number may vary based on configuration.

Security Note

Test accounts should only be used in development and testing environments. Never use DevNet private keys on mainnet or testnet, as they are publicly known and insecure.

Related Methods


FeeToken

Represents the token used for transaction fees on the DevNet network.

Type Definition

type FeeToken struct {
	Symbol  string
	Address *felt.Felt
}

Fields

Symbol

Symbol string

Token symbol identifying the fee token.

Common values:

  • "ETH" - Ethereum token
  • "STRK" - Starknet token

Example: "ETH"

Address

Address *felt.Felt

Contract address of the fee token on the DevNet network as a felt value.

Example: 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 (ETH on Sepolia)

Usage Example

package main
 
import (
	"fmt"
	"log"
 
	"github.com/NethermindEth/starknet.go/devnet"
)
 
func main() {
	devNet := devnet.NewDevNet()
 
	// Get fee token information
	feeToken, err := devNet.FeeToken()
	if err != nil {
		log.Fatal(err)
	}
 
	fmt.Printf("Fee Token Information:\n")
	fmt.Printf("  Symbol: %s\n", feeToken.Symbol)
	fmt.Printf("  Address: %s\n", feeToken.Address.String())
	fmt.Printf("  Address (hex): 0x%s\n", feeToken.Address.Text(16))
}

Usage Example with RPC

package main
 
import (
	"context"
	"fmt"
	"log"
 
	"github.com/NethermindEth/juno/core/felt"
	"github.com/NethermindEth/starknet.go/devnet"
	"github.com/NethermindEth/starknet.go/rpc"
	"github.com/NethermindEth/starknet.go/utils"
)
 
func main() {
	// Get fee token info from DevNet
	devNet := devnet.NewDevNet()
	feeToken, err := devNet.FeeToken()
	if err != nil {
		log.Fatal(err)
	}
 
	// Create RPC provider
	provider, err := rpc.NewProvider("http://localhost:5050/rpc")
	if err != nil {
		log.Fatal(err)
	}
 
	// Query token balance
	accounts, _ := devNet.Accounts()
	accountAddress, _ := utils.HexToFelt(accounts[0].Address)
 
	// Get balance selector
	balanceOfSelector := utils.GetSelectorFromNameFelt("balanceOf")
 
	// Call balanceOf
	result, err := provider.Call(
		context.Background(),
		rpc.FunctionCall{
			ContractAddress:    feeToken.Address,
			EntryPointSelector: balanceOfSelector,
			Calldata:           []*felt.Felt{accountAddress},
		},
		rpc.WithBlockTag("latest"),
	)
	if err != nil {
		log.Fatal(err)
	}
 
	// result[0] contains the balance (low), result[1] contains high bits
	fmt.Printf("Account balance of %s: %s\n",
		feeToken.Symbol,
		result[0].String())
}

Usage Example with Token Contract

package main
 
import (
	"context"
	"fmt"
	"log"
 
	"github.com/NethermindEth/juno/core/felt"
	"github.com/NethermindEth/starknet.go/account"
	"github.com/NethermindEth/starknet.go/devnet"
	"github.com/NethermindEth/starknet.go/rpc"
	"github.com/NethermindEth/starknet.go/utils"
)
 
func main() {
	devNet := devnet.NewDevNet()
 
	// Get fee token
	feeToken, err := devNet.FeeToken()
	if err != nil {
		log.Fatal(err)
	}
 
	// Setup account (simplified)
	provider, _ := rpc.NewProvider("http://localhost:5050/rpc")
	accounts, _ := devNet.Accounts()
	// ... create acc from accounts[0] ...
 
	var acc *account.Account // Assume created
 
	// Transfer fee tokens
	recipientAddress, _ := utils.HexToFelt("0x1234...")
	amount := felt.Zero.SetUint64(1000000000000000000) // 1 token
	lowBits := amount
	highBits := felt.Zero
 
	functionCalls := []rpc.InvokeFunctionCall{
		{
			ContractAddress:    feeToken.Address,
			EntryPointSelector: utils.GetSelectorFromNameFelt("transfer"),
			Calldata:           []*felt.Felt{recipientAddress, lowBits, highBits},
		},
	}
 
	response, err := acc.BuildAndSendInvokeTxn(
		context.Background(),
		functionCalls,
		nil,
	)
	if err != nil {
		log.Fatal(err)
	}
 
	fmt.Printf("Transferred %s tokens\n", feeToken.Symbol)
	fmt.Printf("Transaction hash: %s\n", response.TransactionHash)
}

Description

FeeToken provides information about the token used for paying transaction fees on the DevNet network. This information is useful for:

  • Balance Queries: Check fee token balances before transactions
  • Token Transfers: Transfer fee tokens between accounts
  • Contract Interactions: Approve token spending for contracts
  • Testing: Verify correct fee token usage in contracts

The fee token address can be used with the RPC provider to interact with the token contract directly, enabling operations like:

  • balanceOf(account) - Query balance
  • transfer(to, amount) - Transfer tokens
  • approve(spender, amount) - Approve spending

Related Methods

  • FeeToken - Retrieve fee token information
  • Mint - Mint fee tokens

MintResponse

Represents the response from a token minting operation.

Type Definition

type MintResponse struct {
	NewBalance      string
	Unit            string
	TransactionHash string
}

Fields

NewBalance

NewBalance string

New token balance of the address after minting, as a decimal string.

Format: Decimal string in wei (smallest unit)

Example: "2000000000000000000" (2 tokens)

Unit

Unit string

Unit of the minted token.

Common values:

  • "WEI" - Wei (10^-18 of a token)
  • "ETH" - Ethereum token
  • "STRK" - Starknet token

Example: "WEI"

TransactionHash

TransactionHash string

Hash of the minting transaction as a hex string with 0x prefix.

Format: 0x followed by 64 hexadecimal characters

Example: 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef

Usage Example

package main
 
import (
	"fmt"
	"log"
	"math/big"
 
	"github.com/NethermindEth/starknet.go/devnet"
	"github.com/NethermindEth/starknet.go/utils"
)
 
func main() {
	devNet := devnet.NewDevNet()
 
	// Mint tokens
	address, _ := utils.HexToFelt("0x1234...")
	amount := big.NewInt(1000000000000000000) // 1 token
 
	mintResp, err := devNet.Mint(address, amount)
	if err != nil {
		log.Fatal(err)
	}
 
	// Access response fields
	fmt.Printf("Mint Response:\n")
	fmt.Printf("  New Balance: %s %s\n", mintResp.NewBalance, mintResp.Unit)
	fmt.Printf("  Transaction Hash: %s\n", mintResp.TransactionHash)
 
	// Parse balance
	balance := new(big.Int)
	balance.SetString(mintResp.NewBalance, 10)
	fmt.Printf("  Balance (big.Int): %s\n", balance.String())
}

Usage Example with Transaction Verification

package main
 
import (
	"context"
	"fmt"
	"log"
	"math/big"
	"time"
 
	"github.com/NethermindEth/starknet.go/devnet"
	"github.com/NethermindEth/starknet.go/rpc"
	"github.com/NethermindEth/starknet.go/utils"
)
 
func main() {
	devNet := devnet.NewDevNet()
 
	// Mint tokens
	address, _ := utils.HexToFelt("0x1234...")
	amount := big.NewInt(5000000000000000000) // 5 tokens
 
	mintResp, err := devNet.Mint(address, amount)
	if err != nil {
		log.Fatal(err)
	}
 
	fmt.Printf("Minted %s %s\n", mintResp.NewBalance, mintResp.Unit)
 
	// Verify transaction on-chain
	provider, err := rpc.NewProvider("http://localhost:5050/rpc")
	if err != nil {
		log.Fatal(err)
	}
 
	txHash, err := utils.HexToFelt(mintResp.TransactionHash)
	if err != nil {
		log.Fatal(err)
	}
 
	// Wait for transaction (on devnet it's instant, but good practice)
	time.Sleep(1 * time.Second)
 
	// Get transaction receipt
	receipt, err := provider.TransactionReceipt(
		context.Background(),
		txHash,
	)
	if err != nil {
		log.Fatal(err)
	}
 
	fmt.Printf("Transaction Status: %s\n", receipt.ExecutionStatus)
	fmt.Printf("Block Number: %d\n", receipt.BlockNumber)
}

Usage Example with Balance Tracking

package main
 
import (
	"fmt"
	"log"
	"math/big"
 
	"github.com/NethermindEth/starknet.go/devnet"
	"github.com/NethermindEth/starknet.go/utils"
)
 
func mintAndTrack(
	devNet *devnet.DevNet,
	address string,
	amounts []*big.Int,
) error {
	addr, err := utils.HexToFelt(address)
	if err != nil {
		return err
	}
 
	fmt.Printf("Minting to address: %s\n", address)
 
	for i, amount := range amounts {
		mintResp, err := devNet.Mint(addr, amount)
		if err != nil {
			return fmt.Errorf("mint %d failed: %w", i, err)
		}
 
		fmt.Printf("  [%d] Minted %s, New Balance: %s %s\n",
			i+1,
			amount.String(),
			mintResp.NewBalance,
			mintResp.Unit)
	}
 
	return nil
}
 
func main() {
	devNet := devnet.NewDevNet()
 
	amounts := []*big.Int{
		big.NewInt(1000000000000000000),  // 1 token
		big.NewInt(2000000000000000000),  // 2 tokens
		big.NewInt(5000000000000000000),  // 5 tokens
	}
 
	err := mintAndTrack(devNet, "0x1234...", amounts)
	if err != nil {
		log.Fatal(err)
	}
}

Description

MintResponse contains the results of a token minting operation on DevNet. The response provides:

  • Balance Confirmation: New total balance after minting
  • Transaction Proof: Hash of the minting transaction
  • Unit Information: Token denomination for clarity

This information is useful for:

  • Verifying successful minting
  • Tracking balance changes
  • Confirming transaction inclusion
  • Debugging test scenarios

The new balance represents the total balance after the mint operation, not the amount minted. If the address already had tokens, the new balance includes both the previous balance and the newly minted amount.

Balance Calculation

// If address had 1 token and you mint 2 tokens:
// NewBalance = "3000000000000000000" (3 tokens total)
 
// To calculate minted amount:
previousBalance := big.NewInt(1000000000000000000) // 1 token
newBalance := new(big.Int)
newBalance.SetString(mintResp.NewBalance, 10)
 
mintedAmount := new(big.Int).Sub(newBalance, previousBalance)
fmt.Printf("Minted: %s wei\n", mintedAmount.String())

Related Methods

  • Mint - Mint tokens and get response

Summary

The DevNet package provides four main types for local development:

  • DevNet: Connection to DevNet instance
  • TestAccount: Pre-funded test account with keys
  • FeeToken: Fee token metadata
  • MintResponse: Token minting result

These types work together to enable seamless local testing without external dependencies or gas costs.

Type Relationships

DevNet
  |
  +-- Accounts() -> []TestAccount
  |
  +-- FeeToken() -> *FeeToken
  |
  +-- Mint() -> *MintResponse

Related Documentation