aptos

package
v0.0.0-...-977d577 Latest Latest
Warning

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

Go to latest
Published: Dec 2, 2022 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

APTOS golang sdk

Aptos is a blockchain written in rust and smart contracts are written in move.

This work derives from the work for aux.exchange, where we are looking for a lightweight tool to interact with various part of the chain.

Example

This is an example of creating 5 traders, to trade on Fake AUX/ Fake USDC Exchange. The order information will be streaming from coinbase

const network = aptos.Devnet

const (
	desiredAptosBalance = 1_000_000_000_000     // 10_000 ATP
	desiredUSDCBalance  = 1_000_000_000_000_000 // 1_000_000_000 USDC
	desiredAuxBalance   = 1_000_000_000_000_000 //
)

auxConfig, _ := aptos.GetAuxClientConfig(network)

restUrl, faucetUrl, _ := aptos.GetDefaultEndpoint(network)
auxFakeCoinCoin := must(aptos.GetAuxFakeCoinCoinType(auxConfig.Address, aptos.AuxFakeCoin_AUX))
usdcFakeCoinCoin := must(aptos.GetAuxFakeCoinCoinType(auxConfig.Address, aptos.AuxFakeCoin_USDC))

// cancel the whole process after 15 minutes
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*15)
defer cancel()

client := aptos.MustNewClient(network, restUrl)

traders := []*aptos.LocalAccount{
	must(aptos.NewLocalAccountWithRandomKey()),
	must(aptos.NewLocalAccountWithRandomKey()),
	must(aptos.NewLocalAccountWithRandomKey()),
	must(aptos.NewLocalAccountWithRandomKey()),
	must(aptos.NewLocalAccountWithRandomKey()),
}

// setup the traders
for _, trader := range traders {
	// get some gas
	txes := must(aptos.RequestFromFaucet(ctx, faucetUrl, &(trader.Address), desiredAptosBalance*2))
	for _, txhash := range txes {
		client.WaitForTransaction(ctx, txhash)
	}

	// create user account
	must(client.SignSubmitTransactionWait(ctx, trader, auxConfig.Vault_CreateAuxAccount(trader.Address), false))
	<-time.After(5 * time.Second)
	// request fake coins
	must(client.SignSubmitTransactionWait(ctx, trader, auxConfig.FakeCoin_RegisterAndMint(trader.Address, aptos.AuxFakeCoin_USDC, desiredUSDCBalance), false))
	<-time.After(5 * time.Second)
	must(client.SignSubmitTransactionWait(ctx, trader, auxConfig.FakeCoin_RegisterAndMint(trader.Address, aptos.AuxFakeCoin_AUX, desiredAuxBalance), false))
	<-time.After(5 * time.Second)

	// deposit fake coins
	must(client.SignSubmitTransactionWait(ctx, trader, auxConfig.Vault_Deposit(trader.Address, trader.Address, usdcFakeCoinCoin, desiredUSDCBalance), false))
	<-time.After(5 * time.Second)
	must(client.SignSubmitTransactionWait(ctx, trader, auxConfig.Vault_Deposit(trader.Address, trader.Address, auxFakeCoinCoin, desiredAuxBalance), false))
	<-time.After(5 * time.Second)
}

// connect to coinbase
asset := "APT-USD"
endpoint := "wss://ws-feed.exchange.coinbase.com"
dialer := &websocket.Dialer{
	Proxy: http.ProxyFromEnvironment,
}
conn, rsp, err := dialer.DialContext(ctx, endpoint, nil)
if err != nil {
	orPanic(fmt.Errorf("failed to open connection: %v %v", err, rsp))
}
defer conn.Close()
orPanic(conn.WriteJSON(map[string]any{
	"type":        "subscribe",
	"product_ids": []string{asset},
	"channels":    []string{"full"},
}))

var wg sync.WaitGroup
defer wg.Wait()

waitForWs := make(chan struct{})
orderChannel := make(chan *Order, 100)

// first goroutine read the data from websocket and pipe it into a channel
wg.Add(1)
go func() {
	defer wg.Done()
	defer func() {
		// once the websocket is disconnected, we indicate that we are done.
		waitForWs <- struct{}{}
		close(waitForWs)
		close(orderChannel)
	}()
readLoop:
	for {
		_, data, err := conn.ReadMessage()
		if err != nil {
			fmt.Printf("failed to read websocket...: %v", err)
			break
		}

		var order Order
		if err := json.Unmarshal(data, &order); err != nil {
			fmt.Printf("failed to parse: %v\n", err)
			continue
		}

		if !(order.Type == "received" && order.OrderType == "limit") {
			continue
		}
		// stop piping order if cancelled
		select {
		case orderChannel <- &order:
		case <-ctx.Done():
			break readLoop
		}

	}
}()

// a second websocket will read from the channel,
// and select the next trader to trade.
// each trader will wait 30 seconds to avoid flooding the fullnode.
wg.Add(1)
go func() {
	defer wg.Done()
	client := aptos.MustNewClient(network, restUrl)
	buyId := 0
	sellId := 1
	wait := time.Second * 30
orderLoop:
	for {
		var order *Order
		var ok bool

		// make sure we don't hang on orderChannel if ctx is cancelled
		select {
		case order, ok = <-orderChannel:
		case <-ctx.Done():
			break orderLoop
		}

		if !ok {
			break
		}

		// stop waiting if cancelled
		select {
		case <-time.After(wait):
		case <-ctx.Done():
			break orderLoop
		}

		price, err := strconv.ParseFloat(order.Price, 64)
		if err != nil {
			fmt.Printf("failed to parse price: %s %v\n", order.Price, err)
		}
		size, err := strconv.ParseFloat(order.Size, 64)
		if err != nil {
			fmt.Printf("failed to parse size: %s %v\n", order.Size, err)
		}
		priceInt := uint64(price * 1_000_000)
		priceInt = (priceInt / 10000) * 10000
		sizeInt := uint64(size * 1_000_000)
		sizeInt = (sizeInt / 100000) * 100000

		var trader *aptos.LocalAccount
		if order.Side == "buy" {
			buyId %= len(traders)
			trader = traders[buyId]
			buyId += 2
			priceInt += 10000
		} else {
			sellId %= len(traders)
			trader = traders[sellId]
			sellId += 2
		}

		fmt.Printf("place %s size %d price %d\n", order.Side, sizeInt, priceInt)

		// create a place order transaction
		tx := auxConfig.ClobMarket_PlaceOrder(
			trader.Address,
			order.Side == "buy",
			auxFakeCoinCoin,
			usdcFakeCoinCoin,
			priceInt,
			sizeInt,
			0,
			bcs.Uint128{},
			aptos.AuxClobMarketOrderType_Limit,
			0,
			false,
			math.MaxInt64,
			aptos.AuxClobMarketSelfTradeType_CancelBoth,
			aptos.TransactionOption_MaxGasAmount(30000),
		)
		// print out the order
		orderString, _ := json.Marshal(tx)
		fmt.Println(string(orderString))

		// submit transaction
		_, err = client.SignSubmitTransactionWait(ctx, trader, tx, false)
		if err != nil {
			spew.Dump(err)
		}
	}
}()

select {
case <-waitForWs:
case <-ctx.Done():
	conn.Close()
	<-waitForWs
}
Output:

Index

Examples

Constants

View Source
const AddressLength = 32

AddressLength is the length of aptos account address, 32.

View Source
const AuxAmmModuleName = "amm"

AuxAmmModuleName aux::amm

View Source
const AuxClobMarketModuleName = "clob_market"

AuxClobMarketModuleName is the module name for clob market.

View Source
const AuxFakeCoinModuleName = "fake_coin"

AuxFakeCoinModuleName is the module name for fake coin.

View Source
const AuxRouter2PoolModuleName = "router_2pool"

AuxRouter2PoolModuleName aux::router_2pool

View Source
const AuxRouter3PoolModuleName = "router_3pool"

AuxRouter3PoolModuleName aux::router_3pool

View Source
const AuxRouter4PoolModuleName = "router_4pool"

AuxRouter4PoolModuleName aux::router_4pool

View Source
const AuxStable2PoolModuleName = "stable_2pool"

AuxStable2PoolModuleName aux::stable_2pool

View Source
const AuxStable3PoolModuleName = "stable_3pool"

AuxStable3PoolModuleName aux::stable_3pool

View Source
const AuxStable4PoolModuleName = "stable_4pool"

AuxStable4PoolModuleName aux::stable_4pool

View Source
const AuxVaultModuleName = "vault"

AuxVaultModuleName is the module name for vault.

View Source
const Ed25519SignatureType = "ed25519_signature"

Ed25519SinatureType is the signature type for single signer based on a public/private key of ed25519 type.

View Source
const HardenedOffset = 0x80000000

HardenedOffset is for bip39

View Source
const HmacKey = "ed25519 seed"

HmacKey for bip39

View Source
const PetraPath = "m/44'/637'/0'/0'/0'"

PetraPath is the path Petra wallet used to derive the private key. See the doc on aptos.dev.

View Source
const SignatureLength = 64

SignatureLength aptos uses ed25519 and signature is 64 bytes.

Variables

View Source
var AptosCoin = MoveStructTag{
	MoveModuleTag: MoveModuleTag{
		Address: AptosStdAddress,
		Module:  "aptos_coin",
	},
	Name: "AptosCoin",
}

AptosCoin is the type for aptos coin

View Source
var AptosStdAddress = MustParseAddress("0x1")

AptosStdAddress is the aptos standard library and aptos framework's address on chain, which is 0x1.

AuxAllFakeCoins contains all the fake coins provided by aux for testing

Functions

func Bip32DerivePath

func Bip32DerivePath(path string, seed []byte, offset uint32) (*ed25519.PrivateKey, error)

see corresponding code in typescript

func EncodeTransaction

func EncodeTransaction(tx *Transaction) []byte

EncodeTransaction for signing. See here: doc on aptos.dev, also see the implementation in typescript

The process is follows:

  • generate sha3_256 of "APTOS::RawTransaction"

Then bcs serialize in the following order:

  • sender
  • sequence_number
  • payload
  • max_gas_amount
  • gas_unit_price
  • expiration_timestamp_secs
  • chain_id

for entry function payload, see [EntryFunctionPayload.ToBCS].

func GetAccountResourceWithType

func GetAccountResourceWithType[T any](ctx context.Context, client *Client, address Address, moveType *MoveStructTag, ledgerVersion uint64) (*T, error)

GetAccountResourceWithType get the resource of specified move type, then marshal it into requested type T.

This is equivalent of calling Client.GetAccountResource, then marshal the response into the type.

This is a function since golang doesn't support generic method.

func GetAuxFakeCoinDecimal

func GetAuxFakeCoinDecimal(fakeCoin AuxFakeCoin) uint8

GetAuxFakeCoinDecimal provides the decimals for fake coins

func GetChainIdForNetwork

func GetChainIdForNetwork(network Network) uint8

func GetDefaultEndpoint

func GetDefaultEndpoint(network Network) (restUrl string, faucetUrl string, err error)

func IsNamedAddress

func IsNamedAddress(address string) bool

Check if an address string is named address

func IsValidBip32Path

func IsValidBip32Path(path string) bool

see corresponding code in typescript

func NewPrivateKeyFromHexString

func NewPrivateKeyFromHexString(hexString string) (*ed25519.PrivateKey, error)

NewPrivateKeyFromHexString generates a private key from hex string.

func ParseBip32Path

func ParseBip32Path(path string) ([]uint32, error)

ParseBip32Path

func RequestFromFaucet

func RequestFromFaucet(ctx context.Context, faucetUrl string, address *Address, amount uint64) ([]string, error)

Types

type AccountModule

type AccountModule struct {
	Bytecode MoveBytecode   `json:"bytecode"`
	Abi      *MoveModuleABI `json:"abi"`
}

AccountModule contains the byte codes and the abi of the module.

type AccountResource

type AccountResource struct {
	Type *MoveStructTag  `json:"type"`
	Data json.RawMessage `json:"data,omitempty"`
}

AccountResource includes the type and json encoding of the data.

type Address

type Address [AddressLength]byte

Address in aptos, 32 byte long.

func CalculateResourceAddress

func CalculateResourceAddress(sourceAddress Address, seed []byte) Address

CalculateResourceAddress creates a new resource address from the source address and seeds.

func GenerateAuthenticationKey

func GenerateAuthenticationKey(
	totalSignerCount int,
	requiredSignerCount int,
	signerPublicKeys ...ed25519.PublicKey,
) (Address, error)

GenerateAuthenticationKey calculates the authentication key for a scheme.

The information is based on documentation on aptos.dev

Account in aptos is presented by SHA3-256 of

  • a public key of ed25519 public key (pub_key|0x00)
  • a series of ed25519 public keys, the number of signature required (pub_key_1 | pub_key_2 ... | pub_key_n | K | 0x01)
  • an address and some seed (address | seed| 0xFF) if on chain.

func GetAuxOnChainSignerAddress

func GetAuxOnChainSignerAddress(auxModuleAddress, userAddress Address) Address

GetAuxOnChainSignerAddress calculates the onchain account holding assets for a given address. Assets for an aux user is held in a separate resource account, which is derived from the aux module address and seed "aux-user".

func MustParseAddress

func MustParseAddress(s string) Address

func ParseAddress

func ParseAddress(s string) (Address, error)

ParseAddress converts a hex encoded string to address.

func (Address) IsZero

func (address Address) IsZero() bool

Checks if the address is zero.

func (Address) MarshalBCS

func (a Address) MarshalBCS() ([]byte, error)

func (Address) MarshalJSON

func (address Address) MarshalJSON() ([]byte, error)

func (*Address) Set

func (a *Address) Set(s string) error

Set is to support cobra value

func (Address) String

func (address Address) String() string

Hex representation of the address, with 0x prefix

func (Address) Type

func (a Address) Type() string

Type is to support cobra value

func (*Address) UnmarshalJSON

func (address *Address) UnmarshalJSON(input []byte) error

type AptosReponseHeader

type AptosReponseHeader struct {
	AptosBlockHeight         string
	AptosChainId             string
	AptosEpoch               string
	AptosLedgerOldestVersion string
	AptosLedgerTimestampUsec string
	AptosLedgerVersion       string
	AptosOldestBlockHeight   string
}

AptosReponseHeader contains the header information on a successful aptos response

type AptosRequest

type AptosRequest interface {
	PathSegments() ([]string, error)
	Body() ([]byte, error)
	HttpMethod() string
}

AptosRequest

type AptosResponse

type AptosResponse[T any] struct {
	RawData []byte
	Parsed  *T
	Headers *AptosReponseHeader
}

type AptosRestError

type AptosRestError struct {
	// HttpStatusCode returned
	HttpStatusCode int

	// Body of the response
	Body []byte

	// Message
	Message string
}

AptosRestError contains the http status code, message body and message of the response. This is returned when status code >= 400 is returned.

func (*AptosRestError) Error

func (e *AptosRestError) Error() string

type AuxAmmPool

