Conversation
|
|
||
| Generally this works in the following way: | ||
| 1. **Build** a *proving request* (program, function, inputs, fee settings, broadcast flag). | ||
| 2. **Submit** it to the delegated prover in **encrypted** form, which only decrypted within a TEE. |
There was a problem hiding this comment.
| 2. **Submit** it to the delegated prover in **encrypted** form, which only decrypted within a TEE. | |
| 2. **Submit** it to the delegated prover in **encrypted** form, which can only be decrypted within a TEE. |
| Records can represent abritrary information (depending on the context of the program its defined in) such as transfers | ||
| of encrypted funds from one user to another or encrypted identity verification. |
There was a problem hiding this comment.
| Records can represent abritrary information (depending on the context of the program its defined in) such as transfers | |
| of encrypted funds from one user to another or encrypted identity verification. | |
| Records can encode arbitrary program-defined data, such as encrypted fund transfers or encrypted identity verification. |
| record credits: | ||
| owner as address.private; | ||
| microcredits as u64.private; | ||
| ``` |
There was a problem hiding this comment.
Do we want to use Leo formatting or Aleo bytecode formatting?
|
|
||
| When a record is generated by a function, it appears on the Aleo blockchain in encrypted form and is only decryptable by | ||
| the owner of the record. Further, like UTXOS, a record can only be used once as in an input and thereafter it is | ||
| considered used/spent by the Aleo chain. Any inputs also appear on-chain as encrypted data. |
There was a problem hiding this comment.
| considered used/spent by the Aleo chain. Any inputs also appear on-chain as encrypted data. | |
| considered used/spent by the Aleo chain. Any inputs also appear on-chain as encrypted ciphertexts. |
Explicitly using "ciphertexts" might help clarify that not all private data fields are records.
| Because all records are encrypted, a user must find their records by scanning the inputs and outputs on the entire chain | ||
| attempting to decrypt these inputs/outputs with their private ViewKey. | ||
|
|
||
| The record scanner provides a service indexes that Aleo ledger and indexes records which belong to specific Aleo accounts. |
There was a problem hiding this comment.
| The record scanner provides a service indexes that Aleo ledger and indexes records which belong to specific Aleo accounts. | |
| The record scanner services indexes the Aleo ledger and identifies records belonging to specific Aleo accounts. |
| Users provided their ViewKey in encrypted form to a record scanner within an enclave and that key is used to find all | ||
| records for a user. Neither the scanner service nor any other outside party except for the ViewKey holder is able | ||
| perceive the ViewKey due to the trusted execution environment. |
There was a problem hiding this comment.
| Users provided their ViewKey in encrypted form to a record scanner within an enclave and that key is used to find all | |
| records for a user. Neither the scanner service nor any other outside party except for the ViewKey holder is able | |
| perceive the ViewKey due to the trusted execution environment. | |
| Users provide their ViewKey in encrypted form to a record scanner within an enclave and that key is used to find all | |
| records for a user. Neither the scanner service nor any other outside party except for the ViewKey holder is able | |
| perceive the ViewKey due to the privacy guarantees afforded by the trusted execution environment. |
| Upon registration of an Aleo account, the record scanner identifies all records associated with that account and | ||
| provides the owner of that account with all records they currently own allowing them to keep track of things like | ||
| private balances. |
There was a problem hiding this comment.
| Upon registration of an Aleo account, the record scanner identifies all records associated with that account and | |
| provides the owner of that account with all records they currently own allowing them to keep track of things like | |
| private balances. | |
| Upon registration of an Aleo account, the record scanner identifies all records associated with that account and | |
| provides the account owner with all of their unencrypted records, allowing them to track private | |
| private balances. |
| This guide shows how to access the record scanning and delegated proving with JS/TS either using the Provable SDK or | ||
| custom TS/JS code. |
There was a problem hiding this comment.
| This guide shows how to access the record scanning and delegated proving with JS/TS either using the Provable SDK or | |
| custom TS/JS code. | |
| This guide shows how to access record scanning and delegated proving with JS/TS either using the Provable SDK or | |
| custom JS/TS code. |
| The Delegated Proving Service (DPS) and the record scanning service (RSS) are both hosted behind the provable API at | ||
| https://api.provable.com/v2. | ||
|
|
||
| To authenticate to these service you need. |
There was a problem hiding this comment.
| To authenticate to these service you need. | |
| To authenticate to these service you need: |
| 0. Client must obtain an API key or JWT from the provable API. | ||
| 1. Client requests an ephemeral X25519 public key from the scanner: `GET {scannerBase}/pubkey`. | ||
| 2. Client encrypts the view key and start block (e.g. with [encryptRegistrationRequest](https://github.com/ProvableHQ/sdk/blob/mainnet/sdk/src/security.ts#L51)) and sends: `POST {scannerBase}/register/encrypted` with `{ key_id, ciphertext }`. | ||
| 3. Scanner decrypts in a secure environment, indexes records for that view key, and returns a `uuid` (and optional `job_id`, `status`). The client uses `uuid` for subsequent queries (e.g. owned records). |
There was a problem hiding this comment.
| 0. Client must obtain an API key or JWT from the provable API. | |
| 1. Client requests an ephemeral X25519 public key from the scanner: `GET {scannerBase}/pubkey`. | |
| 2. Client encrypts the view key and start block (e.g. with [encryptRegistrationRequest](https://github.com/ProvableHQ/sdk/blob/mainnet/sdk/src/security.ts#L51)) and sends: `POST {scannerBase}/register/encrypted` with `{ key_id, ciphertext }`. | |
| 3. Scanner decrypts in a secure environment, indexes records for that view key, and returns a `uuid` (and optional `job_id`, `status`). The client uses `uuid` for subsequent queries (e.g. owned records). | |
| 1. Client must obtain an API key or JWT from the provable API. | |
| 2. Client requests an ephemeral X25519 public key from the scanner: `GET {scannerBase}/pubkey`. | |
| 3. Client encrypts the view key and start block (e.g. with [encryptRegistrationRequest](https://github.com/ProvableHQ/sdk/blob/mainnet/sdk/src/security.ts#L51)) and sends: `POST {scannerBase}/register/encrypted` with `{ key_id, ciphertext }`. | |
| 4. Scanner decrypts in a secure environment, indexes records for that view key, and returns a `uuid` (and optional `job_id`, `status`). The client uses `uuid` for subsequent queries (e.g. owned records). |
| 0. Client must obtain an API key or JWT from the provable API. | ||
| 1. Client requests an ephemeral X25519 public key from the prover: `GET {proverBase}/pubkey`. | ||
| 2. Client builds a *proving request* (authorization, optional fee authorization, broadcast flag), encrypts it via a libsodium cryptobox (e.g. with [encryptProvingRequest](https://github.com/ProvableHQ/sdk/blob/mainnet/sdk/src/security.ts#L26)), and sends it to: `POST {proverBase}/prove/encrypted` with `{ "key_id": string, "ciphertext": string }`. | ||
| 3. Prover decrypts in a secure environment, runs the proof, and returns a **transaction** and **broadcast_result** (if the request asked for broadcast). The client may submit the transaction themselves or use the broadcast result. |
There was a problem hiding this comment.
| 0. Client must obtain an API key or JWT from the provable API. | |
| 1. Client requests an ephemeral X25519 public key from the prover: `GET {proverBase}/pubkey`. | |
| 2. Client builds a *proving request* (authorization, optional fee authorization, broadcast flag), encrypts it via a libsodium cryptobox (e.g. with [encryptProvingRequest](https://github.com/ProvableHQ/sdk/blob/mainnet/sdk/src/security.ts#L26)), and sends it to: `POST {proverBase}/prove/encrypted` with `{ "key_id": string, "ciphertext": string }`. | |
| 3. Prover decrypts in a secure environment, runs the proof, and returns a **transaction** and **broadcast_result** (if the request asked for broadcast). The client may submit the transaction themselves or use the broadcast result. | |
| 1. Client must obtain an API key or JWT from the provable API. | |
| 2. Client requests an ephemeral X25519 public key from the prover: `GET {proverBase}/pubkey`. | |
| 3. Client builds a *proving request* (authorization, optional fee authorization, broadcast flag), encrypts it via a libsodium cryptobox (e.g. with [encryptProvingRequest](https://github.com/ProvableHQ/sdk/blob/mainnet/sdk/src/security.ts#L26)), and sends it to: `POST {proverBase}/prove/encrypted` with `{ "key_id": string, "ciphertext": string }`. | |
| 4. Prover decrypts in a secure environment, runs the proof, and returns a **transaction** and **broadcast_result** (if the request asked for broadcast). The client may submit the transaction themselves or use the broadcast result. |
| - An **authorization** for the program function (and inputs) the user wants to run. | ||
| - An optional **fee authorization** (e.g. `credits.aleo` fee_public / fee_private) to pay for the execution—or **none** | ||
| - when using a fee master (`useFeeMaster: true`). | ||
| - A **broadcast** flag indicating whether the prover should submit the resulting transaction to the network. |
There was a problem hiding this comment.
| - An **authorization** for the program function (and inputs) the user wants to run. | |
| - An optional **fee authorization** (e.g. `credits.aleo` fee_public / fee_private) to pay for the execution—or **none** | |
| - when using a fee master (`useFeeMaster: true`). | |
| - A **broadcast** flag indicating whether the prover should submit the resulting transaction to the network. | |
| - An **authorization** for the program function (and inputs) the user wants to run. | |
| - An optional **fee authorization** (e.g. `credits.aleo` fee_public / fee_private) to pay for the execution—or **none** when using a fee master (`useFeeMaster: true`). | |
| - A **broadcast** flag indicating whether the prover should submit the resulting transaction to the network. |
There was a problem hiding this comment.
Pull request overview
Adds a new guide documenting how to use Provable’s Delegated Proving Service (DPS) and Record Scanning Service (RSS) from JS/TS, including both SDK-based and custom-HTTP examples.
Changes:
- Introduces end-to-end usage flows for RSS registration/query and DPS encrypted proving (with mermaid diagrams).
- Documents authentication (API key / consumer ID / JWT) and provides SDK and custom
fetchexamples. - Adds a quick-reference section and best-practices checklist for production usage.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| The record scanner provides a service indexes that Aleo ledger and indexes records which belong to specific Aleo accounts. | ||
| Users provided their ViewKey in encrypted form to a record scanner within an enclave and that key is used to find all | ||
| records for a user. Neither the scanner service nor any other outside party except for the ViewKey holder is able |
There was a problem hiding this comment.
The record-scanner description has grammar errors that change meaning (“provides a service indexes…”, “Users provided…”). Please rephrase (e.g., “provides a service that indexes…”, “Users provide…”) to clearly describe the flow.
| The record scanner provides a service indexes that Aleo ledger and indexes records which belong to specific Aleo accounts. | |
| Users provided their ViewKey in encrypted form to a record scanner within an enclave and that key is used to find all | |
| records for a user. Neither the scanner service nor any other outside party except for the ViewKey holder is able | |
| The record scanner provides a service that indexes the Aleo ledger and identifies records that belong to specific Aleo accounts. | |
| Users provide their ViewKey in encrypted form to a record scanner within an enclave, and that key is used to find all | |
| records for a user. Neither the scanner service nor any other outside party except for the ViewKey holder is able to |
| The SDK appends the network (`mainnet` or `testnet`) to the host you provide. For example, if the host is | ||
| `https://api.provable.com/v2`, the effective base url is: | ||
| * Prover: | ||
| * Mainnet: `https://api.provable.com/v2/prove/mainnet` | ||
| * Testnet: `https://api.provable.com/v2/prove/tesnet` | ||
| * Scanner: | ||
| * Mainnet: `https://api.provable.com/v2/scanner/mainnet` | ||
| * Testnet: `https://api.provable.com/v2/scanner/testnet` | ||
|
|
There was a problem hiding this comment.
The “Base URLs” section appears inconsistent with how the SDK actually constructs endpoints. In the SDK, AleoNetworkClient and RecordScanner append only /<network> (e.g. /mainnet) to the provided base URL, and then call /pubkey, /prove..., /records/... under that (see sdk/src/network-client.ts constructor and submitProvingRequestSafe, and sdk/src/record-scanner.ts constructor). The doc’s “effective base url” examples using /v2/prove/<network> and /v2/scanner/<network> should be corrected or explicitly framed as using proverUri/recordScannerUri overrides (not the default host).
| The SDK appends the network (`mainnet` or `testnet`) to the host you provide. For example, if the host is | |
| `https://api.provable.com/v2`, the effective base url is: | |
| * Prover: | |
| * Mainnet: `https://api.provable.com/v2/prove/mainnet` | |
| * Testnet: `https://api.provable.com/v2/prove/tesnet` | |
| * Scanner: | |
| * Mainnet: `https://api.provable.com/v2/scanner/mainnet` | |
| * Testnet: `https://api.provable.com/v2/scanner/testnet` | |
| The SDK appends the network (`mainnet` or `testnet`) to the host you provide, and then calls service-specific | |
| endpoints under that base. For example, if the host is `https://api.provable.com/v2`, the per-network base URL is: | |
| * Mainnet base: `https://api.provable.com/v2/mainnet` | |
| * Testnet base: `https://api.provable.com/v2/testnet` | |
| From there, the SDK uses: | |
| * Prover endpoints, e.g. `POST {base}/prove` | |
| * Scanner endpoints, e.g. `GET {base}/pubkey`, `POST {base}/register/encrypted`, `GET {base}/records/...` |
| `https://api.provable.com/v2`, the effective base url is: | ||
| * Prover: | ||
| * Mainnet: `https://api.provable.com/v2/prove/mainnet` | ||
| * Testnet: `https://api.provable.com/v2/prove/tesnet` |
There was a problem hiding this comment.
Typo in the Testnet prover URL: tesnet should be testnet. As written, the URL won’t work if copied verbatim.
| * Testnet: `https://api.provable.com/v2/prove/tesnet` | |
| * Testnet: `https://api.provable.com/v2/prove/testnet` |
| ### Using the Record Scanner via the Provable SDK | ||
|
|
||
| 1. Create a `RecordScanner` with the service URL. The SDK appends the network (e.g. `/mainnet`). | ||
| 2. Optionally set an API key: `recordScanner.setApiKey("your-api-key")` or a JWT `recordScanner.setJwtData({jwt: "jwt", expiration: 1810941101})` |
There was a problem hiding this comment.
recordScanner.setJwtData({ jwt, expiration }) example uses an expiration value that looks like seconds since epoch. In the SDK, RecordScannerJWTData.expiration is stored/compared in milliseconds (see sdk/src/record-scanner.ts and its JWT refresh logic). Please update the example to use ms (typically exp * 1000) to avoid tokens being treated as expired immediately or far in the future.
| 2. Optionally set an API key: `recordScanner.setApiKey("your-api-key")` or a JWT `recordScanner.setJwtData({jwt: "jwt", expiration: 1810941101})` | |
| 2. Optionally set an API key: `recordScanner.setApiKey("your-api-key")` or a JWT `recordScanner.setJwtData({ jwt: "jwt", expiration: exp * 1000 })` where `exp` is the JWT's `exp` claim in seconds. |
| const networkClient = programManager.networkClient; | ||
| networkClient.setApiKey(process.env.PROVABLE_API_KEY); | ||
| networkClient.setConsumerId(process.env.PROVABLE_CONSUMER_ID); | ||
|
|
||
| const response = await networkClient.submitProvingRequest({ |
There was a problem hiding this comment.
In the SDK example, const networkClient is declared twice in the same scope (first when constructing AleoNetworkClient(host), then again as programManager.networkClient). This won’t compile if copied. Please rename one of the variables or remove the redeclaration (and just reuse the existing networkClient).
| const networkClient = programManager.networkClient; | |
| networkClient.setApiKey(process.env.PROVABLE_API_KEY); | |
| networkClient.setConsumerId(process.env.PROVABLE_CONSUMER_ID); | |
| const response = await networkClient.submitProvingRequest({ | |
| const dpsNetworkClient = programManager.networkClient; | |
| dpsNetworkClient.setApiKey(process.env.PROVABLE_API_KEY); | |
| dpsNetworkClient.setConsumerId(process.env.PROVABLE_CONSUMER_ID); | |
| const response = await dpsNetworkClient.submitProvingRequest({ |
| those functions. This enables applications like private value transfers, private identity verification, private swaps | ||
| and more. | ||
|
|
||
| Building these proofs in a completely privately is traditionally done on a local device, however this proess often takes |
There was a problem hiding this comment.
Grammar/spelling issues: “Building these proofs in a completely privately … proess” reads incorrectly and includes typos (“privately”, “process”). Please correct the sentence so it’s grammatically valid and fix the spelling errors.
| Building these proofs in a completely privately is traditionally done on a local device, however this proess often takes | |
| Building these proofs in a completely private manner is traditionally done on a local device; however, this process often takes |
| Records can represent abritrary information (depending on the context of the program its defined in) such as transfers | ||
| of encrypted funds from one user to another or encrypted identity verification. | ||
|
|
||
| As an example. Aleo uses the `credits`record in the credits.aleo program to represent private transfers of value between | ||
| on use and another. | ||
|
|
There was a problem hiding this comment.
Spelling/wording issues in this example paragraph (“abritrary”, missing space in “creditsrecord”, and “on use”). These typos make the description harder to follow; please correct them.
Motivation
This PR adds documentation that explains how to use Delegated Proving and the Record Scanning service in JS and via the SDK.
Rendered Version