feat(binance): add spot OpenAPI skill and Ed25519 signer#187
Conversation
Review: PR #187 - feat(binance): add spot OpenAPI skill and Ed25519 signerSummaryThis PR adds Ed25519 query signing support alongside the existing HMAC SHA256 signer, introduces a curated Binance Spot OpenAPI skill, and fixes OpenAPI auth resolution to prevent business query parameters from polluting schema URL fetches. The implementation is well-tested with comprehensive unit tests, CLI integration tests, and skill validation scripts. Overall Assessment: APPROVE with minor suggestions Key FindingsStrengths
IssuesMust Fix (None)No correctness bugs, security issues, or API compatibility concerns identified. Should Fix
Optional Improvements
Testing CoveragePassing Tests
Manual Testing NotedThe PR description mentions live Binance Spot testnet verification for:
This is excellent practice for a financial API integration. Security Considerations
CompatibilityBackward Compatibility
Breaking ChangesNone intentionally introduced, but the stricter HMAC algorithm validation could affect existing configurations. RecommendationsBefore Merge
After Merge
ConclusionThis is a high-quality PR that successfully adds Ed25519 support for Binance Spot API integration while maintaining backward compatibility with HMAC. The OpenAPI auth resolution fix is a valuable improvement that prevents a subtle bug. The comprehensive testing and documentation demonstrate strong engineering practices. Recommendation: APPROVE after addressing the two should-fix items above. |
There was a problem hiding this comment.
Pull request overview
Adds Binance Spot OpenAPI skill support and extends UXC’s auth/signing pipeline to support Binance’s Ed25519 query-signing flow, while tightening auth resolution for OpenAPI operations and preventing business auth from contaminating schema-fetch requests.
Changes:
- Add
ed25519_query_v1signer (PKCS#8 PEM Ed25519, base64 signatures) alongside existing HMAC query signer, plus CLI/unit tests. - Adjust daemon/OpenAPI auth application so OpenAPI execution resolves auth against the final operation URL and schema URL fetching avoids business auth injection.
- Add new
binance-spot-openapi-skillpackage (schema, docs, usage patterns, validation script).
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/auth_binding_cli_test.rs | Adds CLI test coverage for --signer-json with ed25519_query_v1. |
| src/main.rs | Updates help text/examples to include ed25519_query_v1. |
| src/daemon.rs | Separates detection-time vs execution-time auth for OpenAPI; resolves auth using final operation URL. |
| src/auth/mod.rs | Implements Ed25519 query signer config/validation and signing; refactors signer header handling. |
| src/adapters/openapi.rs | Prevents auth being applied to schema URL override requests; adds regression test. |
| skills/binance-spot-openapi-skill/scripts/validate.sh | Adds skill package validation checks (files, docs patterns, schema assertions). |
| skills/binance-spot-openapi-skill/references/usage-patterns.md | Documents link/auth/signing flows for mainnet/testnet with Ed25519 + HMAC. |
| skills/binance-spot-openapi-skill/references/binance-spot.openapi.json | Adds curated OpenAPI 3.1 schema for key Spot endpoints. |
| skills/binance-spot-openapi-skill/agents/openai.yaml | Adds agent metadata for the new skill. |
| skills/binance-spot-openapi-skill/SKILL.md | Adds primary skill documentation and operational guidance/guardrails. |
| Cargo.toml | Adds ed25519-dalek dependency (pkcs8/pem features). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| uxc auth credential set binance-spot-mainnet \ | ||
| --auth-type api_key \ | ||
| --field api_key=env:BINANCE_MAINNET_API_KEY \ | ||
| --field secret_key=env:BINANCE_MAINNET_SECRET_KEY | ||
|
|
||
| uxc auth credential set binance-spot-testnet \ | ||
| --auth-type api_key \ | ||
| --field api_key=env:BINANCE_TESTNET_API_KEY \ | ||
| --field secret_key=env:BINANCE_TESTNET_SECRET_KEY | ||
|
|
||
| uxc auth binding add \ | ||
| --id binance-spot-mainnet \ | ||
| --host api.binance.com \ | ||
| --path-prefix /api/v3 \ | ||
| --scheme https \ | ||
| --credential binance-spot-mainnet \ | ||
| --signer-json '{"kind":"hmac_query_v1","algorithm":"hmac_sha256","signing_field":"secret_key","key_field":"api_key","key_placement":"header","key_name":"X-MBX-APIKEY","signature_param":"signature","signature_encoding":"hex","timestamp_param":"timestamp","timestamp_unit":"milliseconds","canonicalization":{"mode":"preserve_order"}}' \ | ||
| --priority 100 | ||
|
|
||
| uxc auth binding add \ | ||
| --id binance-spot-testnet \ | ||
| --host testnet.binance.vision \ | ||
| --path-prefix /api/v3 \ | ||
| --scheme https \ | ||
| --credential binance-spot-testnet \ |
There was a problem hiding this comment.
The HMAC fallback commands reuse the same credential IDs (binance-spot-mainnet / binance-spot-testnet) as the recommended Ed25519 setup above, so following this section would overwrite the Ed25519 credentials. Use distinct IDs (e.g. *-hmac) or explicitly call out that this replaces the earlier credentials.
| uxc auth credential set binance-spot-mainnet \ | |
| --auth-type api_key \ | |
| --field api_key=env:BINANCE_MAINNET_API_KEY \ | |
| --field secret_key=env:BINANCE_MAINNET_SECRET_KEY | |
| uxc auth credential set binance-spot-testnet \ | |
| --auth-type api_key \ | |
| --field api_key=env:BINANCE_TESTNET_API_KEY \ | |
| --field secret_key=env:BINANCE_TESTNET_SECRET_KEY | |
| uxc auth binding add \ | |
| --id binance-spot-mainnet \ | |
| --host api.binance.com \ | |
| --path-prefix /api/v3 \ | |
| --scheme https \ | |
| --credential binance-spot-mainnet \ | |
| --signer-json '{"kind":"hmac_query_v1","algorithm":"hmac_sha256","signing_field":"secret_key","key_field":"api_key","key_placement":"header","key_name":"X-MBX-APIKEY","signature_param":"signature","signature_encoding":"hex","timestamp_param":"timestamp","timestamp_unit":"milliseconds","canonicalization":{"mode":"preserve_order"}}' \ | |
| --priority 100 | |
| uxc auth binding add \ | |
| --id binance-spot-testnet \ | |
| --host testnet.binance.vision \ | |
| --path-prefix /api/v3 \ | |
| --scheme https \ | |
| --credential binance-spot-testnet \ | |
| uxc auth credential set binance-spot-mainnet-hmac \ | |
| --auth-type api_key \ | |
| --field api_key=env:BINANCE_MAINNET_API_KEY \ | |
| --field secret_key=env:BINANCE_MAINNET_SECRET_KEY | |
| uxc auth credential set binance-spot-testnet-hmac \ | |
| --auth-type api_key \ | |
| --field api_key=env:BINANCE_TESTNET_API_KEY \ | |
| --field secret_key=env:BINANCE_TESTNET_SECRET_KEY | |
| uxc auth binding add \ | |
| --id binance-spot-mainnet-hmac \ | |
| --host api.binance.com \ | |
| --path-prefix /api/v3 \ | |
| --scheme https \ | |
| --credential binance-spot-mainnet-hmac \ | |
| --signer-json '{"kind":"hmac_query_v1","algorithm":"hmac_sha256","signing_field":"secret_key","key_field":"api_key","key_placement":"header","key_name":"X-MBX-APIKEY","signature_param":"signature","signature_encoding":"hex","timestamp_param":"timestamp","timestamp_unit":"milliseconds","canonicalization":{"mode":"preserve_order"}}' \ | |
| --priority 100 | |
| uxc auth binding add \ | |
| --id binance-spot-testnet-hmac \ | |
| --host testnet.binance.vision \ | |
| --path-prefix /api/v3 \ | |
| --scheme https \ | |
| --credential binance-spot-testnet-hmac \ |
| uxc auth credential set binance-spot-mainnet \ | ||
| --auth-type api_key \ | ||
| --field api_key=env:BINANCE_MAINNET_API_KEY \ | ||
| --field secret_key=env:BINANCE_MAINNET_SECRET_KEY | ||
|
|
||
| uxc auth credential set binance-spot-testnet \ | ||
| --auth-type api_key \ | ||
| --field api_key=env:BINANCE_TESTNET_API_KEY \ | ||
| --field secret_key=env:BINANCE_TESTNET_SECRET_KEY | ||
|
|
||
| uxc auth binding add \ | ||
| --id binance-spot-mainnet \ | ||
| --host api.binance.com \ | ||
| --path-prefix /api/v3 \ | ||
| --scheme https \ | ||
| --credential binance-spot-mainnet \ | ||
| --signer-json '{"kind":"hmac_query_v1","algorithm":"hmac_sha256","signing_field":"secret_key","key_field":"api_key","key_placement":"header","key_name":"X-MBX-APIKEY","signature_param":"signature","signature_encoding":"hex","timestamp_param":"timestamp","timestamp_unit":"milliseconds","canonicalization":{"mode":"preserve_order"}}' \ | ||
| --priority 100 | ||
|
|
||
| uxc auth binding add \ | ||
| --id binance-spot-testnet \ | ||
| --host testnet.binance.vision \ | ||
| --path-prefix /api/v3 \ | ||
| --scheme https \ | ||
| --credential binance-spot-testnet \ |
There was a problem hiding this comment.
The HMAC fallback binding examples reuse the same binding IDs and credentials as the Ed25519 section (binance-spot-mainnet/binance-spot-testnet). That can unintentionally replace the Ed25519 binding or mix signers depending on how bindings are stored/updated. Use distinct binding/credential IDs for HMAC (e.g. *-hmac) or document the required removal/replace step.
| uxc auth credential set binance-spot-mainnet \ | |
| --auth-type api_key \ | |
| --field api_key=env:BINANCE_MAINNET_API_KEY \ | |
| --field secret_key=env:BINANCE_MAINNET_SECRET_KEY | |
| uxc auth credential set binance-spot-testnet \ | |
| --auth-type api_key \ | |
| --field api_key=env:BINANCE_TESTNET_API_KEY \ | |
| --field secret_key=env:BINANCE_TESTNET_SECRET_KEY | |
| uxc auth binding add \ | |
| --id binance-spot-mainnet \ | |
| --host api.binance.com \ | |
| --path-prefix /api/v3 \ | |
| --scheme https \ | |
| --credential binance-spot-mainnet \ | |
| --signer-json '{"kind":"hmac_query_v1","algorithm":"hmac_sha256","signing_field":"secret_key","key_field":"api_key","key_placement":"header","key_name":"X-MBX-APIKEY","signature_param":"signature","signature_encoding":"hex","timestamp_param":"timestamp","timestamp_unit":"milliseconds","canonicalization":{"mode":"preserve_order"}}' \ | |
| --priority 100 | |
| uxc auth binding add \ | |
| --id binance-spot-testnet \ | |
| --host testnet.binance.vision \ | |
| --path-prefix /api/v3 \ | |
| --scheme https \ | |
| --credential binance-spot-testnet \ | |
| uxc auth credential set binance-spot-mainnet-hmac \ | |
| --auth-type api_key \ | |
| --field api_key=env:BINANCE_MAINNET_API_KEY \ | |
| --field secret_key=env:BINANCE_MAINNET_SECRET_KEY | |
| uxc auth credential set binance-spot-testnet-hmac \ | |
| --auth-type api_key \ | |
| --field api_key=env:BINANCE_TESTNET_API_KEY \ | |
| --field secret_key=env:BINANCE_TESTNET_SECRET_KEY | |
| uxc auth binding add \ | |
| --id binance-spot-mainnet-hmac \ | |
| --host api.binance.com \ | |
| --path-prefix /api/v3 \ | |
| --scheme https \ | |
| --credential binance-spot-mainnet-hmac \ | |
| --signer-json '{"kind":"hmac_query_v1","algorithm":"hmac_sha256","signing_field":"secret_key","key_field":"api_key","key_placement":"header","key_name":"X-MBX-APIKEY","signature_param":"signature","signature_encoding":"hex","timestamp_param":"timestamp","timestamp_unit":"timestamp","timestamp_unit":"milliseconds","canonicalization":{"mode":"preserve_order"}}' \ | |
| --priority 100 | |
| uxc auth binding add \ | |
| --id binance-spot-testnet-hmac \ | |
| --host testnet.binance.vision \ | |
| --path-prefix /api/v3 \ | |
| --scheme https \ | |
| --credential binance-spot-testnet-hmac \ |
| short_description: "Operate Binance Spot public market, signed account, and order endpoints via UXC with curated OpenAPI mapping and HMAC query signing" | ||
| default_prompt: "Use $binance-spot-openapi-skill to discover and execute Binance Spot REST operations through UXC with separate mainnet/testnet link flows, HMAC signer bindings, and testnet-first write guardrails." |
There was a problem hiding this comment.
This agent metadata describes the skill as using only “HMAC query signing” / “HMAC signer bindings”, but the PR adds and recommends Ed25519 as well. Update the short_description/default_prompt to reflect both signers (or emphasize Ed25519 as recommended) to avoid misleading users.
| short_description: "Operate Binance Spot public market, signed account, and order endpoints via UXC with curated OpenAPI mapping and HMAC query signing" | |
| default_prompt: "Use $binance-spot-openapi-skill to discover and execute Binance Spot REST operations through UXC with separate mainnet/testnet link flows, HMAC signer bindings, and testnet-first write guardrails." | |
| short_description: "Operate Binance Spot public market, signed account, and order endpoints via UXC with curated OpenAPI mapping and Ed25519 (recommended) and HMAC query signing" | |
| default_prompt: "Use $binance-spot-openapi-skill to discover and execute Binance Spot REST operations through UXC with separate mainnet/testnet link flows, Ed25519 (recommended) and HMAC signer bindings, and testnet-first write guardrails." |
src/main.rs
Outdated
| commands: vec![], | ||
| notes: vec![ | ||
| "--signer-json attaches a typed signer config to this binding, for example kind=hmac_query_v1.".to_string(), | ||
| "--signer-json attaches a typed signer config to this binding, for example kind=hmac_query_v1 or kind=ed25519_query_v1.".to_string(), |
There was a problem hiding this comment.
The note says “for example kind=hmac_query_v1 ...”, but --signer-json expects a JSON object (as shown in the examples). Consider rephrasing to something like “e.g. {"kind":"hmac_query_v1", ...}” to avoid implying a non-JSON format is accepted.
| "--signer-json attaches a typed signer config to this binding, for example kind=hmac_query_v1 or kind=ed25519_query_v1.".to_string(), | |
| "--signer-json attaches a typed signer config to this binding, e.g. {\"kind\":\"hmac_query_v1\", ...} or {\"kind\":\"ed25519_query_v1\", ...}.".to_string(), |
040f6a5 to
d1521e4
Compare
What
ed25519_query_v1alongside the existing HMAC query signer for Binance-style signed requestsWhy
Binance Spot testnet now practically needs Ed25519 support for the recommended key flow, and the Spot skill was missing the operational guidance needed to obtain and pair the correct API key with signing material.
How
hmac_query_v1unchanged for compatibilityskills/binance-spot-openapi-skillpackage and validation script-1022mismatch pitfallTesting
bash skills/binance-spot-openapi-skill/scripts/validate.shcargo test auth::tests:: --lib -- --test-threads=1cargo test --test auth_binding_cli_test -- --test-threads=1cargo test daemon::tests:: --lib -- --test-threads=1cargo test openapi::tests:: --lib -- --test-threads=1get:/api/v3/accountpost:/api/v3/order/test