type AuxAmmPool struct {
	FeeBps   JsonUint64 `json:"fee_bps"`
	Frozen   bool       `json:"frozen"`
	XReserve Coin       `json:"x_reserve"`
	YReserve Coin       `json:"y_reserve"`

	AddLiquidityEvents    *EventHandler `json:"add_liquidity_events"`
	RemoveLiquidityEvents *EventHandler `json:"remove_liquidity_events"`
	SwapEvents            *EventHandler `json:"swap_events"`
}

AuxAmmPool is a constant product amm

type AuxAmm_AddLiquidityEvent

type AuxAmm_AddLiquidityEvent struct {
	Timestamp  JsonUint64     `json:"timestamp"`
	XCoinType  *MoveStructTag `json:"x_coin_type"`
	YCoinType  *MoveStructTag `json:"y_coin_type"`
	XAddedAu   JsonUint64     `json:"x_added_au"`
	YAddedAu   JsonUint64     `json:"y_added_au"`
	LpMintedAu JsonUint64     `json:"lp_minted_au"`
}

AuxAmm_AddLiquidityEvent is emitted when liquidity is added. contract here

type AuxAmm_RemoveLiquidityEvent

type AuxAmm_RemoveLiquidityEvent struct {
	Timestamp  JsonUint64     `json:"timestamp"`
	XCoinType  *MoveStructTag `json:"x_coin_type"`
	YCoinType  *MoveStructTag `json:"y_coin_type"`
	XRemovedAu JsonUint64     `json:"x_removed_au"`
	YRemovedAu JsonUint64     `json:"y_removed_au"`
	LpBurnedAu JsonUint64     `json:"lp_burned_au"`
}

AuxAmm_RemoveLiquidityEvent is emitted when liquidity is removed. contract here

type AuxAmm_SwapEvent

type AuxAmm_SwapEvent struct {
	SenderAddr  Address        `json:"sender_addr"`
	Timestamp   JsonUint64     `json:"timestamp"`
	InCoinType  *MoveStructTag `json:"in_coin_type"`
	OutCoinType *MoveStructTag `json:"out_coin_type"`
	InReserve   JsonUint64     `json:"in_reserve"`
	OutReserve  JsonUint64     `json:"out_reserve"`
	InAu        JsonUint64     `json:"in_au"`
	OutAu       JsonUint64     `json:"out_au"`
	FeeBps      JsonUint64     `json:"fee_bps"`
}

AuxAmm_SwapEvent is emitted when a swap happens on chain. contract here

type AuxClient

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

AuxClient combines AuxClientConfig, Client, and Signer for aptos for convenient access

func NewAuxClient

func NewAuxClient(client *Client, config *AuxClientConfig, signer Signer) *AuxClient

func (*AuxClient) GetClobMarket

func (client *AuxClient) GetClobMarket(ctx context.Context, baseCoin, quoteCoin *MoveStructTag, ledgerVersion uint64) (*AuxClobMarket, error)

func (*AuxClient) ListAllOrders

func (client *AuxClient) ListAllOrders(ctx context.Context, baseCoin, quoteCoin *MoveStructTag, options ...TransactionOption) (*AuxClobMarket_AllOrdersEvent, error)

func (*AuxClient) ListLevel2

func (client *AuxClient) ListLevel2(ctx context.Context, baseCoin, quoteCoin *MoveStructTag, options ...TransactionOption) (*AuxClobMarket_Level2Event, error)

type AuxClientConfig

type AuxClientConfig struct {
	Address           Address
	Deployer          Address
	DataFeedAddress   Address
	DataFeedPublicKey ed25519.PublicKey
}

func GetAuxClientConfig

func GetAuxClientConfig(chain Network) (*AuxClientConfig, error)

GetAuxClientConfig gets the aux exchange configuration for an aptos network. Only mainnet, devnet, and testnet are supported.

func GetAuxClientConfigFromLocalAccount

func GetAuxClientConfigFromLocalAccount(localAccount *LocalAccount) *AuxClientConfig

GetAuxClientConfigFromLocalAccount returns the aux configuration based on a local account. The input local account must be the account that deploys aux to the chain.

func MustGetAuxClientConfig

func MustGetAuxClientConfig(chain Network) *AuxClientConfig

MustGetAuxClientConfig returns the aux exchange configuration for an aptos network. Panic if fails.

func (*AuxClientConfig) AmmPoolType

func (info *AuxClientConfig) AmmPoolType(coinX *MoveStructTag, coinY *MoveStructTag) (*MoveStructTag, error)

AmmPoolType returns the move type (MoveTypeTag) for a pool

func (*AuxClientConfig) Amm_AddLiquidity

func (info *AuxClientConfig) Amm_AddLiquidity(sender Address, coinX *MoveStructTag, xAmount uint64, coinY *MoveStructTag, yAmount uint64, maxSlippage uint64, options ...TransactionOption) *Transaction

Amm_AddLiquidity adds liquidity to amm. See contract here

func (*AuxClientConfig) Amm_CreatePool

func (info *AuxClientConfig) Amm_CreatePool(sender Address, coinX, coinY *MoveStructTag, feeBps uint64, options ...TransactionOption) *Transaction

Amm_CreatePool creates a new pool with the give coin x and coin y. contract here

func (*AuxClientConfig) Amm_RemoveLiquidity

func (info *AuxClientConfig) Amm_RemoveLiquidity(sender Address, coinX, coinY *MoveStructTag, amountLp uint64, options ...TransactionOption) *Transaction

Amm_RemoveLiquidity removes liquidity from amm. See contract here

func (*AuxClientConfig) Amm_SwapExactCoinForCoin

func (info *AuxClientConfig) Amm_SwapExactCoinForCoin(sender Address, coinX, coinY *MoveStructTag, amountIn uint64, minAmountOut uint64, options ...TransactionOption) *Transaction

Amm_SwapExactCoinForCoin swaps coins, with the output amount decided by the input amount. See contract here

func (*AuxClientConfig) Amm_UpdateFee

func (info *AuxClientConfig) Amm_UpdateFee(sender Address, coinX, coinY *MoveStructTag, feeBps uint64, options ...TransactionOption) *Transaction

Amm_UpdateFee updates the fee of the amm pool. the pool is identified by the coin types. contract here.

func (*AuxClientConfig) ClobMarket_CancelAll

func (info *AuxClientConfig) ClobMarket_CancelAll(sender Address, baseCoin, quoteCoin *MoveStructTag, options ...TransactionOption) *Transaction

ClobMarket_CancelAll constructs a transaction to cancel all open orders on a given market.

func (*AuxClientConfig) ClobMarket_CancelOrder

func (info *AuxClientConfig) ClobMarket_CancelOrder(sender Address, baseCoin, quoteCoin *MoveStructTag, orderId bcs.Uint128, options ...TransactionOption) *Transaction

ClobMarket_CancelOrder constructs a transaction to cancel an open orde on a given market.

func (*AuxClientConfig) ClobMarket_CreateMarket

func (info *AuxClientConfig) ClobMarket_CreateMarket(sender Address, baseCoin, quoteCoin *MoveStructTag, lotSize, tickSize uint64, options ...TransactionOption) *Transaction

ClobMarket_CreateMarket constructs a transaction to create a market.

lot size and quote size must guarantee that the minimal quote coin quantity is available and no rounding happens. This requires (assuming base coin has decimal of b)

  • lot size * tick size / 10^b > 0 (the minimal quote coin quantity must be greater than zero)
  • lot size * tick size % 10^b == 0 (the minimal quote coin quantity must be whole integers)

func (*AuxClientConfig) ClobMarket_LoadAllOrdersIntoEvent

func (info *AuxClientConfig) ClobMarket_LoadAllOrdersIntoEvent(baseCoin, quoteCoin *MoveStructTag, options ...TransactionOption) *Transaction

func (*AuxClientConfig) ClobMarket_LoadMarketIntoEvent

func (info *AuxClientConfig) ClobMarket_LoadMarketIntoEvent(baseCoin, quoteCoin *MoveStructTag, options ...TransactionOption) *Transaction

ClobMarket_LoadMarketIntoEvent constructs a transaction to load price level and total quantities of each price level into an event. This is useful if the price/quantity of the market is needed since the market is stored on TableWithLength and is cumbersome to query.

func (*AuxClientConfig) ClobMarket_PlaceOrder

func (info *AuxClientConfig) ClobMarket_PlaceOrder(
	sender Address,
	isBid bool,
	baseCoin,
	quoteCoin *MoveStructTag,
	limitPrice uint64,
	quantity uint64,
	auxToBurnPerLot uint64,
	clientOrderId bcs.Uint128,
	orderType AuxClobMarketOrderType,
	ticksToSlide uint64,
	directionAggressive bool,
	timeoutTimestamp uint64,
	selfTradeType AuxClobMarketSelfTradeType,
	options ...TransactionOption,
) *Transaction

ClobMarket_PlaceOrder creates a transaction to place an orde on aux.echange.

Each order placed on the clob will receive an order id, even if it is cancelled or filled immediately. The order id is unique to the market, which is specified by base coin - quote coin pair.

To link an order id generate from the contract on the client side, user can pass in a clientOrderId, which is unsigned int128 (which go doesn't support). However, the contract doesn't check of uniqueness of clientOrderIds.

Limit price of the order must be in the quote coin decimals for one unit of base coin, and quantity is specified in base coin quantity. For example, assume coin Base has a decimal of 8, and coin Quote has a decimal of 6. To buy 0.5 unit of base at a price of 66.8, the limit price should be 66,800,000, and the quantity should be 50,000,000.

also see contract at here

func (*AuxClientConfig) FakeCoin_Burn

func (info *AuxClientConfig) FakeCoin_Burn(sender Address, fakeCoin AuxFakeCoin, amount uint64, options ...TransactionOption) *Transaction

FakeCoin_Burn burns the fake coins for a user. The is useful when tests require users' balances must start from zero.

func (*AuxClientConfig) FakeCoin_Mint

func (info *AuxClientConfig) FakeCoin_Mint(sender Address, fakeCoin AuxFakeCoin, amount uint64, options ...TransactionOption) *Transaction

FakeCoin_Mint mints coins to the user. The user must be registered.

func (*AuxClientConfig) FakeCoin_Register

func (info *AuxClientConfig) FakeCoin_Register(sender Address, fakeCoin AuxFakeCoin, options ...TransactionOption) *Transaction

FakeCoin_Register registers the user for the fake coin. No effect if the user is already registered.

func (*AuxClientConfig) FakeCoin_RegisterAndMint

func (info *AuxClientConfig) FakeCoin_RegisterAndMint(sender Address, fakeCoin AuxFakeCoin, amount uint64, options ...TransactionOption) *Transaction

FakeCoin_RegisterAndMint register and mint fake coins. Any signer can self sign and get those coins. If the sender is not registered, this operation will register user for the coin. If the sender is registered for the coin, it will simply mint.

func (*AuxClientConfig) GetCoinBalanceType

func (info *AuxClientConfig) GetCoinBalanceType(coinType *MoveStructTag) *MoveStructTag

GetCoinBalanceType get the coin balance and available balance in vault for a user.

func (*AuxClientConfig) MarketType

func (info *AuxClientConfig) MarketType(baseCoin *MoveStructTag, quoteCoin *MoveStructTag) (*MoveStructTag, error)

MarketType provides the market for a pair of currencies

func (*AuxClientConfig) Router2Pool_AddLiquidity

func (info *AuxClientConfig) Router2Pool_AddLiquidity(
	sender Address,
	coin0 *MoveStructTag,
	amount0 uint64,
	coin1 *MoveStructTag,
	amount1 uint64,
	minLpAmount uint64,
	options ...TransactionOption,
) *Transaction

Router2Pool_AddLiquidity constructs the transaction to add liquidity to a pool

func (*AuxClientConfig) Router2Pool_RemoveLiquidity

func (info *AuxClientConfig) Router2Pool_RemoveLiquidity(
	sender Address,
	coin0 *MoveStructTag,
	coin1 *MoveStructTag,
	lpAmount uint64,
	options ...TransactionOption,
) *Transaction

Router2Pool_RemoveLiquidity constructs the transaction to remove liquidity from the pool by specifying the amount of lp coins to burn.

func (*AuxClientConfig) Router2Pool_RemoveLiquidityForCoin

func (info *AuxClientConfig) Router2Pool_RemoveLiquidityForCoin(
	sender Address,
	coin0 *MoveStructTag,
	amount0ToWithdraw uint64,
	coin1 *MoveStructTag,
	amount1ToWithdraw uint64,
	maxLpAmount uint64,
	options ...TransactionOption,
) *Transaction

Router2Pool_RemoveLiquidityForCoin constructs the transaction to remove liquidity from the pool by specifying the coin amount to withdraw.

func (*AuxClientConfig) Router2Pool_SwapCoinForExactCoin

func (info *AuxClientConfig) Router2Pool_SwapCoinForExactCoin(
	sender Address,
	coin0 *MoveStructTag,
	requestAmount0 uint64,
	coin1 *MoveStructTag,
	requestAmount1 uint64,
	inCoinIndex int,
	maxQuantityIn uint64,
	options ...TransactionOption,
) *Transaction

Router2Pool_SwapCoinForExactCoin constructs the transaction to swap coins by by specifying the input amount of coins to swap.

func (*AuxClientConfig) Router2Pool_SwapExactCoinForCoin

func (info *AuxClientConfig) Router2Pool_SwapExactCoinForCoin(
	sender Address,
	coin0 *MoveStructTag,
	amount0 uint64,
	coin1 *MoveStructTag,
	amount1 uint64,
	outCoinIndex int,
	minQuantityOut uint64,
	options ...TransactionOption,
) *Transaction

Router2Pool_SwapExactCoinForCoin constructs the transaction to swap coins by by specifying the input amount of coins to swap.

func (*AuxClientConfig) Router3Pool_AddLiquidity

func (info *AuxClientConfig) Router3Pool_AddLiquidity(
	sender Address,
	coin0 *MoveStructTag,
	amount0 uint64,
	coin1 *MoveStructTag,
	amount1 uint64,
	coin2 *MoveStructTag,
	amount2 uint64,
	minLpAmount uint64,
	options ...TransactionOption,
) *Transaction

Router3Pool_AddLiquidity constructs the transaction to add liquidity to a pool

func (*AuxClientConfig) Router3Pool_RemoveLiquidity

func (info *AuxClientConfig) Router3Pool_RemoveLiquidity(
	sender Address,
	coin0 *MoveStructTag,
	coin1 *MoveStructTag,
	coin2 *MoveStructTag,
	lpAmount uint64,
	options ...TransactionOption,
) *Transaction

Router3Pool_RemoveLiquidity constructs the transaction to remove liquidity from the pool by specifying the amount of lp coins to burn.

func (*AuxClientConfig) Router3Pool_RemoveLiquidityForCoin

func (info *AuxClientConfig) Router3Pool_RemoveLiquidityForCoin(
	sender Address,
	coin0 *MoveStructTag,
	amount0ToWithdraw uint64,
	coin1 *MoveStructTag,
	amount1ToWithdraw uint64,
	coin2 *MoveStructTag,
	amount2ToWithdraw uint64,
	maxLpAmount uint64,
	options ...TransactionOption,
) *Transaction

Router3Pool_RemoveLiquidityForCoin constructs the transaction to remove liquidity from the pool by specifying the coin amount to withdraw.

func (*AuxClientConfig) Router3Pool_SwapCoinForExactCoin

func (info *AuxClientConfig) Router3Pool_SwapCoinForExactCoin(
	sender Address,
	coin0 *MoveStructTag,
	requestAmount0 uint64,
	coin1 *MoveStructTag,
	requestAmount1 uint64,
	coin2 *MoveStructTag,
	requestAmount2 uint64,
	inCoinIndex int,
	maxQuantityIn uint64,
	options ...TransactionOption,
) *Transaction

Router3Pool_SwapCoinForExactCoin constructs the transaction to swap coins by by specifying the input amount of coins to swap.

func (*AuxClientConfig) Router3Pool_SwapExactCoinForCoin

func (info *AuxClientConfig) Router3Pool_SwapExactCoinForCoin(
	sender Address,
	coin0 *MoveStructTag,
	amount0 uint64,
	coin1 *MoveStructTag,
	amount1 uint64,
	coin2 *MoveStructTag,
	amount2 uint64,
	outCoinIndex int,
	minQuantityOut uint64,
	options ...TransactionOption,
) *Transaction

Router3Pool_SwapExactCoinForCoin constructs the transaction to swap coins by by specifying the input amount of coins to swap.

Example

Using localnet deployed contract. Make sure there is contract deployed with profile local.

package main

import (
	"context"
	"fmt"
	"os"
	"path"
	"time"

	"github.com/1makarov/go-aptos/aptos"
	"github.com/davecgh/go-spew/spew"
)

func main() {
	client := aptos.MustNewClient(aptos.Localnet, "")

	userHome, err := os.UserHomeDir()
	if err != nil {
		panic(err)
	}

	configFileBytes, err := os.ReadFile(path.Join(userHome, ".aptos", "config.yaml"))
	if err != nil {
		panic(err)
	}

	configFile, err := aptos.ParseAptosConfigFile(configFileBytes)
	if err != nil {
		panic(err)
	}

	localProfile, ok := configFile.Profiles[string(aptos.Localnet)]
	if !ok {
		panic(fmt.Errorf("profile %s is not in config file", aptos.Localnet))
	}

	localAccount, err := localProfile.GetLocalAccount()
	if err != nil {
		panic(err)
	}

	auxConfig := aptos.GetAuxClientConfigFromLocalAccount(localAccount)

	usdc, _ := aptos.GetAuxFakeCoinCoinType(auxConfig.Address, aptos.AuxFakeCoin_USDC)
	usdt, _ := aptos.GetAuxFakeCoinCoinType(auxConfig.Address, aptos.AuxFakeCoin_USDT)
	usdcd8, _ := aptos.GetAuxFakeCoinCoinType(auxConfig.Address, aptos.AuxFakeCoin_USDCD8)

	creatPoolTx := auxConfig.Stable3Pool_CreatePool(localAccount.Address, usdc, usdt, usdcd8, 15_000_000, 85)
	if err := client.FillTransactionData(context.Background(), creatPoolTx, false); err != nil {
		panic(err)
	}

	ctx, cancel := context.WithTimeout(context.TODO(), time.Second*120)
	defer cancel()

	if txInfo, err := client.SignSubmitTransactionWait(ctx, localAccount, creatPoolTx, false); err != nil {
		spew.Fdump(os.Stderr, err)
	} else {
		spew.Fdump(os.Stderr, txInfo)
	}

	for _, coin := range []aptos.AuxFakeCoin{aptos.AuxFakeCoin_USDC, aptos.AuxFakeCoin_USDT, aptos.AuxFakeCoin_USDCD8} {
		tx := auxConfig.FakeCoin_RegisterAndMint(localAccount.Address, coin, 1_000_000_000)
		if err := client.FillTransactionData(ctx, tx, false); err != nil {
			panic(err)
		}
		if _, err := client.SignSubmitTransactionWait(ctx, localAccount, tx, false); err != nil {
			panic(err)
		}
	}

	addLiquidityTx := auxConfig.Router3Pool_AddLiquidity(localAccount.Address, usdc, 1_000_000, usdt, 1_000_000, usdcd8, 100_000_000, 0)
	if err := client.FillTransactionData(ctx, addLiquidityTx, false); err != nil {
		panic(err)
	}
	if txInfo, err := client.SignSubmitTransactionWait(ctx, localAccount, addLiquidityTx, false); err != nil {
		spew.Fdump(os.Stderr, err)
	} else {
		spew.Fdump(os.Stderr, txInfo)
	}

	swapTx := auxConfig.Router3Pool_SwapExactCoinForCoin(localAccount.Address, usdc, 1_000, usdt, 1_000, usdcd8, 0, 2, 190_000, aptos.TransactionOption_MaxGasAmount(100_000))
	if err := client.FillTransactionData(ctx, swapTx, false); err != nil {
		panic(err)
	}
	if txInfo, err := client.SignSubmitTransactionWait(ctx, localAccount, swapTx, false); err != nil {
		spew.Fdump(os.Stderr, err)
	} else {
		spew.Fdump(os.Stderr, txInfo)
	}

}
Output:

func (*AuxClientConfig) Router4Pool_AddLiquidity

func (info *AuxClientConfig) Router4Pool_AddLiquidity(
	sender Address,
	coin0 *MoveStructTag,
	amount0 uint64,
	coin1 *MoveStructTag,
	amount1 uint64,
	coin2 *MoveStructTag,
	amount2 uint64,
	coin3 *MoveStructTag,
	amount3 uint64,
	minLpAmount uint64,
	options ...TransactionOption,
) *Transaction

Router4Pool_AddLiquidity constructs the transaction to add liquidity to a pool

func (*AuxClientConfig) Router4Pool_RemoveLiquidity

func (info *AuxClientConfig) Router4Pool_RemoveLiquidity(
	sender Address,
	coin0 *MoveStructTag,
	coin1 *MoveStructTag,
	coin2 *MoveStructTag,
	coin3 *MoveStructTag,
	lpAmount uint64,
	options ...TransactionOption,
) *Transaction

Router4Pool_RemoveLiquidity constructs the transaction to remove liquidity from the pool by specifying the amount of lp coins to burn.

func (*AuxClientConfig) Router4Pool_RemoveLiquidityForCoin

func (info *AuxClientConfig) Router4Pool_RemoveLiquidityForCoin(
	sender Address,
	coin0 *MoveStructTag,
	amount0ToWithdraw uint64,
	coin1 *MoveStructTag,
	amount1ToWithdraw uint64,
	coin2 *MoveStructTag,
	amount2ToWithdraw uint64,
	coin3 *MoveStructTag,
	amount3ToWithdraw uint64,
	maxLpAmount uint64,
	options ...TransactionOption,
) *Transaction

Router4Pool_RemoveLiquidityForCoin constructs the transaction to remove liquidity from the pool by specifying the coin amount to withdraw.

func (*AuxClientConfig) Router4Pool_SwapCoinForExactCoin

func (info *AuxClientConfig) Router4Pool_SwapCoinForExactCoin(
	sender Address,
	coin0 *MoveStructTag,
	requestAmount0 uint64,
	coin1 *MoveStructTag,
	requestAmount1 uint64,
	coin2 *MoveStructTag,
	requestAmount2 uint64,
	coin3 *MoveStructTag,
	requestAmount3 uint64,
	inCoinIndex int,
	maxQuantityIn uint64,
	options ...TransactionOption,
) *Transaction

Router4Pool_SwapCoinForExactCoin constructs the transaction to swap coins by by specifying the input amount of coins to swap.

func (*AuxClientConfig) Router4Pool_SwapExactCoinForCoin

func (info *AuxClientConfig) Router4Pool_SwapExactCoinForCoin(
	sender Address,
	coin0 *MoveStructTag,
	amount0 uint64,
	coin1 *MoveStructTag,
	amount1 uint64,
	coin2 *MoveStructTag,
	amount2 uint64,
	coin3 *MoveStructTag,
	amount3 uint64,
	outCoinIndex int,
	minQuantityOut uint64,
	options ...TransactionOption,
) *Transaction

Router4Pool_SwapExactCoinForCoin constructs the transaction to swap coins by by specifying the input amount of coins to swap.

func (*AuxClientConfig) Stable2PoolType

func (info *AuxClientConfig) Stable2PoolType(coin0, coin1 *MoveStructTag) (*MoveStructTag, error)

Stable2PoolType returns the move struct tag (MoveStructTag) for a stable 2 pool

func (*AuxClientConfig) Stable2Pool_CreatePool

func (info *AuxClientConfig) Stable2Pool_CreatePool(
	sender Address,
	coin0 *MoveStructTag,
	coin1 *MoveStructTag,
	feeNumerator uint64,
	amp uint64,
	options ...TransactionOption,
) *Transaction

Stable2Pool_CreatePool construct the transaction to create a new 2pool

func (*AuxClientConfig) Stable3PoolType

func (info *AuxClientConfig) Stable3PoolType(coin0, coin1, coin2 *MoveStructTag) (*MoveStructTag, error)

Stable3PoolType returns the move struct tag (MoveStructTag) for a stable 3 pool

func (*AuxClientConfig) Stable3Pool_CreatePool

func (info *AuxClientConfig) Stable3Pool_CreatePool(
	sender Address,
	coin0 *MoveStructTag,
	coin1 *MoveStructTag,
	coin2 *MoveStructTag,
	feeNumerator uint64,
	amp uint64,
	options ...TransactionOption,
) *Transaction

Stable3Pool_CreatePool construct the transaction to create a new 3pool

func (*AuxClientConfig) Stable4PoolType

func (info *AuxClientConfig) Stable4PoolType(coin0, coin1, coin2, coin3 *MoveStructTag) (*MoveStructTag, error)

Stable4PoolType returns the move struct tag (MoveStructTag) for a stable 4 pool

func (*AuxClientConfig) Stable4Pool_CreatePool

func (info *AuxClientConfig) Stable4Pool_CreatePool(
	sender Address,
	coin0 *MoveStructTag,
	coin1 *MoveStructTag,
	coin2 *MoveStructTag,
	coin3 *MoveStructTag,
	feeNumerator uint64,
	amp uint64,
	options ...TransactionOption,
) *Transaction

Stable4Pool_CreatePool construct the transaction to create a new 4pool

func (*AuxClientConfig) Vault_CreateAuxAccount

func (info *AuxClientConfig) Vault_CreateAuxAccount(sender Address, options ...TransactionOption) *Transaction

func (*AuxClientConfig) Vault_Deposit

func (info *AuxClientConfig) Vault_Deposit(sender Address, to Address, coinType *MoveStructTag, amount uint64, options ...TransactionOption) *Transaction

Vault_Deposit deposits into vault.

func (*AuxClientConfig) Vault_Withdraw

func (info *AuxClientConfig) Vault_Withdraw(sender Address, coinType *MoveStructTag, amount uint64, options ...TransactionOption) *Transaction

Vault_Withdraw withdraw from the vault.

type AuxClobMarket

type AuxClobMarket struct {
	Asks          *AuxCritbit `json:"asks,omitempty"`
	Bids          *AuxCritbit `json:"bids,omitempty"`
	BaseDecimals  uint8       `json:"base_decimals"`
	QuoteDecimals uint8       `json:"quote_decimals"`
	LotSize       JsonUint64  `json:"lot_size"`
	TickSize      JsonUint64  `json:"tick_size"`

	FillEvents   *EventHandler `json:"fill_events"`
	PlacedEvents *EventHandler `json:"placed_events"`
	CancelEvents *EventHandler `json:"cancel_events"`
}

AuxClobMarket contains two sided book of bids and asks.

type AuxClobMarketCancelAllResult

type AuxClobMarketCancelAllResult struct {
	RawTransation     *TransactionWithInfo
	CancelledOrderIds []bcs.Uint128
}

type AuxClobMarketCancelOrderResult

type AuxClobMarketCancelOrderResult struct {
	RawTransation *TransactionWithInfo
	IsCancelled   bool
}

AuxClobMarketCancelOrderResult contains the results from a [AuxClientConfig.ClobMarket_Cancel] transaction.

type AuxClobMarketEventCounter

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

func (*AuxClobMarketEventCounter) FillFromAuxClobMarket

func (counter *AuxClobMarketEventCounter) FillFromAuxClobMarket(market *AuxClobMarket)

type AuxClobMarketOrderEvent

type AuxClobMarketOrderEvent struct {
	*AuxClobMarket_OrderFillEvent
	*AuxClobMarket_OrderCancelEvent
	*AuxClobMarket_OrderPlacedEvent
	// the event is identified, but failed to parse
	ParsingFailure error
}

AuxClobMarketOrderEvent is an union of all order events

func FilterAuxClobMarketOrderEvent

func FilterAuxClobMarketOrderEvent(events []*RawEvent, moduleAddress Address, ignoreAddress bool, dropOtherEvents bool) []*AuxClobMarketOrderEvent

FilterAuxClobMarketOrderEvent filers out the clob market events emitted during the placing/cancelling process. It will parse out all the order related events. However, the output slice will have the same length of the input slice. The events unrelated to the orders will have AuxClobMarketOrderEvent.IsOrderEvent returns false. This is useful when the events needs to be put into context of composition with other protocols.

func (*AuxClobMarketOrderEvent) IsOrderEvent

func (ev *AuxClobMarketOrderEvent) IsOrderEvent() bool

IsOrderEvent checks if this AuxClobMarketOrderEvent is order related or not.

type AuxClobMarketOrderStatus

type AuxClobMarketOrderStatus uint64

AuxClobMarketOrderStatus contains the onchain status of the order

  • Placed: the order is placed into the limit order book and is open.
  • Cancelled: the order is cancelled. Order can be cancelled due to user sending a cancel transaction, self trade handling of a new order, time out, or fok/ioc/post only/passive join failed to meet the condition.
  • Filled: the order is fully filled.
const (
	AuxClobMarketOrderStatus_Placed    AuxClobMarketOrderStatus = iota // Placed
	AuxClobMarketOrderStatus_Filled                                    // Filled
	AuxClobMarketOrderStatus_Cancelled                                 // Cancelled
)

func (AuxClobMarketOrderStatus) String

func (i AuxClobMarketOrderStatus) String() string

type AuxClobMarketOrderType

type AuxClobMarketOrderType uint64

AuxClobMarketOrderType, can be limit, fok, ioc, post only or passive join

const (
	AuxClobMarketOrderType_Limit        AuxClobMarketOrderType = iota + 100 // LIMIT
	AuxClobMarketOrderType_FOK                                              // FOK
	AuxClobMarketOrderType_IOC                                              // IOC
	AuxClobMarketOrderType_POST_ONLY                                        // POST_ONLY
	AuxClobMarketOrderType_PASSIVE_JOIN                                     // PASSIVE_JOIN
)

func (AuxClobMarketOrderType) String

func (i AuxClobMarketOrderType) String() string

type AuxClobMarketPlaceOrderError

type AuxClobMarketPlaceOrderError struct {
	ErroredResult        *AuxClobMarketPlaceOrderResult
	InnerError           error
	IsTransactionFailure bool
}

AuxClobMarketPlaceOrderError is the error returned if the transaction is successfully submitted to the chain and executed, but post processing somehow failed. It will contain a copy of the AuxClobMarketPlaceOrderResult that is processed uptil failure.

func IsAuxClobMarketPlaceOrderError

func IsAuxClobMarketPlaceOrderError(err error) (*AuxClobMarketPlaceOrderError, bool)

IsAuxClobMarketPlaceOrderError checks if the error is AuxClobMarketPlaceOrderError, returns the casted AuxClobMarketPlaceOrderError and a bool indicate if it is AuxClobMarketPlaceOrderError

func (*AuxClobMarketPlaceOrderError) Error

func (err *AuxClobMarketPlaceOrderError) Error() string

type AuxClobMarketPlaceOrderResult

type AuxClobMarketPlaceOrderResult struct {
	RawTransaction *TransactionWithInfo

	// OrderId for this order
	OrderId *bcs.Uint128
	// ClientOrderId if there is any. Otherwise this will be 0.
	ClientOrderId *bcs.Uint128
	// Status of the order
	OrderStatus AuxClobMarketOrderStatus

	Events []*AuxClobMarketOrderEvent

	FillEvents []*AuxClobMarket_OrderFillEvent
}

AuxClobMarketPlaceOrderResult contains the results from a AuxClientConfig.ClobMarket_PlaceOrder transaction.

If the transaction is successfully committed to the blockchain, the order will get an order id even if it never goes onto the order book. Note there is no way to differentiate between an empty client order id or a 0 client order id.

Status of the order indicates the status right after the transaction is committed.

type AuxClobMarketSelfTradeType

type AuxClobMarketSelfTradeType uint64

AuxClobMarketSelfTradeType gives instruction on how to handle self trade

const (
	// cancel the order that is on the book
	AuxClobMarketSelfTradeType_CancelPassive AuxClobMarketSelfTradeType = iota + 200 // CANCEL_PASSIVE
	// cancel the order that is being placed.
	AuxClobMarketSelfTradeType_CancelAggressive // CANCEL_AGGRESSIVE
	// cancel both.
	AuxClobMarketSelfTradeType_CancelBoth // CANCEL_BOTH
)

func (AuxClobMarketSelfTradeType) String

type AuxClobMarketTrader

type AuxClobMarketTrader struct {

	// OriginalState contains the state of the market when the AuxClobMarketTrader first start trading.
	// This is useful to monitor the event queues to check if an order is filled or cancelled.
	OriginalState *AuxClobMarket
	// contains filtered or unexported fields
}

AuxClobMarketTrader contains the market state, a client to aptos/aux,

Example

Example creating 5 traders, each maintain 3 orders at most

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"math"
	"net/http"
	"strconv"
	"sync"
	"time"

	"github.com/1makarov/go-aptos/aptos"
	"github.com/davecgh/go-spew/spew"
	"github.com/fardream/go-bcs/bcs"
	"github.com/gorilla/websocket"
)

func must[T any](in T, err error) T {
	orPanic(err)

	return in
}

func orPanic(err error) {
	if err != nil {
		panic(err)
	}
}

type Order struct {
	OrderId   string `json:"order_id"`
	Price     string `json:"price"`
	OrderType string `json:"order_type"`
	Type      string `json:"type"`
	Size      string `json:"size"`
	Side      string `json:"side"`
}

type TraderWithOrdreIds struct {
	*aptos.AuxClobMarketTrader

	orderIds []string
}

// Example creating 5 traders, each maintain 3 orders at most
func main() {
	const network = aptos.Devnet

	const (
		desiredAptosBalance = 1_000_000_000_000     // 10_000 ATP
		desiredUSDCBalance  = 1_000_000_000_000_000 // 1_000_000_000 USDC
		desiredAuxBalance   = 1_000_000_000_000_000 //
	)

	auxConfig, _ := aptos.GetAuxClientConfig(network)

	restUrl, faucetUrl, _ := aptos.GetDefaultEndpoint(network)
	auxFakeCoinCoin := must(aptos.GetAuxFakeCoinCoinType(auxConfig.Address, aptos.AuxFakeCoin_AUX))
	usdcFakeCoinCoin := must(aptos.GetAuxFakeCoinCoinType(auxConfig.Address, aptos.AuxFakeCoin_USDC))

	// cancel the whole process after 15 minutes
	ctx, cancel := context.WithTimeout(context.Background(), time.Minute*15)
	defer cancel()

	client := aptos.MustNewClient(network, restUrl)

	traders := make([]*TraderWithOrdreIds, 0, 5)
	for _, account := range []*aptos.LocalAccount{
		must(aptos.NewLocalAccountWithRandomKey()),
		must(aptos.NewLocalAccountWithRandomKey()),
		must(aptos.NewLocalAccountWithRandomKey()),
		must(aptos.NewLocalAccountWithRandomKey()),
		must(aptos.NewLocalAccountWithRandomKey()),
	} { // get some gas
		txes := must(aptos.RequestFromFaucet(ctx, faucetUrl, &(account.Address), desiredAptosBalance*2))
		for _, txhash := range txes {
			client.WaitForTransaction(ctx, txhash)
		}

		// create user account
		must(client.SignSubmitTransactionWait(ctx, account, auxConfig.Vault_CreateAuxAccount(account.Address), false))
		<-time.After(5 * time.Second)
		// request fake coins
		must(client.SignSubmitTransactionWait(ctx, account, auxConfig.FakeCoin_RegisterAndMint(account.Address, aptos.AuxFakeCoin_USDC, desiredUSDCBalance), false))
		<-time.After(5 * time.Second)
		must(client.SignSubmitTransactionWait(ctx, account, auxConfig.FakeCoin_RegisterAndMint(account.Address, aptos.AuxFakeCoin_AUX, desiredAuxBalance), false))
		<-time.After(5 * time.Second)

		// deposit fake coins
		must(client.SignSubmitTransactionWait(ctx, account, auxConfig.Vault_Deposit(account.Address, account.Address, usdcFakeCoinCoin, desiredUSDCBalance), false))
		<-time.After(5 * time.Second)
		must(client.SignSubmitTransactionWait(ctx, account, auxConfig.Vault_Deposit(account.Address, account.Address, auxFakeCoinCoin, desiredAuxBalance), false))
		<-time.After(5 * time.Second)

		traders = append(traders,
			&TraderWithOrdreIds{
				AuxClobMarketTrader: must(
					aptos.NewAuxClobMarketTrader(
						ctx,
						aptos.NewAuxClient(client, auxConfig, account),
						auxFakeCoinCoin,
						usdcFakeCoinCoin),
				),
			})
	}

	// connect to coinbase
	asset := "APT-USD"
	endpoint := "wss://ws-feed.exchange.coinbase.com"
	dialer := &websocket.Dialer{
		Proxy: http.ProxyFromEnvironment,
	}
	conn, rsp, err := dialer.DialContext(ctx, endpoint, nil)
	if err != nil {
		orPanic(fmt.Errorf("failed to open connection: %v %v", err, rsp))
	}
	defer conn.Close()
	orPanic(conn.WriteJSON(map[string]any{
		"type":        "subscribe",
		"product_ids": []string{asset},
		"channels":    []string{"full"},
	}))

	var wg sync.WaitGroup
	defer wg.Wait()

	waitForWs := make(chan struct{})
	orderChannel := make(chan *Order, 100)

	// first goroutine read the data from websocket and pipe it into a channel
	wg.Add(1)
	go func() {
		defer wg.Done()
		defer func() {
			// once the websocket is disconnected, we indicate that we are done.
			waitForWs <- struct{}{}
			close(waitForWs)
			close(orderChannel)
		}()
	readLoop:
		for {
			_, data, err := conn.ReadMessage()
			if err != nil {
				fmt.Printf("failed to read websocket...: %v", err)
				break
			}

			var order Order
			if err := json.Unmarshal(data, &order); err != nil {
				fmt.Printf("failed to parse: %v\n", err)
				continue
			}

			if !(order.Type == "received" && order.OrderType == "limit") {
				continue
			}
			// stop piping order if cancelled
			select {
			case orderChannel <- &order:
			case <-ctx.Done():
				break readLoop
			}

		}
	}()

	// a second websocket will read from the channel,
	// and select the next trader to trade.
	// each trader will wait 30 seconds to avoid flooding the fullnode.
	wg.Add(1)
	go func() {
		defer wg.Done()
		buyId := 0
		sellId := 1
		wait := time.Second * 5
		var clienOrderId uint64 = 1
	orderLoop:
		for {
			var order *Order
			var ok bool

			// make sure we don't hang on orderChannel if ctx is cancelled
			select {
			case order, ok = <-orderChannel:
			case <-ctx.Done():
				break orderLoop
			}

			if !ok {
				break
			}

			// stop waiting if cancelled
			select {
			case <-time.After(wait):
			case <-ctx.Done():
				break orderLoop
			}

			price, err := strconv.ParseFloat(order.Price, 64)
			if err != nil {
				fmt.Printf("failed to parse price: %s %v\n", order.Price, err)
			}
			size, err := strconv.ParseFloat(order.Size, 64)
			if err != nil {
				fmt.Printf("failed to parse size: %s %v\n", order.Size, err)
			}
			priceInt := uint64(price * 1_000_000)
			priceInt = (priceInt / 10000) * 10000
			sizeInt := uint64(size * 1_000_000)
			sizeInt = (sizeInt / 100000) * 100000

			var trader *TraderWithOrdreIds
			if order.Side == "buy" {
				buyId %= len(traders)
				trader = traders[buyId]
				buyId += 2
				priceInt += 10000
			} else {
				sellId %= len(traders)
				trader = traders[sellId]
				sellId += 2
			}

			fmt.Printf("place %s size %d price %d\n", order.Side, sizeInt, priceInt)

			result, err := trader.PlaceOrder(
				ctx,
				order.Side == "buy",
				priceInt,
				sizeInt,
				0,
				*bcs.NewUint128FromUint64(clienOrderId, 0),
				aptos.AuxClobMarketOrderType_Limit,
				0,
				false,
				math.MaxInt64,
				aptos.AuxClobMarketSelfTradeType_CancelBoth,
				aptos.TransactionOption_MaxGasAmount(30000),
			)
			// print out the order
			if err != nil {
				spew.Dump(err)
			} else {
				fmt.Println(string(result.RawTransaction.Hash))
				if result.OrderStatus == aptos.AuxClobMarketOrderStatus_Placed {
					trader.orderIds = append(trader.orderIds, result.OrderId.Big().String())
					if len(trader.orderIds) >= 3 {
						idToCancel := must(bcs.NewUint128(trader.orderIds[0]))
						trader.orderIds = trader.orderIds[1:]
						result, err := trader.CancelOrder(ctx, *idToCancel)
						if err != nil {
							spew.Dump(err)
						} else {
							spew.Dump(result)
						}
					}
				}
			}
		}
	}()

	select {
	case <-waitForWs:
	case <-ctx.Done():
		conn.Close()
		<-waitForWs
	}
}
Output:

func NewAuxClobMarketTrader

func NewAuxClobMarketTrader(ctx context.Context, auxClient *AuxClient, baseCoin, quoteCoin *MoveStructTag) (*AuxClobMarketTrader, error)

NewAuxClobMarketTrader creates a new trader.

func (*AuxClobMarketTrader) CancelAll

func (*AuxClobMarketTrader) CancelOrder

func (trader *AuxClobMarketTrader) CancelOrder(
	ctx context.Context,
	orderId bcs.Uint128,
	options ...TransactionOption,
) (*AuxClobMarketCancelOrderResult, error)

Cancel an order

func (*AuxClobMarketTrader) PlaceOrder

func (trader *AuxClobMarketTrader) PlaceOrder(
	ctx context.Context,
	isBid bool,
	limitPrice uint64,
	quantity uint64,
	auxToBurnPerLot uint64,
	clientOrderId bcs.Uint128,
	orderType AuxClobMarketOrderType,
	ticksToSlide uint64,
	directionAggressive bool,
	timeoutTimestamp uint64,
	selfTradeType AuxClobMarketSelfTradeType,
	options ...TransactionOption,
) (*AuxClobMarketPlaceOrderResult, error)

PlaceOrder places a new order on clob, check AuxClientConfig.ClobMarket_PlaceOrder for more information on the parameters.

type AuxClobMarket_AllOrdersEvent

type AuxClobMarket_AllOrdersEvent struct {
	Bids [][]*AuxClobMarket_OpenOrderEventInfo `json:"bids"`
	Asks [][]*AuxClobMarket_OpenOrderEventInfo `json:"asks"`
}

AuxClobMarket_AllOrdersEvent contains all the open orders. This is an event because table api doesn't support mass query.

type AuxClobMarket_Level2Event

type AuxClobMarket_Level2Event struct {
	Bids []*AuxClobMarket_Level2Event_Level `json:"bids"`
	Asks []*AuxClobMarket_Level2Event_Level `json:"asks"`
}

AuxClobMarket_Level2Event contains the bids and asks from a `load_market_into_event` call. Since tranversing the orderbook from off-chain is difficult, we run those entry functions to emit data into event queues.

type AuxClobMarket_Level2Event_Level

type AuxClobMarket_Level2Event_Level struct {
	Price    JsonUint64 `json:"price"`
	Quantity JsonUint64 `json:"quantity"`
}

AuxClobMarket_Level2Event_Level is price/quantity in an aux level 2 event

type AuxClobMarket_OpenOrderEventInfo

type AuxClobMarket_OpenOrderEventInfo struct {
	Id                bcs.Uint128 `json:"id"`
	CilentOrderId     bcs.Uint128 `json:"client_order_id"`
	Price             JsonUint64  `json:"price"`
	Quantity          JsonUint64  `json:"quantity"`
	AuxAuToBurnPerLot JsonUint64  `json:"aux_au_to_burn_per_lot"`
	IsBid             bool        `json:"is_bid"`
	OwnerId           Address     `json:"owner_id"`
	TimeoutTimestamp  JsonUint64  `json:"timeout_timestsamp"`
	OrderType         JsonUint64  `json:"order_type"`
	Timestamp         JsonUint64  `json:"timestamp"`
}

AuxClobMarket_OpenOrderEventInfo contains the open order information for an order that is on the order book.

type AuxClobMarket_OrderCancelEvent

type AuxClobMarket_OrderCancelEvent struct {
	OrderId        bcs.Uint128 `json:"order_id"`
	ClientOrderId  bcs.Uint128 `json:"client_order_id"`
	Owner          Address     `json:"owner"`
	CancelQuantity JsonUint64  `json:"cancel_qty"`
	Timestamp      JsonUint64  `json:"timestamp"`
}

