VXL Common Syntax Patterns

Vektor Execution Language (VXL) is an extremely powerful language to interact with DeFi, and very versatile. But great power need not mean great complexity, and we've put a lot of thought into making VXL easy to get to grips with, especially if you've used spreadsheet formulas before. Despite having well over 100 functions, the vast majority use common syntax patterns that should allow the user to quickly learn and even intuit the various function capabilities. Some of these patterns and ergonomics are outlined here - learn these and you'll be a VXL pro in no time!

Anatomy of a VXL function

VXL functions comprise of the function name and arguments, as you can see in the example below:

The arguments are the inputs required by the function and are enclosed in parentheses.

Some arguments are mandatory and others are optional. The optional arguments ("Options") are stipulated using a key=value syntax. In some cases, if you omit optional arguments Vektor will apply a default that's specific to each function.

Functions & Subfunctions

Functions and subfunctions are simply a name grouping system. To avoid having an extremely long list of function names, similar or extended capabilities are often referenced as 'subfunctions' that are grouped under a common 'function' name. You might think of the subfunctions as 'children' of the function 'parents'.

All functions have a default behaviour that occur if you omit any subfunction. Often the default behaviour will be the primary capability (e.g. LEND) while the subfunctions will be complementary/extended capabilities (e.g. LEND.MARKETS, LEND.WITHDRAW etc.)

Subfunctions are accessed by using a dot . separator after the main function name.

The BORROW and LIST functions and their subfunctions

Singular and Plural Function Names

Many VXL functions have both singular and plural variants (e.g. BALANCE and BALANCES). As a general rule, anything that is singular will return an individual object (e.g. a single-chain balance, a specific lending market, a specific LP position) while anything that is plural will return a list of objects (e.g. a list of balances, a list of lending markets, a list of LP positions). Some examples below.

Singular Plural                                                                                                                          
BALANCE Get an asset balance on a single chain BALANCES Get balances of all assets on all chains
ASSET Get info on a specific asset on a single chain ASSETS Get info on all assets on all chains
BUY.QUOTE Get the best buy quote for an order BUY.QUOTES Get a list of buy quotes for an order
LEND.MARKET Get info on a specific lending market LEND.MARKETS Get info on all lending markets on all chains
BORROW.POSITION Get info on a specific borrow position BORROW.POSITIONS Get info on all borrow positions on all chains
LP.POOL Get info on a specific LP pool on a single chain LP.POOLS Get info on all pools on all chains

Plural version of LEND.MARKETS returns a list of markets; Singular version LEND.MARKET returns a single market object

You can use the LIST function to process the lists returned by plural functions (e.g. use LIST.FIRST(LEND.MARKETS) to return the top market from the list of lending markets).

Default Everything; Filter Something

Vektor's plural functions (e.g. BALANCES, POOLS) can generally be used without any arguments to return a full search of all blockchains, venues, and labelled addresses (where applicable). The default behaviour in doing so is to see the greatest amount of information at the top level. You would typically then use filters to narrow down the information to something more specific (or skip straight to this step).

Examples of multi-criteria filtering on the BALANCES function

Filters are expressed as optional arguments (see Anatomy of a VXL function above). As you can see from the above, it's possible to put multiple different filters in one function (using commas to separate the optional arguments) and it's possible to put multiple different values in one filter (using square brackets as value arrays). This gives you complete control and powerful optionality.

Some filter options are common across many functions. The most common are:

  • INCLUDE_BLOCKCHAINS / EXCLUDE_BLOCKCHAINS
  • INCLUDE_LABELS / EXCLUDE_LABELS
  • INCLUDE_VENUES / EXCLUDE_VENUES
  • INCLUDE_ASSETS / EXCLUDE_ASSETS

which can be used with BALANCES, LEND.MARKETS, LEND.POSITIONS, BORROW.MARKETS, BORROW.POSITIONS, BORROW.ACCOUNTS, BUY.QUOTES, SELL.QUOTES, LP.POOLS, LP.POSITIONS, PRICES, ASSETS and many more!

Getting and using data from objects

In the Vektor data model, almost everything is an object, containing structured data. For instance, the BLOCKCHAINS function at first glance appears to be a table of static data...

... but this is not static data at all; it is a list of blockchain objects. You can reference each of them individually in the command line to see their structured data...

... after which, you can extract individual data points in one of two ways: (i) Either use the GET function, or (ii) use the dot . notation as an accessor suffix.

Two ways to access data points from an object

You can use these techniques to access data from nested function statements. For instance the below pulls the SUPPLY_APY data point from the result of a function that returns the top USDC lend market from a list of lend markets.

Extracting a data point from the object returned by a nested function

You can even keep drilling down through multiple structures to get to the data you need. For instance the below example first returns the highest borrow MARKET for ETH, then extracts the VENUE from that borrow market, then extracts the WEBSITE from that venue:

Multi-level data point access drill-down using the dot notation
⚠️
Note: The alternative syntax for the above using the GET function would be GET(LIST.FIRST(BORROW.MARKETS(INCLUDE_ASSETS=[ETH])), ["VENUE", "WEBSITE"])

Depending on your use case, you may be passing objects directly as function arguments e.g.

  • passing a LP POOL object into the LP function to specify which pool you want to add liquidity to, or
  • passing a LEND MARKET object into the LEND function to specifiy which market you want to participate in

or you may be passing individual extracted data points as function arguments e.g.

  • using a SUPPLY_APY data point in a conditional statement for the ALERT function, to have Vektor send you an email when the SUPPLY_APY drops, or
  • using a BALANCE data point in a SELL function, to have Vektor sell not a specific amount but the entire balance of your labelled address

In any case, Vektor's data model is powerful and versatile, and will allow you to unlock a huge number of use cases for querying, executing, and automating your DeFi activities. This standardized model puts you in complete control.


Any questions about these VXL Common Syntax Patterns, or feedback about this topic? Do let us know.

Read more: