View Source NumscriptEx

Hex Version Hex Docs

NumscriptEx is a library that allows its users to run Numscripts in Elixir. If this is your first time hearing about Numscripts, here is a quick explanation:

Numscript is a DSL made by Formance that simplifies complex financial transactions with scripts that are easy to read, so you don't need a big, complex and error-prone codebase to deal with your finances.

You can see and execute some examples at the Numscript Playground.

Installation

You will just need to add :numscriptex as a dependency on your mix.exs, and run the mix deps.get command:

def deps do
  [
    {:numscriptex, "~> 0.2.6"}
  ]
end

Configuration

NumscriptEx needs some external assets (Numscript-WASM), and you can override the default version.

Available configurations:

  • :version the binary release version to use (see numscript-wasm releases).
  • :retries number of times to retry the download in case of a network failure.
  • :binary_path where the WASM binary file will be downloaded

Ex:

config :numscriptex,
       binary_path: :numscriptex |> :code.priv_dir() |> Path.join("numscript.wasm")
       version: "0.1.0",
       retries: 3

These above are the default values.

Usage

You can build Numscripts dynamically with Numscriptex.Builder.build/1 and run your script with Numscriptex.run/2.

You can read more about the Numscriptex.Builder module and how to use it on its guide

And before introducing the other two functions, you will need to know what is the Numscriptex.Run struct.

Numscriptex.Run

A numscript needs some other data aside the script itself to run correctly, and Numscriptex.Run solves this problem.

If you want to know what exactly these additional data are, you can see the Numscript Playground for examples.

The abstraction is made by creating a struct:

iex>  %Numscriptex.Run{
...>    balances: %{},
...>    metadata: %{},
...>    variables: %{},
...>    feature_flags: []
...>  }

Where:

  • :balances a map with the account's assets balances.
  • :metadata metada variables;
  • :variables variables.
  • :feature_flags feature flags that enables numscript experimental features.

The avaialable feature flags are:

  • experimental_overdraft_function
  • experimental_get_asset_function
  • experimental_get_amount_function
  • experimental_oneof
  • experimental_account_interpolation
  • experimental_mid_script_function_call
  • experimental_asset_colors

And to create a new struct, you can use the Numscriptex.Run.put/3 or Numscriptex.Run.put!/3 functions. Ex:

iex>  variables = %{"order" => "orders:2345"}
...>  balances = %{"orders:2345" => %{"USD/2" => 1000}}
...>  feature_flags = [:experimental_oneof]
...>  metadata = %{
...>    "merchants:1234" => %{"commission" => "15%"},
...>    "orders:2345" => %{"merchant" => "merchants:1234"}
...>  }
...>
...>  Numscriptex.Run.new()
...>  |> Numscriptex.Run.put!(:balances, balances)
...>  |> Numscriptex.Run.put!(:metadata, metadata)
...>  |> Numscriptex.Run.put!(:variables, variables)
...>  |> Numscriptex.Run.put!(:feature_flags, feature_flags)

Will return:

iex> %Numscriptex.Run{
...>   variables: %{"orders:2345" => %{"USD/2" => 1000}},
...>   balances: %{"order" => "orders:2345"},
...>   feature_flags: [:experimental_oneof]
...>   metadata: %{
...>     "merchants:1234" => %{"commission" => "15%"},
...>     "orders:2345" => %{"merchant" => "merchants:1234"}
...>   }
...> }

Kindly reminder: you will always need a valid Numscriptex.Run struct to successfully execute your scripts.

Run

To use Numscriptex.run/2 you must pass your script as the first argument, and the %Numscriptex.Run{} struct as the second. Ex:

iex>  Numscriptex.run(script, struct)
{:ok, result}

Where result will be something like this:

iex> %{
...>   postings: [
...>           %Numscriptex.Posting{
...>             amount: 100,
...>             decimal_amount: 1.0,
...>             asset: "USD/2",
...>             destination: "bar",
...>             source: "foo"
...>           }
...>         ],
...>   balances: [
...>           %Numscriptex.Balance{
...>             account: "foo",
...>             asset: "EUR/2",
...>             final_balance: 300,
...>             initial_balance: 300,
...>             decimal_final_balance: 3.0,
...>             decimal_initial_balance: 3.0,
...>           },
...>           %Numscriptex.Balance{
...>             account: "foo",
...>             asset: "USD/2",
...>             final_balance: 400,
...>             initial_balance: 500,
...>             decimal_final_balance: 4.0,
...>             decimal_initial_balance: 5.0,
...>           },
...>           %Numscriptex.Balance{
...>             account: "bar",
...>             asset: "USD/2",
...>             final_balance: 100,
...>             initial_balance: 0,
...>             decimal_final_balance: 1.0,
...>             decimal_initial_balance: 0.0,
...>           }
...>         ],
...>   accountMeta: %{}
...>   txMeta: %{}
...> }

License

Copyright (c) 2025 MedFlow

This library is MIT licensed. See the LICENSE for details.