General Concepts

What are server-less functions and how they look like.

Don't serialize/use as response i128. We're investigating a bug that crashes the program's execution when i128s are being serialized. Consider converting them to i64s in the responses. Converting to string won't work either.

Serverless functions are similar to other functions in your program, but they are not executed for each ledger close. Instead, they are triggered externally through a web request that fetches our program, specifically our function, which contains the logic for what to return and how to return it to the caller.

They are called severless as you will have them available without running any infrastructure: just create the function in your program that will live on our servers, and call it externally afterwords.

Therefore, they have some unique characteristics compared to regular functions.

EnvClient::empty()

The first thing to note is that when getting a handle on the host environment client from inside a serverless function, you should never use the standard EnvClient::new() that we have inside the on_close() functions. Using that handle will result in the program's execution stopping immediately if called as a serverless function.

You should rather use the EnvClient::empty() function which is compatible with serverless functions.

Reading the request body

We said that the function will be called through a web request: the request body that you provide in the web request is forwarded to the VM and can be accessed guest-side with env.read_request_body() . The request structure will also need to be defined in the program:

#[derive(Serialize, Deserialize)]
pub struct Request {
    account: String
}

#[no_mangle]
pub extern "C" fn test_function() {
    let env = EnvClient::empty();
    let request: Request = env.read_request_body();
}

Returning the response

Returning the response is done through env.conclude(response) where response is a serializable type.

That is the general pattern, in the next chapters we will see a lot of examples of how these elements work together.


Calling functions

To call functions you can run a web request against the /zephyr/execute endpoint:

curl -X POST https://api.mercurydata.app/zephyr/execute -H "Authorization: Bearer $MERCURY_JWT" -H 'Content-Type: application/json' -d '{"mode":{"Function": {"fname": "test_function", "arguments": "{\"account\": \"GC5PGBLWLRPBIJ7AC2KD3MI34BXYKCJIRVXXFBR2CP2NBLVN2LLY2HUJ\" "}}}'

Where you specify the request body within the arguments field. Remember also to specify the correct Zephyr endpoint in the request. You can find a list of our endpoints here.

Making Functions Public and A Note on Auth

Calling functions as showed above is an authorized action, as a result, code deployed by a certain user can only be called with a JWT token that authenticates the user. This is a common practice and should always be enforced, but in some situations one might prefer to open certain data retrieval functions of the API to the public.

You can make a function publicly callable (by anyone) by calling the Mercury API. For example, if the program exports API functions retrieve and users you can make these public with:

curl -X POST https://mainnet.mercurydata.app/zephyr/pubfunctions -H "Authorization: Bearer $MERCURY_JWT" -H "Content-Type: application/json" -d '{"public":["retrieve", "users"]}'

Invoking Public Functions

Once your function is public, you must invoke it by specifying the identifier of the program (which on the other hand is derived when providing the JWT). That identifier corresponds to your user id. If you don't know your user id yet (it will be soon added to the webapp), you can query the API with allUsers along with your authorization header:

Once you know your id, you can invoke the program specifying the user id with execute/{id} :

curl -X POST https://mainnet.mercurydata.app/zephyr/execute/30 -H 'Content-Type: application/json' -d '{"mode":{"Function": {"fname": "retrieve", "arguments": "{\"kind\": \"Collateral\", \"address\": \"GDJSH2NU2WF6J4P5DL4522DUCABWSTZOKFQ7BHBCFYQ3QKC6FRYWP6OL\"}"}}}'

Last updated