Releases: ProjectOpenSea/tool-sdk
Release list
v0.29.0
What's changed
Breaking. A paid tool whose settlement fails now returns 502 without the output, instead of 200 with the result. createToolHandler gains settlement, defaulting to "required". Set settlement: "best-effort" to restore the previous behavior, which only suits callers who reconcile failed settlements out of band. This is a minor version because the package is pre-1.0, not because the change is small.
Also in this release:
replayGuardon the hosted x402 gates andpaidPredicateGate, an optional single-use claim over each authorization's(payer, nonce)pair. Off by default, since it needs storage shared across instances.RPC_URLis resolved as a universal RPC fallback for all wallet providers.- Hostnames are resolved and re-checked against private ranges before anything is fetched, in
probe-endpointand ininspect. The previous guard only inspected the hostname string, so a public name whose A record points inward was fetched.inspectmatters most here because itsmetadataURIcomes from a permissionlessly writable registry. A DNS-rebinding window remains and needs a connect-time-pinned dial. deployrunsvercel linkandvercel env addby argv rather than building a shell string. It interpolated the working directory'spackage.jsonname, variable names parsed from.env.local.example, andvercel whoamioutput into a string passed toexecSync.- The usage reporters refuse a plaintext aggregator URL consistently. Only one of the three checked, while all three send an
x-api-keyand one forwards a signed authorization.
Community contributions
- Shell interpolation in
deploy, thanks @ygd58 for the fix (#18) and @bilguunbicktivism for the report (#14), which identified all three call sites and recommended the argv approach used here. - Lexical-only private address guard, thanks @ygd58 for the fix (#19) and @bilguunbicktivism for the report (#13), which demonstrated the bypass through
inspect.
Full changelog: ProjectOpenSea/opensea-devtools@tool-sdk-v0.28.5...tool-sdk-v0.29.0
v0.28.5
What's Changed
- Normalize x402 registry references to the public usage-reporting source tokens.
Full Changelog: ProjectOpenSea/opensea-devtools@tool-sdk-v0.28.4...tool-sdk-v0.28.5
v0.28.4
What's Changed
- Reject negative and malformed x402 payment amounts. A negative
maxAmountRequiredpreviously slipped under the signed-BigIntmaxAmountcap check and, when signed, wrapped into a huge positiveuint256EIP-3009 authorization, bypassing the caller's spending limit. Amounts are now validated as canonical non-negative integers invalidatePaymentRequirements(unconditionally, even without a cap) and again in the EIP-3009 signer as defense-in-depth for directsignX402Paymentcallers. (#530) - Updated dependency
@opensea/wallet-adaptersto 0.3.3 (EIP-712 encoding hardening).
Full Changelog: ProjectOpenSea/opensea-devtools@tool-sdk-v0.28.3...tool-sdk-v0.28.4
v0.28.3
What's Changed
- fix(tool-sdk): scope predicate gate reads to the configured chain (#520):
predicateGate/paidPredicateGateno longer force reads to the Base RPC whenrpcUrlis unset, so a non-Base registry chain is actually queried. The x402 identity/payment chain (Base/Base-Sepolia) is decoupled from the registry chain so non-Base gating no longer fails closed. Includes regression tests for a non-Base registry with Base identity/payment.
Full Changelog: ProjectOpenSea/opensea-devtools@tool-sdk-v0.28.2...tool-sdk-v0.28.3
v0.28.2
What's Changed
Security and hardening patch release.
Security
paidAuthenticatedFetchper-invocationmaxAmountcap (#508): at most one nonzero x402 authorization is signed per call, and cumulative authorized value can never exceedmaxAmount. Closes a double-challenge bypass where a malicious tool could obtain two independently-settleable authorizations, each under the cap.verifyXPaymentAuthhardening (#509): the freepredicateGaterejects non-zero-value X-Payment authorizations,validBeforeis capped to 1h, the resolved chainId is pinned to the gate's chain, and the operator-recipient check fails closed when unset.inspectmetadataURI SSRF guard (#511): validate the registry-suppliedmetadataURIbefore fetching (http(s) + reject private/internal hosts).isPrivateHostnamenow numerically parses IP literals, closing decimal/octal/hex/partial-dotted IPv4 and IPv4-mapped IPv6 encoding bypasses, and covers 0.0.0.0/8, link-local 169.254.0.0/16, CGNAT 100.64.0.0/10, and IPv6 unique-local fc00::/7.
Fixes
- Audit findings (#510): pin EIP-712 domain name/version for canonical USDC, surface the default registry lookup-block window, cache resolved manifests in
createToolHandler, and decouple caller API-key provisioning from per-request abort signals.
Community Contributions
- Thanks to @Nexory for reporting the
inspectmetadataURI SSRF that #511 fixes (tool-sdk#12).
Full Changelog: ProjectOpenSea/opensea-devtools@tool-sdk-v0.28.1...tool-sdk-v0.28.2
v0.28.1
What's Changed
Security
eip3009AuthenticatedFetchnow validates the 402 challenge'sassetandnetworkbefore signing: the network must be supported and the asset must be the canonical USDC contract for that network. This closes a signature-phishing surface where a zero-value challenge could name an arbitrary verifying contract / EIP-712 domain and still get signed (#507).eip3009AuthenticatedFetchenforces the documented zero-value guarantee: it only signsX-Paymentauthorizations withvalue: 0, and returns non-zero (or unparseable-amount) 402 challenges as-is instead of signing an authorization that could move USDC to the server's advertisedpayTo(#504).
Internal
- Deduplicate CLI command boilerplate: shared
WALLET_PROVIDER_OPTION_DESCRIPTIONconstant andparseToolId()helper incli/commands/shared.ts. No behavior change (#501). - Deduplicate predicate-client boilerplate: shared
openSeaAssetLinks()helper plus typedread()/write()helpers onBasePredicateClient. No behavior change (#503).
Community Contributions
- Thanks to @Nexory for raising the x402-signing hardening that motivated the
eip3009AuthenticatedFetchasset/network and zero-value validation in this release (tool-sdk#11).
Full Changelog: ProjectOpenSea/opensea-devtools@tool-sdk-v0.28.0...tool-sdk-v0.28.1
v0.28.0
What's Changed
- Add Robinhood Chain (4663) support:
--network robinhoodon all CLI commands (custom viem chain definition until viem ships one) and 4663 added to every canonicalDeployment.chainsarray inchains.ts. - Fix x402 CAIP-2 network handling asymmetry: server-side predicate gates now accept CAIP-2 (
eip155:8453) and numeric (8453) network identifiers in theX-Paymentpayload, and the client normalizes the v1 payloadnetworkto the canonical short name. - Fix x402 usage reporting when the facilitator returns a CAIP-2/numeric network:
settle()resolves the settlement network viaresolveNetwork, sosettlementChainIdis populated foreip155:8453/8453responses. - tool-registry: add an explicit Etherscan v2
urlto themonadentry infoundry.tomlsoforge script --verifyconfig resolution no longer aborts.
Full Changelog: ProjectOpenSea/opensea-devtools@tool-sdk-v0.27.0...tool-sdk-v0.28.0
v0.27.0
What's Changed
- feat: add Monad (chain 143) support. The
--networkflag now acceptsmonadin addition tobase,mainnet,shape, andabstract. Monad is defined locally (mirroring viem's definition) because the pinned viem version predates Monad mainnet.143is added to everyDeployment.chainsarray inchains.ts, and the deployed-address docs are updated: the canonical v0.2 addresses are identical on Monad (verified via CREATE2 dry-run). (#477)
Full Changelog: ProjectOpenSea/opensea-devtools@tool-sdk-v0.26.1...tool-sdk-v0.27.0
v0.26.1
What's Changed
- Fix
createBankrAccountreading the wrong shape from Bankr's/wallet/me. The endpoint returns{ wallets: [{ chain, address }, ...] }(no top-leveladdress), so the account was created with an undefined address. Now resolves the EVM entry fromwallets[]. (#473) - Picks up the
@opensea/wallet-adapters@0.3.2dependency bump (BigInt EIP-712 signing fix).
Full Changelog: ProjectOpenSea/opensea-devtools@tool-sdk-v0.26.0...tool-sdk-v0.26.1
v0.26.0
What's Changed
Minor Changes
- BREAKING: Unify
predicateGateto use the standard 402 + X-Payment (EIP-3009) auth flow only (#471).PredicateGateConfig.operatorAddressis now required (was optional)Authorization: EIP-3009 <token>header is no longer accepted: use the X-Payment header via the 402 challenge flowAuthorization: SIWE <msg>.<sig>header is no longer accepted (was already deprecated)- CLI
dry-run-predicate-gatenow requires--operator-addressand asserts a 402 response
Fixes
- Use the Bankr
/wallet/meendpoint instead of/wallet/info(#470).
Full Changelog: ProjectOpenSea/opensea-devtools@tool-sdk-v0.25.0...tool-sdk-v0.26.0