Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions docs/examples/05_download_and_save_keys_to_disc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
This example will demonstrate how to save proving and verifying keys locally for the "transfer_public" in credits.aleo and for any arbitrary Aleo program.

```typescript
import {
AleoKeyProvider,
CREDITS_PROGRAM_KEYS,
ProvingKey, // these are WASM-backed types
VerifyingKey,
} from "@provablehq/sdk";
import fs from "node:fs/promises";
import path from "node:path";

const keyProvider = new AleoKeyProvider();

// Fetch the on-chain "fee" and "transfer_public" proving and verifying keys
const [feePk, feeVk] = await keyProvider.fetchCreditsKeys(CREDITS_PROGRAM_KEYS.fee_public);
const [txPk, txVk] = await keyProvider.fetchCreditsKeys(CREDITS_PROGRAM_KEYS.transfer_public);

// For methods that consume or mint a record, the inclusion circuit will be required.
const [incPk, incVk] = await keyProvider.fetchCreditsKeys(CREDITS_PROGRAM_KEYS.inclusion);

// For a transition method in any deployed Aleo program, use the following pattern to fetch the proving and verifying
// keys associated with that transition.
const keySearchParams = { "cacheKey": "myProgram:myFunction" };
const [transition_Pk, transition_Vk] = await keyProvider.functionKeys(keySearchParams);

// You can use this method for saving the keys to disc.
async function writeKeyToFile(key, filePath) {
// Serialize the key into a Uint8Array
const raw = key.toBytes(); // or key.to_bytes() depending on your SDK version
// Then write it as binary
await fs.writeFile(filePath, Buffer.from(raw));
console.log(`Wrote ${filePath}`);
}

const keyDir = "./keys";
await fs.mkdir(keyDir, { recursive: true });

await writeKeyToFile(feePk, path.join(keyDir, "fee_public.prover"));
await writeKeyToFile(feeVk, path.join(keyDir, "fee_public.verifier"));
await writeKeyToFile(txPk, path.join(keyDir, "transfer_public.prover"));
await writeKeyToFile(txVk, path.join(keyDir, "transfer_public.verifier"));
await writeKeyToFile(incPk, path.join(keyDir, "inclusion.prover"));
await writeKeyToFile(incVk, path.join(keyDir, "inclusion.verifier"));

await writeKeyToFile(transition_Pk, path.join(keyDir, "transition.prover"));
await writeKeyToFile(transition_Vk, path.join(keyDir, "transition.verifier"));


54 changes: 54 additions & 0 deletions docs/examples/06_transfer_public_using_stored_keys.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
This example demonstrates how to execute public_transfer using locally saved proving and verifying keys.
```typescript
import { Account, ProgramManager, ProvingKey, VerifyingKey, initThreadPool, OfflineKeyProvider} from '@provablehq/sdk';
import fs from "node:fs/promises";

// Helper method to load the keys from storage.
async function loadFunctionKeyPair(proverPath) {
const proverBytes = await fs.readFile(proverPath);

const provingKey = ProvingKey.fromBytes(new Uint8Array(proverBytes));

return provingKey;
}

// Initialize multi-threading to allow WASM execution.
await initThreadPoool();

// Load the proving and verifying keys for public_transfer and fee_public from local storage.
const feeProvingKey = await loadFunctionKeyPair("./keys/fee_public.prover");
const transferPublicProvingKey = await loadFunctionKeyPair("./keys/transfer_public.prover");

// Create an offline Key provider
const keyProvider = new OfflineKeyProvider();


// Store the proving keys in the offline key provider.
offlineKeyProvider.insertTransferPublicKeys(transferPublicProvingKey);
offlineKeyProvider.insertFeePublicKeys(feeProvingKey);

// Create program manager using the OfflineKeyProvider and NetworkProvider.
const programManager = new ProgramManager("https://api.explorer.provable.com/v1", offlineKeyProvider);

// Create or import an account.
const account = new Account();

// Set the account as the program caller.
programManager.setAccount(account);

// Create recipient account.
const recipient = new Account();

// Build a transfer_public transaction.
// Publicly send 5 microcredits to the recipient
const transaction = await programManager
.buildTransferPublicTransaction(
5, // The amount to be transferred in credits (not microcredits)
recipient // The address of the recipient.
.address()
.to_string(),
0.0 // The optional priority fee amount.
);

// Broadcast the transaction to the Aleo network.
const result = await programManager.networkClient.submitTransaction(transaction);
71 changes: 71 additions & 0 deletions docs/examples/07_transfer_private_using_stored_keys.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
This example demonstrates how to execute transfer_private using locally saved proving and verifying keys.
```typescript
import { Account, ProgramManager, ProvingKey, VerifyingKey, initThreadPool, OfflineKeyProvider} from '@provable.sdk';

// Helper method to load the keys from storage.
async function loadFunctionKeyPair(proverPath, verifierPath) {
const proverBytes = await fs.readFile(proverPath);
const verifierBytes = await fs.readFile(verifierPath);

const provingKey = ProvingKey.fromBytes(new Uint8Array(proverBytes));
const verifyingKey = VerifyingKey.fromBytes(new Uint8Array(verifierBytes));

return [provingKey, verifyingKey];
}

// Download the inclusion proving and verifying keys.
const [inclusionProver, inclusionVerifier] = await loadFunctionKeyPair(
"./keys/inclusion.prover",
"./keys/inclusion.verifier"
);

// Download the transfer_private proving and verifying keys.
const [transferPrivateProvingKey, transferPrivateVerifyingKey] = await loadFunctionKeyPair(
"./keys/transfer_private.prover",
"./keys/transfer_private.verifier"
);

// Download the fee_private proving and verifying keys.
const [feeProvingKey, feeVerifyingKey] = await loadFunctionKeyPair(
"./keys/fee_private.prover",
"./keys/fee_private.verifier"
);

// Initialize multi-threading to allow WASM execution.
await initThreadPoool();

// Create a new Account, Program Manager, NetworkClient, KeyProvider, and RecordProvider.
const account = new Account();
const programManager = new ProgramManager();
const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");
const offlineKeyProvider = new OfflineKeyProvider();
const recordProvider = new NetworkRecordProvider(account, networkClient);

// Add the keys for fee_private, transfer_private, and the inclusion circuit to the key provider.
offlineKeyProvider.insertFeePrivateKeys(feeProvingKey)
offlineKeyProvider.insertTransferPrivateKeys(transferPrivateProvingKey)
offlineKeyProvider.insertInclusionKeys(inclusionProver);

// Create an offline query using the latest state root for the inclusion proof.
const offlineQuery = new OfflineQuery("latestStateRoot");

// Create the program manager
const programManager = new ProgramManager("https://api.explorer.provable.com/v1", offlineKeyProvider, recordProvider);
programManager.setAccount(account);

// Build the execution.
const offlineExecuteTx = await programManager.buildExecutionTransaction(
programName: "credits.aleo",
functionName: "transfer_private",
priorityFee: 0.0,
privateFee: true,
inputs: 5u32,
offlineQuery
);

// Broadcast the transaction to the network
const txId = await networkClient.broadcastTransaction(offlineExecuteTx);




72 changes: 72 additions & 0 deletions docs/examples/08_execute_program_with_records.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
The following template demonstrates how to create an execution using saved proving keys for transactions that either mint or consume records.

```typescript
import { Account, ProgramManager, ProvingKey, VerifyingKey, initThreadPool, OfflineKeyProvider} from '@provable.sdk';

// Helper method to load the keys from storage.
async function loadFunctionKeyPair(proverPath, verifierPath) {
const proverBytes = await fs.readFile(proverPath);
const verifierBytes = await fs.readFile(verifierPath);

const provingKey = ProvingKey.fromBytes(new Uint8Array(proverBytes));
const verifyingKey = VerifyingKey.fromBytes(new Uint8Array(verifierBytes));

return [provingKey, verifyingKey];
}

// Load the inclusion proving and verifying keys.
const [inclusionProver, inclusionVerifier] = await loadFunctionKeyPair(
"./keys/inclusion.prover",
"./keys/inclusion.verifier"
);

// Load the fee public proving and verifying keys.
const [feeProvingKey, feeVerifyingKey] = await loadFunctionKeyPair(
"./keys/fee_public.prover",
"./keys/fee_public.verifier"
);

// Load the proving and verifying keys associate with the transition method.
const [transitionProvingKey, transitionVerifyingKey] = await loadFunctionKeyPair(
"./keys/transition.prover",
"./keys/transition.verifier"
);

// Create a new Account, Program Manager, NetworkClient, KeyProvider, and RecordProvider.
const account = new Account();
const programManager = new ProgramManager();
const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");
const offlineKeyProvider = new OfflineKeyProvider();
const recordProvider = new NetworkRecordProvider(account, networkClient);

// Add the keys for fee_public and the inclusion circuit to the key provider.
offlineKeyProvider.insertFeePublicKeys(feeProvingKey)
offlineKeyProvider.insertInclusionKeys(inclusionProver);

// Cache the proving key for the transition method.
// Replace "program_name" and "transition_name" with the your program and transition method.
OfflineKeyProvider.cacheKeys("program_name.aleo/transition_name", transitionProvingKey, transitionerifyingKey);

// Create an offline search params object.
const offlineSearchParams = new OfflineSearchParams("program_name.aleo/transition_name");

// Create an offline query using the latest state root for the inclusion proof.
const offlineQuery = new OfflineQuery("latestStateRoot");

// Create the program manager
const programManager = new ProgramManager("https://api.explorer.provable.com/v1", offlineKeyProvider, recordProvider);
programManager.setAccount(account);

// Build the execution.
const offlineExecuteTx = await programManager.buildExecutionTransaction(
programName: "program_name.aleo",
functionName: "transition_method",
priorityFee: 0.0,
privateFee: false,
inputs: 5u32, // replace with whatever input(s) your transition method requires
offlineSearchParams,
offlineQuery
);

// Broadcast the transaction to the network
const txId = await networkClient.broadcastTransaction(offlineExecuteTx);
Loading