This project exposes a minimal AWS Lambda handler that wraps the leo CLI. You can invoke it through a Lambda Function URL and pass the command arguments to run leo with faster CPU (by using larger Lambda sizes).
- Accepts args via POST JSON
{ "cmd": "..." }or{ "args": ["..."] }(POST-only) - Optional
workdir(default/tmp/leo) - Captures stdout/stderr, exit code, and reports when output is truncated (limit configurable via
MAX_OUTPUT_BYTES, default ~5.5MB) - Configurable binary via
LEO_BINenv var; useDRY_RUN=trueto echo the command for testing - Allowlist subcommands with
ALLOWED_COMMANDS(comma-separated, defaults toexecute) - Injects
--endpointfromENDPOINTenv if not provided explicitly in args (default: https://api.explorer.provable.com/v1) - Forces leo home to the workdir by injecting
--home <workdir>when not set
The Lambda wraps leo execute and supports argument passing via POST. It also supports a contract allowlist and private key injection via environment variables.
- ALLOWED_COMMANDS: defaults to
execute(only execute allowed). You may addversionif you want to permit--versiontests. - ALLOWED_CONTRACTS: optional comma-separated list of allowed contracts (without method), e.g.
vlink_token_service_v7.aleo. - Private key injection: if
--private-key/-kis not present in args, the handler injects--private-keyfromPRIVATE_KEY.
{
"args": [
"execute",
"vlink_token_service_v7.aleo/token_receive_public",
"--amount", "1",
"--recipient", "aleo1..."
]
}{
"cmd": "execute vlink_token_service_v7.aleo/token_receive_public --amount 1 --recipient aleo1..."
}curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"args": [
"execute",
"vlink_token_service_v7.aleo/token_receive_public",
"--amount", "1",
"--recipient", "aleo1..."
],
"timeout": "90s"
}' \
"$FUNCTION_URL"{
"exitCode": 0,
"duration": 1.234,
"stdout": "...",
"stderr": "...",
"truncated": false,
"meta": {"home": "/tmp/leo", "version": "leo 3.2.0"}
}This repository ships with a lightweight Go client in sdk to help you invoke the Lambda from other services:
client, err := sdk.New(os.Getenv("LEO_LAMBDA_URL"))
if err != nil {
log.Fatal(err)
}
resp, err := client.Invoke(ctx, sdk.Request{
Args: []string{
"execute",
"example.aleo/foo",
"--amount", "1",
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println("exit", resp.ExitCode)
fmt.Println("stdout", resp.Stdout)By default the client uses http.DefaultClient; override it with sdk.WithHTTPClient when you need custom timeouts or transport settings.
Import path: github.com/debendraoli/leo-lambda/sdk.
go test ./...
go build -o bin/bootstrap .This repo includes a Dockerfile that builds the Go bootstrap and includes a pre-built leo binary.
- Build and push the image to ECR.
- Create a Lambda function from the container image; set environment variables:
LEO_BIN=/usr/local/bin/leo(if not default)ALLOWED_COMMANDS=execute(default)ALLOWED_CONTRACTS=vlink_token_service_v7.aleo(example)PRIVATE_KEY=<your_private_key>ENDPOINT=https://api.explorer.provable.com/v1(optional; default shown)
- Enable a Function URL (auth as needed) and invoke with the API above.
# Login to ECR first, create repo, then:
docker buildx build --platform linux/amd64,linux/arm64 -t <account>.dkr.ecr.<region>.amazonaws.com/leo-lambda:latest --push .- Lambda storage is ephemeral. Use
/tmpfor temporary files. - If
leoneeds large datasets, consider S3 and download at runtime. - Network and IAM permissions may be required depending on your leo usage.
If you have the leo CLI installed locally, you can run integration tests that execute the real binary. These tests are opt-in to avoid failures in CI.
export LEO_INTEGRATION=1
# optionally set the path explicitly
# export LEO_BIN=/usr/local/bin/leo
go test ./...The suite will auto-detect LEO_BIN or look up leo in PATH, and skip gracefully if not found.