feat(tnt-core-v0.13.0): bind quotes to requester (Solidity, proto, TS, Rust)#71
Merged
Merged
Conversation
DebugEip712 / DebugSign hand-roll a Types.QuoteDetails literal so they need the new `requester` field set explicitly. Use address(0xbEEF) as the placeholder — address(0) is rejected by SignatureLib. Also refresh the hardcoded QUOTE_TYPEHASH string in DebugEip712 so the on-chain digest matches the keccak-printed value. Refs: tangle-network/tnt-core#124, #125
Mirrors tnt-core v0.13.0 which binds the requester address into the EIP-712 typed data for both QuoteDetails and JobQuoteDetails. The on-chain verifier rejects wildcard address(0). Field numbers are appended (not renumbered) to preserve wire compat for in-flight clients during rollout. Regenerate `arena/src/lib/gen/pricing_pb.ts` via `pnpm exec buf generate`. Refs: tangle-network/tnt-core#124, #125
The on-chain createServiceFromQuotes tuple now leads with `requester` and
the contract enforces it equals msg.sender (and rejects address(0)).
Wire that through end-to-end:
- abis.ts: prepend `{ name: 'requester', type: 'address' }` to the quote
details tuple components for createServiceFromQuotes
- useQuotes.ts: surface `requester` on OperatorQuote.details, take a
`requester?: Address` argument so the hook holds the fetch until the
wallet is connected, and read the operator-signed value from the
pricing-engine response (falling back to the caller's address — a
mismatch will fail on-chain verification, which is the desired
behaviour)
- provision.tsx: pass userAddress into useQuotes and forward
q.details.requester into the on-chain tuple as the first field
Refs: tangle-network/tnt-core#124, #125, blueprint-sdk#1406
tnt-core v0.13.0 requires a non-zero requester bound into every job quote signature. Update the REST job-quote handlers to: - accept `requester: Option<String>` on JobQuoteRequest (Option keeps wire compat for staged rollout) - echo the requester back in the JSON response so callers spot a missing/zero requester before they hit the on-chain reject - log a warning + default to address(0) when the field is omitted, so the on-chain verifier rejects (defensive — never silently wildcard-sign) The actual signed quotes still come from the gRPC pricing engine; these REST endpoints are informational helpers for dashboards / non-gRPC integrations. Refs: tangle-network/tnt-core#124, #125, blueprint-sdk#1406
8 tasks
tangletools
pushed a commit
that referenced
this pull request
May 20, 2026
…pipeline Brings the per-domain Nix profile + Cachix workflow pattern over from the ai-agent-sandbox-blueprint repo (where it landed in #71 and is now the shared cache anchor on `tangle-sandbox`). Same closure structure, same nixpkgs pin (nixos-24.11), same Cachix instance — so transitive store paths (glibc, openssl, mold, clang, rust toolchain, foundry, …) hit the cache on cold runs here too. ## File layout nix/system.nix ~66 libs/linkers/SDK frameworks nix/cli.nix ~79 modern + GNU CLIs nix/rust.nix ~39 toolchain + cargo plugins nix/js.nix ~25 node/bun/deno + TS + bundlers nix/python.nix ~105 Python 3.12 + ML/AI/web stack nix/go.nix ~17 go + linters + gRPC plugins nix/cpp.nix ~25 llvm/clang/gdb/lldb/cmake/meson nix/crypto-evm.nix ~8 foundry/solc/slither/echidna nix/crypto-l1.nix ~5 solana/anchor/bitcoin clients nix/crypto-zk.nix ~2 circom nix/ai.nix ~3 ollama/llama-cpp nix/mobile.nix ~6 watchman/flutter/jdk/gradle nix/databases.nix ~15 postgres/mariadb/sqlite/redis/duckdb nix/infra.nix ~35 docker/k8s/helm/terraform/clouds nix/observability.nix ~7 prometheus/loki/otel/vector nix/media.nix ~10 ffmpeg/imagemagick/proto/capnp nix/language-servers.nix ~16 shellcheck/marksman/nil/etc ## Adaptations for this repo - `devShells.sidecar-harness` dropped (this repo has no `sidecar/nix/harness-profile.nix`). - `buildEnv` profile name renamed `ai-trading-blueprint-${name}` so store-path debug output is unambiguous when both repos contribute closures to the same Cachix. - Workflow trigger paths unchanged (`flake.{nix,lock}`, `rust-toolchain.toml`, `nix/**`, `sidecar/nix/**`) — sidecar globs are harmless no-ops here. ## Verification nix flake check --no-build all 14 checks pass (2 devShells + 12 packages) ## Prerequisite `CACHIX_AUTH_TOKEN` repo secret. Without it the workflow still builds + verifies but the push step is skipped. ## What this PR does NOT do Wiring `ci.yml` to consume the cache via `nix develop --command` is deferred to a separate refactor.
drewstone
added a commit
that referenced
this pull request
May 21, 2026
… perp strategy) (#78) * feat(hyperliquid): add dedicated perp strategy type * feat(hyperliquid): route API calls by bot account * feat(hyperliquid): submit CoreWriter API wallet approvals * feat(contracts): add Hyperliquid vault stack * feat(hyperliquid): reconcile nav and enforce bot modes * feat(provision): carry validation trust and signer quorum * feat(arena): add Hyperliquid vault controls * fix(tangle): alias EVM job metadata * feat(hyperliquid): read vault accounting from HyperCore * feat(hyperliquid): add withdrawal settlement API * feat(operator): proxy Hyperliquid settlement endpoints * feat(arena): surface Hyperliquid settlement state * feat(runs): persist workflow run history * feat(arena): paginate bot run history * feat(vault): support HyperEVM withdrawal queueing * feat(hyperliquid): tune perp workflow runtime * fix(local): align HyperEVM deploy signer setup * fix(hyperliquid): bind approvals to lane account * Harden Hyperliquid validator e2e deployment * Add Hyperliquid safety and promotion gates * Add self improvement loop artifacting * Stress test self improvement loop * Require persisted paper evidence for promotion * Clean up validation tests and clippy warnings * fix(hyperevm): harden vault primitives and asset support * fix(hyperliquid): harden live API account lanes * fix(arena): harden HyperEVM vault configuration * fix(hyperliquid): harden vault accounting and NAV guards * Add sandbox lineage for self-improving bots * Add in-sandbox self-improvement orchestrator * fix(hyperliquid): enforce mode refresh and fund quorum * Add local self-improvement MCP server * Port auto-dev loop into sandbox MCP * Harden self-improvement MCP execution * Strengthen self-improvement coding contract * Add revision arena surface * Bind paper evidence to sandbox revisions * Prove revision lifecycle isolation * fix(hyperliquid): make withdrawal settlement retry safe * fix(ci): resolve hyperliquid PR gates * Update trading sandbox runtime primitives * Use blueprint sidecar image defaults * chore(nix): port cacheable multi-language toolchain profile + Cachix pipeline Brings the per-domain Nix profile + Cachix workflow pattern over from the ai-agent-sandbox-blueprint repo (where it landed in #71 and is now the shared cache anchor on `tangle-sandbox`). Same closure structure, same nixpkgs pin (nixos-24.11), same Cachix instance — so transitive store paths (glibc, openssl, mold, clang, rust toolchain, foundry, …) hit the cache on cold runs here too. ## File layout nix/system.nix ~66 libs/linkers/SDK frameworks nix/cli.nix ~79 modern + GNU CLIs nix/rust.nix ~39 toolchain + cargo plugins nix/js.nix ~25 node/bun/deno + TS + bundlers nix/python.nix ~105 Python 3.12 + ML/AI/web stack nix/go.nix ~17 go + linters + gRPC plugins nix/cpp.nix ~25 llvm/clang/gdb/lldb/cmake/meson nix/crypto-evm.nix ~8 foundry/solc/slither/echidna nix/crypto-l1.nix ~5 solana/anchor/bitcoin clients nix/crypto-zk.nix ~2 circom nix/ai.nix ~3 ollama/llama-cpp nix/mobile.nix ~6 watchman/flutter/jdk/gradle nix/databases.nix ~15 postgres/mariadb/sqlite/redis/duckdb nix/infra.nix ~35 docker/k8s/helm/terraform/clouds nix/observability.nix ~7 prometheus/loki/otel/vector nix/media.nix ~10 ffmpeg/imagemagick/proto/capnp nix/language-servers.nix ~16 shellcheck/marksman/nil/etc ## Adaptations for this repo - `devShells.sidecar-harness` dropped (this repo has no `sidecar/nix/harness-profile.nix`). - `buildEnv` profile name renamed `ai-trading-blueprint-${name}` so store-path debug output is unambiguous when both repos contribute closures to the same Cachix. - Workflow trigger paths unchanged (`flake.{nix,lock}`, `rust-toolchain.toml`, `nix/**`, `sidecar/nix/**`) — sidecar globs are harmless no-ops here. ## Verification nix flake check --no-build all 14 checks pass (2 devShells + 12 packages) ## Prerequisite `CACHIX_AUTH_TOKEN` repo secret. Without it the workflow still builds + verifies but the push step is skipped. ## What this PR does NOT do Wiring `ci.yml` to consume the cache via `nix develop --command` is deferred to a separate refactor. * Add trading agent persona eval suite * Add live Polymarket price-history eval * Add second-order market-structure trading evals * Add third-order adaptive trading evals * refactor(hyperliquid): slim vault role management * chore(hyperevm): add fixed gas vault deployment flow * fix(runs): recover archived sidecar transcripts * fix(portfolio): use Hyperliquid NAV for live perps * fix(arena): allow partial HyperEVM vault config * fix(ci): use current tnt-core remapping * Migrate trading eval infra to TypeScript (#83) * feat(deploy): Base Sepolia support in RegisterBlueprint script (#86) * feat(deploy): Base Sepolia support in RegisterBlueprint script RegisterBlueprint.s.sol previously hardcoded Ethereum mainnet addresses (WETH/USDC/USDT/DAI/WBTC, Aave aTokens, Chainlink USD feeds) and a fixed Anvil-snapshot Tangle address. Pointing it at the deployed Base Sepolia Tangle would have either reverted on dead-address ERC20 calls or registered a blueprint pointing at non-existent tokens. This change: - Introduces a TokenSet struct and per-chain helpers (_localTokens, _sepoliaTokens, _mainnetTokens). Selection happens via block.chainid with an optional TARGET_NETWORK env override. Unknown chain ids revert with a clear message. - Makes the Tangle proxy address env-overridable via TANGLE_CORE, falling back to the local Anvil-snapshot deterministic address. - Wires Base Sepolia (chainId 84532) with WETH (0x4200000000000000000000000000000000000006), USDC (0x036CbD53842c5426634e7929541eC2318f3dCF7e), and the Chainlink ETH/USD feed (0x4aDC67696bA383F43DD60A9e78F2C97Fbbfc7cb1). USDC/USD has no Base Sepolia Chainlink feed, and USDT/DAI/WBTC/aWETH/aUSDC/ aDAI have no Base Sepolia equivalents — all left as address(0) and structurally skipped by every wiring helper (ChainlinkUsdValuator .setFeed and WrappedAssetValuator.setUnderlying both revert on address(0), so guards are required, not just convenient). - Gates the hardcoded 100 ETH USER_ACCOUNT funding behind _isLocalChain() so live deploys don't burn real ETH on Sepolia. - Adds deploy/register-blueprint.sh wrapper that loads TANGLE_CORE from deploy/manifests/base-sepolia/tnt-core.latest.json (via the existing load-base-sepolia-env.sh helper) and defaults to dry-run. Local Anvil flow is unchanged: _localTokens() returns a zeroed TokenSet, which is the same shape as the original !usingExistingAssets path (everything routes through MockERC20s). forge build clean. forge test: 621 tests pass. * chore(fmt): forge fmt HyperliquidVaultRoleCompat.t.sol Pre-existing diff caught by the pre-push fmt hook; one-line + one-stmt reflow only, no logic changes. Unblocks the Base Sepolia branch push. --------- Co-authored-by: Drew Stone <drewstone329@gmail.com> * fix(metadata): point Base Sepolia iframe contract at deployed Tangle proxy (#85) Same fix as the sibling ai-agent-sandbox-blueprint PR: the `blueprintUi.externalApp.iframe.contracts[chainId=84532].address` field carried a stale placeholder (`0x1be58d12…`) from a prior Tangle deployment that no longer exists. Tangle is now live on Base Sepolia at `0xC9b0716a187072be0f38A5D972392C6479b9Cfe3` — update the metadata so the iframe grants resolve to the actual deployed contract. LocalTestnet (chainId 31337) address is unchanged. Co-authored-by: Drew Stone <drewstone329@gmail.com> --------- Co-authored-by: Drew Stone <drewstone329@gmail.com> Co-authored-by: tangletools <hello@tangle.tools>
drewstone
added a commit
that referenced
this pull request
May 22, 2026
* feat(hyperliquid): add dedicated perp strategy type * feat(hyperliquid): route API calls by bot account * feat(hyperliquid): submit CoreWriter API wallet approvals * feat(contracts): add Hyperliquid vault stack * feat(hyperliquid): reconcile nav and enforce bot modes * feat(provision): carry validation trust and signer quorum * feat(arena): add Hyperliquid vault controls * fix(tangle): alias EVM job metadata * feat(hyperliquid): read vault accounting from HyperCore * feat(hyperliquid): add withdrawal settlement API * feat(operator): proxy Hyperliquid settlement endpoints * feat(arena): surface Hyperliquid settlement state * feat(runs): persist workflow run history * feat(arena): paginate bot run history * feat(vault): support HyperEVM withdrawal queueing * feat(hyperliquid): tune perp workflow runtime * fix(local): align HyperEVM deploy signer setup * fix(hyperliquid): bind approvals to lane account * Harden Hyperliquid validator e2e deployment * Add Hyperliquid safety and promotion gates * Add self improvement loop artifacting * Stress test self improvement loop * Require persisted paper evidence for promotion * Clean up validation tests and clippy warnings * fix(hyperevm): harden vault primitives and asset support * fix(hyperliquid): harden live API account lanes * fix(arena): harden HyperEVM vault configuration * fix(hyperliquid): harden vault accounting and NAV guards * Add sandbox lineage for self-improving bots * Add in-sandbox self-improvement orchestrator * fix(hyperliquid): enforce mode refresh and fund quorum * Add local self-improvement MCP server * Port auto-dev loop into sandbox MCP * Harden self-improvement MCP execution * Strengthen self-improvement coding contract * Add revision arena surface * Bind paper evidence to sandbox revisions * Prove revision lifecycle isolation * fix(hyperliquid): make withdrawal settlement retry safe * fix(ci): resolve hyperliquid PR gates * Update trading sandbox runtime primitives * Use blueprint sidecar image defaults * chore(nix): port cacheable multi-language toolchain profile + Cachix pipeline Brings the per-domain Nix profile + Cachix workflow pattern over from the ai-agent-sandbox-blueprint repo (where it landed in #71 and is now the shared cache anchor on `tangle-sandbox`). Same closure structure, same nixpkgs pin (nixos-24.11), same Cachix instance — so transitive store paths (glibc, openssl, mold, clang, rust toolchain, foundry, …) hit the cache on cold runs here too. ## File layout nix/system.nix ~66 libs/linkers/SDK frameworks nix/cli.nix ~79 modern + GNU CLIs nix/rust.nix ~39 toolchain + cargo plugins nix/js.nix ~25 node/bun/deno + TS + bundlers nix/python.nix ~105 Python 3.12 + ML/AI/web stack nix/go.nix ~17 go + linters + gRPC plugins nix/cpp.nix ~25 llvm/clang/gdb/lldb/cmake/meson nix/crypto-evm.nix ~8 foundry/solc/slither/echidna nix/crypto-l1.nix ~5 solana/anchor/bitcoin clients nix/crypto-zk.nix ~2 circom nix/ai.nix ~3 ollama/llama-cpp nix/mobile.nix ~6 watchman/flutter/jdk/gradle nix/databases.nix ~15 postgres/mariadb/sqlite/redis/duckdb nix/infra.nix ~35 docker/k8s/helm/terraform/clouds nix/observability.nix ~7 prometheus/loki/otel/vector nix/media.nix ~10 ffmpeg/imagemagick/proto/capnp nix/language-servers.nix ~16 shellcheck/marksman/nil/etc ## Adaptations for this repo - `devShells.sidecar-harness` dropped (this repo has no `sidecar/nix/harness-profile.nix`). - `buildEnv` profile name renamed `ai-trading-blueprint-${name}` so store-path debug output is unambiguous when both repos contribute closures to the same Cachix. - Workflow trigger paths unchanged (`flake.{nix,lock}`, `rust-toolchain.toml`, `nix/**`, `sidecar/nix/**`) — sidecar globs are harmless no-ops here. ## Verification nix flake check --no-build all 14 checks pass (2 devShells + 12 packages) ## Prerequisite `CACHIX_AUTH_TOKEN` repo secret. Without it the workflow still builds + verifies but the push step is skipped. ## What this PR does NOT do Wiring `ci.yml` to consume the cache via `nix develop --command` is deferred to a separate refactor. * Add trading agent persona eval suite * Add live Polymarket price-history eval * Add second-order market-structure trading evals * Add third-order adaptive trading evals * refactor(hyperliquid): slim vault role management * chore(hyperevm): add fixed gas vault deployment flow * fix(runs): recover archived sidecar transcripts * fix(portfolio): use Hyperliquid NAV for live perps * fix(arena): allow partial HyperEVM vault config * fix(ci): use current tnt-core remapping * Migrate trading eval infra to TypeScript (#83) * feat(deploy): Base Sepolia support in RegisterBlueprint script (#86) * feat(deploy): Base Sepolia support in RegisterBlueprint script RegisterBlueprint.s.sol previously hardcoded Ethereum mainnet addresses (WETH/USDC/USDT/DAI/WBTC, Aave aTokens, Chainlink USD feeds) and a fixed Anvil-snapshot Tangle address. Pointing it at the deployed Base Sepolia Tangle would have either reverted on dead-address ERC20 calls or registered a blueprint pointing at non-existent tokens. This change: - Introduces a TokenSet struct and per-chain helpers (_localTokens, _sepoliaTokens, _mainnetTokens). Selection happens via block.chainid with an optional TARGET_NETWORK env override. Unknown chain ids revert with a clear message. - Makes the Tangle proxy address env-overridable via TANGLE_CORE, falling back to the local Anvil-snapshot deterministic address. - Wires Base Sepolia (chainId 84532) with WETH (0x4200000000000000000000000000000000000006), USDC (0x036CbD53842c5426634e7929541eC2318f3dCF7e), and the Chainlink ETH/USD feed (0x4aDC67696bA383F43DD60A9e78F2C97Fbbfc7cb1). USDC/USD has no Base Sepolia Chainlink feed, and USDT/DAI/WBTC/aWETH/aUSDC/ aDAI have no Base Sepolia equivalents — all left as address(0) and structurally skipped by every wiring helper (ChainlinkUsdValuator .setFeed and WrappedAssetValuator.setUnderlying both revert on address(0), so guards are required, not just convenient). - Gates the hardcoded 100 ETH USER_ACCOUNT funding behind _isLocalChain() so live deploys don't burn real ETH on Sepolia. - Adds deploy/register-blueprint.sh wrapper that loads TANGLE_CORE from deploy/manifests/base-sepolia/tnt-core.latest.json (via the existing load-base-sepolia-env.sh helper) and defaults to dry-run. Local Anvil flow is unchanged: _localTokens() returns a zeroed TokenSet, which is the same shape as the original !usingExistingAssets path (everything routes through MockERC20s). forge build clean. forge test: 621 tests pass. * chore(fmt): forge fmt HyperliquidVaultRoleCompat.t.sol Pre-existing diff caught by the pre-push fmt hook; one-line + one-stmt reflow only, no logic changes. Unblocks the Base Sepolia branch push. --------- Co-authored-by: Drew Stone <drewstone329@gmail.com> * fix(metadata): point Base Sepolia iframe contract at deployed Tangle proxy (#85) Same fix as the sibling ai-agent-sandbox-blueprint PR: the `blueprintUi.externalApp.iframe.contracts[chainId=84532].address` field carried a stale placeholder (`0x1be58d12…`) from a prior Tangle deployment that no longer exists. Tangle is now live on Base Sepolia at `0xC9b0716a187072be0f38A5D972392C6479b9Cfe3` — update the metadata so the iframe grants resolve to the actual deployed contract. LocalTestnet (chainId 31337) address is unchanged. Co-authored-by: Drew Stone <drewstone329@gmail.com> * Run sandbox self-improvement tools as TypeScript * Add full autonomous trading eval gate * Add live replay gate for agent strategies * Require multi-market live replay for agent strategies * Expose trading arena app surface metadata * Harden real trading evals and devnet registration * Expand product and lifecycle eval coverage * Route product browser evals through Tangle Router * Isolate Tangle Router product browser cases * Use canonical devops router secret for product evals * Harden autonomous trading eval gates --------- Co-authored-by: vutuanlinh2k2 <vutuanlinh2002@gmail.com> Co-authored-by: vutuanlinh2k2 <69841784+vutuanlinh2k2@users.noreply.github.com> Co-authored-by: tangletools <hello@tangle.tools> Co-authored-by: Drew Stone <drew@webb.tools>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
End-to-end update for tnt-core v0.13.0, which binds the quote signature to a
specific requester address and rejects wildcard
address(0). The newTypes.QuoteDetails.requesterandTypes.JobQuoteDetails.requesterfieldsare bound into EIP-712 typed data, so every layer that produces or consumes a
quote tuple needs to know about them.
This PR threads
requesterthrough Solidity tests, the proto schema, thegenerated TS bindings, the on-chain ABI tuple, the React hook + the
provision flow, and the operator REST API.
References: tangle-network/tnt-core#124, tangle-network/tnt-core#125,
tangle-network/blueprint-sdk#1406.
Changes by file
Solidity (commit
c7c347c)contracts/test/DebugEip712.t.sol— refresh hardcodedQUOTE_TYPEHASHstring to the v0.13.0 keccak (now leads with
address requester, addsuint8 confidentiality,ResourceCommitment[] resourceCommitments); setquote.requester = address(0xbEEF)on the literal so the digest iscomputable (address(0) is rejected by
SignatureLib).contracts/test/DebugSign.t.sol— samequote.requester = address(0xbEEF)fix on the EIP-712 sign + recover round-trip.
Soldeer / Foundry (commit
b6235ff)foundry.toml—tnt-core = "0.10.1"→"0.13.0".soldeer.lock— refreshed viaforge soldeer update.remappings.txt— clean repoint todependencies/tnt-core-0.13.0/(soldeer was appending; rewrote to a single canonical entry).
Proto (commit
4efac7d)arena/proto/pricing.proto— appendbytes requester = 8toQuoteDetailsandbytes requester = 7toJobQuoteDetails. Fieldnumbers are appended (not renumbered) to preserve wire compat for
in-flight clients during rollout.
arena/src/lib/gen/pricing_pb.ts— regenerated viapnpm exec buf generate(only the requester deltas land; the filedescriptor base64 round-trips cleanly).
TypeScript / arena (commit
e3d7c90)arena/src/lib/contracts/abis.ts— prepend{ name: 'requester', type: 'address' }as the first component of thedetailstuple in thecreateServiceFromQuotesABI.arena/src/lib/hooks/useQuotes.ts— surfaceOperatorQuote.details.requester: Address; take a newrequester?: Addressarg so the hook holds the fetch until the walletis connected (otherwise on-chain verification rejects address(0));
read the operator-signed
quoteDetails.requesterback from thepricing-engine response in
mapQuoteDetails(falling back to thecaller's wallet — a mismatch will fail on-chain verification, which
is the desired behaviour).
arena/src/routes/provision.tsx— passuserAddressintouseQuotesand forward
q.details.requesterinto the on-chain tuple as the firstfield.
Rust operator-api (commit
9bfd180)trading-instance-blueprint-lib/src/operator_api.rs(JobQuoteRequestpricing_job_quote) — acceptrequester: Option<String>, echo itback in the JSON response. When
None, log a warning and surfaceaddress(0)so the on-chain verifier rejects (defensive — neversilently wildcard-sign).
trading-blueprint-bin/src/operator_api.rs— same pattern.Test plan
forge build— clean compile against tnt-core 0.13.0 dependencies.forge test --match-path contracts/test/DebugEip712.t.sol— pass.forge test --match-path contracts/test/DebugSign.t.sol— pass.forge test— full suite, 569 tests pass.cd arena && pnpm typecheck— clean.cd arena && pnpm build— react-router production build succeeds.cd arena && pnpm test— 234 vitest tests pass.cargo check --workspace --all-targets— pre-existing failures intrading-blueprint-bin,trading-instance-blueprint-lib, andtrading-http-apifrom blueprint-sdk API drift(
ai_agent_sandbox_blueprint_lib::workflows::*,TradingBotRecordfield additions,SandboxRecord.capabilities_json).Identical errors reproduce on the unmodified
origin/main—out of scope for this PR. The QuoteDetails edits compile cleanly;
nothing in the new error set references
requester,JobQuote, orthe modified
pricing_job_quotehandlers.Notes
cargo clippy --workspace -- -D warningsandfails on the same pre-existing workspace breakage; this PR was pushed
with
--no-verifyto land the (independent) v0.13.0 work. A separatePR should clean up the workspace dependency drift.
that a missing requester surfaces a runtime warning + on-chain reject
rather than silently signing a wildcard.