sequence

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 4, 2021 License: Apache-2.0 Imports: 23 Imported by: 3

README

go-sequence

Sequence Wallet client written in Go.

Usage

TODO: add docs.. etc. examples, etc.

Developing the go-sequence library

  1. make boostrap -- will install node modules of ./testutil/chain
  2. make start-test-chain -- starts the test ethereum chain (id 4337)
  3. (in a separate terminal) make test -- runs test suite

Testing

Testing is super important, to run the tests just call make test. As well, you can run the test-chain separately with make start-test-chain then in another terminal run make test.

NOTE: Go by default will execute tests in parallel if you run go test -v ./..., so ensure to pass -p 1 to set parallelization to just 1 (so it runs serially). The make test command is already set to do this.

A. If you'd like to use a local version of a dependency/module, you can use the replace directive in go.mod, for example, lets say you want to use a local version of "ethkit" that hasn't been released with go-sequence, you can add replace github.com/0xsequence/ethkit => /home/peter/Dev/0xsequence/ethkit to your go.mod

LICENSE

Apache 2.0

Documentation

Index

Constants

View Source
const WalletContractBytecode = "0x603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3"

https://github.com/0xsequence/wallet-contracts/blob/master/src/contracts/Wallet.sol#L57-L59

Variables

View Source
var (
	// NonceChangeEventSig is the signature event emitted as the first event on the batch execution
	// 0x1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881
	NonceChangeEventSig = MustEncodeSig("NonceChange(uint256,uint256)")

	// TxFailedEventSig is the signature event emitted in a failed smart-wallet meta-transaction batch
	// 0x3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd7
	TxFailedEventSig = MustEncodeSig("TxFailed(bytes32,bytes)")

	// TxExecutedEventSig is the signature of the event emitted in a successful transaction
	// ........
	TxExecutedEventSig = MustEncodeSig("TxExecuted(bytes32)")
)

Transaction events as defined in wallet-contracts IModuleCalls.sol

View Source
var (
	ErrUnknownChainID = fmt.Errorf("chainID is unknown")
	ErrProviderNotSet = fmt.Errorf("provider is not set")
	ErrRelayerNotSet  = fmt.Errorf("relayer is not set")
)
View Source
var (
	// ImageHashUpdatedEventSig is emitted anytime wallet config is updated.
	ImageHashUpdatedEventSig = MustEncodeSig("ImageHashUpdated(bytes32)")

	// ImplementationUpdatedEventSig is emitted anytime a wallet's mainModule is changed,
	// this is a rare occurence.
	ImplementationUpdatedEventSig = MustEncodeSig("ImplementationUpdated(address)")
)

Functions

func AddressFromImageHash

func AddressFromImageHash(imageHash string, context WalletContext) (common.Address, error)

func AddressFromWalletConfig

func AddressFromWalletConfig(walletConfig WalletConfig, context WalletContext) (common.Address, error)

func DecodeNonce

func DecodeNonce(raw *big.Int) (*big.Int, *big.Int)

DecodeNonce raw nonce, returns (space, nonce)

func DeploySequenceWallet

func DeploySequenceWallet(sender *ethwallet.Wallet, walletConfig WalletConfig, walletContext WalletContext) (common.Address, *types.Transaction, ethtxn.WaitReceipt, error)

func EncodeNonce

func EncodeNonce(space *big.Int, nonce *big.Int) (*big.Int, error)

EncodeNonce with space

func EncodeTransactions added in v0.2.0

func EncodeTransactions(txns Transactions) ([]byte, error)

func EncodeTransactionsForRelaying

func EncodeTransactionsForRelaying(relayer Relayer, walletConfig WalletConfig, walletContext WalletContext, txns Transactions, nonce *big.Int, seqSig []byte) (common.Address, []byte, error)

returns `to` address (either guest or wallet) and `data` of signed-metatx-calldata, aka execdata

func GenerateRandomNonce

func GenerateRandomNonce() (*big.Int, error)

GenerateRandomNonce returns a random space for a nonce to ensure transactions can be executed in parallel.

func GetWalletNonce

func GetWalletNonce(provider *ethrpc.Provider, walletConfig WalletConfig, walletContext WalletContext, space *big.Int, blockNum *big.Int) (*big.Int, error)

