Skip to content

Commit 0fdfc7b

Browse files
committed
fix: rewrite to use proper NAT register_function API
Signed-off-by: plagtech <mngoswp@gmail.com>
1 parent b52a446 commit 0fdfc7b

7 files changed

Lines changed: 362 additions & 351 deletions

File tree

examples/spraay_crypto_payments/README.md

Lines changed: 77 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
11
# Spraay Crypto Payments Agent
22

3-
An AI agent that executes cryptocurrency payments across 13 blockchains using the [Spraay x402 gateway](https://gateway.spraay.app). The agent can batch-send tokens, create escrow contracts, check balances, get token prices, and hire robots via the Robot Task Protocol (RTP).
3+
An AI agent that queries cryptocurrency data across 15 blockchains using the
4+
[Spraay x402 gateway](https://gateway.spraay.app). The agent can check gateway
5+
health, list supported chains and routes, look up wallet balances, and get
6+
token prices — all through natural language.
47

58
## Overview
69

7-
This example demonstrates how to build a **crypto payment agent** using NeMo Agent Toolkit with custom tools that interact with the Spraay x402 protocol gateway. The agent uses a ReAct pattern to reason about payment tasks and execute them via HTTP API calls.
10+
This example demonstrates how to build a **crypto query agent** using NeMo
11+
Agent Toolkit with custom tools that interact with the Spraay x402 protocol
12+
gateway. The agent uses a ReAct pattern to reason about queries and execute
13+
them via HTTP API calls.
814

915
### What is x402?
1016

11-
The [x402 protocol](https://www.x402.org) enables AI agents to pay for API services using USDC micropayments over HTTP. When an agent calls a paid endpoint, the server returns HTTP 402 (Payment Required) with payment details. The agent signs a USDC transaction, resends the request with the payment proof, and the server executes the operation.
17+
The [x402 protocol](https://www.x402.org) enables AI agents to pay for API
18+
services using USDC micropayments over HTTP. When an agent calls a paid
19+
endpoint, the server returns HTTP 402 (Payment Required) with payment details.
20+
The agent signs a USDC transaction, resends the request with payment proof,
21+
and the server executes the operation.
1222

1323
### Supported Chains
1424

15-
Base · Ethereum · Arbitrum · Polygon · BNB Chain · Avalanche · Solana · Bitcoin · Stacks · Unichain · Plasma · BOB · Bittensor
25+
Base · Ethereum · Arbitrum · Polygon · BNB Chain · Avalanche · Solana ·
26+
Bitcoin · Stacks · Unichain · Plasma · BOB · Bittensor · Stellar · XRP Ledger
1627

1728
## Prerequisites
1829

@@ -31,33 +42,71 @@ cd examples/spraay_crypto_payments
3142
2. Install dependencies:
3243

3344
```bash
34-
uv venv --python 3.12 --seed .venv
35-
source .venv/bin/activate # Linux/Mac
36-
# .venv\Scripts\activate # Windows
37-
uv pip install nvidia-nat httpx
45+
uv pip install -e .
3846
```
3947

4048
3. Set environment variables:
4149

4250
```bash
4351
export NVIDIA_API_KEY=<your-nvidia-api-key>
44-
export SPRAAY_GATEWAY_URL=https://gateway.spraay.app
52+
export SPRAAY_GATEWAY_URL=https://gateway.spraay.app # optional, this is the default
4553
```
4654

4755
## Running the Example
4856

49-
### Using the CLI
57+
### Check gateway health
5058

5159
```bash
52-
nat run --config_file configs/config.yml --input "What chains does Spraay support and what is the current price of ETH on Base?"
60+
nat run \
61+
--config_file configs/config.yml \
62+
--input "Is the Spraay gateway healthy?"
5363
```
5464

55-
### Example Prompts
65+
### List supported chains
5666

57-
- `"Check the USDC balance for address 0xAd62f03C7514bb8c51f1eA70C2b75C37404695c8 on Base"`
58-
- `"What is the current price of ETH on Base?"`
59-
- `"List all available Spraay gateway routes and their pricing"`
60-
- `"Discover available robots on the RTP network"`
67+
```bash
68+
nat run \
69+
--config_file configs/config.yml \
70+
--input "What blockchains does Spraay support?"
71+
```
72+
73+
### Get token price
74+
75+
```bash
76+
nat run \
77+
--config_file configs/config.yml \
78+
--input "What is the current price of ETH on Base?"
79+
```
80+
81+
## Expected Output
82+
83+
```
84+
$ nat run --config_file configs/config.yml --input "Is the Spraay gateway healthy?"
85+
86+
Configuration Summary:
87+
--------------------
88+
Workflow Type: react_agent
89+
Number of Functions: 5
90+
Number of LLMs: 1
91+
92+
Agent's thoughts:
93+
Thought: The user wants to check if the Spraay gateway is healthy.
94+
I should use the spraay_health tool.
95+
Action: spraay_health
96+
Action Input: check health
97+
98+
Observation: {
99+
"status": "ok",
100+
"version": "3.6.0",
101+
"uptime": "..."
102+
}
103+
104+
Thought: The gateway is healthy and running.
105+
Final Answer: Yes, the Spraay x402 gateway is healthy. It is running
106+
version 3.6.0 and reporting an "ok" status.
107+
------------------------------
108+
Workflow Result: ['Yes, the Spraay x402 gateway is healthy...']
109+
```
61110

62111
## Architecture
63112

@@ -66,17 +115,14 @@ nat run --config_file configs/config.yml --input "What chains does Spraay suppor
66115
│ NeMo Agent Toolkit │
67116
│ │
68117
│ ┌───────────────────────────────────┐ │
69-
│ │ ReAct Agent (Nemotron) │ │
118+
│ │ ReAct Agent (Llama 3.1) │ │
70119
│ │ │ │
71120
│ │ Tools: │ │
72-
│ │ ├── spraay_health │ │
73-
│ │ ├── spraay_routes │ │
74-
│ │ ├── spraay_chains │ │
75-
│ │ ├── spraay_balance │ │
76-
│ │ ├── spraay_price │ │
77-
│ │ ├── spraay_batch_send │ │
78-
│ │ ├── spraay_escrow_create │ │
79-
│ │ └── spraay_rtp_discover │ │
121+
│ │ ├── spraay_health │ │
122+
│ │ ├── spraay_routes │ │
123+
│ │ ├── spraay_chains │ │
124+
│ │ ├── spraay_balance │ │
125+
│ │ └── spraay_price │ │
80126
│ └──────────────┬────────────────────┘ │
81127
│ │ │
82128
└─────────────────┼────────────────────────┘
@@ -86,8 +132,8 @@ nat run --config_file configs/config.yml --input "What chains does Spraay suppor
86132
│ Spraay x402 Gateway │
87133
│ gateway.spraay.app │
88134
│ │
89-
76+ paid endpoints │
90-
13 blockchains │
135+
84+ paid endpoints │
136+
15 blockchains │
91137
│ USDC micropayments │
92138
└────────────────────────┘
93139
```
@@ -97,14 +143,14 @@ nat run --config_file configs/config.yml --input "What chains does Spraay suppor
97143
| File | Description |
98144
|------|-------------|
99145
| `configs/config.yml` | NeMo Agent Toolkit workflow configuration |
100-
| `src/spraay_crypto_payments/spraay_tools.py` | Custom Spraay gateway tools |
101-
| `src/spraay_crypto_payments/__init__.py` | Package init with tool registration |
102-
| `pyproject.toml` | Project dependencies |
146+
| `src/spraay_crypto_payments/register.py` | Tool registration with `@register_function` |
147+
| `src/spraay_crypto_payments/spraay_client.py` | Async HTTP client for the Spraay gateway |
148+
| `src/spraay_crypto_payments/__init__.py` | Package init |
149+
| `pyproject.toml` | Project dependencies and NAT entry points |
103150

104151
## Links
105152

106153
- [Spraay Gateway Docs](https://docs.spraay.app)
107154
- [x402 Protocol](https://www.x402.org)
108155
- [Spraay MCP Server](https://smithery.ai/server/@plagtech/spraay-x402-mcp)
109156
- [NeMo Agent Toolkit Docs](https://docs.nvidia.com/nemo/agent-toolkit/latest/)
110-
- [Spraay on OpenShell](https://github.com/NVIDIA/OpenShell-Community/pull/50)

examples/spraay_crypto_payments/configs/config.yml

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,46 @@
22
# NeMo Agent Toolkit workflow configuration
33
#
44
# This agent uses the Spraay x402 gateway to execute cryptocurrency
5-
# payments across 13 blockchains via USDC micropayments.
5+
# payments across 15 blockchains via USDC micropayments.
66

77
functions:
8-
# Query tools (free endpoints — no x402 payment required)
8+
# Free query tools (no x402 payment required)
99
spraay_health:
10-
_type: spraay_health
10+
_type: spraay_gateway_tool
11+
gateway_url: ${SPRAAY_GATEWAY_URL:-https://gateway.spraay.app}
12+
endpoint: /health
13+
method: GET
1114
description: "Check the health status of the Spraay x402 gateway"
1215

1316
spraay_routes:
14-
_type: spraay_routes
17+
_type: spraay_gateway_tool
18+
gateway_url: ${SPRAAY_GATEWAY_URL:-https://gateway.spraay.app}
19+
endpoint: /v1/routes
20+
method: GET
1521
description: "List all available Spraay gateway routes with pricing info"
1622

1723
spraay_chains:
18-
_type: spraay_chains
24+
_type: spraay_gateway_tool
25+
gateway_url: ${SPRAAY_GATEWAY_URL:-https://gateway.spraay.app}
26+
endpoint: /v1/chains
27+
method: GET
1928
description: "List all supported blockchains on the Spraay gateway"
2029

2130
spraay_balance:
22-
_type: spraay_balance
31+
_type: spraay_balance_tool
32+
gateway_url: ${SPRAAY_GATEWAY_URL:-https://gateway.spraay.app}
2333
description: "Check the token balance of a wallet address on a specific chain"
2434

2535
spraay_price:
26-
_type: spraay_price
36+
_type: spraay_price_tool
37+
gateway_url: ${SPRAAY_GATEWAY_URL:-https://gateway.spraay.app}
2738
description: "Get the current price of a token on a specific chain"
2839

29-
# Action tools (paid endpoints — requires x402 USDC payment)
30-
spraay_batch_send:
31-
_type: spraay_batch_send
32-
description: "Send tokens to multiple recipients in a single batch transaction"
33-
34-
spraay_escrow_create:
35-
_type: spraay_escrow_create
36-
description: "Create an escrow contract with milestone-based fund releases"
37-
38-
spraay_rtp_discover:
39-
_type: spraay_rtp_discover
40-
description: "Discover available robots and IoT devices on the RTP network"
41-
4240
llms:
4341
nim_llm:
4442
_type: nim
45-
model_name: nvidia/nemotron-3-nano-30b-a3b
43+
model_name: meta/llama-3.1-70b-instruct
4644
temperature: 0.0
47-
chat_template_kwargs:
48-
enable_thinking: false
4945

5046
workflow:
5147
_type: react_agent
@@ -55,9 +51,6 @@ workflow:
5551
- spraay_chains
5652
- spraay_balance
5753
- spraay_price
58-
- spraay_batch_send
59-
- spraay_escrow_create
60-
- spraay_rtp_discover
6154
llm_name: nim_llm
6255
verbose: true
6356
parse_agent_response_max_retries: 3

examples/spraay_crypto_payments/pyproject.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES.
2+
# SPDX-License-Identifier: Apache-2.0
3+
14
[project]
25
name = "spraay-crypto-payments"
36
version = "0.1.0"
@@ -6,7 +9,7 @@ readme = "README.md"
69
license = { text = "Apache-2.0" }
710
requires-python = ">=3.11,<3.14"
811
dependencies = [
9-
"nvidia-nat>=1.5.0",
12+
"nvidia-nat>=1.3.0",
1013
"httpx>=0.27.0",
1114
]
1215

@@ -16,3 +19,6 @@ build-backend = "setuptools.build_meta"
1619

1720
[tool.setuptools.packages.find]
1821
where = ["src"]
22+
23+
[project.entry-points.'nat.components']
24+
spraay_crypto_payments = "spraay_crypto_payments.register"
Lines changed: 1 addition & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,2 @@
1-
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES.
1+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES.
22
# SPDX-License-Identifier: Apache-2.0
3-
4-
"""Spraay Crypto Payments — NeMo Agent Toolkit plugin.
5-
6-
Registers Spraay x402 gateway tools for use in NeMo Agent Toolkit workflows.
7-
"""
8-
9-
from nat.components.functions.tool import tool
10-
from nat.registry import register
11-
12-
from .spraay_tools import (
13-
spraay_balance,
14-
spraay_batch_send,
15-
spraay_chains,
16-
spraay_escrow_create,
17-
spraay_health,
18-
spraay_price,
19-
spraay_routes,
20-
spraay_rtp_discover,
21-
)
22-
23-
24-
@register("spraay_health")
25-
def _register_health(**kwargs):
26-
return tool(spraay_health, description=kwargs.get("description", ""))
27-
28-
29-
@register("spraay_routes")
30-
def _register_routes(**kwargs):
31-
return tool(spraay_routes, description=kwargs.get("description", ""))
32-
33-
34-
@register("spraay_chains")
35-
def _register_chains(**kwargs):
36-
return tool(spraay_chains, description=kwargs.get("description", ""))
37-
38-
39-
@register("spraay_balance")
40-
def _register_balance(**kwargs):
41-
return tool(spraay_balance, description=kwargs.get("description", ""))
42-
43-
44-
@register("spraay_price")
45-
def _register_price(**kwargs):
46-
return tool(spraay_price, description=kwargs.get("description", ""))
47-
48-
49-
@register("spraay_batch_send")
50-
def _register_batch_send(**kwargs):
51-
return tool(spraay_batch_send, description=kwargs.get("description", ""))
52-
53-
54-
@register("spraay_escrow_create")
55-
def _register_escrow_create(**kwargs):
56-
return tool(spraay_escrow_create, description=kwargs.get("description", ""))
57-
58-
59-
@register("spraay_rtp_discover")
60-
def _register_rtp_discover(**kwargs):
61-
return tool(spraay_rtp_discover, description=kwargs.get("description", ""))

0 commit comments

Comments
 (0)