feat(tnt-core-v0.13.0): bind quotes to requester (Solidity, proto, TS, Rust) [mainwork]#72
Closed
drewstone wants to merge 5 commits into
Closed
feat(tnt-core-v0.13.0): bind quotes to requester (Solidity, proto, TS, Rust) [mainwork]#72drewstone wants to merge 5 commits into
drewstone wants to merge 5 commits into
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
Contributor
Author
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
Sibling/mirror PR of #71 — same end-to-end update for tnt-core v0.13.0,
landed from the parallel
ai-trading-blueprints-mainworkworktree. Bothtrees were verified identical for every file touched here, so this PR
applies byte-equivalent edits.
tnt-core v0.13.0 binds the quote signature to a specific requester address
and rejects wildcard
address(0). The newTypes.QuoteDetails.requesterand
Types.JobQuoteDetails.requesterfields are bound into EIP-712 typeddata, 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
200271a)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
d72a579)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
7118cb3)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
c254cfc)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
d56b0f9)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.
Relationship to #71
This PR was opened in parallel from
/home/drew/code/ai-trading-blueprints-mainworkto satisfy a request for two PR streams. Both were checked against identical
working trees for the touched files, but pick whichever review path is most
convenient — the diffs are byte-equivalent except for the trailing branch
suffix.