feat: Add Spraay payment tools — batch payments, escrow, and balance#6609
feat: Add Spraay payment tools — batch payments, escrow, and balance#6609plagtech wants to merge 6 commits into
Conversation
📝 WalkthroughWalkthroughAdds CrewAI tools for Spraay batch payments, escrow creation, and wallet balance queries. Shared utilities convert chains and token amounts, while paid requests support x402 payment challenges. The package exports the tools and documents setup, endpoint behavior, and examples. ChangesSpraay Tools
Sequence Diagram(s)sequenceDiagram
participant CrewAI
participant SpraayTool
participant SpraayGateway
participant x402Client
CrewAI->>SpraayTool: Submit tool inputs
SpraayTool->>SpraayGateway: Send free or paid request
SpraayGateway-->>SpraayTool: Return response or payment challenge
SpraayTool->>x402Client: Sign payment requirements
x402Client->>SpraayGateway: Retry paid request
SpraayGateway-->>SpraayTool: Return gateway result
SpraayTool-->>CrewAI: Return formatted JSON result
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_balance_tool.py`:
- Around line 75-79: The Spraay balance tool must use the paid balance API
instead of the free route. In
lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_balance_tool.py:75-79,
update the request in the balance lookup method to use the documented
/api/v1/balances endpoint and its x402 payment flow. In
lib/crewai-tools/src/crewai_tools/tools/spraay_tool/README.md:11 and :119,
remove or revise claims that the balance endpoint is free.
In
`@lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_batch_payment_tool.py`:
- Around line 34-40: Replace the recipients type in the payment tool’s input
model with a nested Pydantic model that requires both address and amount fields,
then type recipients as a list of that model. Update _run to access the
validated model fields while preserving the existing payment behavior and
description.
- Around line 164-172: Update _execute_batch in
lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_batch_payment_tool.py
(lines 164-172) and the corresponding paid request flow in
lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_escrow_tool.py (lines
103-109) to handle the initial HTTP 402 challenge before calling
raise_for_status: construct the required payment payload from the challenge,
retry the request with the PAYMENT-SIGNATURE header, then validate the final
response.
- Around line 146-150: Update the request in the batch payment estimation flow
to use GET for the `/free/estimate-batch` endpoint instead of POST, and pass the
existing payload parameters using the query-parameter shape expected by that
endpoint rather than a JSON body.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 13b0a54b-8daa-4649-81a9-eead76f7ef53
📒 Files selected for processing (5)
lib/crewai-tools/src/crewai_tools/tools/spraay_tool/README.mdlib/crewai-tools/src/crewai_tools/tools/spraay_tool/__init__.pylib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_balance_tool.pylib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_batch_payment_tool.pylib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_escrow_tool.py
| response = requests.get( | ||
| f"{self.gateway_url}/free/balance", | ||
| params=params, | ||
| timeout=30, | ||
| ) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== files =="
git ls-files 'lib/crewai-tools/src/crewai_tools/tools/spraay_tool/*' | sed 's#^`#-` #'
echo
echo "== spraay_balance_tool.py (relevant slice) =="
sed -n '1,220p' lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_balance_tool.py
echo
echo "== README.md (relevant slices) =="
sed -n '1,180p' lib/crewai-tools/src/crewai_tools/tools/spraay_tool/README.md
echo
echo "== search for balance endpoints / x402 / free-balance =="
rg -n "free/balance|/api/v1/balances|balance|x402|free endpoints|paid endpoints" lib/crewai-tools/src/crewai_tools/tools/spraay_tool -SRepository: crewAIInc/crewAI
Length of output: 13330
🌐 Web query:
Spraay gateway balance endpoint free/balance api/v1/balances x402 docs
💡 Result:
The Spraay gateway provides a balance lookup endpoint at /api/v1/balances [1][2]. This endpoint is a paid service, typically requiring a small USDC payment (e.g., $0.002 to $0.005) via the x402 protocol [1][2][3]. When you call this endpoint without prior payment, the gateway returns a 402 Payment Required status code, indicating that x402 payment is necessary to access the resource [4][5][6]. The x402 protocol allows agents to pay for API access per request using USDC (e.g., via EIP-3009 on Base) without needing traditional API keys or accounts [5][7][6]. For developers and agents: - Base URL: https://gateway.spraay.app [8][5][6] - Endpoint: GET /api/v1/balances [1][2] - Documentation & Catalog: The official endpoint catalog and pricing are available at https://docs.spraay.app and via the machine-readable manifest at https://gateway.spraay.app/.well-known/x402.json [1][2][6]. - Integration: Tools like the Spraay MCP server automate the handling of 402 responses, enabling seamless balance checks within agent workflows [9][6]. Note that while some utility endpoints (such as /api/health, /api/chains, and token prices) may be free or have different pricing, the /api/v1/balances endpoint is specifically listed as a paid data primitive [8][2][3].
Citations:
- 1: https://docs.spraay.app/
- 2: https://github.com/plagtech/spraay-x402-gateway
- 3: https://www.mppscan.com/server/bfe04c362908c0b65d5d7d2ef8cd53866c7412729da911dba78ef02d45e4ce05
- 4: https://dev.to/mr_hamlin/spraay-just-introduced-new-endpoints-for-solana-agents-45fp
- 5: https://github.com/plagtech/spraay-compute
- 6: https://github.com/plagtech/spraay-x402-mcp
- 7: https://spraay.app/
- 8: https://openclawdir.com/skills/spraay-openclaw-QNqIY_
- 9: https://github.com/plagtech/haystack-spraay
Use the paid /api/v1/balances endpoint here. spraay_balance_tool.py still calls GET /free/balance, but the published gateway catalog lists balance lookup as GET /api/v1/balances and treats it as an x402-paid route. Update the tool to use the documented balance API/payment flow, and remove the README claims that balance is free.
📍 Affects 2 files
lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_balance_tool.py#L75-L79(this comment)lib/crewai-tools/src/crewai_tools/tools/spraay_tool/README.md#L11-L11lib/crewai-tools/src/crewai_tools/tools/spraay_tool/README.md#L119-L119
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_balance_tool.py`
around lines 75 - 79, The Spraay balance tool must use the paid balance API
instead of the free route. In
lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_balance_tool.py:75-79,
update the request in the balance lookup method to use the documented
/api/v1/balances endpoint and its x402 payment flow. In
lib/crewai-tools/src/crewai_tools/tools/spraay_tool/README.md:11 and :119,
remove or revise claims that the balance endpoint is free.
Source: MCP tools
There was a problem hiding this comment.
♻️ Duplicate comments (1)
lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_balance_tool.py (1)
77-83: 🎯 Functional Correctness | 🟠 MajorComplete the x402 payment flow for the paid balance endpoint.
Changing the URL to
/api/v1/balancesis correct, but this remains a plain unauthenticatedGET. A paid gateway response of402is converted byraise_for_status()into an error, so balance checks cannot succeed unless x402 settlement is implemented elsewhere. Reuse the paid-tool flow or confirm this endpoint is free and update the contract accordingly.#!/bin/bash set -euo pipefail rg -n -C 8 '402|x402|payment|requests\.(get|post)' \ lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_batch_payment_tool.py \ lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_escrow_tool.py🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_balance_tool.py` around lines 77 - 83, Update the balance request flow in SpraayBalanceTool to support x402 payment settlement for a 402 response, reusing the existing paid-tool implementation from SpraayBatchPaymentTool or SpraayEscrowTool before retrying the request. Preserve normal successful responses and ensure paid balance checks no longer fail solely because raise_for_status() receives an initial 402.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_balance_tool.py`:
- Around line 77-83: Update the balance request flow in SpraayBalanceTool to
support x402 payment settlement for a 402 response, reusing the existing
paid-tool implementation from SpraayBatchPaymentTool or SpraayEscrowTool before
retrying the request. Preserve normal successful responses and ensure paid
balance checks no longer fail solely because raise_for_status() receives an
initial 402.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d75c67f3-5c6b-42e8-b209-1786bf3dc7d4
📒 Files selected for processing (2)
lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_balance_tool.pylib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_batch_payment_tool.py
🚧 Files skipped from review as they are similar to previous changes (1)
- lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_batch_payment_tool.py
- Replace recipients list[dict] with nested SpraayRecipient Pydantic model (required address and amount fields) in the batch payment tool - Add x402 payment challenge handling to paid endpoints (batch execute, escrow create) via the official x402 package: on HTTP 402, sign the payment requirements with SPRAAY_WALLET_PRIVATE_KEY and retry with the payment header attached; without the key, return the parsed payment requirements as structured JSON instead of raising - Document wallet requirement for paid endpoints in the README - Verified endpoints against the live gateway discovery doc (/.well-known/x402.json): batch execute $0.02, escrow create $0.10, x402 v2 on Base/USDC
- Register SpraayBatchPaymentTool, SpraayEscrowTool, SpraayBalanceTool,
and SpraayRecipient in crewai_tools __init__ so top-level imports work
- Align request bodies with the gateway (verified against openapi.json,
the BPA 1.0 spec/schema, and live probes of the free endpoints):
- POST /api/v1/batch/execute: {token, recipients[], amounts[], sender}
with flat parallel arrays and base-unit amount strings
- POST /free/validate-batch: {chain, token, recipients: [{to, amount}]}
with chain slugs (base, ethereum, ...) not chain IDs
- GET /free/estimate-batch: ?recipients=<count>&chain=<slug>
- POST /api/v1/escrow/create: {depositor, beneficiary, token, amount}
- Add spraay_payload module: chain-ID-to-slug map, known token decimals,
and Decimal-based decimal-to-base-unit conversion at the request
boundary; public input schemas (SpraayRecipient address/amount decimal
strings) unchanged
- Free endpoints verified live: validate-batch returns valid:true with
the new shape; estimate-batch returns per-chain estimates
|
Addressed the review in 97d3dd9 and b54fea2: Recipients schema — now a nested SpraayRecipient Pydantic model with required address and amount fields. Also verified all request body shapes against the gateway's openapi spec rather than assuming — this caught additional fixes (chain slugs instead of chain IDs, base-unit amounts, to vs address in validate-batch). Tested end-to-end against the live gateway: free endpoints with real calls, and the paid execute path with a funded wallet completing the full 402 → payment → retry flow successfully. |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_batch_payment_tool.py (1)
106-147: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
_runlacks a docstring despite nontrivial dispatch/validation logic.As per coding guidelines, "Document public APIs and complex logic in Python code."
_runvalidates action/recipients/sender, converts amounts, and dispatches to three different handlers — worth a short docstring summarizing the flow (this mirrors the same gap inspraay_escrow_tool.py's_run).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_batch_payment_tool.py` around lines 106 - 147, Add a concise docstring to SpraayBatchPaymentTool._run describing its validation and normalization of inputs, amount conversion, and dispatch to validate, estimate, or execute handlers. Keep the existing control flow and behavior unchanged.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_payload.py`:
- Around line 18-28: Update the descriptions and docstrings in
spraay_batch_payment_tool.py and spraay_escrow_tool.py to accurately state
support for the nine EVM chains represented by CHAIN_SLUGS, removing Solana and
the overstated “13+”/“14+” claims. Keep chain validation behavior unchanged
unless broader support is intentionally implemented by extending CHAIN_SLUGS.
- Around line 30-54: The token_decimals logic must not assume 18 decimals for
arbitrary contract addresses on the supported non-Base/Ethereum chains. Update
TOKEN_DECIMALS and the surrounding token-decimal resolution used by
token_decimals to cover the supported chain deployments, or resolve ERC-20
decimals dynamically through the gateway/RPC; preserve known native-symbol
handling and ensure supported tokens such as USDC and USDT produce their actual
base-unit amounts.
- Around line 81-99: Update to_base_units to reject non-finite Decimal values
using an is_finite() check immediately after scaling and before comparisons or
conversion. Raise the same ValueError-style invalid-amount error used for
malformed values, ensuring NaN and Infinity are handled consistently by batch
and escrow callers.
In `@lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_x402.py`:
- Around line 76-81: Update post_with_x402 around Account.from_key and
register_exact_evm_client to catch wallet-signing/setup exceptions, including
malformed private keys. Return the same structured payment_required response
used by the missing-key and missing-package branches, preserving the existing
request and successful response flow when setup succeeds.
---
Nitpick comments:
In
`@lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_batch_payment_tool.py`:
- Around line 106-147: Add a concise docstring to SpraayBatchPaymentTool._run
describing its validation and normalization of inputs, amount conversion, and
dispatch to validate, estimate, or execute handlers. Keep the existing control
flow and behavior unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 7a89e15d-8c9f-416b-b26c-113fa8513e1b
📒 Files selected for processing (8)
lib/crewai-tools/src/crewai_tools/__init__.pylib/crewai-tools/src/crewai_tools/tools/spraay_tool/README.mdlib/crewai-tools/src/crewai_tools/tools/spraay_tool/__init__.pylib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_balance_tool.pylib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_batch_payment_tool.pylib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_escrow_tool.pylib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_payload.pylib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_x402.py
🚧 Files skipped from review as they are similar to previous changes (3)
- lib/crewai-tools/src/crewai_tools/tools/spraay_tool/init.py
- lib/crewai-tools/src/crewai_tools/tools/spraay_tool/README.md
- lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_balance_tool.py
| CHAIN_SLUGS: dict[int, str] = { | ||
| 1: "ethereum", | ||
| 56: "bnb", | ||
| 130: "unichain", | ||
| 137: "polygon", | ||
| 8453: "base", | ||
| 9745: "plasma", | ||
| 42161: "arbitrum", | ||
| 43114: "avalanche", | ||
| 60808: "bob", | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Chain support is overstated in the batch/escrow tool docs.
CHAIN_SLUGS supports 9 EVM chains total (including Base/Ethereum), yet spraay_batch_payment_tool.py's docstring/description claim "Base, Ethereum, Solana, and 13+ other chains" and spraay_escrow_tool.py claims "Base, Ethereum, and 14+ other chains." Solana isn't representable at all here since chain_id is an EVM integer and chain_slug only maps EVM IDs — any Solana input will simply fail with "Unsupported chain_id." Agents relying on the tool description to pick a chain will be misled into round-tripping on unsupported chains.
Update the tool descriptions to match the actual supported set (or expand CHAIN_SLUGS if broader support is intended).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_payload.py` around
lines 18 - 28, Update the descriptions and docstrings in
spraay_batch_payment_tool.py and spraay_escrow_tool.py to accurately state
support for the nine EVM chains represented by CHAIN_SLUGS, removing Solana and
the overstated “13+”/“14+” claims. Keep chain validation behavior unchanged
unless broader support is intentionally implemented by extending CHAIN_SLUGS.
- Resolve token decimals dynamically per (chain, token) instead of
silently defaulting unknown tokens to 18: static known-token table ->
gateway token directory (/api/v1/tokens, Base) -> the token contract's
decimals() via public JSON-RPC eth_call, with results cached. If none
resolve, return a clear error rather than guessing (e.g. USDC on
Polygon is 6 decimals and now resolves correctly via RPC; previously
it was mis-scaled by 10^12). Symbol shortcuts are now Base-only since
the same symbol can use different decimals on other chains.
- Reject non-finite amounts in to_base_units: Decimal('NaN')/'Infinity'
previously escaped as InvalidOperation/OverflowError past the
ValueError handlers; now guarded with is_finite() (and scaleb overflow
is mapped to ValueError too).
- Wrap x402 signer initialization (Account.from_key +
register_exact_evm_client) in try/except so a malformed
SPRAAY_WALLET_PRIVATE_KEY returns a structured payment_required
response instead of crashing, matching the sibling failure branches.
- Correct chain claims in docstrings/descriptions: the gateway supports
exactly 9 EVM chains (Base, Ethereum, BNB Chain, Unichain, Polygon,
Plasma, Arbitrum, Avalanche, BOB); removed inaccurate Solana and
13+/14+/15+ chain references in the batch, escrow, and README docs.
Smoke-tested against the live gateway and public RPCs: unknown token on
Polygon errors instead of guessing, USDC on Polygon resolves to 6 via
RPC, NaN/Infinity amounts raise ValueError, malformed wallet key returns
structured JSON, and the existing validate/estimate/execute/escrow
payload shapes are unchanged.
|
Round two addressed in ee3bdfc: Token decimals — removed the static fallback entirely. Decimals now resolve dynamically: known-token table → gateway token directory → on-chain decimals() via RPC, cached per chain+token. Unknown tokens that can't be resolved return a clear error instead of guessing — for a payment tool, refusing to guess beats silently sending 10^12x the wrong amount. Verified live that USDC on Polygon resolves to 6 decimals (the exact case flagged). Chain claims — corrected all docstrings to the 9 EVM chains this tool's interface can actually reach (chain_id is an EVM integer). The Spraay gateway itself serves 15 chains including Solana, Stellar, XRP, and Bitcoin; non-EVM paths are documented at docs.spraay.app. A follow-up could extend the tool to accept chain slugs directly for non-EVM support. Non-finite amounts — to_base_units now rejects NaN/sNaN/±Infinity via is_finite() with a ValueError, and maps scaleb overflow to ValueError as well. Malformed wallet key — key parsing and client registration are wrapped; a bad SPRAAY_WALLET_PRIVATE_KEY now returns the same structured payment_required-style response as the other failure branches instead of raising. Re-verified end-to-end after the changes: live paid execute against the gateway completed the full 402 → payment → retry flow. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_payload.py`:
- Around line 184-195: Update the token handling in the decimals-resolution
logic to remove the token.upper() == "ETH" shortcut from the native-token
condition. Keep NATIVE_ADDRESS mapped to NATIVE_DECIMALS, and allow Base ETH
resolution through BASE_SYMBOL_DECIMALS while requiring NATIVE_ADDRESS on other
chains.
- Around line 236-239: Update the exception handling around Decimal.scaleb in
the amount-scaling logic to catch decimal.Overflow alongside InvalidOperation
and convert both to the existing ValueError with the same structured
invalid-amount message. Ensure Overflow is imported or referenced from the
decimal module, while preserving the existing finite-value guard and exception
chaining.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 6fce6d9d-98d4-4905-b87a-bb957244055f
📒 Files selected for processing (5)
lib/crewai-tools/src/crewai_tools/tools/spraay_tool/README.mdlib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_batch_payment_tool.pylib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_escrow_tool.pylib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_payload.pylib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_x402.py
🚧 Files skipped from review as they are similar to previous changes (4)
- lib/crewai-tools/src/crewai_tools/tools/spraay_tool/README.md
- lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_x402.py
- lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_escrow_tool.py
- lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_batch_payment_tool.py
| if token == NATIVE_ADDRESS or token.upper() == "ETH": | ||
| return NATIVE_DECIMALS | ||
|
|
||
| if not _ADDRESS_RE.fullmatch(token): | ||
| symbol = token.upper() | ||
| if chain_id == BASE_CHAIN_ID and symbol in BASE_SYMBOL_DECIMALS: | ||
| return BASE_SYMBOL_DECIMALS[symbol] | ||
| raise ValueError( | ||
| f"Unknown token symbol {token!r} on chain {chain_id}. Symbol " | ||
| "shortcuts are only supported on Base (8453); pass the token's " | ||
| "contract address (0x...) instead." | ||
| ) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Restrict the ETH symbol shortcut to Base.
ETH returns 18 decimals before the Base-only symbol check, so it is accepted on BNB Chain, Polygon, Avalanche, etc. Both supplied payment callers then forward that raw token value unchanged. Remove the or token.upper() == "ETH" special case; Base already resolves ETH through BASE_SYMBOL_DECIMALS, while other chains can use NATIVE_ADDRESS.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_payload.py` around
lines 184 - 195, Update the token handling in the decimals-resolution logic to
remove the token.upper() == "ETH" shortcut from the native-token condition. Keep
NATIVE_ADDRESS mapped to NATIVE_DECIMALS, and allow Base ETH resolution through
BASE_SYMBOL_DECIMALS while requiring NATIVE_ADDRESS on other chains.
| try: | ||
| scaled = value.scaleb(decimals) | ||
| except InvalidOperation as e: | ||
| raise ValueError(f"Invalid amount {amount!r}: out of range.") from e |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python - <<'PY'
from decimal import Decimal, InvalidOperation, Overflow, localcontext
with localcontext() as context:
context.Emax = 9
try:
Decimal("1e9").scaleb(1)
except Overflow:
print("Confirmed: scaleb() raises decimal.Overflow.")
except InvalidOperation:
raise SystemExit("Unexpected InvalidOperation")
PYRepository: crewAIInc/crewAI
Length of output: 199
Map decimal overflow to ValueError. Decimal.scaleb() can raise decimal.Overflow for finite values with extreme exponents, so that path bypasses the structured input error handling. Catch Overflow here as well; the is_finite() guard only covers non-finite return values.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/crewai-tools/src/crewai_tools/tools/spraay_tool/spraay_payload.py` around
lines 236 - 239, Update the exception handling around Decimal.scaleb in the
amount-scaling logic to catch decimal.Overflow alongside InvalidOperation and
convert both to the existing ValueError with the same structured invalid-amount
message. Ensure Overflow is imported or referenced from the decimal module,
while preserving the existing finite-value guard and exception chaining.
Spraay Payment Tools
Adds three new tools for cryptocurrency payments via the Spraay x402 payment gateway.
Tools
Why this belongs in crewai-tools
CrewAI has 80+ tools for web scraping, databases, search, file I/O, and vector stores — but currently no payment tool. This is the first tool that gives CrewAI agents the ability to handle real financial transactions. Agents can now:
No API key required
The gateway uses the x402 payment protocol. Free endpoints (validate, estimate, balance) just work with no auth. Paid endpoints (execute, escrow) are paid per-request via x402 micropayment — no signup, no API key, no dashboard.
Architecture
0x1646452F98E36A3c9Cfc3eDD8868221E207B5eECrequestsEcosystem
Spraay is integrated into NVIDIA NeMo Agent Toolkit (PRs #20, #27 merged), Google ADK, and AWS Strands.
Docs: https://docs.spraay.app