package examples
import (
"fmt"
"github.com/availproject/avail-go-sdk/metadata/pallets"
baPallet "github.com/availproject/avail-go-sdk/metadata/pallets/balances"
utPallet "github.com/availproject/avail-go-sdk/metadata/pallets/utility"
"github.com/availproject/avail-go-sdk/primitives"
prim "github.com/availproject/avail-go-sdk/primitives"
SDK "github.com/availproject/avail-go-sdk/sdk"
)
func RunBatch() {
sdk, err := SDK.NewSDK(SDK.LocalEndpoint)
PanicOnError(err)
// Use SDK.Account.NewKeyPair("Your key") to use a different account than Alice
acc := SDK.Account.Alice()
callsToExecute := []prim.Call{}
// One way to create a suitable call for the batch transaction is to manually create the desired call and then convert it to a generic call
{
destBob, err := primitives.NewAccountIdFromAddress("5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty")
PanicOnError(err)
call := baPallet.CallTransferKeepAlive{Dest: destBob.ToMultiAddress(), Value: SDK.OneAvail()}
callsToExecute = append(callsToExecute, pallets.ToCall(call))
}
// The other was it to create a transaction using the sdk api and then use the `call` field member
{
destCharlie, err := primitives.NewAccountIdFromAddress("5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y")
PanicOnError(err)
tx := sdk.Tx.Balances.TransferKeepAlive(destCharlie.ToMultiAddress(), SDK.OneAvail())
callsToExecute = append(callsToExecute, tx.Payload.Call)
}
//
// Happy Path
//
// Batch call
{
tx := sdk.Tx.Utility.Batch(callsToExecute)
res, err := tx.ExecuteAndWatchInclusion(acc, SDK.NewTransactionOptions().WithAppId(0))
PanicOnError(err)
AssertTrue(res.IsSuccessful().UnsafeUnwrap(), "Transaction is supposed to succeed")
events := res.Events.UnsafeUnwrap()
event := SDK.EventFindFirst(events, utPallet.EventBatchCompleted{})
AssertTrue(event.IsSome(), "BatchCompleted event must be present.")
event_count := len(SDK.EventFind(events, utPallet.EventItemCompleted{}))
AssertEq(event_count, 2, "ItemCompleted events must be produced twice")
fmt.Println("Batch call done")
}
// Batch All call
{
tx := sdk.Tx.Utility.BatchAll(callsToExecute)
res, err := tx.ExecuteAndWatchInclusion(acc, SDK.NewTransactionOptions().WithAppId(0))
PanicOnError(err)
AssertTrue(res.IsSuccessful().UnsafeUnwrap(), "Transaction is supposed to succeed")
events := res.Events.UnsafeUnwrap()
event := SDK.EventFindFirst(events, utPallet.EventBatchCompleted{})
AssertTrue(event.IsSome(), "BatchCompleted event must be present.")
event_count := len(SDK.EventFind(events, utPallet.EventItemCompleted{}))
AssertEq(event_count, 2, "ItemCompleted events must be produced twice")
fmt.Println("Batch All call done")
}
// Force Batch call
{
tx := sdk.Tx.Utility.ForceBatch(callsToExecute)
res, err := tx.ExecuteAndWatchInclusion(acc, SDK.NewTransactionOptions().WithAppId(0))
PanicOnError(err)
AssertTrue(res.IsSuccessful().UnsafeUnwrap(), "Transaction is supposed to succeed")
events := res.Events.UnsafeUnwrap()
event := SDK.EventFindFirst(events, utPallet.EventBatchCompleted{})
AssertTrue(event.IsSome(), "BatchCompleted event must be present.")
event_count := len(SDK.EventFind(events, utPallet.EventItemCompleted{}))
AssertEq(event_count, 2, "ItemCompleted events must be produced twice")
fmt.Println("Force Batch call done")
}
//
// Things differ when we introduce a call that will fail
//
// The 3. is poisoned with a too high transfer amount
{
destEve, err := primitives.NewAccountIdFromAddress("5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw")
PanicOnError(err)
tx := sdk.Tx.Balances.TransferKeepAlive(destEve.ToMultiAddress(), SDK.OneAvail().Mul64(uint64(1_000_000_000)))
callsToExecute = append(callsToExecute, tx.Payload.Call)
}
// The 4. call is a normal one
{
destDave, err := primitives.NewAccountIdFromAddress("5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy")
PanicOnError(err)
tx := sdk.Tx.Balances.TransferKeepAlive(destDave.ToMultiAddress(), SDK.OneAvail())
callsToExecute = append(callsToExecute, tx.Payload.Call)
}
// Batch call
{
tx := sdk.Tx.Utility.Batch(callsToExecute)
res, err := tx.ExecuteAndWatchInclusion(acc, SDK.NewTransactionOptions().WithAppId(0))
PanicOnError(err)
AssertTrue(res.IsSuccessful().UnsafeUnwrap(), "Transaction is supposed to succeed")
events := res.Events.UnsafeUnwrap()
event := SDK.EventFindFirst(events, utPallet.EventBatchInterrupted{})
AssertTrue(event.IsSome(), "BatchInterrupted event must be present.")
event2 := SDK.EventFindFirst(events, utPallet.EventBatchCompleted{})
AssertTrue(event2.IsNone(), "BatchCompleted event must NOT be present.")
event_count := len(SDK.EventFind(events, utPallet.EventItemCompleted{}))
AssertEq(event_count, 2, "ItemCompleted events must be produced twice")
fmt.Println("Batch call done")
}
// Batch All call
{
tx := sdk.Tx.Utility.BatchAll(callsToExecute)
res, err := tx.ExecuteAndWatchInclusion(acc, SDK.NewTransactionOptions().WithAppId(0))
PanicOnError(err)
AssertEq(res.IsSuccessful(), prim.Some(false), "Transaction is supposed to fail")
fmt.Println("Batch All call done")
}
// Force Batch call
{
tx := sdk.Tx.Utility.ForceBatch(callsToExecute)
res, err := tx.ExecuteAndWatchInclusion(acc, SDK.NewTransactionOptions().WithAppId(0))
PanicOnError(err)
AssertTrue(res.IsSuccessful().UnsafeUnwrap(), "Transaction is supposed to succeed")
events := res.Events.UnsafeUnwrap()
event := SDK.EventFindFirst(events, utPallet.EventBatchCompletedWithErrors{})
AssertTrue(event.IsSome(), "BatchCompletedWithErrors event must be present.")
event_count := len(SDK.EventFind(events, utPallet.EventItemCompleted{}))
AssertEq(event_count, 3, "ItemCompleted events must be produced thrice")
event_count2 := len(SDK.EventFind(events, utPallet.EventItemFailed{}))
AssertEq(event_count2, 1, "ItemFailed events must be produced once")
fmt.Println("Force Batch call done")
}
fmt.Println("RunBatch finished correctly.")
}