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.
Subfunctions are accessed by using a dot
. separator after the main function name.
Singular and Plural Function Names
Many VXL functions have both singular and plural variants (e.g.
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.
||Get an asset balance on a single chain||
||Get balances of all assets on all chains|
||Get info on a specific asset on a single chain||
||Get info on all assets on all chains|
||Get the best buy quote for an order||
||Get a list of buy quotes for an order|
||Get info on a specific lending market||
||Get info on all lending markets on all chains|
||Get info on a specific borrow position||
||Get info on all borrow positions on all chains|
||Get info on a specific LP pool on a single chain||
||Get info on all pools on all chains|
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.
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).
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:
which can be used with
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.
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.
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
ETH, then extracts the
VENUE from that borrow market, then extracts the
WEBSITE from that venue:
GETfunction 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 POOLobject into the
LPfunction to specify which pool you want to add liquidity to, or
- passing a
LEND MARKETobject into the
LENDfunction 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_APYdata point in a conditional statement for the
ALERTfunction, to have Vektor send you an email when the
- using a
BALANCEdata point in a
SELLfunction, 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.