Documentation
¶
Overview ¶
Package dexvm implements a high-performance decentralized exchange VM for the Lux blockchain network.
The DEX VM provides:
- Central Limit Order Book (CLOB) trading with nanosecond price updates
- Automated Market Maker (AMM) liquidity pools
- Cross-chain atomic swaps via Warp messaging
- 200ms block times for high-frequency trading
- LX-First arbitrage strategy support
Architecture:
- Uses Quasar consensus (BLS + Corona + ML-DSA) for finality
- Integrates with Warp 1.5 for cross-chain messaging
- Supports both spot and perpetual trading
- Designed for institutional-grade performance
Index ¶
- Constants
- Variables
- type Block
- func (b *Block) Accept(ctx context.Context) error
- func (b *Block) Bytes() []byte
- func (b *Block) Height() uint64
- func (b *Block) ID() ids.ID
- func (b *Block) Parent() ids.ID
- func (b *Block) ParentID() ids.ID
- func (b *Block) Reject(ctx context.Context) error
- func (b *Block) Status() uint8
- func (b *Block) Timestamp() time.Time
- func (b *Block) Verify(ctx context.Context) error
- type BlockResult
- type ChainVM
- func (cvm *ChainVM) BuildBlock(ctx context.Context) (chain.Block, error)
- func (cvm *ChainVM) BuildVertex(ctx context.Context) (vertex.Vertex, error)
- func (cvm *ChainVM) Connected(ctx context.Context, nodeID ids.NodeID, v *chain.VersionInfo) error
- func (cvm *ChainVM) CreateHandlers(ctx context.Context) (map[string]http.Handler, error)
- func (cvm *ChainVM) Disconnected(ctx context.Context, nodeID ids.NodeID) error
- func (cvm *ChainVM) FeePolicy() fee.Policy
- func (cvm *ChainVM) GetBlock(ctx context.Context, blkID ids.ID) (chain.Block, error)
- func (cvm *ChainVM) GetBlockIDAtHeight(ctx context.Context, height uint64) (ids.ID, error)
- func (cvm *ChainVM) GetInnerVM() *VM
- func (cvm *ChainVM) Gossip(ctx context.Context, nodeID ids.NodeID, msg []byte) error
- func (cvm *ChainVM) HealthCheck(ctx context.Context) (chain.HealthResult, error)
- func (cvm *ChainVM) Initialize(ctx context.Context, vmInit vm.Init) error
- func (cvm *ChainVM) LastAccepted(ctx context.Context) (ids.ID, error)
- func (cvm *ChainVM) NewHTTPHandler(ctx context.Context) (http.Handler, error)
- func (cvm *ChainVM) ParseBlock(ctx context.Context, data []byte) (chain.Block, error)
- func (cvm *ChainVM) ParseVertex(ctx context.Context, b []byte) (vertex.Vertex, error)
- func (cvm *ChainVM) Request(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, ...) error
- func (cvm *ChainVM) Response(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error
- func (cvm *ChainVM) SetPreference(ctx context.Context, blkID ids.ID) error
- func (cvm *ChainVM) SetState(ctx context.Context, state uint32) error
- func (cvm *ChainVM) Shutdown(ctx context.Context) error
- func (cvm *ChainVM) SubmitTx(tx []byte) error
- func (cvm *ChainVM) Version(ctx context.Context) (string, error)
- func (cvm *ChainVM) WaitForEvent(ctx context.Context) (vm.Message, error)
- type DexVertex
- func (v *DexVertex) Accept(ctx context.Context) error
- func (v *DexVertex) Bytes() []byte
- func (v *DexVertex) Conflicts(other *DexVertex) bool
- func (v *DexVertex) ConflictsVertex(other vertex.Vertex) bool
- func (v *DexVertex) Epoch() uint32
- func (v *DexVertex) Height() uint64
- func (v *DexVertex) ID() ids.ID
- func (v *DexVertex) Parents() []ids.ID
- func (v *DexVertex) Reject(ctx context.Context) error
- func (v *DexVertex) Status() choices.Status
- func (v *DexVertex) Timestamp() time.Time
- func (v *DexVertex) Txs() []ids.ID
- func (v *DexVertex) Verify(ctx context.Context) error
- type Factory
- type Fill
- type Genesis
- type OrderKey
- type RelayClient
- type Status
- type VM
- func (vm *VM) BuildBlockResult(ctx context.Context, blockHeight uint64, blockTime time.Time, ...) (*BlockResult, error)
- func (vm *VM) Connected(ctx context.Context, nodeID ids.NodeID, v *version.Application) error
- func (vm *VM) CreateHandlers(ctx context.Context) (map[string]http.Handler, error)
- func (vm *VM) CrossChainRequest(ctx context.Context, sourceChainID ids.ID, requestID uint32, ...) error
- func (vm *VM) CrossChainRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32, ...) error
- func (vm *VM) CrossChainResponse(ctx context.Context, chainID ids.ID, requestID uint32, response []byte) error
- func (vm *VM) Disconnected(ctx context.Context, nodeID ids.NodeID) error
- func (vm *VM) GetBlockHeight() uint64
- func (vm *VM) GetLastBlockTime() time.Time
- func (vm *VM) Gossip(ctx context.Context, nodeID ids.NodeID, msg []byte) error
- func (vm *VM) HealthCheck(ctx context.Context) (chain.HealthResult, error)
- func (vm *VM) Initialize(ctx context.Context, vmInit vmcore.Init) error
- func (vm *VM) IsBootstrapped() bool
- func (vm *VM) ProcessBlock(ctx context.Context, blockHeight uint64, blockTime time.Time, ...) (*BlockResult, error)
- func (vm *VM) Relay() api.Relayer
- func (vm *VM) Request(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, ...) error
- func (vm *VM) RequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, ...) error
- func (vm *VM) Response(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error
- func (vm *VM) SetState(ctx context.Context, stateNum uint32) error
- func (vm *VM) Shutdown(ctx context.Context) error
- func (vm *VM) Version(ctx context.Context) (string, error)
Constants ¶
const ( ZAPMethodEnsureMarket = "clob_ensure_market" ZAPMethodPlace = "clob_place" ZAPMethodCancel = "clob_cancel" ZAPMethodSubmit = "clob_submit" // Custody methods — the funds-in / funds-out rail between the atomic // shared-memory leg and the D-Chain balance ledger (where the money lives in // the order book). FROZEN, byte-identical with the d-chain gateway // (github.com/luxfi/dex/pkg/zapwire Method{Deposit,Withdraw,OpenMarket}). // - clob_deposit : credit an account's available D-Chain balance from value // this proxy atomically IMPORTED (so the book can draw from it). // - clob_withdraw: debit an account's realized D-Chain balance; the returned // realized amount is what this proxy atomically EXPORTS back out. // - clob_open_market: bind a market's (base,quote) asset handles. ZAPMethodDeposit = "clob_deposit" ZAPMethodWithdraw = "clob_withdraw" ZAPMethodOpenMarket = "clob_open_market" )
ZAP CLOB method names. These are FROZEN and MUST stay byte-identical with the d-chain gateway (github.com/luxfi/dex/pkg/api/zap_server.go) and the EVM precompile (github.com/luxfi/precompile/dex/engine_zap.go). The proxy never interprets order semantics — it forwards these frames verbatim to the single source-of-truth matcher.
const ( // DepositReqSize / WithdrawReqSize: user[16] + asset[8] + amount[8]. DepositReqSize = 16 + 8 + 8 // 32 WithdrawReqSize = 16 + 8 + 8 // 32 // BalanceRespSize: status[1] + realizedAmount[8]. BalanceRespSize = 1 + 8 )
Custody wire sizes (FROZEN, == github.com/luxfi/dex/pkg/zapwire). The proxy re-defines them since it cannot import the cgo-tagged d-chain package; a parity test pins byte-equality.
const FillWireSize = 17
FillWireSize is one fill in a clob_submit response: price[8]+size[8]+side[1]. FROZEN — must equal dex/pkg/api.FillWireSize and the precompile's fillWireSize.
Variables ¶
var ErrRelayNotConfigured = errors.New("dexvm: d-chain ZAP endpoint not configured")
ErrRelayNotConfigured is returned when an order relay is attempted but no d-chain ZAP endpoint is configured. The proxy is inert on the relay leg until the venue operator points dex-zap-endpoint at a d-chain gateway.
var ( // VMID is the unique identifier for the DEX VM VMID = ids.ID{'d', 'e', 'x', 'v', 'm'} )
Functions ¶
This section is empty.
Types ¶
type Block ¶
type Block struct {
// contains filtered or unexported fields
}
Block represents a DEX VM block that wraps the functional ProcessBlock results. It implements the chain.Block interface required for the ChainVM.
func (*Block) Accept ¶
Accept marks the block as accepted and commits the proxy's state batch ATOMICALLY with the cross-chain shared-memory operations accumulated during Verify (the settlement leg) — the single commit point.
func (*Block) Bytes ¶
Bytes returns the serialized block.
WIRE FORMAT (NETWORK-UPGRADE-GATED, LOCKSTEP — RED finding #9). The block now carries the proposer's confirmed d-chain fills so every validator settles from bytes instead of relaying per-validator. The layout is:
height[8] | timestamp[8] | parentID[32] | txCount[4] | txCount × ( txLen[4] | txBytes ) | carried-fills section (carried_fills.go encodeCarriedFills): entryCount[4] | entryCount × ( txIndex[4] | fillCount[4] | fillCount×17 ) | sigLen[4] | sig[sigLen] // reserved fill-attestation, empty today
The txCount prefix (NEW) makes the txs self-delimiting so the carried-fills section can follow unambiguously; the prior format ran txs to end-of-buffer. This is a consensus-breaking change activated in lockstep across the validator set behind a network upgrade.
func (*Block) Verify ¶
Verify verifies the block is valid by processing it deterministically, then attaches the block-CARRIED fills (RED #9) so accept settles from bytes rather than relaying. Verify performs NO d-chain I/O on any node — the proposer already relayed once at build (BuildBlockResult) and the fills travel in the block bytes.
type BlockResult ¶
type BlockResult struct {
// BlockHeight is the height of the processed block.
BlockHeight uint64
// Timestamp is when this block was processed.
Timestamp time.Time
// StateRoot is the merkle root of the proxy's state after this block.
StateRoot ids.ID
// contains filtered or unexported fields
}
BlockResult is the deterministic result of processing a block on the proxy. A STATELESS ATOMIC ZAP PROXY produces NO MatchedTrades / FundingPayments / Liquidations — matching lives ONLY on the d-chain. The proxy's per-block output is the cross-chain atomic operations it accumulated (committed at accept) and the state root over its (tiny) replay/consumption state.
type ChainVM ¶
type ChainVM struct {
// contains filtered or unexported fields
}
ChainVM wraps the functional DEX VM to implement the chain.ChainVM interface required for running as an L2 chain plugin.
func NewChainVM ¶
NewChainVM creates a new ChainVM that wraps a functional DEX VM
func (*ChainVM) BuildBlock ¶
BuildBlock implements the chain.ChainVM interface. It builds a new block from pending transactions AND, as the block PROPOSER, performs the network-wide-ONCE d-chain relay (VM.BuildBlockResult -> obtainFills), carrying the confirmed fills in the block bytes so every validator settles from them without relaying (RED finding #9). This is the ONLY chain entry point that triggers a d-chain relay; Verify and Accept never do.
The proposer chooses the block time here (wall clock, clamped non-decreasing) and carries it in the bytes — the consensus-agreement point. The block id is the hash of the serialized bytes (header + txs + carried fills), so the id commits to the carried fills (a peer cannot swap fills while keeping the same id).
func (*ChainVM) BuildVertex ¶
BuildVertex drains pending txs and batches non-conflicting ones.
func (*ChainVM) CreateHandlers ¶
CreateHandlers implements the interface expected by chain manager for HTTP registration
func (*ChainVM) Disconnected ¶
Disconnected implements the VM interface
func (*ChainVM) FeePolicy ¶ added in v1.2.6
FeePolicy exposes the chain's declared fee policy for diagnostics and the boot-time Validate gate.
func (*ChainVM) GetBlock ¶
GetBlock implements the chain.ChainVM interface. It returns a block by its ID.
func (*ChainVM) GetBlockIDAtHeight ¶
GetBlockIDAtHeight returns the block ID at the given height
func (*ChainVM) GetInnerVM ¶
GetInnerVM returns the inner proxy VM for direct access.
func (*ChainVM) HealthCheck ¶
HealthCheck implements the VM interface
func (*ChainVM) Initialize ¶
Initialize implements the VM interface
func (*ChainVM) LastAccepted ¶
LastAccepted implements the chain.ChainVM interface. It returns the ID of the last accepted chain.
func (*ChainVM) NewHTTPHandler ¶
NewHTTPHandler implements the chain.ChainVM interface
func (*ChainVM) ParseBlock ¶
ParseBlock implements the chain.ChainVM interface. It parses a block from bytes.
func (*ChainVM) ParseVertex ¶
ParseVertex deserializes a vertex from bytes.
func (*ChainVM) Request ¶
func (cvm *ChainVM) Request(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error
Request implements the VM interface
func (*ChainVM) Response ¶
func (cvm *ChainVM) Response(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error
Response implements the VM interface
func (*ChainVM) SetPreference ¶
SetPreference implements the chain.ChainVM interface. It sets the preferred block for building new blocks.
func (*ChainVM) SubmitTx ¶
SubmitTx adds a transaction to the pending pool. This is the canonical user-mempool entry on D-Chain — every public submission funnels through here. The FeePolicy gate refuses zero-fee tx before the bytes touch pendingTxs.
Internal callers (consensus engine -> VM, replay) feed pendingTxs directly via BuildBlock; they do NOT route through SubmitTx, so the fee gate stays out of the consensus-internal path.
type DexVertex ¶
type DexVertex struct {
// contains filtered or unexported fields
}
DexVertex represents a DAG vertex in the DEX proxy chain.
func (*DexVertex) Conflicts ¶
Conflicts returns true if this vertex and other share any (symbol, side, orderID) tuple.
func (*DexVertex) ConflictsVertex ¶
ConflictsVertex performs the same check against the vertex.Vertex interface.
type Factory ¶
Factory creates new DEX VM instances.
func (*Factory) New ¶
New implements vms.Factory interface. It creates a new DEX ChainVM instance with the factory's configuration. The ChainVM wrapper implements block.ChainVM for integration with the chains manager. Allocates a per-VM GPU session at PriorityHigh because the DEX hot path is latency-critical (1ms block times).
type Fill ¶ added in v1.3.8
Fill is one execution returned by the d-chain matcher: price + size + the taker side this submit took with. The proxy derives the settlement delta ONLY from these server-returned fills — never from a client-supplied amount.
func DecodeFills ¶ added in v1.3.8
DecodeFills parses a clob_submit response: count[4] then count×(price[8] + size[8] + side[1]). Every field is range-checked so a backend that lies (or a MITM on the socket) cannot inject a structurally invalid fill into settlement: price/size must be finite and strictly positive, and side MUST be a valid CLOB side (0=BUY, 1=SELL). A side byte outside {0,1} is malformed wire exactly like a NaN price — rejecting it here keeps a Fill value always well-formed, so no downstream consumer ever sees an impossible side. (Cross-fill side CONSISTENCY — "a single submit takes exactly one side" — is a settlement-policy invariant enforced in settleFromFills, not a per-fill wire property; the two checks own different invariants and do not overlap.)
type Genesis ¶
type Genesis struct {
// DexZapEndpoint optionally overrides the d-chain ZAP gateway address.
DexZapEndpoint string `json:"dexZapEndpoint,omitempty"`
// TrustedChains are chain IDs trusted for the Warp attestation channel.
TrustedChains []string `json:"trustedChains,omitempty"`
}
Genesis is the proxy's genesis configuration: trusted chains for the attestation channel and the d-chain ZAP endpoint. There are NO trading pairs / pools / perp markets — the proxy seeds no DEX state.
type OrderKey ¶
type OrderKey struct {
// Market is the 32-byte poolId (hex) for order relays, or "utxo" for the
// atomic-import double-spend key.
Market string
Side uint8
OrderID ids.ID
}
OrderKey is the conflict key for the proxy: (poolId, side, orderID) for relay envelopes, or the consumed source-UTXO id for imports. Two vertices conflict iff their OrderKey sets intersect — relays/cancels touching the same resting order, or imports claiming the same exported UTXO. The proxy does NOT match, so this is a transport-level conflict key, not a matching one.
type RelayClient ¶ added in v1.3.8
type RelayClient struct {
// contains filtered or unexported fields
}
RelayClient forwards byte-identical clob_* frames to the d-chain's ZAP gateway. It is PURE TRANSPORT to the single source-of-truth matcher: it holds NO order/pool/book state, performs NO matching, and never mints. This is the ORDER RELAY leg (NOT atomic, NOT consensus) of the two-primitive proxy; value settlement is the separate atomic SharedMemory import/export leg (atomic.go).
func NewRelayClient ¶ added in v1.3.8
func NewRelayClient(addr string, timeout time.Duration) *RelayClient
NewRelayClient creates a relay targeting the d-chain ZAP endpoint (e.g. "127.0.0.1:9100"). An empty addr yields a relay that returns ErrRelayNotConfigured on every call — the inert relay leg.
func (*RelayClient) Close ¶ added in v1.3.8
func (r *RelayClient) Close() error
Close closes the cached connection, if any.
func (*RelayClient) Configured ¶ added in v1.3.8
func (r *RelayClient) Configured() bool
Configured reports whether a d-chain endpoint is set.
type VM ¶
VM implements the DEX proxy Virtual Machine: a STATELESS ATOMIC ZAP PROXY on the Lux consensus network. It holds ZERO canonical DEX state. It does exactly two orthogonal things, each its own primitive (do NOT conflate them):
ORDER RELAY (proxy -> d-chain): forwards byte-identical clob_* frames over ZAP (RelayClient) to the single source-of-truth matcher. NOT atomic, NOT consensus — pure transport.
VALUE SETTLEMENT (C-Chain <-> proxy, atomic): moves value in/out via atomic.SharedMemory import/export (atomic.go), exactly as X/P-chains do. The ONLY primitive in the proxy that moves value across chains.
Warp is retained ONLY as the optional fill-attestation channel (off the hot path) — it is NOT the settlement primitive.
DESIGN: No background goroutines. All operations are block-driven and deterministic, so every node produces identical state from identical inputs.
func NewVMForTest ¶
NewVMForTest creates a new VM instance for testing purposes.
func (*VM) BuildBlockResult ¶ added in v1.3.8
func (vm *VM) BuildBlockResult(ctx context.Context, blockHeight uint64, blockTime time.Time, blockTxs [][]byte) (*BlockResult, error)
BuildBlockResult is the PROPOSER's full build of a block: it plans the block (the deterministic ProcessBlock pass) and then performs the network-wide-ONCE d-chain relay (obtainFills), attaching the confirmed fills to the result. The caller (BuildBlock / BuildVertex) serializes result.carriedFills + result.fillSig into the block/vertex bytes so every validator settles from them — the matcher is hit exactly once for the whole network (RED finding #9).
This is the ONLY method that triggers a d-chain relay. Verify (ProcessBlock) and Accept (acceptBlock) never relay. A non-proposer obtains the same fills by parsing the block bytes, not by calling this.
The relay is best-effort per order: obtainFills carries a zero-fill entry for any order whose relay failed, so the build always yields a valid block (the escrow is refunded at settle). It returns an error only on a fault that should abort the proposal entirely (e.g. the planning pass failed).
func (*VM) CreateHandlers ¶
CreateHandlers implements consensuscore.VM. The proxy's API is a thin pass-through to the relay client (no local book to query).
func (*VM) CrossChainRequest ¶
func (vm *VM) CrossChainRequest(ctx context.Context, sourceChainID ids.ID, requestID uint32, deadline time.Time, request []byte) error
CrossChainRequest implements consensuscore.VM. The proxy retains ONLY the Warp attestation-ingress dispatch — it does NOT move value over Warp (the atomic SharedMemory import/export leg does that). Cross-chain swap/transfer value handlers were removed; an incoming Warp message is a fill attestation receipt, off the settlement hot path.
func (*VM) CrossChainRequestFailed ¶
func (vm *VM) CrossChainRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32, appErr *consensuscore.AppError) error
CrossChainRequestFailed implements consensuscore.VM.
func (*VM) CrossChainResponse ¶
func (vm *VM) CrossChainResponse(ctx context.Context, chainID ids.ID, requestID uint32, response []byte) error
CrossChainResponse implements consensuscore.VM.
func (*VM) Disconnected ¶
Disconnected implements consensuscore.VM.
func (*VM) GetBlockHeight ¶
GetBlockHeight returns the current block height.
func (*VM) GetLastBlockTime ¶
GetLastBlockTime returns the timestamp of the last processed block.
func (*VM) Gossip ¶
Gossip implements consensuscore.VM. The proxy gossips nothing matcher-related (it has no book); it only acknowledges peer messages.
func (*VM) HealthCheck ¶
HealthCheck implements consensuscore.VM.
func (*VM) Initialize ¶
Initialize implements consensuscore.VM. It sets up the proxy with the provided context, database, and genesis/config data.
func (*VM) IsBootstrapped ¶
IsBootstrapped reports whether the proxy is fully bootstrapped.
func (*VM) ProcessBlock ¶
func (vm *VM) ProcessBlock(ctx context.Context, blockHeight uint64, blockTime time.Time, blockTxs [][]byte) (*BlockResult, error)
ProcessBlock is the proxy's PURE DETERMINISTIC VERIFY: it validates the block's transactions and builds a plan, performing ZERO d-chain I/O. Concretely it applies the atomic IMPORT legs (consuming UTXOs into the versiondb in-memory layer, accumulating RemoveRequests) and the EXPORT legs, and it records every order RELAY as a plannedRelay. Matching is NEVER done here — it lives only on the d-chain.
Why no relay here (RED finding #9): a Verified block is later decided Accept OR Reject, and Reject must undo everything Verify did with a plain db.Abort(). But more fundamentally, Verify runs on EVERY validator: a clob_submit issued here would be relayed per-validator against a MOVING d-chain book, so each validator would observe independently-timed fills => divergent settlement => divergent StateRoot => the network forks. The relay is therefore performed exactly ONCE, by the block PROPOSER at build (VM.obtainFills), and the confirmed fills are CARRIED in the block bytes; every validator settles purely from those carried fills (settleCarried at accept). Block output is thus a pure function of (height, carried time, tx bytes, carried fills).
CONSERVATION ORDERING within a block: each tx is processed in order, and an import always precedes the relay/export that depends on its locked value. The plan preserves that order (settleCarried settles in capture order at accept).
func (*VM) Relay ¶ added in v1.3.8
Relay exposes the relay client to the API pass-through layer as the neutral api.Relayer surface (the proxy's only DEX capability is transport).
func (*VM) Request ¶
func (vm *VM) Request(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error
Request implements consensuscore.VM. The proxy serves no orderbook/pool sync (it holds no such state); unknown requests are ignored.
func (*VM) RequestFailed ¶
func (vm *VM) RequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *consensuscore.AppError) error
RequestFailed implements consensuscore.VM.
func (*VM) Response ¶
func (vm *VM) Response(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error
Response implements consensuscore.VM.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package api provides the RPC API for the DEX VM proxy.
|
Package api provides the RPC API for the DEX VM proxy. |
|
Package block implements block structure for the DEX VM.
|
Package block implements block structure for the DEX VM. |
|
cmd
|
|
|
plugin
command
|
|
|
Package config defines configuration types for the DEX VM — a STATELESS ATOMIC ZAP PROXY.
|
Package config defines configuration types for the DEX VM — a STATELESS ATOMIC ZAP PROXY. |
|
Package network provides peer-to-peer networking and Warp messaging for the DEX VM.
|
Package network provides peer-to-peer networking and Warp messaging for the DEX VM. |
|
Package state manages persistent state for the DEX VM proxy.
|
Package state manages persistent state for the DEX VM proxy. |
|
Package txs defines transaction types for the DEX VM — a STATELESS ATOMIC ZAP PROXY.
|
Package txs defines transaction types for the DEX VM — a STATELESS ATOMIC ZAP PROXY. |