Skip to content

Commit ebbf2f1

Browse files
authored
Merge pull request #7 from PagoPlus/feat/add-readme-and-license
[DOCS] Add README and LICENSE
2 parents b2d4bb6 + 6b9a80b commit ebbf2f1

File tree

3 files changed

+344
-1
lines changed

3 files changed

+344
-1
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 MedFlow
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
# Numscript WASM CLI
2+
3+
This project is a WebAssembly (WASM) port of the [formancehq/numscript](https://github.com/formancehq/numscript) CLI, enabling you to run Numscript execution in any WASM-compatible environment. Originally forked from the official repository, it now provides a standalone WASM binary that maintains full compatibility with the original CLI functionality.
4+
5+
## What is Numscript?
6+
7+
Numscript is a Domain-Specific Language (DSL) designed to help you model complex financial transactions, replacing complex and error-prone custom code with easy-to-read, declarative scripts. Originally developed by Formance, Numscript is used to express financial transactions within the Formance ledger system.
8+
9+
The language provides:
10+
- **Declarative syntax** for modeling financial operations
11+
- **Built-in validation** for transaction integrity
12+
- **Account management** with metadata support
13+
- **Variable substitution** for dynamic scripts
14+
- **Feature flags** for experimental functionality
15+
16+
You can try Numscript online at [playground.numscript.org](https://playground.numscript.org/).
17+
18+
## Installation
19+
20+
### Prerequisites
21+
22+
You'll need a WebAssembly (WASM) runtime to execute the numscript-wasm binary. This guide uses Wasmtime, but you can also use other WASM runtimes like Wasmer.
23+
24+
**Install Wasmtime:**
25+
```bash
26+
curl https://wasmtime.dev/install.sh -sSf | bash
27+
```
28+
29+
### Download the Binary
30+
31+
Download the WASM binary from the [latest release](https://github.com/PagoPlus/numscript-wasm/releases/latest) for your platform.
32+
33+
## Usage
34+
35+
The CLI provides two commands: `version` and `run`.
36+
37+
### Version Command
38+
39+
Display the current version of the CLI:
40+
41+
```bash
42+
wasmtime numscript.wasm version
43+
```
44+
45+
**Output:**
46+
```bash
47+
# If you are using the released binary this will print the real app version:
48+
v0.1.0
49+
# Otherwise will print dev:
50+
dev
51+
```
52+
53+
### Run Command
54+
55+
Execute a Numscript with the provided input data. The command reads JSON input from stdin containing the script, variables, account metadata, balances, and feature flags.
56+
57+
#### Input Format
58+
59+
The input JSON must follow this structure:
60+
61+
| Field | Type | Required | Description |
62+
|-------|------|----------|-------------|
63+
| `script` | string || The Numscript code to execute |
64+
| `variables` | object || [Variables](https://docs.formance.com/modules/numscript/reference/variables) |
65+
| `metadata` | object || [Account metadata](https://docs.formance.com/modules/numscript/reference/metadata) |
66+
| `balances` | object || Current account balances. [Example below](#balances). |
67+
| `featureFlags` | object || Experimental features to enable (empty objects as values). [Example below](#featureflags) |
68+
69+
##### balances
70+
Is an object containing the account name and their respective assets and balances. Ex:
71+
```json
72+
"balances": {
73+
"foo": {
74+
"USD/2": 200,
75+
"EUR/2": 100
76+
},
77+
"bar": {
78+
"BRL/2": 200,
79+
"JPY/2": 100
80+
}
81+
},
82+
```
83+
###### Asset Format
84+
Assets use the format `CURRENCY/PRECISION`:
85+
- `USD/2` = US Dollars with 2 decimal places
86+
- `EUR/2` = Euros with 2 decimal places
87+
- `BTC/8` = Bitcoin with 8 decimal places
88+
89+
##### featureFlags
90+
Is an object containing the name of the feature flag you want to use with an empty object as their value. Ex:
91+
```json
92+
"featureFlags": {
93+
"experimental-oneof": {},
94+
"experimental-get-amount-function": {},
95+
"experimental-mid-script-function-call": {}
96+
}
97+
```
98+
99+
Numscript does not have an official list of feature flags, but you can see the [source code](https://github.com/formancehq/numscript/blob/v0.0.17/internal/flags/flags.go) and the documentation with the [experimental features usage](https://github.com/formancehq/numscript/blob/main/differences-with-machine.md#new-functionalities-feature-flags)
100+
101+
#### Examples
102+
103+
##### Basic Transfer
104+
Simple account-to-account transfer:
105+
106+
1. **Create an input file** (`example.json`):
107+
108+
```json
109+
{
110+
"script": "send [USD/2 100] (\n source = @foo\n destination = @bar\n)",
111+
"balances": {
112+
"foo": {
113+
"USD/2": 200,
114+
"EUR/2": 100
115+
}
116+
},
117+
"variables": {},
118+
"metadata": {},
119+
"featureFlags": {}
120+
}
121+
```
122+
123+
2. **Execute the script**:
124+
125+
```bash
126+
wasmtime numscript.wasm run < example.json
127+
```
128+
129+
3. **Expected output** (JSON format):
130+
131+
```json
132+
{
133+
"postings": [
134+
{
135+
"source": "foo",
136+
"destination": "bar",
137+
"asset": "USD/2",
138+
"amount": 100
139+
}
140+
],
141+
"txMeta": {},
142+
"accountsMeta": {}
143+
}
144+
```
145+
146+
#### Using variables
147+
148+
1. **Input File:** (`example.json`):
149+
```json
150+
{
151+
"script": "vars { account $user monetary $fee portion $tax } send $fee (source = $user destination = { $tax to @platform:tax remaining to @platform:revenue })",
152+
"balances": {
153+
"users:1234": {
154+
"USD/2": 10000
155+
}
156+
},
157+
"variables": {
158+
"user": "users:1234",
159+
"fee": "USD/2 100",
160+
"tax": "20%"
161+
},
162+
"metadata": {},
163+
"featureFlags": {
164+
"experimental-oneof": {},
165+
"experimental-get-amount-function": {},
166+
"experimental-mid-script-function-call": {}
167+
}
168+
}
169+
```
170+
171+
2. **Execute the script**:
172+
```bash
173+
wasmtime numscript.wasm run < example.json
174+
```
175+
176+
3. **Expected output** (JSON format):
177+
```json
178+
{
179+
"postings": [
180+
{
181+
"source": "users:1234",
182+
"destination": "platform:tax",
183+
"amount": 20,
184+
"asset": "USD/2"
185+
},
186+
{
187+
"source": "users:1234",
188+
"destination": "platform:revenue",
189+
"amount": 80,
190+
"asset": "USD/2"
191+
}
192+
],
193+
"txMeta": {},
194+
"accountsMeta": {}
195+
}
196+
```
197+
198+
199+
#### Using metadata
200+
201+
1. **Input File:** (`example.json`):
202+
```json
203+
{
204+
"script": "vars { account $order account $merchant = meta($order, \"merchant\") portion $commission = meta($merchant, \"commission\") } send [USD/2 *] ( source = $order destination = { $commission to @platform:fees remaining to $merchant })",
205+
"balances": {
206+
"orders:2345": {
207+
"USD/2": 1000
208+
}
209+
},
210+
"variables": {
211+
"order": "orders:2345"
212+
},
213+
"metadata": {
214+
"orders:2345": {
215+
"merchant": "merchants:1234"
216+
},
217+
"merchants:1234": {
218+
"commission": "15%"
219+
}
220+
},
221+
"featureFlags": {
222+
"experimental-oneof": {},
223+
"experimental-get-amount-function": {},
224+
"experimental-mid-script-function-call": {}
225+
}
226+
}
227+
```
228+
229+
2. **Execute the script**:
230+
```bash
231+
wasmtime numscript.wasm run < example.json
232+
```
233+
234+
3. **Expected output** (JSON format):
235+
```json
236+
{
237+
"postings": [
238+
{
239+
"source": "orders:2345",
240+
"destination": "platform:fees",
241+
"amount": 150,
242+
"asset": "USD/2"
243+
},
244+
{
245+
"source": "orders:2345",
246+
"destination": "merchants:1234",
247+
"amount": 850,
248+
"asset": "USD/2"
249+
}
250+
],
251+
"txMeta": {},
252+
"accountsMeta": {}
253+
}
254+
```
255+
256+
#### Allowing experimental features
257+
258+
If you want to use experimental features, you need to enable them by adding their respective feature flag:
259+
260+
1. **Input File:** (`example.json`):
261+
```json
262+
{
263+
"script": "vars { monetary $mon = [USD/2 100] number $n = get_amount($mon) } send [USD/2 $n] (source = oneof { @foo @bar } destination = @baz)",
264+
"balances": {
265+
"foo": {
266+
"USD/2": 99
267+
},
268+
"bar": {
269+
"USD/2": 100
270+
}
271+
},
272+
"variables": {},
273+
"metadata": {},
274+
"featureFlags": {
275+
"experimental-oneof": {},
276+
"experimental-get-amount-function": {},
277+
"experimental-mid-script-function-call": {}
278+
}
279+
}
280+
```
281+
282+
2. **Execute the script**:
283+
```bash
284+
wasmtime numscript.wasm run < example.json
285+
```
286+
287+
3. **Expected output** (JSON format):
288+
```json
289+
{
290+
"postings": [
291+
{
292+
"source": "bar",
293+
"destination": "baz",
294+
"amount": 100,
295+
"asset": "USD/2"
296+
}
297+
],
298+
"txMeta": {},
299+
"accountsMeta": {}
300+
}
301+
```
302+
303+
## Error Handling
304+
305+
The CLI will exit with status code 1 and write error messages to stderr if:
306+
307+
- The input JSON is malformed
308+
- The Numscript has parsing errors
309+
- The execution fails due to insufficient balances or other runtime errors
310+
311+
Example error output:
312+
```
313+
Exception: Not enough funds. Needed [USD/2 100] (only [USD/2 99] available)
314+
```
315+
316+
## License
317+
318+
This project maintains the same license as the original [formancehq/numscript](https://github.com/formancehq/numscript) repository.
319+
320+
## Contributing
321+
322+
This is a fork focused on WASM compatibility. For core Numscript language contributions, please consider contributing to the upstream [formancehq/numscript](https://github.com/formancehq/numscript) repository.

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module numscript
1+
module numscript-wasm
22

33
go 1.23.0
44

0 commit comments

Comments
 (0)