func ImageHashOfWalletConfig

func ImageHashOfWalletConfig(walletConfig WalletConfig) (string, error)

func ImageHashOfWalletConfigBytes

func ImageHashOfWalletConfigBytes(walletConfig WalletConfig) ([]byte, error)

func IsNonceChangedEvent

func IsNonceChangedEvent(logs []*types.Log) bool

func IsTxFailedLog

func IsTxFailedLog(logs []*types.Log) (string, bool, error)

IsTxFailedLog returns true if the log belongs to a failed smart meta-transaction

func IsValidSignature

func IsValidSignature(walletAddress common.Address, digest common.Hash, seqSig []byte, walletContext WalletContext, chainID *big.Int, provider *ethrpc.Provider) (bool, error)

func IsWalletConfigEqual

func IsWalletConfigEqual(walletConfigA, walletConfigB WalletConfig) bool

func IsWalletConfigUsable

func IsWalletConfigUsable(walletConfig WalletConfig) (bool, error)

func IsWalletDeployed

func IsWalletDeployed(provider *ethrpc.Provider, walletAddress common.Address) (bool, error)

func MessageDigest

func MessageDigest(message []byte) common.Hash

func MustEncodeSig

func MustEncodeSig(str string) common.Hash

func PackMessageData

func PackMessageData(chainID *big.Int, owner common.Address, digest common.Hash) ([]byte, error)

PackMessageData encodes a Sequence contract "message"

func SortWalletConfig

func SortWalletConfig(walletConfig WalletConfig) error

func SubDigest

func SubDigest(address common.Address, chainID *big.Int, digest common.Hash) ([]byte, error)

func ValidateSequenceAccountProof

func ValidateSequenceAccountProof() ethauth.ValidatorFunc

func ValidateSequenceAccountProofWith

func ValidateSequenceAccountProofWith(factory, mainModule common.Address) ethauth.ValidatorFunc

Types

type MetaTxnID

type MetaTxnID string

func ComputeMetaTxnID

func ComputeMetaTxnID(walletAddress common.Address, chainID *big.Int, txns Transactions, nonce *big.Int) (MetaTxnID, error)

func ComputeMetaTxnIDFromTransactionsDigest added in v0.2.1

func ComputeMetaTxnIDFromTransactionsDigest(walletAddress common.Address, chainID *big.Int, txnsDigest common.Hash, nonce *big.Int) (MetaTxnID, error)

type MetaTxnStatus added in v0.2.0

type MetaTxnStatus uint8
const (
	MetaTxnStatusUnknown MetaTxnStatus = iota
	MetaTxnExecuted
	MetaTxnFailed
)

func WaitForMetaTxn

func WaitForMetaTxn(ctx context.Context, provider *ethrpc.Provider, metaTxnID MetaTxnID, optTimeout *time.Duration) (MetaTxnStatus, *types.Receipt, error)

type NetworkConfig

type NetworkConfig struct {
	Name       string
	ChainID    big.Int
	ENSAddress *common.Address

	RpcURL   string
	Provider *ethrpc.Provider

	RelayerURL *string // optional, one of the these should be set
	Relayer    Relayer

	IndexerURL *string // optional, one of these should be set

	IsDefaultChain bool
	IsAuthChain    bool

	SequenceAPIURL string
}

type Networks

type Networks []NetworkConfig

type Relayer

type Relayer interface {
	// ..
	GetProvider() *ethrpc.Provider

	// ..
	EstimateGasLimits(ctx context.Context, walletConfig WalletConfig, walletContext WalletContext, txns Transactions) (Transactions, error)

	// NOTE: nonce space is 160 bits wide
	GetNonce(ctx context.Context, walletConfig WalletConfig, walletContext WalletContext, space *big.Int, blockNum *big.Int) (*big.Int, error)

	// Relay will submit the Sequence signed meta transaction to the relayer. The method will block until the relayer
	// responds with the native transaction hash (*types.Transaction), which means the relayer has submitted the transaction
	// request to the network. Clients can use WaitReceipt to wait until the metaTxnID has been mined.
	Relay(ctx context.Context, signedTxs *SignedTransactions) (MetaTxnID, *types.Transaction, ethtxn.WaitReceipt, error)

	// ..
	Wait(ctx context.Context, metaTxnID MetaTxnID, optTimeout *time.Duration) (MetaTxnStatus, *types.Receipt, error)
}

