Rebase on main + regenerate READMEs (1 squashed commit, all 9 CI jobs pass locally)#1
Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements the core EIP-712 typed data signing function for API key (agent) mode. Gates on EVM-only, parses typed data JSON before policy evaluation to populate TypedDataContext, and calls EvmSigner::sign_typed_data. Includes 6 integration tests covering happy path, non-EVM rejection, wrong contract denial, malformed JSON, expired key, and wallet scope. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove hard-blocks in ops.rs and sign_message.rs that rejected API key usage for typed data signing. Wire up the dispatcher to delegate to sign_typed_data_with_api_key, and handle the new AllowedTypedDataContracts policy rule in the CLI policy display. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rule Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…t bypass Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix Node.js and Python binding tests: the denied-chain test case used typed data with chainId=8453 but chain="ethereum", which now correctly triggers the new chain mismatch check instead of AllowedChains. Updated tests to use matching chainId so AllowedChains is exercised. - Run cargo fmt to satisfy CI formatting checks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…efactor Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add raw 32-byte hash signing (secp256k1 chains) and EIP-7702 authorization signing (EVM chains) across Rust core, Node, and Python bindings. Both paths support owner-mode and API-key-mode with full policy evaluation. Refactors key_ops to share policy enforcement via enforce_policy_and_decrypt_key_with_raw_hex, eliminating duplicated boilerplate across sign_with_api_key, sign_message_with_api_key, and the new sign_hash_with_api_key. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
parse_quantity_bytes now checks the decimal string length against a conservative upper bound (3 * max_len + 1 digits) before entering the O(n·m) byte-conversion loop. Prevents CPU abuse from million-digit nonce or chain_id strings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merge the two separate `use ows_signer` statements into a single import block, resolving the CI cargo fmt check failure. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Deduplicate the chainId parsing logic that was repeated in the domain validation (step 5b) and TypedDataContext construction (step 6) of sign_typed_data_with_api_key. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Verify that an empty contracts list [] in AllowedTypedDataContracts denies all typed data signing, confirming no accidental allow-all behavior when no contracts are specified. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use consistent terminology across the codebase — the rest of OWS uses 'allowlist', so the AllowedTypedDataContracts docs should too. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move the `import copy` statement from inside the function body to the module-level imports where it belongs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use a shared EVM chain-id helper instead of ad hoc parsing in typed-data and x402 flows. Stop reusing transaction.raw_hex for typed-data JSON bytes and validate the executable policy path against typed_data.raw_json instead. Add Node and Python binding coverage for AllowedTypedDataContracts.
Separate packages for framework-specific adapters: - @open-wallet-standard/viem — owsToViemAccount() creates a viem Account with signing delegated to OWS (key never leaves vault) - @open-wallet-standard/solana — owsToSolanaKeypair() creates a @solana/web3.js Keypair from an OWS wallet (32→64 byte key expansion via @noble/curves ed25519) Tests: 10 viem + 6 solana, all passing locally. CI: two new jobs (node-viem, node-solana) depending on node build.
Single package with subpath exports: - @open-wallet-standard/adapters/viem → owsToViemAccount() - @open-wallet-standard/adapters/solana → owsToSolanaKeypair() Peer deps (viem, @solana/web3.js) are optional — only needed if importing the corresponding adapter. 16 tests passing (10 viem, 6 solana). Addresses review feedback: single package is easier to extend with ethers, CosmJS, wagmi, Sui adapters later.
- Fix raw hex message signing: handle 0x-prefixed hex strings correctly instead of treating them as UTF-8 - Lazy-load adapters in barrel export so solana-only users don't crash from missing viem peer dep (and vice versa)
- signTransaction: serialize TransactionSerializable objects via viem's serializeTransaction() instead of JSON.stringify - package.json exports: use "default" condition instead of "require" so ESM import works - solana adapter: narrow try-catch to only JSON.parse, surface missing ed25519 key as a distinct error
viem's toAccount expects signTransaction to return an RLP-encoded signed transaction (sendRawTransaction-ready). Previously returned just the raw ECDSA signature bytes. Now: serialize tx → keccak256 → sign → re-serialize with r/s/v attached. Test updated to verify EIP-1559 prefix and length.
EIP-1559/2930 transactions need yParity (0 or 1), not legacy v (27/28). Pass raw recovery byte as yParity to serializeTransaction.
OWS sign_transaction already applies keccak256 internally. Pass raw serialized tx bytes instead of pre-hashing, which was producing keccak256(keccak256(tx)) — invalid signatures.
Use result.recovery_id from OWS SignResult for yParity, with fallback to parsing from signature bytes if not present.
viem's toAccount always passes TransactionSerializable objects, never raw strings. Remove the string branch that would silently produce corrupt output by serializing an empty object.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…m-account feat: add @open-wallet-standard/adapters (viem + solana)
feat: add Nano (XNO) chain support
…istake_x402 fix: printing mistake while executing x402 payments
…712-api-key-signing feat: EIP-712 typed data signing via API key
Register Tempo (eip155:4217) and Hyperliquid (eip155:999) as known EVM chains with friendly name aliases and default RPC endpoints.
…eip7702 # Conflicts: # bindings/node/__test__/index.spec.mjs # bindings/python/tests/test_bindings.py # ows/crates/ows-lib/src/key_ops.rs
…/nj/wdk-integration feat: native wdk integration with ows
No behavioral changes. Applies rustfmt to bindings/node/src/lib.rs and bindings/python/src/lib.rs.
…chain-alias feat: add Tempo and Hyperliquid chain aliases
…n-hash-and-eip7702 feat: add signHash and signAuthorization
…/chore/bump-version-1.3.0 chore: bump version to 1.3.0
…formatting style: run cargo fmt on node and python SDK bindings
…/nj/publish-npm-adaptors-package feat: publish npm adaptors package
…/chore/bump-version-1.3.1 chore: bump version to 1.3.1
…/nj/add-adapters-readme Nj/add adapters readme
…/chore/bump-version-1.3.2 chore: bump version to 1.3.2
Closes open-wallet-standard#219 Adds NEAR Protocol as a supported chain in OWS. Ed25519 over canonical Borsh transactions, with SHA-256 pre-hash before signing. Genesis-agnostic signer (network binding lives in Transaction.block_hash, same model Algorand uses for `gh`). ## Chain spec ChainType: Near CAIP-2: near:mainnet, near:testnet BIP-44 coin type: 397 (SLIP-44) Curve: Ed25519 (existing Curve::Ed25519) Default derivation path: m/44'/397'/{index}' (NEAR Foundation, hardened) Address (implicit): 64-char lowercase hex of the ed25519 pubkey TX serialization: Borsh TX signing preimage: Ed25519(SHA-256(borsh(Transaction))) encode_signed_transaction: borsh(Transaction) || 0x00 || sig64 signMessage (V1): raw ed25519 over message bytes (parity with Solana). NEP-413 follow-up tracked. Default RPC: https://rpc.{mainnet,testnet}.near.org ## Files (23 changed, +702 / -50) Core implementation: - ows-signer/src/chains/near.rs (new) — NearSigner, 15 inline tests - ows-signer/src/chains/mod.rs — module + factory registration - ows-core/src/chain.rs — ChainType::Near, KNOWN_CHAINS rows, namespace, coin_type, FromStr, Display, serde tests, parse_chain test. Also fixes pre-existing Spark omission from ALL_CHAIN_TYPES (was [10] now [12]). - ows-core/src/config.rs — default RPC URLs - ows-lib/src/near_rpc.rs (new) — broadcast_tx_commit JSON-RPC helper. Sanitized error messages: never embeds raw RPC response payload in Display output (would leak operational data — tx details, account identifiers — into logs/UI). - ows-lib/src/lib.rs, ops.rs — module export, broadcast dispatch, 3 integration-test loops include "near". - ows-pay/src/discovery.rs — format_near() with yoctoNEAR divisor (10^24 = 1 NEAR), wired into format_price(). 6 unit tests. Bindings tests: - bindings/node/__test__/index.spec.mjs — "near" in chain coverage, account count 10 -> 12 (Spark omission fix), spark:* assertion. - bindings/python/tests/test_bindings.py — same pattern, also fixes pre-existing missing "xrpl" in derive-all loop. Documentation (DUAL — docs/ AND website-docs/md/ kept in sync): - 07-supported-chains.md: chain families table, non-EVM networks, shorthand aliases, HD derivation tree. - 02-signing-interface.md: chain-specific signMessage / signTransaction semantics for NEAR. README normalization: - ows/README.md, bindings/{node,python}/README.md, readme/templates/{ows,node,python}.md, readme/partials/{supported-chains,why-ows}.md, skills/ows/SKILL.md — chain enumerations now consistently include Spark, Nano, NEAR (also fixed pre-existing Nano omissions). ## Why these design choices - No new dependencies. ed25519-dalek, sha2, hex, bs58, base64 are already in the workspace. We do NOT pull near-primitives (heavy: tokio + dozens of transitive crates). NearSigner is ~330 LoC. - Implicit account, not named. derive_address returns the implicit account ID (hex(pubkey)). Named accounts (alice.near) require on-chain registration and are out of scope for a stateless signer. - HD derivation reuses existing SLIP-10. NEAR's hardened-only path works through the existing ed25519 SLIP-10 implementation in hd.rs. No new HD machinery (in contrast to Algorand PR open-wallet-standard#124 which needed BIP32-Ed25519 with Peikert). - Stateless signing. block_hash inside the Transaction binds it to a network, so the signer doesn't need a network parameter at signing time. Same model Algorand PR open-wallet-standard#124 uses. ## Production reference A production x402 facilitator with full NEAR support runs at facilitator.ultravioletadao.xyz, source at UltravioletaDAO/x402-rs (Rust, ~600 LoC NEAR implementation). It uses NEP-366 SignedDelegateAction for gasless meta-transactions on the facilitator side; this PR provides the underlying signer primitives. Meta-tx wrapping belongs in ows-pay as a follow-up. ## Test strategy - 15 unit tests inline in chains/near.rs covering trait properties, derivation, RFC 8032 vector 1 implicit address, sign/verify roundtrip, determinism, sign_message parity, invalid key length, sha256 prehash semantics, encode_signed layout, sig length rejection, empty input rejection, full extract -> sign -> encode pipeline. - Byte-parity test against near-api-js test/unit/transactions/data/ transaction1.json: hard-coded canonical Transaction borsh hex (transfer test.near -> whatever.near, nonce=1). Verifies extract_signable_bytes is identity AND encode_signed_transaction emits exactly tx_bytes || 0x00 || sig64 matching near-api-js's borsh(SignedTransaction) layout. - 6 format_near unit tests: whole / fractional / zero / one yoctoNEAR / typical NEP-141 storage deposit / non-numeric input. - 3 ops.rs integration loops include "near" (derive_address_all_chains, mnemonic_wallet_sign_message_all_chains, mnemonic_wallet_sign_tx_all_chains). CI gates verified locally: cargo fmt --all --check clean cargo clippy --workspace --all-targets -- -D warnings clean cargo test --workspace 604 passed .githooks/pre-commit pass ## Out of scope (tracked as follow-ups) - NEP-413 prefixed message signing (V1 sign_message is raw ed25519 for parity with Solana; NEP-413 is a structurally distinct flow). - NEP-366 SignedDelegateAction (belongs in ows-pay, not the signer). - Named-account resolution (alice.near -> AccountId requires RPC). - Live testnet broadcast smoke test (Nano open-wallet-standard#109 didn't include one either; can be added behind #[ignore] later). References: - near-api-js: https://github.com/near/near-api-js - NEP-413: https://github.com/near/NEPs/blob/master/neps/nep-0413.md - NEP-366: https://github.com/near/NEPs/blob/master/neps/nep-0366.md - SLIP-44 coin type 397: https://github.com/satoshilabs/slips/blob/master/slip-0044.md - Nano PR open-wallet-standard#109 (merged) — closest structural template - Algorand PR open-wallet-standard#124 (open) — sibling ed25519 chain addition Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…near-chain-support feat: add NEAR Protocol chain support (Ed25519 + Borsh + NEP-413)
…enerated This is a rebase of open-wallet-standard#181 (soumyacodes007/feature/stellar-integration) onto current main (post NEAR + Spark merges). All three of soumyacodes007's original commits (03edec5, 4160e9e, 4b5c554) are squashed here to keep the PR a single clean commit on top of the latest main. Original Stellar work: - Ed25519 signing with hardened SEP-0005 derivation m/44'/148'/{index}' - StrKey Base32 address encoding (G...) — 56 chars - Canonical TransactionSignaturePayload XDR signing (handles TxV0, Tx, TxFeeBump variants) - encode_signed_transaction wraps the signature as DecoratedSignature inside a TransactionEnvelope, broadcastable to Horizon - testnet/mainnet network passphrase isolation via signer_for_chain_id(chain_type, chain_id) — addresses @njdawn's original review finding - Stellar broadcast helper (Horizon submit-transaction), Friendbot testnet faucet support in ows fund - Stellar fixture for the cross-chain sign_transaction integration test Conflicts resolved during the rebase: - ows-core/src/{chain.rs, config.rs}: ChainType::Stellar added alongside Nano + Near; ALL_CHAIN_TYPES bumped to [13]; KNOWN_CHAINS gains stellar/stellar-testnet; namespace/coin_type/from_namespace/Display/ FromStr/serde tests extended with stellar - ows-signer/src/chains/mod.rs: Stellar arm joined the Nano + Near arms in the chain match - ows-lib/src/key_ops.rs, src/ops.rs: imports merged (signer_for_chain_info now exported alongside signer_for_chain), broadcast_stellar joined the broadcast dispatch alongside broadcast_nano + broadcast_tx_commit for NEAR - ows-lib/Cargo.toml: stellar-xdr dev-dependency kept; ows-signer pinned to =1.3.2 (current workspace version) - All 7 generated READMEs (bindings/{node,python}/README.md, ows/README.md, and the 4 ows/crates/*/README.md files) regenerated via ./readme/generate.sh — readme job verified locally with --check - bindings/{node,python} tests: universal wallet count 12 -> 13; stellar:* startswith assertion added; "stellar" added to the derive-all chain coverage loop - docs/07-supported-chains.md: chain families table + non-EVM networks + shorthand aliases + HD derivation tree all gain Stellar entries - readme/templates/ows.md, readme/partials/supported-chains.md: Stellar appended after NEAR CI gates verified locally after rebase: - cargo fmt --all --check clean - cargo clippy --workspace --all-targets -- -D warnings clean - cargo test --workspace 640 passed, 0 failed - ./readme/generate.sh --check clean Original PR: open-wallet-standard#181 Closes review feedback: @njdawn 2026-04-04 Co-Authored-By: 0xultravioleta <0xultravioleta@gmail.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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 |
Hi @soumyacodes007 — as discussed in #181 comment, rebased your branch onto current main (post NEAR + Spark merges) so the upstream PR is mergeable again.
Squash strategy
Your three commits (
03edec5,4160e9e,4b5c554) are squashed into a single commit on top of main, with you preserved as the primary author (0xrick <rickbhowmik4@gmail.com>) viagit commit --author. I added myself + Claude asCo-Authored-By. The single-commit form mirrors how @njdawn merged the NEAR PR last night.Conflicts resolved during the rebase
Main moved with the NEAR + Spark merge so most conflicts were "combine NEAR/Nano arms with Stellar arms":
ows-core/src/chain.rs—ChainType::Stellaradded alongsideNano+Near;ALL_CHAIN_TYPESis now[13];KNOWN_CHAINSgainsstellar+stellar-testnet; namespace/coin_type/from_namespace/Display/FromStr/serde tests extendedows-signer/src/chains/mod.rs— Stellar arm joined the chain matchows-lib/src/key_ops.rs,src/ops.rs—signer_for_chain_infoimport merged alongsidesigner_for_chain;broadcast_stellarjoined the dispatchows-lib/Cargo.toml—stellar-xdrdev-dep kept,ows-signerpinned to current workspace version=1.3.2./readme/generate.sh(this is the gate that failed on the original CI before, now passes)docs/07-supported-chains.md+readme/templates/ows.md+readme/partials/supported-chains.md— Stellar appended after NEAR everywherebindings/{node,python}tests — universal wallet count12 → 13,stellar:*assertion addedCI gates verified locally on the new commit
What this gets you
When you merge this PR into your
feature/stellar-integrationbranch, it propagates to upstream PR open-wallet-standard#181 as a single rebased commit on top of main. Thereadmejob that's been silently failing will pass, and open-wallet-standard#181 becomes mergeable. @njdawn should then be able to merge it directly.If you'd rather a different squash policy (e.g., keep your 3 commits + my rebase fix as a 4th), let me know and I'll restructure.
Two community members (including @0xsnackbaker) are pinging on open-wallet-standard#181 asking about the merge timeline — this should unblock it.