General multi-request signing#1355
Conversation
| let function_id_str = get_field(&external_inputs, "functionId")? | ||
| .as_string() | ||
| .ok_or_else(|| "external_inputs.functionId must be a string".to_string())?; | ||
| let function_id = FieldNative::from_str(&function_id_str).map_err(|e| e.to_string())?; |
There was a problem hiding this comment.
It's true, this boils down to the mix of representations here: https://github.com/ProvableHQ/sdk/blob/mainnet/wasm/src/programs/request.rs#L759-L762. I will fix as suggested (i.e. maintain both and be able to handle them) since I don't know whether changing to "functionId" will have any unexpected consequences (e.g. other libraries deserializing this objects breaking).
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Antonio Mejías Gil <anmegi.95@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Antonio Mejías Gil <anmegi.95@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Antonio Mejías Gil <anmegi.95@gmail.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 81266c7. Configure here.
iamalwaysuncomfortable
left a comment
There was a problem hiding this comment.
Some tests were failing + lints were failing, I fixed those.
Otherwise this PR is very well done, very excellent first contribution to the SDK!
|
@iamalwaysuncomfortable I've pushed a couple of commits to try and fix the last remaining CI errors. Can you please confirm this change a24bf5e makes sense? Only two CI failures remain:
|

This PR adds an example test with the general external-signing flow for arbitrary transactions (that is, transactions with any call structure and record flows).
sdk/tests/external-signing.test.ts. It is specifically run on a call toldgbatcher_p28/transfer_private_3, but the flow is independent of that transaction’s structure.An important piece of this PR relies on snarkVM’sThe snarkVM changes are now meged and the snarkVM dependencies in the SDK have been bumped to a revision containing those changes.sample_authorization_extendedfrom Extendsample_authorizationto facilitate multi-request flows snarkVM#3310, so this PR is in draft mode and has a path-patched Cargo.toml until the snarkVM PR is merged.view_keybut no private key.sample_authorization_extended. Then it engages in one round of communication per request (i.e. per call in the transaction) with the signer as follows:to_fieldsrepresentation for most types and (H, tag) for static-record inputs.sample_authorization_extended) to update the nonces of record-like (static/external/dynamic-record) inputs to subsequent requests.sampleAuthorizationExtended(exposed from snarkVM), corresponding to the step before 1 above.fromPreprocessedInputs, corresponding to step 2 above and returning a new structurePreprocessedSigningResult. It internally calls the also newsignRequestFromPreprocessedInputs.computeMintedNonceandapplyMintedNonce, corresponding to step 4 above.authorizeRequests(exposed from snarkVM), which is called after step 4 in the test. This is optional, and I believe in our case it is done on the the DPS side.Tests
sample_authorizationto facilitate multi-request flows snarkVM#3310 checksample_authorization_extendedreturns the correct mocked requests and (importantly) record-tracking machinery on hundreds of transactions, including quite wild flows of static/dynamic/external records and conversion between them — so we can be confident on that front.Note
High Risk
Changes authorization and request signing in WASM plus a breaking network-client API; incorrect nonce patching or preprocessed signing would produce invalid authorizations.
Overview
Adds delegated signing for arbitrary multi-call transactions: authorizer holds a view key, signer holds the private key, and requests are signed one transition at a time with nonce patching when minted records flow into later calls.
WASM / snarkVM (bumped to
8e2397ee…) exposessampleAuthorizationWithRecordTracking(mock auth plus record-tracking, record names, and program checksums),authorizeRequests(build anAuthorizationfrom already-signedExecutionRequests),ExecutionRequest.fromPreprocessedInputs/signRequestFromPreprocessedInputs(sign fromcomputeExternalSigningInputsoutput), andGroup.gScalarMultiply.SDK adds
computeMintedNonce(on-chaincastnonce from TVK + output index) and exports it from the browser bundle.getProgramAmendmentCountis a breaking change: it now requires aneditionargument and uses/program/.../amendment_count?edition=;ProgramManager.resolveEditionAndAmendmentfirst callsgetLatestProgramEdition.Tests add a long end-to-end case on
ldgbatcher_p28.aleo/transfer_private_3(four requests, join/transfer chain) and update program-import mocks for the two-step edition/amendment lookup.Reviewed by Cursor Bugbot for commit 9e9276b. Bugbot is set up for automated code reviews on this repo. Configure here.