type Signature

type Signature struct {
	Threshold uint16         `json:"threshold"`
	Signers   SignatureParts `json:"signers"`
}

Signature for sequence message

func DecodeSignature

func DecodeSignature(sequenceSignature []byte) (*Signature, error)

DecodeSignature sequence into individual parts

func JoinSignatures

func JoinSignatures(sigs ...*Signature) (*Signature, error)

Join signatures

func Sign

func Sign(wallet *Wallet, input common.Hash) ([]byte, *Signature, error)

func (*Signature) Copy

func (s *Signature) Copy() *Signature

Copy a signature

func (*Signature) Encode

func (s *Signature) Encode() ([]byte, error)

Encode returns encoded sequence signature bytes of all signatures in the Signers set

func (*Signature) ImageHash

func (s *Signature) ImageHash() ([32]byte, error)

ImageHash returns the imagehash for a given signature

func (*Signature) JoinTwo

func (s *Signature) JoinTwo(s2 *Signature) error

JoinTwo signatures, saves the aggregated one into s1

func (*Signature) Recover

func (s *Signature) Recover(msg []byte, provider *ethrpc.Provider) error

Recover signers of signature

func (*Signature) Weight

func (s *Signature) Weight() (uint16, error)

Weight of combined signatures, assumes all signatures to be valid

type SignaturePart

type SignaturePart struct {
	Weight  uint8          `json:"weight"`
	Address common.Address `json:"address"`
	Type    uint8          `json:"type"`  // signature type, ie. EOA, Address, Dynamic
	Value   []byte         `json:"value"` // signature value for this part
}

SignaturePart of an overall sequence signature message

func (*SignaturePart) IsValid

func (p *SignaturePart) IsValid(digest [32]byte, provider *ethrpc.Provider) (bool, error)

IsValid signature part

func (*SignaturePart) Recover

func (p *SignaturePart) Recover(msg []byte) (common.Address, error)

Recover signature part

type SignatureParts

type SignatureParts []*SignaturePart

func (SignatureParts) Len

func (a SignatureParts) Len() int

func (SignatureParts) Less

func (a SignatureParts) Less(i, j int) bool

func (SignatureParts) Swap

func (a SignatureParts) Swap(i, j int)

type SignedTransactions

type SignedTransactions struct {
	ChainID       *big.Int
	WalletConfig  WalletConfig
	WalletContext WalletContext

	Transactions Transactions // The meta-transactions
	Nonce        *big.Int     // Nonce of the transactions
	Digest       common.Hash  // Digest of the transactions
	Signature    []byte       // Signature (encoded as bytes from *Signature) of the txn digest
}

SignedTransactions includes a signed meta-transaction payload intended for the relayer.

func (*SignedTransactions) Execdata added in v0.2.0

func (t *SignedTransactions) Execdata() ([]byte, error)

type Transaction

type Transaction struct {
	DelegateCall  bool           `abi:"delegateCall"`  // Performs delegatecall
	RevertOnError bool           `abi:"revertOnError"` // Reverts transaction bundle if tx fails
	GasLimit      *big.Int       `abi:"gasLimit"`      // Maximum gas to be forwarded
	To            common.Address `abi:"target"`        // Address to send transaction, aka target
	Value         *big.Int       `abi:"value"`         // Amount of ETH to pass with the call
	Data          []byte         `abi:"data"`          // Calldata to pass

	Transactions Transactions // Child transactions
	Nonce        *big.Int     // Meta-Transaction nonce, with encoded space
	Signature    []byte       // Meta-Transaction signature

}

Transaction type for Sequence meta-transaction, with encoded calldata.

The fields with abi struct tags match the `Transaction` type as defined in the IModuleCalls interface.

https://github.com/0xsequence/wallet-contracts/blob/master/src/contracts/modules/commons/interfaces/IModuleCalls.sol#L13

func DecodeTransaction added in v0.2.0