AuxClobMarket_OrderCancelEvent is the event emitted when an order is cancelled, either during a new order process or by a cancel transaction.

type AuxClobMarket_OrderFillEvent

type AuxClobMarket_OrderFillEvent struct {
	OrderId           bcs.Uint128 `json:"order_id"`
	ClientOrderId     bcs.Uint128 `json:"client_order_id"`
	Owner             Address     `json:"owner"`
	IsBid             bool        `json:"is_bid"`
	BaseQuantity      JsonUint64  `json:"base_qty"`
	Price             JsonUint64  `json:"price"`
	Fee               JsonUint64  `json:"fee"`
	Rebate            JsonUint64  `json:"rebate"`
	RemainingQuantity JsonUint64  `json:"remaining_qty"`
	Timestamp         JsonUint64  `json:"timestamp"`
}

AuxClobMarket_OrderFillEvent is the event emitted when an order is filled.

type AuxClobMarket_OrderPlacedEvent

type AuxClobMarket_OrderPlacedEvent struct {
	OrderId       bcs.Uint128 `json:"order_id"`
	ClientOrderId bcs.Uint128 `json:"client_order_id"`
	Owner         Address     `json:"owner"`
	IsBid         bool        `json:"is_bid"`
	Quantity      JsonUint64  `json:"qty"`
	Price         JsonUint64  `json:"price"`
	Timestamp     JsonUint64  `json:"timestamp"`
}

AuxClobMarket_OrderPlacedEvent is the event emitted when an order is placed onto the order book.

type AuxCoinBalance

type AuxCoinBalance struct {
	Balance          JsonUint64 `json:"balance"`           // note on aux this is uint128.
	AvailableBalance JsonUint64 `json:"available_balance"` // note on aux this is uint128.
}

AuxCoinBalance

type AuxCritbit

type AuxCritbit struct {
	Entries  *TableWithLength `json:"entries,omitempty"`
	MaxIndex JsonUint64       `json:"max_index"`
	MinIndex JsonUint64       `json:"min_index"`
	Root     JsonUint64       `json:"root"`
	Tree     *TableWithLength `json:"tree"`
}

AuxCritbit is a critbit tree, used to store order books. It has better tail behavior when adding/removing large number of elements, but on average performs worse than red/black tree.

type AuxFakeCoin

type AuxFakeCoin int

AuxFakeCoin contains some fake coins to use on devnet and testnet. They don't have any value and can be freely minted to anyone. Simply call mint (or register_and_mint if not signed up for it already).

const (
	AuxFakeCoin_USDC   AuxFakeCoin = iota // USDC
	AuxFakeCoin_ETH                       // ETH
	AuxFakeCoin_BTC                       // BTC
	AuxFakeCoin_SOL                       // SOL
	AuxFakeCoin_AUX                       // AUX
	AuxFakeCoin_USDT                      // USDT
	AuxFakeCoin_USDCD8                    // USDCD8
)

func ParseAuxFakeCoin

func ParseAuxFakeCoin(s string) (AuxFakeCoin, error)

ParseAuxFakeCoin converts a string into fake coin.

func (AuxFakeCoin) String

func (i AuxFakeCoin) String() string

type AuxStable2Pool

type AuxStable2Pool struct {
	/// FeeNumerator, denominator is 10^10
	FeeNumerator *bcs.Uint128 `json:"fee_numerator"`
	/// BalancedReserve
	BalancedReserve *bcs.Uint128 `json:"balanced_reserve"`
	/// Amp
	Amp *bcs.Uint128 `json:"amp"`

	Reserve0 *Coin        `json:"reserve_0"`
	Fee0     *Coin        `json:"fee_0"`
	Scaler0  *bcs.Uint128 `json:"scaler_0"`

	Reserve1 *Coin        `json:"reserve_1"`
	Fee1     *Coin        `json:"fee_1"`
	Scaler1  *bcs.Uint128 `json:"scaler_1"`
}

AuxStable2Pool is a pool with 2 coins that priced at parity.

type AuxStable3Pool

type AuxStable3Pool struct {
	/// FeeNumerator, denominator is 10^10
	FeeNumerator *bcs.Uint128 `json:"fee_numerator"`
	/// BalancedReserve
	BalancedReserve *bcs.Uint128 `json:"balanced_reserve"`
	/// Amp
	Amp *bcs.Uint128 `json:"amp"`

	Reserve0 *Coin        `json:"reserve_0"`
	Fee0     *Coin        `json:"fee_0"`
	Scaler0  *bcs.Uint128 `json:"scaler_0"`

	Reserve1 *Coin        `json:"reserve_1"`
	Fee1     *Coin        `json:"fee_1"`
	Scaler1  *bcs.Uint128 `json:"scaler_1"`

	Reserve2 *Coin        `json:"reserve_2"`
	Fee2     *Coin        `json:"fee_2"`
	Scaler2  *bcs.Uint128 `json:"scaler_2"`
}

AuxStable3Pool is a pool with 3 coins that priced at parity.

type AuxStable4Pool

type AuxStable4Pool struct {
	/// FeeNumerator, denominator is 10^10
	FeeNumerator *bcs.Uint128 `json:"fee_numerator"`
	/// BalancedReserve
	BalancedReserve *bcs.Uint128 `json:"balanced_reserve"`
	/// Amp
	Amp *bcs.Uint128 `json:"amp"`

	Reserve0 *Coin        `json:"reserve_0"`
	Fee0     *Coin        `json:"fee_0"`
	Scaler0  *bcs.Uint128 `json:"scaler_0"`

	Reserve1 *Coin        `json:"reserve_1"`
	Fee1     *Coin        `json:"fee_1"`
	Scaler1  *bcs.Uint128 `json:"scaler_1"`

	Reserve2 *Coin        `json:"reserve_2"`
	Fee2     *Coin        `json:"fee_2"`
	Scaler2  *bcs.Uint128 `json:"scaler_2"`

	Reserve3 *Coin        `json:"reserve_3"`
	Fee3     *Coin        `json:"fee_3"`
	Scaler3  *bcs.Uint128 `json:"scaler_3"`
}

AuxStable4Pool is a pool with 4 coins that priced at parity.

type AuxUserAccount

type AuxUserAccount struct {
	AuthorizedTraders Table `json:"authorized_traders"`
}

AuxUserAccount

type Bip32Key

type Bip32Key struct {
	Key       []byte
	ChainCode []byte
}

Bip32Key

func CKDPriv

func CKDPriv(key *Bip32Key, index uint32) (*Bip32Key, error)

see corresponding code in typescript

func GetBip39MasterKeyFromSeed

func GetBip39MasterKeyFromSeed(seed []byte) (*Bip32Key, error)

see corresponding code in typescript

type Client

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

Client for aptos

func MustNewClient

func MustNewClient(network Network, restUrl string, transactionOptions ...TransactionOption) *Client

MustNewClient creates a new client, panic if error happens.

func NewClient

func NewClient(network Network, restUrl string, transactionOptions ...TransactionOption) (*Client, error)

NewClient creates a new client for the given network. Values will be taken from the default of the network. URL can be left empty. Client's default option includes expire after 5 minutes and max gas of 20,000.

func (*Client) EstimateGasPrice

func (client *Client) EstimateGasPrice(ctx context.Context) (*AptosResponse[EstimateGasPriceResponse], error)

EstimateGasPrice

func (*Client) FillTransactionData

func (client *Client) FillTransactionData(ctx context.Context, tx *Transaction, seqNumIsZero bool) error

FillTransactionData fills the missing data for a transaction. seqNumIsZero indicates the sequence number is 0 for the account and therefore doesn't need to check

func (*Client) GetAccount

func (client *Client) GetAccount(ctx context.Context, request *GetAccountRequest) (*AptosResponse[GetAccountResponse], error)

GetAccount

func (*Client) GetAccountModule

func (client *Client) GetAccountModule(ctx context.Context, request *GetAccountModuleRequest) (*AptosResponse[GetAccountModuleResponse], error)

GetAccountModule

Example

Example: get the clob_market of aux.exchange from testnet

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/1makarov/go-aptos/aptos"
	"github.com/davecgh/go-spew/spew"
)

func main() {
	client := aptos.MustNewClient(aptos.Testnet, "")
	auxConfig, _ := aptos.GetAuxClientConfig(aptos.Testnet)

	modules, err := client.GetAccountModule(context.Background(), &aptos.GetAccountModuleRequest{
		Address:    auxConfig.Address,
		ModuleName: "clob_market",
	})
	if err != nil {
		panic(err)
	}

	spew.Fdump(os.Stderr, modules.Parsed)
	fmt.Println("got clob_market")

}
Output:

got clob_market

func (*Client) GetAccountModules

func (client *Client) GetAccountModules(ctx context.Context, request *GetAccountModulesRequest) (*AptosResponse[GetAccountModulesResponse], error)

GetAccountModules

Example

Example: get the modules of aux.exchange from testnet

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/1makarov/go-aptos/aptos"
	"github.com/davecgh/go-spew/spew"
)

func main() {
	client := aptos.MustNewClient(aptos.Testnet, "")
	auxConfig, _ := aptos.GetAuxClientConfig(aptos.Testnet)

	modules, err := client.GetAccountModules(context.Background(), &aptos.GetAccountModulesRequest{
		Address: auxConfig.Address,
	})
	if err != nil {
		panic(err)
	}

	spew.Fdump(os.Stderr, modules.Parsed)
	if len(*modules.Parsed) >= 10 {
		fmt.Println("got all the modules")
	}

}
Output:

got all the modules

func (*Client) GetAccountResource

func (client *Client) GetAccountResource(ctx context.Context, request *GetAccountResourceRequest) (*AptosResponse[GetAccountResourceResponse], error)

GetAccountResource

Example

How to get account resource

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"os"

	"github.com/1makarov/go-aptos/aptos"
	"github.com/google/go-cmp/cmp"
)

func main() {
	client := aptos.MustNewClient(aptos.Testnet, "")
	// account resource is identified by a type.
	// AptosCoin is type
	aptosCoin, _ := aptos.NewMoveStructTag(aptos.AptosStdAddress, "aptos_coin", "AptosCoin", nil)
	// The coin value of an account is stored in a coin store
	aptosCoinStore, _ := aptos.NewMoveStructTag(aptos.AptosStdAddress, "coin", "CoinStore", []*aptos.MoveStructTag{aptosCoin})

	// let's check the coin balance of our deployer
	auxConfig, _ := aptos.GetAuxClientConfig(aptos.Testnet)

	// getting the coin store will get us the coin balance
	resp, err := client.GetAccountResource(context.Background(), &aptos.GetAccountResourceRequest{
		Address: auxConfig.Address,
		Type:    aptosCoinStore,
	})
	if err != nil {
		panic(err)
	}

	// check we have the correct type
	if !cmp.Equal(resp.Parsed.Type, aptosCoinStore) {
		panic(fmt.Errorf("differenet types: %s - %s", resp.Parsed.Type.String(), aptosCoinStore.String()))
	}

	// unfortuantely, we still need to parse the store into a proper golang object
	var coinStore aptos.CoinStore
	if err := json.Unmarshal(resp.Parsed.Data, &coinStore); err != nil {
		panic(err)
	}

	if coinStore.Coin.Value == 0 {
		panic("empty store")
	}

	fmt.Fprintln(os.Stderr, coinStore.Coin.Value)
	fmt.Println("we have money")

}
Output:

we have money

func (*Client) GetAccountResources

func (client *Client) GetAccountResources(ctx context.Context, request *GetAccountResourcesRequest) (*AptosResponse[GetAccountResourcesResponse], error)

GetAccountResources

Example

Listing Account Resources

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/1makarov/go-aptos/aptos"
)

func main() {
	client := aptos.MustNewClient(aptos.Devnet, "")
	// let's check the coin balance of our deployer
	auxConfig, _ := aptos.GetAuxClientConfig(aptos.Devnet)

	// getting the coin store will get us the coin balance
	resp, err := client.GetAccountResources(context.Background(), &aptos.GetAccountResourcesRequest{
		Address: auxConfig.Deployer,
	})
	if err != nil {
		panic(err)
	}

	fmt.Fprintln(os.Stderr, string(resp.RawData))
	fmt.Println("done")
}
Output:

done

func (*Client) GetAuxCoinBalance

func (client *Client) GetAuxCoinBalance(ctx context.Context, auxInfo *AuxClientConfig, user Address, coinType *MoveStructTag) (*AuxCoinBalance, error)

GetAuxCoinBalance retrieves the balance for the user.

Example
client := aptos.MustNewClient(aptos.Devnet, "")
eth, _ := aptos.GetAuxFakeCoinCoinType(devnetConfig.Address, aptos.AuxFakeCoin_ETH)
cb, err := client.GetAuxCoinBalance(context.Background(), devnetConfig, trader.Address, eth)
if err != nil {
	panic(fmt.Errorf("failed to get balance: %v", err))
}

spew.Dump(cb)
Output:

func (*Client) GetChainId

func (client *Client) GetChainId(ctx context.Context) (uint8, error)

GetChainId

func (*Client) GetCoinBalance

func (client *Client) GetCoinBalance(ctx context.Context, address Address, coinType *MoveStructTag) (uint64, error)

GetCoinBalance

func (*Client) GetEventsByCreationNumber

func (client *Client) GetEventsByCreationNumber(ctx context.Context, request *GetEventsByCreationNumberRequest) (*AptosResponse[GetEventsByCreationNumberResponse], error)

[GetEventsByCreationNumber] [GetEventsByCreationNumber]: https://fullnode.mainnet.aptoslabs.com/v1/spec#/operations/get_events_by_creation_number

Example

Example: getting clob market events by their creation numbers

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/davecgh/go-spew/spew"

	"github.com/1makarov/go-aptos/aptos"
)

func main() {
	client := aptos.MustNewClient(aptos.Devnet, "")

	auxConfig, _ := aptos.GetAuxClientConfig(aptos.Devnet)

	fakeEth, _ := aptos.GetAuxFakeCoinCoinType(auxConfig.Address, aptos.AuxFakeCoin_ETH)
	fakeUsdc, _ := aptos.GetAuxFakeCoinCoinType(auxConfig.Address, aptos.AuxFakeCoin_USDC)
	marketType := aptos.MustNewMoveStructTag(auxConfig.Address, "clob_market", "Market", []*aptos.MoveStructTag{fakeEth, fakeUsdc})

	market, err := aptos.GetAccountResourceWithType[aptos.AuxClobMarket](context.Background(), client, auxConfig.Address, marketType, 0)
	if err != nil {
		panic(err)
	}

	if market.PlacedEvents == nil {
		panic(fmt.Errorf("placed_events is nil"))
	}

	creation_number := market.PlacedEvents.GUID.Id.CreationNumber

	resp, err := client.GetEventsByCreationNumber(context.Background(), &aptos.GetEventsByCreationNumberRequest{
		CreationNumber: creation_number,
		Address:        auxConfig.Address,
	})
	if err != nil {
		panic(err)
	}

	spew.Fdump(os.Stderr, resp)

	fmt.Println("done")

}
Output:

done

func (*Client) GetEventsByEventHandler

func (client *Client) GetEventsByEventHandler(ctx context.Context, request *GetEventsByEventHandlerRequest) (*AptosResponse[GetEventsByEventHandlerResponse], error)

[GetEventsByEventHandler] [GetEventsByEventHandler]: https://fullnode.mainnet.aptoslabs.com/v1/spec#/operations/get_events_by_event_handle

Example
package main

import (
	"context"
	"fmt"
	"os"

	"github.com/davecgh/go-spew/spew"

	"github.com/1makarov/go-aptos/aptos"
)

func main() {
	client := aptos.MustNewClient(aptos.Devnet, "")

	auxConfig, _ := aptos.GetAuxClientConfig(aptos.Devnet)

	fakeEth, _ := aptos.GetAuxFakeCoinCoinType(auxConfig.Address, aptos.AuxFakeCoin_ETH)
	fakeUsdc, _ := aptos.GetAuxFakeCoinCoinType(auxConfig.Address, aptos.AuxFakeCoin_USDC)
	marketType := aptos.MustNewMoveStructTag(auxConfig.Address, "clob_market", "Market", []*aptos.MoveStructTag{fakeEth, fakeUsdc})

	resp, err := client.GetEventsByEventHandler(context.Background(), &aptos.GetEventsByEventHandlerRequest{
		EventHandler: marketType,
		Address:      auxConfig.Address,
		FieldName:    "placed_events",
	})
	if err != nil {
		panic(err)
	}

	spew.Fdump(os.Stderr, resp)

	fmt.Println("done")

}
Output:

done

func (*Client) GetLedgerInfo

func (client *Client) GetLedgerInfo(ctx context.Context) (*AptosResponse[GetLedgerInfoResponse], error)

GetLedgerInfo

func (*Client) LoadEvents

func (client *Client) LoadEvents(ctx context.Context, address Address, creationNumber uint64, start, end, sliceSize uint64) ([]*RawEvent, error)

LoadEvents loads the events as defined by the creation number and address. Load sliceSize events at one request.

Example
package main

import (
	"context"
	"fmt"
	"os"
	"time"

	"github.com/1makarov/go-aptos/aptos"
	"github.com/davecgh/go-spew/spew"
)

func main() {
	client := aptos.MustNewClient(aptos.Mainnet, "")
	auxConfig, _ := aptos.GetAuxClientConfig(aptos.Mainnet)

	ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
	defer cancel()
	// pool: Aptos/USDC 0xbd35135844473187163ca197ca93b2ab014370587bb0ed3befff9e902d6bb541::amm::Pool<0x1::aptos_coin::AptosCoin, 0x5e156f1207d0ebfa19a9eeff00d62a282278fb8719f4fab3a586a0a2c0fffbea::coin::T>
	events, err := client.LoadEvents(ctx, auxConfig.Address, 72, 93, 405, 25)
	if err != nil {
		spew.Dump(err)
		panic(err)
	}

	fmt.Println(len(events))

	spew.Sdump(os.Stderr, events)
}
Output:

312
Example (AuxFillEvents)
package main

import (
	"context"
	"fmt"
	"os"
	"time"

	"github.com/1makarov/go-aptos/aptos"
	"github.com/1makarov/go-aptos/aptos/known"
	"github.com/davecgh/go-spew/spew"
)

func main() {
	client := aptos.MustNewClient(aptos.Mainnet, "")
	auxConfig, _ := aptos.GetAuxClientConfig(aptos.Mainnet)

	auxClient := aptos.NewAuxClient(client, auxConfig, nil)

	usdc := known.GetCoinInfoBySymbol(aptos.Mainnet, "USDC").TokenType.Type
	apt := known.GetCoinInfoBySymbol(aptos.Mainnet, "APT").TokenType.Type

	// get the market information
	market, err := auxClient.GetClobMarket(context.Background(), apt, usdc, 0)
	if err != nil {
		panic(err)
	}

	// get the creation number of the event handler for fills, can do the same for OrderPlaced and OrderCancel
	creationNumber := uint64(market.FillEvents.GUID.Id.CreationNumber)

	ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
	defer cancel()
	rawevents, err := client.LoadEvents(ctx, auxConfig.Address, creationNumber, 0, 312, 50)
	if err != nil {
		spew.Dump(err)
		panic(err)
	}

	// converts the raw events into proper fill events
	events := aptos.FilterAuxClobMarketOrderEvent(rawevents, auxConfig.Address, false, true)

	spew.Sdump(os.Stderr, events)
	fmt.Println(len(events))

}
Output:

312

func (*Client) RefreshData

func (client *Client) RefreshData(ctx context.Context) error

RefreshData updates gas price estimates and ledger info.

func (*Client) SetChainId

func (client *Client) SetChainId(chainId uint8)

SetChainId after client is created.

func (*Client) SignSubmitTransactionWait

func (client *Client) SignSubmitTransactionWait(ctx context.Context, signer Signer, tx *Transaction, noWait bool, waitOptions ...TransactionWaitOption) (*TransactionWithInfo, error)

SignSubmitTransactionWait is a convenient function to sign a transaction, submit it, and optionally wait for it.

func (*Client) SubmitTransaction

func (client *Client) SubmitTransaction(ctx context.Context, request *SubmitTransactionRequest) (*AptosResponse[SubmitTransactionResponse], error)

SubmitTransaction

Example

Example Submitting a transaction to the devnet. But first, we need to create a new account, and obtain some gas from faucet.

package main

import (
	"context"
	"encoding/hex"
	"fmt"
	"os"
	"time"

	"github.com/1makarov/go-aptos/aptos"
	"github.com/davecgh/go-spew/spew"
)

const network = aptos.Devnet

// Example Submitting a transaction to the devnet.
// But first, we need to create a new account, and obtain some gas from faucet.
func main() {
	// rest url and faucet url
	restUrl, faucetUrl, _ := aptos.GetDefaultEndpoint(network)

	// create new account, and fund it with faucet
	account, _ := aptos.NewLocalAccountWithRandomKey()

	fmt.Fprintf(os.Stderr, "private key: 0x%s\n", hex.EncodeToString(account.PrivateKey.Seed()))
	fmt.Fprintf(os.Stderr, "address: %s\n", account.Address.String())

	// aptos client
	client := aptos.MustNewClient(network, restUrl)

	// do faucet. note the faucet transaction is still inflight when returned, we need to check for the completion of the transaction.
	faucetTxes, err := aptos.RequestFromFaucet(context.Background(), faucetUrl, &account.Address, 1000000000)
	if err != nil {
		panic(err)
	}
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*60)
	defer cancel()

	for _, faucetTx := range faucetTxes {
		txType, err := client.WaitForTransaction(ctx, faucetTx)
		if err != nil {
			spew.Dump(err)
		}
		fmt.Fprintf(os.Stderr, "fauct tx type: %s\n", txType.Type)
	}

	// construct a transaction from aux suite of transactions.
	auxConfig, _ := aptos.GetAuxClientConfig(network)

	tx := aptos.Transaction{
		Sender:                  account.Address,
		ExpirationTimestampSecs: aptos.JsonUint64(time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC).Unix()),
		Payload: aptos.NewEntryFunctionPayload(
			aptos.MustNewMoveFunctionTag(auxConfig.Address, "fake_coin", "mint"),
			[]*aptos.MoveStructTag{aptos.MustNewMoveStructTag(auxConfig.Address, "fake_coin", "USDC", nil)},
			[]*aptos.EntryFunctionArg{aptos.EntryFunctionArg_Uint64(1000000000000)}),
	}

	// fill the missing information (
	if err := client.FillTransactionData(context.Background(), &tx, false); err != nil {
		panic(err)
	}

	// sign the transaction.
	signature, err := account.Sign(&tx)
	if err != nil {
		panic(err)
	}

	// submit the transaction.
	request := &aptos.SubmitTransactionRequest{
		Transaction: &tx,
		Signature:   *signature,
	}
	// we can take a look at the json body.
	body, _ := request.Body()
	fmt.Fprintln(os.Stderr, string(body))

	// submit the transaction.
	resp, err := client.SubmitTransaction(context.Background(), request)
	if err != nil {
		panic(err)
	} else {
		spew.Fdump(os.Stderr, resp)
		ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
		defer cancel()
		txInfo, err := client.WaitForTransaction(ctx, resp.Parsed.Hash)
		if err != nil {
			panic(err)
		} else {
			fmt.Println(txInfo.Type)
		}
	}
}
Output:

Example (Multiple)
package main

import (
	"context"
	"encoding/hex"
	"fmt"
	"os"
	"sync"
	"time"

	"github.com/1makarov/go-aptos/aptos"
	"github.com/davecgh/go-spew/spew"
)

func main() {
	aptosClient := aptos.MustNewClient(aptos.Devnet, "")
	auxConfig := aptos.MustGetAuxClientConfig(aptos.Devnet)

	localAccount, _ := aptos.NewLocalAccountWithRandomKey()
	fmt.Fprintf(os.Stderr, "0x%s\n", hex.EncodeToString(localAccount.PrivateKey.Seed()))
	_, facuetUrl, _ := aptos.GetDefaultEndpoint(aptos.Devnet)

	txes, err := aptos.RequestFromFaucet(context.Background(), facuetUrl, &(localAccount.Address), 1000000000)
	if err != nil {
		panic(err)
	}

	for _, tx := range txes {
		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
		defer cancel()
		if tx, err := aptosClient.WaitForTransaction(ctx, tx); err != nil {
			panic(err)
		} else {
			if !tx.Success {
				panic(tx)
			}
		}
	}

	// a new account always starts with sequence number 0.
	registerTx := auxConfig.FakeCoin_Register(
		localAccount.Address,
		aptos.AuxFakeCoin_SOL,
		aptos.TransactionOption_SequenceNumber(0), // seqnum 0.
		aptos.TransactionOption_ExpireAfter(5*time.Minute))
	if err := aptosClient.FillTransactionData(context.Background(), registerTx, true); err != nil {
		panic(err)
	}
	// a second transaction that is guaranteed to be executed after the first.
	mintTx := auxConfig.FakeCoin_Mint(
		localAccount.Address,
		aptos.AuxFakeCoin_SOL,
		10000000000,
		aptos.TransactionOption_SequenceNumber(1), // seqnum 1
		aptos.TransactionOption_ExpireAfter(5*time.Minute))
	if err := aptosClient.FillTransactionData(context.Background(), mintTx, true); err != nil {
		panic(err)
	}

	var wg sync.WaitGroup
	defer wg.Wait()

	// send the min transaction first, then send the register transaction.
	// mint transaction will wait for register transaction because it has a later sequence number.
	for _, tx := range []*aptos.Transaction{mintTx, registerTx} {
		fmt.Fprintln(os.Stderr, "wait for 5 seconds")
		<-time.After(5 * time.Second)
		wg.Add(1)
		go func(tx *aptos.Transaction) {
			defer wg.Done()
			ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
			defer cancel()

			txInfo, err := aptosClient.SignSubmitTransactionWait(ctx, localAccount, tx, false)
			if err != nil {
				spew.Fdump(os.Stderr, err)
			} else {
				fmt.Fprintf(os.Stderr, "function: %s - hash: %s- status: %s\n", txInfo.Payload.Function.Name, txInfo.Hash, txInfo.VmStatus)
			}
		}(tx)
	}

	fmt.Println("done")
}
Output:

done

func (*Client) WaitForTransaction

func (client *Client) WaitForTransaction(ctx context.Context, txHash string, waitOptions ...TransactionWaitOption) (*TransactionWithInfo, error)

WaitForTransaction: by default the wait is exponentially backing off with a scale of 2 and initial wait of 1 second. The wait doesn't have a time out, instead, relying context passed in to indicate (e.g. creating a context with context.WithTimeout and pass that in).

type Coin

type Coin struct {
	Value JsonUint64 `json:"value"`
}

Coin, this is golang equivalent of 0x1::coin::Coin

type CoinStore

type CoinStore struct {
	Coin           Coin         `json:"coin"`
	Frozen         bool         `json:"frozen"`
	DepositEvents  EventHandler `json:"deposit_events"`
	WithdrawEvents EventHandler `json:"withdraw_events"`
}

CoinStore, this is golang equivalent of 0x1::coin::CoinStore

type Config

type Config struct {
	PrivateKey string `yaml:"private_key"`
	PublicKey  string `yaml:"public_key"`
	Account    string `yaml:"account"`
	RestUrl    string `yaml:"rest_url"`
	FaucetUrl  string `yaml:"faucet_url"`
}

Config is a configuration section in aptos's yaml config file.

func (*Config) GetLocalAccount

func (config *Config) GetLocalAccount() (*LocalAccount, error)

GetLocalAccount

func (*Config) SetKey

func (config *Config) SetKey(account *LocalAccount) error

SetKey set the configurations' private key, public key, and account to LocalAccount

type ConfigFile

type ConfigFile struct {
	Profiles map[string]*Config `yaml:"profiles"`
}

ConfigFile contains a profiles map

func NewConfigFile

func NewConfigFile() *ConfigFile

func ParseAptosConfigFile

func ParseAptosConfigFile(configFileContent []byte) (*ConfigFile, error)

func (*ConfigFile) ToString

func (c *ConfigFile) ToString() ([]byte, error)

type EncodeSubmissionRequest

type EncodeSubmissionRequest struct {
	*Transaction     `json:",inline" url:"-"`
	SecondarySigners []Address `json:"secondary_signers,omitempty" url:"-"`
}

EncodeSubmissionRequest

func (*EncodeSubmissionRequest) Body

func (r *EncodeSubmissionRequest) Body() ([]byte, error)

func (*EncodeSubmissionRequest) HttpMethod

func (r *EncodeSubmissionRequest) HttpMethod() string

func (*EncodeSubmissionRequest) PathSegments

func (r *EncodeSubmissionRequest) PathSegments() ([]string, error)

type EncodeSubmissionResponse

type EncodeSubmissionResponse string

type EntryFunctionArg

type EntryFunctionArg struct {
	Bool    *bool
	Uint8   *uint8
	Uint64  *JsonUint64
	Uint128 *bcs.Uint128
	Address *Address
	Signer  *struct{}
	String  *string
}

EntryFunctionArg is the argument to entry function. This is kind of an enum, but on the wire actually all bcs byte vectors. This means the values are first bcs serialized to vector of bytes. Then the vector of bytes are serialized.

func EntryFunctionArg_Address

func EntryFunctionArg_Address(v Address) *EntryFunctionArg

func EntryFunctionArg_Bool

func EntryFunctionArg_Bool(v bool) *EntryFunctionArg

EntryFunctionArg_Bool

func EntryFunctionArg_String

func EntryFunctionArg_String(v string) *EntryFunctionArg

func EntryFunctionArg_Uint128

func EntryFunctionArg_Uint128(lo uint64, hi uint64) *EntryFunctionArg

EntryFunctionArg_Uint128 creates a new EntryFunctionArg with Uint128 set from lo/hi [uint64].

func EntryFunctionArg_Uint64

func EntryFunctionArg_Uint64(v uint64) *EntryFunctionArg

EntryFunctionArg_Uint64 is equivalent to uint64, or u64 in move.

func EntryFunctionArg_Uint8

func EntryFunctionArg_Uint8(v uint8) *EntryFunctionArg

EntryFunctionArg_Uint8 represents u8 in move, equivalent to a byte

func (EntryFunctionArg) MarshalBCS

func (m EntryFunctionArg) MarshalBCS() ([]byte, error)

MarshalBCS customizes bcs Marshal for EntryFunctionArg. This method first bcs serialize the non-nil value, then serialize the resulted byte vector (simply prepending the length with ULEB128 encoding).

func (EntryFunctionArg) MarshalJSON

func (m EntryFunctionArg) MarshalJSON() ([]byte, error)

func (*EntryFunctionArg) UnmarshalJSON

func (s *EntryFunctionArg) UnmarshalJSON(data []byte) error

UnmarshalJSON for EntryFunctionArg. json doesn't have type information, so the process uses a series of heuristics.

  • deserializing response from rest api either in json or bcs is difficult without knowing the types of the elements before hand.

    The following logic is used to deserialize the slices: first, the element of the slice will be first tested if it is an u64 or bool. Then, it is checked to see if it is a string. If it is a string and it has 0x prefix, cast it to address. If casting to address is unsuccessful, keep it as a string.

  • during serialization, the element of entry function argument slice is prefixed with the length of the serialized bytes. For example, instead of serialize true to 01, serialize it to 0101.

type EntryFunctionPayload

type EntryFunctionPayload struct {
	Function      *MoveFunctionTag    `json:"function"`
	TypeArguments []*MoveTypeTag      `json:"type_arguments"`
	Arguments     []*EntryFunctionArg `json:"arguments"`
}

EntryFunctionPayload

type EstimateGasPriceResponse

type EstimateGasPriceResponse struct {
	DeprioritizedGasEstimate uint `json:"deprioritized_gas_estimate"`
	GasEstimate              uint `json:"gas_estimate"`
	PrioritizedGasEstimate   uint `json:"prioritized_gas_estimate"`
}

type Event

type Event[T any] struct {
	// GUID is the identifier of the event handler
	GUID GUID_ID `json:"guid"`
	// SequenceNumber of the event.
	// This is monotonically increasing without any gaps.
	SequenceNumber JsonUint64 `json:"sequence_number"`
	// Type of the event
	Type MoveStructTag `json:"type"`
	// Data of the event
	Data *T `json:"data"`
}

Event emitted from aptos transactions

type EventHandler

type EventHandler struct {
	Counter JsonUint64 `json:"counter"`
	GUID    struct {
		Id struct {
			CreationNumber JsonUint64 `json:"creation_num"`
			AccountAddress Address    `json:"addr"`
		} `json:"id"`
	} `json:"guid"`
}

EventHandler contains the information for an event handler.

type FullNodeConfig

type FullNodeConfig struct {
	Base *struct {
		DataDir  string `yaml:"data_dir"`
		Waypoint *struct {
			FromFile string         `yaml:"from_file"`
			Others   map[string]any `yaml:",inline"`
		} `yaml:"waypoint"`
		Others map[string]any `yaml:",inline"`
	} `yaml:"base"`
	Execution *struct {
		GenesisFileLocation string         `yaml:"genesis_file_location"`
		Others              map[string]any `yaml:",inline"`
	} `yaml:"execution"`
	FullNodeNetworks []*struct {
		Others map[string]any `yaml:",inline"`
	} `yaml:"full_node_networks"`

	Api *struct {
		Enabled bool           `yaml:"enabled"`
		Address string         `yaml:"address"`
		Others  map[string]any `yaml:",inline"`
	} `yaml:"api"`
	Others map[string]any `yaml:",inline"`
}

FullNodeConfig is representation of full_node_config.yml

func ParseFullNodeConfig

func ParseFullNodeConfig(data []byte) (*FullNodeConfig, error)

func (*FullNodeConfig) ToConfigFile

func (config *FullNodeConfig) ToConfigFile() ([]byte, error)

type GUID

type GUID struct {
	Id GUID_ID `json:"id"`
}

GUID contains an [ID]. This is an onchain struct.

type GUID_ID

type GUID_ID struct {
	CreationNumber JsonUint64 `json:"creation_number"`
	AccountAddress Address    `json:"account_address"`
}

GUID_ID is the ID type of aptos framework.

type GetAccountModuleRequest

type GetAccountModuleRequest struct {
	GetRequest

	Address       Address `url:"-"`
	LedgerVersion *uint64 `url:"ledger_version,omitempty"`
	ModuleName    string  `url:"-"`
}

func (*GetAccountModuleRequest) PathSegments

func (r *GetAccountModuleRequest) PathSegments() ([]string, error)

type GetAccountModuleResponse

type GetAccountModuleResponse = AccountModule

type GetAccountModulesRequest

type GetAccountModulesRequest struct {
	GetRequest

	Address       Address `url:"-"`
	LedgerVersion *uint64 `url:"ledger_version,omitempty"`
}

func (*GetAccountModulesRequest) PathSegments

func (r *GetAccountModulesRequest) PathSegments() ([]string, error)

type GetAccountModulesResponse

type GetAccountModulesResponse = []AccountModule

type GetAccountRequest

type GetAccountRequest struct {
	GetRequest

	Address       Address `url:"-"`
	LedgerVersion *uint64 `url:"ledger_version,omitempty"`
}

func (*GetAccountRequest) PathSegments

func (r *GetAccountRequest) PathSegments() ([]string, error)

type GetAccountResourceRequest

type GetAccountResourceRequest struct {
	GetRequest

	Address       Address        `url:"-"`
	LedgerVersion *JsonUint64    `url:"ledger_version,omitempty"`
	Type          *MoveStructTag `url:"-"`
}

func (*GetAccountResourceRequest) PathSegments

func (r *GetAccountResourceRequest) PathSegments() ([]string, error)

type GetAccountResourceResponse

type GetAccountResourceResponse struct {
	*AccountResource `json:",inline"`
}

type GetAccountResourcesRequest

type GetAccountResourcesRequest struct {
	GetRequest

	Address       Address `url:"-"`
	LedgerVersion *uint64 `url:"ledger_version,omitempty"`
}

func (*GetAccountResourcesRequest) PathSegments

func (r *GetAccountResourcesRequest) PathSegments() ([]string, error)

type GetAccountResourcesResponse

type GetAccountResourcesResponse []AccountResource

type GetAccountResponse

type GetAccountResponse struct {
	SequenceNumber    JsonUint64 `json:"sequence_number"`
	AuthenticationKey string     `json:"authentication_key"`
}

type GetEventsByCreationNumberRequest

type GetEventsByCreationNumberRequest struct {
	GetRequest

	Limit *JsonUint64 `url:"limit,omitempty"`
	Start *JsonUint64 `url:"start,omitempty"`

	Address        Address    `url:"-"`
	CreationNumber JsonUint64 `url:"-"`
}

func (*GetEventsByCreationNumberRequest) PathSegments

func (request *GetEventsByCreationNumberRequest) PathSegments() ([]string, error)

type GetEventsByCreationNumberResponse

type GetEventsByCreationNumberResponse []*RawEvent

type GetEventsByEventHandlerRequest

type GetEventsByEventHandlerRequest struct {
	GetRequest

	Limit *JsonUint64 `url:"limit,omitempty"`
	Start *JsonUint64 `url:"start,omitempty"`

	Address      Address        `url:"-"`
	EventHandler *MoveStructTag `url:"-"`
	FieldName    string         `url:"-"`
}

func (*GetEventsByEventHandlerRequest) PathSegments

func (request *GetEventsByEventHandlerRequest) PathSegments() ([]string, error)

type GetEventsByEventHandlerResponse

type GetEventsByEventHandlerResponse []*RawEvent

type GetLedgerInfoResponse

type GetLedgerInfoResponse struct {
	*LedgerInfo `json:",inline"`
}

type GetRequest

type GetRequest struct{}

GetRequest embed this struct for a get request where only path segments are necessary.

func (*GetRequest) Body

func (*GetRequest) Body() ([]byte, error)

func (*GetRequest) HttpMethod

func (*GetRequest) HttpMethod() string

type GetTransactionByHashRequest

type GetTransactionByHashRequest struct {
	GetRequest
	Hash string `url:"-"`
}

func (*GetTransactionByHashRequest) PathSegments

func (r *GetTransactionByHashRequest) PathSegments() ([]string, error)

type GetTransactionByHashResponse

type GetTransactionByHashResponse struct {
	*TransactionWithInfo `json:",inline"`
}

type GetTransactionByVersionRequest

type GetTransactionByVersionRequest struct {
	GetRequest
	Version JsonUint64 `url:"-"`
}

func (*GetTransactionByVersionRequest) PathSegments

func (r *GetTransactionByVersionRequest) PathSegments() ([]string, error)

type GetTransactionByVersionResponse

type GetTransactionByVersionResponse struct {
	*TransactionWithInfo `json:",inline"`
}

type JsonUint64

type JsonUint64 uint64

JsonUint64 is an uint64, but serialized into a string, and can be deserialized from either a string or a number from json. This is because aptos fullnode uses string for uint64, whereas golang's json encoding only support number.

func (JsonUint64) MarshalBCS

func (i JsonUint64) MarshalBCS() ([]byte, error)

func (JsonUint64) MarshalJSON

func (i JsonUint64) MarshalJSON() ([]byte, error)

func (JsonUint64) ToBCS

func (i JsonUint64) ToBCS() []byte

func (*JsonUint64) UnmarshalJSON

func (i *JsonUint64) UnmarshalJSON(data []byte) error

type LedgerInfo

type LedgerInfo struct {
	ChainId             uint8      `json:"chain_id"`
	Epoch               JsonUint64 `json:"epoch"`
	LedgerVersion       JsonUint64 `json:"ledger_version"`
	OldestLedgerVersion JsonUint64 `json:"oldest_ledger_version"`
	LedgerTimestamp     JsonUint64 `json:"ledger_timestamp"`
	NodeRole            string     `json:"node_role"`
	OldestBlockHeight   JsonUint64 `json:"oldest_block_height"`
	BlockHeight         JsonUint64 `json:"block_height"`
	GitHash             string     `json:"git_hash"`
}

LedgerInfo contains basic information about the chain.

type LocalAccount

type LocalAccount struct {
	PrivateKey ed25519.PrivateKey
	PublicKey  ed25519.PublicKey
	Address    Address
}

LocalAccount contains the private key, public key, and the address.

func NewLocalAccountFromMnemonic

func NewLocalAccountFromMnemonic(mnemonic string, passphrase string) (*LocalAccount, error)

NewLocalAccountFromMnemonic creates a private key from the mnemonic codes.

see relevant section on aptos.dev. Also see implementation in typescript

This is based on bip32 and bip39 from the bitcoin project.

func NewLocalAccountFromPrivateKey

func NewLocalAccountFromPrivateKey(privateKey *ed25519.PrivateKey) (*LocalAccount, error)

NewLocalAccountFromPrivateKey creates a local account based on the private key. the authentication key will be the one calculated from public key.

func NewLocalAccountWithMnemonic

func NewLocalAccountWithMnemonic() (*LocalAccount, string, error)

NewLocalAccountWithMnemonic creates a new mnemonic, then generate a local account with the associated private key.

func NewLocalAccountWithRandomKey

func NewLocalAccountWithRandomKey() (*LocalAccount, error)

NewLocalAccountWithRandomKey creates a new account with random key.

func (*LocalAccount) IsOriginalAuthenticationKey

func (account *LocalAccount) IsOriginalAuthenticationKey() bool

IsOriginalAuthenticationKey checks if the authentication key is the authentication key generated from the single public key.

func (*LocalAccount) Sign

func (account *LocalAccount) Sign(tx *Transaction) (*SingleSignature, error)

func (*LocalAccount) SignForSimulation

func (account *LocalAccount) SignForSimulation(tx *Transaction) (*SingleSignature, error)

func (*LocalAccount) SignRawData

func (account *LocalAccount) SignRawData(message []byte) (*SingleSignature, error)

SignRawData

func (*LocalAccount) SignRawDataForSimulation

func (account *LocalAccount) SignRawDataForSimulation(message []byte) (*SingleSignature, error)

SignRawDataForSimulation

func (*LocalAccount) SignerAddress

func (account *LocalAccount) SignerAddress() Address

type MoveBytecode

type MoveBytecode []byte

func (MoveBytecode) MarshalJSON

func (b MoveBytecode) MarshalJSON() ([]byte, error)

func (MoveBytecode) String

func (b MoveBytecode) String() string

func (*MoveBytecode) UnmarshalJSON

func (b *MoveBytecode) UnmarshalJSON(date []byte) error

type MoveFunctionTag

type MoveFunctionTag struct {
	MoveModuleTag

	Name string
}

MoveFunctionTag identifies a function on chain. Note the function's generic parameters or parameters are not part of the tag.

func MustNewMoveFunctionTag

func MustNewMoveFunctionTag(address Address, module, name string) *MoveFunctionTag

func NewMoveFunctionTag

func NewMoveFunctionTag(address Address, module, name string) (*MoveFunctionTag, error)

func ParseModuleFunctionTag

func ParseModuleFunctionTag(str string) (*MoveFunctionTag, error)

func (MoveFunctionTag) MarshalJSON

func (f MoveFunctionTag) MarshalJSON() ([]byte, error)

func (MoveFunctionTag) String

func (f MoveFunctionTag) String() string

func (*MoveFunctionTag) UnmarshalJSON

func (f *MoveFunctionTag) UnmarshalJSON(data []byte) error

type MoveModuleABI

type MoveModuleABI struct {
	Address Address `json:"address"`
	Name    string  `json:"name"`

	Friends []string `json:"friends"`

	Functions []*MoveModuleABI_Function `json:"exposed_functions"`
	Structs   []*MoveModuleABI_Struct   `json:"structs"`
}

MoveModuleABI is the smart contract module abi.

type MoveModuleABI_Function

type MoveModuleABI_Function struct {
	Name              string            `json:"name"`
	Visibility        string            `json:"visibility"`
	IsEntry           bool              `json:"is_entry"`
	GenericTypeParams []json.RawMessage `json:"generic_type_params"`
	Params            []string          `json:"params"`
	Return            []string          `json:"return"`
}

MoveModuleABI_Function is the function definition contained in a MoveModuleABI

type MoveModuleABI_Struct

type MoveModuleABI_Struct struct {
	Name              string            `json:"name"`
	IsNative          bool              `json:"is_native"`
	Abilities         []string          `json:"abilities"`
	GenericTypeParams []json.RawMessage `json:"generic_type_params"`
	Fields            []json.RawMessage `json:"fields"`
}

MoveModuleABI_Struct is the struct definition contained in a MoveModuleABI

type MoveModuleTag

type MoveModuleTag struct {
	// Address of module
	Address Address
	// Module name
	Module string
}

MoveModuleTag identifies a move module on the chain

func MustNewMoveModuleTag

func MustNewMoveModuleTag(address Address, module string) *MoveModuleTag

func NewMoveModuleTag

func NewMoveModuleTag(address Address, module string) (*MoveModuleTag, error)

NewMoveModuleTag creates a new module module tag

func ParseMoveModuleTag

func ParseMoveModuleTag(str string) (*MoveModuleTag, error)

func (MoveModuleTag) MarshalJSON

func (m MoveModuleTag) MarshalJSON() ([]byte, error)

func (*MoveModuleTag) Set

func (m *MoveModuleTag) Set(str string) error

func (MoveModuleTag) String

func (m MoveModuleTag) String() string

func (MoveModuleTag) Type

func (m MoveModuleTag) Type() string

func (*MoveModuleTag) UnmarshalJSON

func (m *MoveModuleTag) UnmarshalJSON(data []byte) error

type MoveStructTag

type MoveStructTag struct {
	MoveModuleTag
	// Name of the type
	Name string

	// GenericTypeParameters
	GenericTypeParameters []*MoveTypeTag
}

MoveStructTag represents the type of a move struct in the format of address::module_name::TypeName off-chain, the address is a 0x prefixed hex encoded string, but during move development there can be named addresses.

func GetAuxFakeCoinCoinType

func GetAuxFakeCoinCoinType(moduleAddress Address, fakeCoin AuxFakeCoin) (*MoveStructTag, error)

GetAuxFakeCoinCoinType returns the fake coin **coin** type - **this is a coin as defined by the aptos framework.**

func GetAuxFakeCoinType

func GetAuxFakeCoinType(moduleAddress Address, fakeCoin AuxFakeCoin) (*MoveStructTag, error)

GetAuxFakeCoinType returns the fake coin type. Note, this is actually not a type of coin as defined by aptos framework. Use GetAuxFakeCoinCoinType to get the coin type.

func GetCoinStoreType

func GetCoinStoreType(coin *MoveStructTag) *MoveStructTag

GetCoinStoreType returns the 0x1::coin::CoinStore<T>

func MustNewMoveStructTag

func MustNewMoveStructTag(address Address, module, name string, genericTypeParameters []*MoveStructTag) *MoveStructTag

func NewMoveStructTag

func NewMoveStructTag(address Address, module string, name string, genericTypeParameters []*MoveStructTag) (*MoveStructTag, error)

NewMoveStructTag

func ParseMoveStructTag

func ParseMoveStructTag(fullName string) (*MoveStructTag, error)

ParseMoveStructTag takes the full name of the move type tag

func (*MoveStructTag) MarshalJSON

func (t *MoveStructTag) MarshalJSON() ([]byte, error)

func (*MoveStructTag) Set

func (t *MoveStructTag) Set(data string) error

Set is to support cobra value

func (*MoveStructTag) String

func (t *MoveStructTag) String() string

Get the string presentation of the type, in the form of 0xaddresshex::module_name::TypeName or 0xaddresshex::module_name::TypeName<T1, T2>

func (*MoveStructTag) Type

func (t *MoveStructTag) Type() string

Type is to support cobra value

func (*MoveStructTag) UnmarshalJSON

func (t *MoveStructTag) UnmarshalJSON(data []byte) error

type MoveTypeTag

type MoveTypeTag struct {
	Bool    *struct{}      // 0
	Uint8   *struct{}      // 1
	Uint64  *struct{}      // 2
	Uint128 *struct{}      // 3
	Address *struct{}      // 4
	Signer  *struct{}      // 5
	Vector  *MoveTypeTag   // 6
	Struct  *MoveStructTag // 7
}

MoveTypeTag is an Enum indicating the type of a move value. It is a bcs.Enum aptos right now supports the following types - bool - u8 - u64 - u128 - address - signer - vector - struct

func ParseMoveTypeTag

func ParseMoveTypeTag(str string) (*MoveTypeTag, error)

func (MoveTypeTag) IsBcsEnum

func (m MoveTypeTag) IsBcsEnum()

func (MoveTypeTag) MarshalJSON

func (m MoveTypeTag) MarshalJSON() ([]byte, error)

func (MoveTypeTag) MarshalText

func (m MoveTypeTag) MarshalText() ([]byte, error)

func (MoveTypeTag) String

func (m MoveTypeTag) String() string

func (*MoveTypeTag) UnmarshalJSON

func (m *MoveTypeTag) UnmarshalJSON(data []byte) error

func (*MoveTypeTag) UnmarshalTEXT

func (m *MoveTypeTag) UnmarshalTEXT(data []byte) error

type Network

type Network string
const (
	Devnet    Network = "devnet"
	Testnet   Network = "testnet"
	Localnet  Network = "local"
	Mainnet   Network = "mainnet"
	Customnet Network = "custom"
)

func (*Network) Set

func (network *Network) Set(s string) error

func (Network) String

func (network Network) String() string

func (*Network) Type

func (network *Network) Type() string

type RawDataSigner

type RawDataSigner interface {
	SignRawData([]byte) (*SingleSignature, error)
	SignRawDataForSimulation([]byte) (*SingleSignature, error)
}

RawDataSigner signs arbitrary bytes. Prefer to use Signer

type RawEvent

type RawEvent = Event[json.RawMessage]

RawEvent stores the data as json.RawMessage/byte slice

type Signer

type Signer interface {
	// Sign transaction
	Sign(tx *Transaction) (*SingleSignature, error)
	// Sign transaction for simulation
	SignForSimulation(tx *Transaction) (*SingleSignature, error)

	// Address
	SignerAddress() Address
}

Signer is an interface to sign a transaction

type SimulateTransactionRequest

type SimulateTransactionRequest struct {
	*Transaction `json:",inline" url:"-"`
	Signature    *SingleSignature `json:"signature" url:"-"`
}

func (*SimulateTransactionRequest) Body

func (request *SimulateTransactionRequest) Body() ([]byte, error)

func (*SimulateTransactionRequest) HttpMethod

func (request *SimulateTransactionRequest) HttpMethod() string

func (*SimulateTransactionRequest) PathSegments

func (request *SimulateTransactionRequest) PathSegments() ([]string, error)

type SimulateTransactionResponse

type SimulateTransactionResponse []struct {
	*TransactionWithInfo `json:",inline"`
}

type SingleSignature

type SingleSignature struct {
	Type      string `json:"type"`
	PublicKey string `json:"public_key"`
	Signature string `json:"signature"`
}

SingleSignature

func NewSingleSignature

func NewSingleSignature(publicKey *ed25519.PublicKey, signature []byte) *SingleSignature

NewSingleSignature creates a new signature

func NewSingleSignatureForSimulation

func NewSingleSignatureForSimulation(publicKey *ed25519.PublicKey) *SingleSignature

NewSingleSignatureForSimulation creates a new signature

type SubmitTransactionRequest

type SubmitTransactionRequest struct {
	*Transaction `json:",inline" url:"-"`
	Signature    SingleSignature `json:"signature" url:"-"`
}

func (*SubmitTransactionRequest) Body

func (r *SubmitTransactionRequest) Body() ([]byte, error)

func (*SubmitTransactionRequest) HttpMethod

func (r *SubmitTransactionRequest) HttpMethod() string

func (*SubmitTransactionRequest) PathSegments

func (r *SubmitTransactionRequest) PathSegments() ([]string, error)

type SubmitTransactionResponse

type SubmitTransactionResponse struct {
	*TransactionWithInfo `json:",inline"`
}

type Table

type Table struct {
	Handle Address `json:"handle"`
}

Table is a storage class provided by aptos framework where each individual element can be accessed independently. Table is unlike the move standard vector where the whole vector needs to be loaded even if only one element is needed in the vector. However, Table is actually not stored on chain directly, and needs a separate table api to query off-chain.

type TableWithLength

type TableWithLength struct {
	Inner  *Table     `json:"inner"`
	Length JsonUint64 `json:"length"`
}

TableWithLength is a wrapper around Table, which keeps track of the length of the table.

type Transaction

type Transaction struct {
	// Sender.
	// Note if the signer is the first parameter, it doesn't need to be included in the payload parameter list.
	Sender Address `json:"sender"`
	// SequenceNumber of the transaction for the sender.
	// transactions with sequence number less than the curernt on chain sequence number for address will be rejected.
	SequenceNumber JsonUint64 `json:"sequence_number"`
	// Payload
	Payload *TransactionPayload `json:"payload"`
	// MaxGasAmount
	MaxGasAmount JsonUint64 `json:"max_gas_amount"`
	// UnitGasPrice
	GasUnitPrice JsonUint64 `json:"gas_unit_price"`
	// ExpirationTimestampSecs
	ExpirationTimestampSecs JsonUint64 `json:"expiration_timestamp_secs"`

	// chain id - this is not serialized into json for payload
	ChainId uint8 `json:"-"`
}

Transaction doesn't have signatures attached to them.

func ApplyTransactionOptions

func ApplyTransactionOptions(tx *Transaction, options ...TransactionOption) *Transaction

ApplyTransactionOptions apply multiple options in order

func (*Transaction) GetHash

func (tx *Transaction) GetHash() []byte

GetHash get the hash of the transaction that can be used to look up the transaction on chain.

Hash of the transaction is sha3-256 of ("RawTransaction" | bcs encoded transaction). BCS encoded transaction can be obtained by Transaction.ToBCS method.

See here.

func (*Transaction) ToBCS

func (tx *Transaction) ToBCS() []byte

ToBCS get the signing bytes of the transaction. This is calling EncodeTransaction under the hood.

type TransactionInfo

type TransactionInfo struct {
	// Hash of the transaction.
	Hash string `json:"hash"`

	StateChangeHash     string `json:"state_change_hash"`
	EventRootHash       string `json:"event_root_hash"`
	StateCheckPointHash string `json:"state_checkpoint_hash"`

	GasUsed JsonUint64 `json:"gas_used"`

	// If the transaction is successful or not.
	Success bool `json:"success"`

	// VmStatus is useful for debug if the transaction failed.
	VmStatus            string `json:"vm_status"`
	AccumulatorRootHash string `json:"accumulator_root_hash"`

	Changes []json.RawMessage `json:"changes"`
	Events  []*RawEvent       `json:"events"`

	Timestamp JsonUint64 `json:"timestamp"`
}

TransactionInfo contains the information about the transaction that has been submitted to the blockchain.

type TransactionOption

type TransactionOption interface {
	SetTransactionOption(*Transaction) *Transaction
}

TransactionOption for transaction

type TransactionOption_ExpireAfter

type TransactionOption_ExpireAfter time.Duration

TransactionOption_ExpireAfter specifies a duration after which the transaction will expire. The expiry will be computed when SetTransactionOption is called, instead of right now.

func (TransactionOption_ExpireAfter) SetTransactionOption

func (duration TransactionOption_ExpireAfter) SetTransactionOption(tx *Transaction) *Transaction

type TransactionOption_ExpireAt

type TransactionOption_ExpireAt time.Time

TransactionOption_ExpireAt specifies a time point that the transaction will expire at.

func (TransactionOption_ExpireAt) SetTransactionOption

func (expiry TransactionOption_ExpireAt) SetTransactionOption(tx *Transaction) *Transaction

type TransactionOption_GasUnitPrice

type TransactionOption_GasUnitPrice uint64

TransactionOption_GasUnitPrice sets the gas unit price of the transaction

func (TransactionOption_GasUnitPrice) SetTransactionOption

func (gasUnitPrice TransactionOption_GasUnitPrice) SetTransactionOption(tx *Transaction) *Transaction

type TransactionOption_MaxGasAmount

type TransactionOption_MaxGasAmount uint64

Max Gas Amount Option

func (TransactionOption_MaxGasAmount) SetTransactionOption

func (maxGasAmount TransactionOption_MaxGasAmount) SetTransactionOption(tx *Transaction) *Transaction

type TransactionOption_Sender

type TransactionOption_Sender Address

TransactionOption_Sender sets the sender of the transaction.

func (TransactionOption_Sender) SetTransactionOption

func (sender TransactionOption_Sender) SetTransactionOption(tx *Transaction) *Transaction

type TransactionOption_SequenceNumber

type TransactionOption_SequenceNumber uint64

TransactionOption_SequenceNumber sets the sequence number of transaction.

func (TransactionOption_SequenceNumber) SetTransactionOption

func (seqnum TransactionOption_SequenceNumber) SetTransactionOption(tx *Transaction) *Transaction

type TransactionOptions

TransactionOptions contains all possible transactions

func (*TransactionOptions) FillIfDefault

func (options *TransactionOptions) FillIfDefault(tx *Transaction)

FillIfDefault only overwrite the transaction option if it is set to the default value.

func (*TransactionOptions) SetOption

func (options *TransactionOptions) SetOption(opt TransactionOption)

SetOption sets the specific option on the options. If there is already an option for that specifc option, it will be overwritten.

type TransactionPayload

type TransactionPayload struct {
	ScriptPayload       *json.RawMessage `bcs:"-"`
	ModuleBundlePayload *json.RawMessage `bcs:"-"`
	*EntryFunctionPayload
}

TransactionPayload is payload field of a transaction. Although there are three types, script, module bundle, and entry function, only entry function is supported here.

func NewEntryFunctionPayload

func NewEntryFunctionPayload(
	functionName *MoveFunctionTag,
	typeArguments []*MoveStructTag,
	arguments []*EntryFunctionArg,
) *TransactionPayload

NewEntryFunctionPayload

func (TransactionPayload) IsBcsEnum

func (p TransactionPayload) IsBcsEnum()

func (TransactionPayload) MarshalJSON

func (p TransactionPayload) MarshalJSON() ([]byte, error)

func (*TransactionPayload) UnmarshalJSON

func (p *TransactionPayload) UnmarshalJSON(data []byte) error

type TransactionWaitOption

type TransactionWaitOption struct {
	Scale       float64
	InitialWait time.Duration
	// contains filtered or unexported fields
}

func NewTransactionWaitOption

func NewTransactionWaitOption(scale float64, initialWait time.Duration) TransactionWaitOption

type TransactionWithInfo

type TransactionWithInfo struct {
	*Transaction     `json:",inline"`
	Type             string `json:"type"`
	*TransactionInfo `json:",inline"`
}

TransactionWithInfo is contains the transaction itself and the results of the transaciton execution.

type TypedAccountResource

type TypedAccountResource[T any] struct {
	AccountResource
	ParsedData *T
}

TypedAccountResource

Directories

Path Synopsis
cmd
contains commands that are supported by the aptos-aux cli.
contains commands that are supported by the aptos-aux cli.
aptos-aux
aptos-aux is a cli for aptos and aux.exchange
aptos-aux is a cli for aptos and aux.exchange
Known coins, pools, markets included with the binary.
Known coins, pools, markets included with the binary.

Jump to

Keyboard shortcuts

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