diff --git a/avalanche/avalanche.go b/avalanche/avalanche.go index 47770f3..3f1d49b 100644 --- a/avalanche/avalanche.go +++ b/avalanche/avalanche.go @@ -6,3 +6,22 @@ package avalanche const ( SubnetEVMRepoName = "subnet-evm" ) + +// BaseApp provides a base type that implements the foundation of Avalanche SDK +// including Logger +type BaseApp struct { + // The logger writer interface to write logging messages to. + Logger LeveledLoggerInterface +} + +// New creates a new base type of Avalanche SDK +// if logger is nil, default logger DefaultLeveledLogger will be used instead +func New(logger LeveledLoggerInterface) *BaseApp { + if logger == nil { + logger = DefaultLeveledLogger + } + baseApp := &BaseApp{ + Logger: logger, + } + return baseApp +} diff --git a/avalanche/log.go b/avalanche/log.go new file mode 100644 index 0000000..db44b8a --- /dev/null +++ b/avalanche/log.go @@ -0,0 +1,145 @@ +// Copyright (C) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package avalanche + +import ( + "fmt" + "io" + "os" +) + +// +// Public constants +// + +const ( + // LevelNull sets a logger to show no messages at all. + LevelNull Level = 0 + + // LevelError sets a logger to show error messages only. + LevelError Level = 1 + + // LevelWarn sets a logger to show warning messages or anything more + // severe. + LevelWarn Level = 2 + + // LevelInfo sets a logger to show informational messages or anything more + // severe. + LevelInfo Level = 3 + + // LevelDebug sets a logger to show informational messages or anything more + // severe. + LevelDebug Level = 4 +) + +// +// Public variables +// + +// DefaultLeveledLogger is the default logger that the library will use to log +// errors, warnings, and informational messages. +// +// LeveledLoggerInterface is implemented by LeveledLogger, and one can be +// initialized at the desired level of logging. LeveledLoggerInterface also +// provides out-of-the-box compatibility with a Logrus Logger, but may require +// a thin shim for use with other logging libraries that use less standard +// conventions like Zap. +// +// This Logger will be inherited by any backends created by default, but will +// be overridden if a backend is created with GetBackendWithConfig with a +// custom LeveledLogger set. +var DefaultLeveledLogger LeveledLoggerInterface = &LeveledLogger{ + Level: LevelError, +} + +// +// Public types +// + +// Level represents a logging level. +type Level uint32 + +// LeveledLogger is a leveled logger implementation. +// +// It prints warnings and errors to `os.Stderr` and other messages to +// `os.Stdout`. +type LeveledLogger struct { + // Level is the minimum logging level that will be emitted by this logger. + // + // For example, a Level set to LevelWarn will emit warnings and errors, but + // not informational or debug messages. + // + // Always set this with a constant like LevelWarn because the individual + // values are not guaranteed to be stable. + Level Level + + // Internal testing use only. + stderrOverride io.Writer + stdoutOverride io.Writer +} + +// Debugf logs a debug message using Printf conventions. +func (l *LeveledLogger) Debugf(format string, v ...interface{}) { + if l.Level >= LevelDebug { + fmt.Fprintf(l.stdout(), "[DEBUG] "+format+"\n", v...) + } +} + +// Errorf logs a warning message using Printf conventions. +func (l *LeveledLogger) Errorf(format string, v ...interface{}) { + // Infof logs a debug message using Printf conventions. + if l.Level >= LevelError { + fmt.Fprintf(l.stderr(), "[ERROR] "+format+"\n", v...) + } +} + +// Infof logs an informational message using Printf conventions. +func (l *LeveledLogger) Infof(format string, v ...interface{}) { + if l.Level >= LevelInfo { + fmt.Fprintf(l.stdout(), "[INFO] "+format+"\n", v...) + } +} + +// Warnf logs a warning message using Printf conventions. +func (l *LeveledLogger) Warnf(format string, v ...interface{}) { + if l.Level >= LevelWarn { + fmt.Fprintf(l.stderr(), "[WARN] "+format+"\n", v...) + } +} + +func (l *LeveledLogger) stderr() io.Writer { + if l.stderrOverride != nil { + return l.stderrOverride + } + + return os.Stderr +} + +func (l *LeveledLogger) stdout() io.Writer { + if l.stdoutOverride != nil { + return l.stdoutOverride + } + + return os.Stdout +} + +// LeveledLoggerInterface provides a basic leveled logging interface for +// printing debug, informational, warning, and error messages. +// +// It's implemented by LeveledLogger and also provides out-of-the-box +// compatibility with a Logrus Logger, but may require a thin shim for use with +// other logging libraries that you use less standard conventions like Zap. +type LeveledLoggerInterface interface { + // Debugf logs a debug message using Printf conventions. + Debugf(format string, v ...interface{}) + + // Errorf logs a warning message using Printf conventions. + Errorf(format string, v ...interface{}) + + // Infof logs an informational message using Printf conventions. + Infof(format string, v ...interface{}) + + // Warnf logs a warning message using Printf conventions. + Warnf(format string, v ...interface{}) +} diff --git a/subnet/deploy_subnet.go b/subnet/deploy_subnet.go index 81aae0c..66202b9 100644 --- a/subnet/deploy_subnet.go +++ b/subnet/deploy_subnet.go @@ -19,15 +19,15 @@ import ( "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) -// createSubnetTx creates uncommitted createSubnet transaction -func createSubnetTx(subnet Subnet, wallet primary.Wallet) (*txs.Tx, error) { - addrs, err := address.ParseToIDs(subnet.ControlKeys) +// CreateSubnetTx creates uncommitted createSubnet transaction +func (c *Subnet) CreateSubnetTx(wallet primary.Wallet) (*txs.Tx, error) { + addrs, err := address.ParseToIDs(c.ControlKeys) if err != nil { return nil, fmt.Errorf("failure parsing control keys: %w", err) } owners := &secp256k1fx.OutputOwners{ Addrs: addrs, - Threshold: subnet.Threshold, + Threshold: c.Threshold, Locktime: 0, } unsignedTx, err := wallet.P().Builder().NewCreateSubnetTx( @@ -43,17 +43,17 @@ func createSubnetTx(subnet Subnet, wallet primary.Wallet) (*txs.Tx, error) { return &tx, nil } -// createBlockchainTx creates uncommitted createBlockchain transaction -func createBlockchainTx(subnet Subnet, wallet primary.Wallet, keyChain avalanche.Keychain) (*txs.Tx, error) { +// CreateBlockchainTx creates uncommitted createBlockchain transaction +func (c *Subnet) CreateBlockchainTx(wallet primary.Wallet, keyChain avalanche.Keychain) (*txs.Tx, error) { fxIDs := make([]ids.ID, 0) - options := getMultisigTxOptions(keyChain.Keychain, subnet.SubnetAuthKeys) + options := getMultisigTxOptions(keyChain.Keychain, c.SubnetAuthKeys) // create tx unsignedTx, err := wallet.P().Builder().NewCreateChainTx( - subnet.SubnetID, - subnet.Genesis, - subnet.VMID, + c.SubnetID, + c.Genesis, + c.VMID, fxIDs, - subnet.Name, + c.Name, options..., ) if err != nil { diff --git a/subnet/subnet.go b/subnet/subnet.go index 271687d..af08336 100644 --- a/subnet/subnet.go +++ b/subnet/subnet.go @@ -3,7 +3,10 @@ package subnet -import "github.com/ava-labs/avalanchego/ids" +import ( + "avalanche-tooling-sdk-go/avalanche" + "github.com/ava-labs/avalanchego/ids" +) type SubnetParams struct { // File path of Genesis to use @@ -111,4 +114,13 @@ type Subnet struct { TokenName string TokenSymbol string + + Logger avalanche.LeveledLoggerInterface +} + +func New(client *avalanche.BaseApp, subnetParams *SubnetParams) *Subnet { + subnet := Subnet{ + Logger: client.Logger, + } + return &subnet } diff --git a/subnet/subnet_test.go b/subnet/subnet_test.go new file mode 100644 index 0000000..56e70f0 --- /dev/null +++ b/subnet/subnet_test.go @@ -0,0 +1,42 @@ +// Copyright (C) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package subnet + +import ( + "avalanche-tooling-sdk-go/avalanche" + "context" + "fmt" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" + "testing" +) + +func TestSubnetDeploy(t *testing.T) { + baseApp := avalanche.New(avalanche.DefaultLeveledLogger) + subnetParams := SubnetParams{ + SubnetEVM: SubnetEVMParams{ + EvmChainID: 1234567, + EvmToken: "AVAX", + EvmDefaults: true, + UseLatestReleasedEvmVersion: true, + EnableWarp: true, + EnableTeleporter: true, + EnableRelayer: true, + }, + } + newSubnet := New(baseApp, &subnetParams) + ctx := context.Background() + wallet, _ := primary.MakeWallet( + ctx, + &primary.WalletConfig{ + URI: "", + AVAXKeychain: nil, + EthKeychain: secp256k1fx.NewKeychain(), + PChainTxsToFetch: nil, + }, + ) + //deploy Subnet returns tx ID and error + deploySubnetTx, _ := newSubnet.CreateSubnetTx(wallet) + fmt.Printf("deploySubnetTx %s", deploySubnetTx) +} diff --git a/utils/common.go b/utils/common.go deleted file mode 100644 index fbe5340..0000000 --- a/utils/common.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (C) 2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. -package utils - -func Filter[T any](input []T, f func(T) bool) []T { - output := make([]T, 0, len(input)) - for _, e := range input { - if f(e) { - output = append(output, e) - } - } - return output -}