Skip to content

alt-research/arbitrum-orbit-sdk-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

65 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Arbitrum Orbit SDK

A golang library and command line tool for client-side intereactions with Orbit chains.

Overview

Arbitrum Orbit SDK simplifies the process of deploying nitro contracts, bridge setup, as well as interacting with orbit chains, offering a robust set of tools for asset bridging and cross-chain messaging.

Installation

go get github.com/alt-research/arbitrum-orbit-sdk-go

Key Features

Rollup Creation/Nitro Contract Deployment

Rollup creation or nitro contract deployment is handled through RollupCreator. The creator accepts a set of parameters as rollup config, call CreateRollup on RollupCreator factory contract, parse rollup contracts' address from receipt logs.

Token Bridge Setup

Bridge setup is handled through BridgeDeployer. The deployer accepts a setp of parameters including rollup address created by RollupCreator, simulate and estimate necessary transactions would be happening both on parent chain and child chain, then call CreateTokenBridge on TokenBridgeFactory contract.

Cross-Chain Messages

L1 -> L2 corss chain messaging is handled by ParentToChildMessage, ArbitrumSubmitRetryableTx and ParentTransactionReceipt. Those structs parse logs from inbox and bridge contracts, get all necessary data for calculating retryable id, which can be used for querying redeem status on child chains.

Usage

Important

All exmaple code below is only for demo purpose.

Here's a basic example of using the SDK create rollup:

func main() {
	privateKey := os.Getenv("PRIVATE_KEY")
	owner := os.Getenv("OWNER")
	l1conn := os.Getenv("L1CONN")
	rollupCreator, err := rollup.NewRollupCreator(privateKey, l1conn)
	if err != nil {
		fmt.Printf("create rollup creator failed: %s\n", err.Error())
		os.Exit(1)
	}

	l2configtype := rollup.GenerateL2Config(20240621, owner, false)
	l2config, err := json.Marshal(l2configtype)
	if err != nil {
		fmt.Printf("create l2config failed: %s\n", err.Error())
		os.Exit(1)
	}

	// 0x8b104a2e80ac6165dc58b9048de12f301d70b02a0ab51396c22b4b4b802a16a4
	wmrb, err := hex.DecodeString("8b104a2e80ac6165dc58b9048de12f301d70b02a0ab51396c22b4b4b802a16a4")
	if err != nil {
		fmt.Printf("decode wasm module root failed: %s\n", err.Error())
		os.Exit(1)
	}
	var wasmModuleRoot [32]byte
	copy(wasmModuleRoot[:], wmrb)

	txn, err := rollupCreator.CreateRollup(
		context.Background(),
		common.HexToAddress(owner),
		big.NewInt(20240621),
		421614,
		string(l2config),
		uint64(l2configtype.Arbitrum.GenesisBlockNum),
		common.HexToAddress(owner),
		wasmModuleRoot,
		common.HexToAddress("0x0B03bF93Ef8A8626E5d73DB4d9181E8c10568D7B"),
		[]common.Address{common.HexToAddress("0x7B5bCf696b6C9Ef9189fed66597A4aAC87957a08")},
		big.NewInt(125000000000000000),
		10266112,
	)

	if err != nil {
		fmt.Printf("invoke createRollup failed: %s\n", err.Error())
		os.Exit(1)
	}

	rollupContracts, err := rollupCreator.ParseRollupContracts(context.Background(), 6, txn)
	if err != nil {
		fmt.Printf("parse rollup contracts failed: %s\n", err.Error())
		os.Exit(1)
	}

	contracts, err := json.Marshal(rollupContracts)
	if err != nil {
		fmt.Printf("marshal rollup contracts failed: %s\n", err.Error())
		os.Exit(1)
	}
	fmt.Println(string(contracts))
}

Here's a basic example of using the SDK deploy:

func main() {
	// dummy private key
	privatekey := ""
	baseChainRpc := ""
	chainChainRpc := ""
	rollupAddress := ""
	tokenBridgeCreator := ""
	inboxAddress := ""
	nativeToken := common.Address{}
	bridgeDeployer, err := NewBridgeDeployer(privatekey, baseChainRpc, chainChainRpc, rollupAddress, nativeToken)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	txn, err := bridgeDeployer.CreateNewTokenBridge(
		context.Background(),
		common.HexToAddress(inboxAddress),
		common.HexToAddress(tokenBridgeCreator),
		big.NewInt(100000000),
		nil,
	)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	receipt, err := bind.WaitMined(context.Background(), bridgeDeployer.BaseChainClient, txn)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	fmt.Println(receipt.TxHash)
}

Here's a basic example of using the SDK calculate retryable id:

func main() {
	baseChainRpc := ""
	transactionHash := ""
	from := common.HexToAddress("")
	to := common.HexToAddress("")
	inbox := ""
	l1BaseFee := big.NewInt(100000000)
	baseChainClient, err := ethclient.Dial(baseChainRpc)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}

	txn, _, err := baseChainClient.TransactionByHash(context.Background(), common.HexToHash(transactionHash))
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	receipt, err := bind.WaitMined(context.Background(), baseChainClient, txn)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}

	parentChainReceipt := NewParentTransactionReceipt(to, from, receipt)
	parentToChildMessages, err := parentChainReceipt.GetParentToChildMessages(big.NewInt(20240328), l1BaseFee, inbox)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	for _, parentToChildMessage := range parentToChildMessages {
		fmt.Println(hex.EncodeToString(parentToChildMessage.RetryableCreationId))
	}
}