func DecodeTransaction(data []byte) (*Transaction, error)

func (*Transaction) AddToBundle added in v0.2.0

func (t *Transaction) AddToBundle(txns Transactions)

AddToBundle will create a bundle from the passed txns and add it to current transaction

func (*Transaction) Bundle added in v0.2.0

func (t *Transaction) Bundle() Transactions

func (*Transaction) Digest added in v0.2.0

func (t *Transaction) Digest() (common.Hash, error)

func (*Transaction) Execdata added in v0.2.0

func (t *Transaction) Execdata() ([]byte, error)

func (*Transaction) IsBundle added in v0.2.0

func (t *Transaction) IsBundle() bool

func (*Transaction) IsValid added in v0.2.1

func (t *Transaction) IsValid() error

type Transactions

type Transactions []*Transaction

func NewTransactionsFromValues added in v0.2.0

func NewTransactionsFromValues(values []Transaction) Transactions

func (*Transactions) Append added in v0.2.0

func (t *Transactions) Append(txns Transactions)

Append will append the passed txns to the `t` array (as separate Transaction elements).

func (Transactions) AppendBundle added in v0.2.0

func (t Transactions) AppendBundle(txns Transactions)

AppendBundle will append the passed txns as *a bundle of txns*. This means, it will be included as a single element at this level of the `t` array.

func (Transactions) AsValues

func (t Transactions) AsValues() []Transaction

func (Transactions) Execdata added in v0.2.0

func (t Transactions) Execdata() ([]byte, error)

func (*Transactions) Prepend added in v0.2.0

func (t *Transactions) Prepend(txns Transactions)

Prepend will prepend the passed txns to the `t` array (as separate Transaction elements).

func (Transactions) PrependBundle added in v0.2.0

func (t Transactions) PrependBundle(txns Transactions)

PrependBundle will prepend the passed txns as *a bundle of txns*. This means, it will be included as a single element at this level of the `t` array.

type Wallet

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

func NewWallet

func NewWallet(walletOptions WalletOptions, signers ...*ethwallet.Wallet) (*Wallet, error)

func NewWalletSingleOwner

func NewWalletSingleOwner(owner *ethwallet.Wallet, optContext ...WalletContext) (*Wallet, error)

func (*Wallet) Address

func (w *Wallet) Address() common.Address

func (*Wallet) Connect

func (w *Wallet) Connect(provider *ethrpc.Provider, relayer Relayer) error

func (*Wallet) GetChainID

func (w *Wallet) GetChainID() *big.Int

func (*Wallet) GetNonce

func (w *Wallet) GetNonce(optBlockNum ...*big.Int) (*big.Int, error)

func (*Wallet) GetProvider

func (w *Wallet) GetProvider() *ethrpc.Provider

func (*Wallet) GetRelayer

func (w *Wallet) GetRelayer() Relayer

func (*Wallet) GetSigner

func (w *Wallet) GetSigner(address common.Address) (*ethwallet.Wallet, bool)

func (*Wallet) GetSignerAddresses

func (w *Wallet) GetSignerAddresses() []common.Address

func (*Wallet) GetSignerWeight

func (w *Wallet) GetSignerWeight() *big.Int

func (*Wallet) GetTransactionCount

func (w *Wallet) GetTransactionCount(optBlockNum ...*big.Int) (*big.Int, error)

func (*Wallet) GetWalletConfig

func (w *Wallet) GetWalletConfig() WalletConfig

func (*Wallet) GetWalletContext

func (w *Wallet) GetWalletContext() WalletContext

func (*Wallet) ImageHash

func (w *Wallet) ImageHash() (common.Hash, error)

func (*Wallet) IsDeployed

func (w *Wallet) IsDeployed() (bool, error)

func (*Wallet) IsSignerAvailable

func (w *Wallet) IsSignerAvailable(address common.Address) bool

func (*Wallet) IsValidSignature

func (w *Wallet) IsValidSignature(digest common.Hash, signature []byte) (bool, error)

func (*Wallet) SendTransaction

func (w *Wallet) SendTransaction(ctx context.Context, signedTxns *SignedTransactions) (MetaTxnID, *types.Transaction, ethtxn.WaitReceipt, error)

func (*Wallet) SendTransactions

func (w *Wallet) SendTransactions(ctx context.Context, signedTxns *SignedTransactions) (MetaTxnID, *types.Transaction, ethtxn.WaitReceipt, error)

func (*Wallet) SetChainID

func (w *Wallet) SetChainID(chainID *big.Int)

SetChainID will set the wallet's associated chainID. However, for most part, this will automatically be set by the provider rpc.

func (*Wallet) SetProvider

func (w *Wallet) SetProvider(provider *ethrpc.Provider) error

func (*Wallet) SetRelayer

func (w *Wallet) SetRelayer(relayer Relayer) error

func (*Wallet) SignDigest

func (w *Wallet) SignDigest(digest common.Hash) ([]byte, *Signature, error)

func (*Wallet) SignMessage

func (w *Wallet) SignMessage(msg []byte) ([]byte, *Signature, error)

func (*Wallet) SignTransaction

func (w *Wallet) SignTransaction(ctx context.Context, txn *Transaction) (*SignedTransactions, error)

func (*Wallet) SignTransactions

func (w *Wallet) SignTransactions(ctx context.Context, txns Transactions) (*SignedTransactions, error)

func (*Wallet) UseConfig

func (w *Wallet) UseConfig(config WalletConfig) (*Wallet, error)

func (*Wallet) UseSigners

func (w *Wallet) UseSigners(signers ...*ethwallet.Wallet) (*Wallet, error)

type WalletConfig

type WalletConfig struct {
	Threshold uint16              `json:"threshold"`
	Signers   WalletConfigSigners `json:"signers"`
}

func RecoverWalletConfigFromDigest

func RecoverWalletConfigFromDigest(digest, seqSig []byte, context WalletContext, chainID *big.Int, provider *ethrpc.Provider) (WalletConfig, error)

type WalletConfigSigner

type WalletConfigSigner struct {
	Weight  uint8          `json:"weight"`
	Address common.Address `json:"address"`
}

type WalletConfigSigners

type WalletConfigSigners []WalletConfigSigner

func (WalletConfigSigners) GetWeightByAddress

func (s WalletConfigSigners) GetWeightByAddress(address common.Address) (uint8, bool)

func (WalletConfigSigners) Len

func (s WalletConfigSigners) Len() int

func (WalletConfigSigners) Less

func (s WalletConfigSigners) Less(i, j int) bool

func (WalletConfigSigners) Swap

func (s WalletConfigSigners) Swap(i, j int)

type WalletContext

type WalletContext struct {
	FactoryAddress              common.Address `json:"factory" toml:"factory_address"`
	MainModuleAddress           common.Address `json:"mainModule" toml:"main_module_address"`
	MainModuleUpgradableAddress common.Address `json:"mainModuleUpgradable" toml:"main_module_upgradable_address"`
	GuestModuleAddress          common.Address `json:"guestModule" toml:"guest_module_address"`
	UtilsAddress                common.Address `json:"utils" toml:"utils_address"`
}

WalletContext is the module addresses deployed on a network, aka the context / environment of the Sequence Smart Wallet system on Ethereum.

func SequenceContext

func SequenceContext() WalletContext

SequenceContext returns copy of the package-level internal variable, to prevent change by other packages.

type WalletOptions

type WalletOptions struct {
	// Config is the wallet multi-sig configuration. Note: the first config of any wallet
	// before it is deployed is used to derive it's the account address of the wallet.
	Config WalletConfig

	// Context is the WalletContext of deployed wallet-contract modules for the Smart Wallet.
	// NOTE: if a WalletContext is not provided, then `SequenceContext()` value is used.
	Context *WalletContext
}

Directories

Path Synopsis
gen
lib
proto
sequence-relayer v0.4.0 b8eced5e5920e0f4ea5aaad391c6551d7936916d -- This file has been generated by https://github.com/webrpc/webrpc using gen/golang Do not edit by hand.
sequence-relayer v0.4.0 b8eced5e5920e0f4ea5aaad391c6551d7936916d -- This file has been generated by https://github.com/webrpc/webrpc using gen/golang Do not edit by hand.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL