@provablehq/sdk 0.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,1172 @@
1
+ # Aleo SDK
2
+ <p align="center">
3
+ <img alt="Aleo SDK" width="1412" src="../.resources/banner.png">
4
+ </p>
5
+
6
+ <p align="center">
7
+ <a href="https://developer.aleo.org"> <img alt="Website" src="https://img.shields.io/badge/Developer_Docs-online-blue"></a>
8
+ <a href="https://circleci.com/gh/ProvableHQ/sdk"><img src="https://circleci.com/gh/ProvableHQ/sdk.svg?style=svg"></a>
9
+ <a href="https://discord.com/invite/aleo"><img src="https://img.shields.io/discord/700454073459015690?logo=discord"/></a>
10
+ <a href="https://github.com/ProvableHQ/sdk#%EF%B8%8F-contributors"><img src="https://img.shields.io/badge/contributors-23-ee8449"/></a>
11
+ </p>
12
+
13
+ ## Tools for Building Zero Knowledge Web Apps
14
+
15
+ The Aleo SDK is a collection of JavaScript libraries for building zero knowledge web applications in both the browser
16
+ and node.js.
17
+
18
+ ## Overview
19
+
20
+ Aleo provides the ability to run programs in zero knowledge. The Aleo SDK provides the tools to use these programs
21
+ within the browser and all other levels of the web stack to build privacy preserving applications.
22
+
23
+ The Aleo SDK provides the following functionality (Click to see examples):
24
+ 1. [Aleo account management](https://provable.tools/account)
25
+ 2. [Web-based program execution and deployment](https://provable.tools/develop)
26
+ 3. [Aleo credit transfers](https://provable.tools/transfer)
27
+ 4. [Management of program state and data](https://provable.tools/record)
28
+ 5. [Communication with the Aleo network](https://provable.tools/rest)
29
+
30
+ ## Table of Contents
31
+
32
+ * [Installation](#Installation)
33
+ * [Usage](#Usage)
34
+ * [Zero Knowledge Web App Examples](#Zero-Knowledge-Web-App-Examples)
35
+ * [Create Aleo App](#create-aleo-app)
36
+ * [Provable.tools](#provabletools)
37
+ * [Create An Aleo Account](#1-create-an-aleo-account)
38
+ * [Execute Aleo Programs](#2-execute-aleo-programs)
39
+ * [Aleo Programs](#21-aleo-programs)
40
+ * [Program Execution Model](#22-program-execution-model)
41
+ * [WebAssembly Initialization](#23-wasm-initialization)
42
+ * [Local Program Execution](#24-local-program-execution)
43
+ * [Online Program Execution](#25-program-execution-on-the-aleo-network)
44
+ * [Program Proving Keys and Records](#26-program-proving-keys--program-records)
45
+ * [Deploy Programs](#27-deploy-a-new-program-to-the-aleo-network)
46
+ * [React Example](#28-react-example)
47
+ * [Aleo Credit Transfers](#3-value-transfers)
48
+ * [Aleo Credits](#31-aleo-credits)
49
+ * [Transfer Aleo Credits](#32-transfer-aleo-credits)
50
+ * [Check Public Balances](#32-checking-public-balances)
51
+ * [Program Data and Private State](#4-managing-program-data-and-private-state)
52
+ * [Private State Data: Records](#41-private-state-data--records)
53
+ * [Record Usage Example](#42-record-usage-example--private-value-transfers)
54
+ * [Public State Data: Mappings](#43-public-state-data--mappings)
55
+ * [Reading Mappings](#44-reading-mappings)
56
+ * [Initializing and Updating Mappings](#45-initializing--updating-mappings)
57
+ * [Communicating with the Aleo Network](#5-communicating-with-the-aleo-network)
58
+ * [Further Documentation](#further-documentation)
59
+ ## Installation
60
+
61
+ ### NPM
62
+
63
+ To install the Aleo SDK from NPM run:
64
+
65
+ `npm install @provablehq/sdk` or `yarn add @provablehq/sdk`.
66
+
67
+ ### Build from source
68
+
69
+ To build the project from source, go to this project's root and execute:
70
+
71
+ `npm install && npm run build`
72
+
73
+ ## Getting Started: Zero Knowledge Web App Examples
74
+
75
+ ### Create Aleo App
76
+ A set of fully functional examples of zero knowledge web apps can be found in
77
+ [create-aleo-app](https://github.com/ProvableHQ/sdk/tree/testnet3/create-aleo-app). Create-aleo-app provides several web-app
78
+ templates in common web frameworks such as React that can be used as a starting point for building zero knowledge web apps.
79
+
80
+ Developers can get started immediately with create-react-app by running:
81
+ `npm create aleo-app@latest`
82
+
83
+ ### Provable.tools
84
+
85
+ Additionally, the SDK powers [provable.tools](https://provable.tools) - a React app that provides a graphical interface for most
86
+ of the functionality provided by the SDK and can be used as a reference for usage of the SDK. Source code for provable.tools
87
+ can be found [in the SDK repo here](https://github.com/ProvableHQ/sdk/tree/testnet3/website)
88
+
89
+ ## Usage
90
+
91
+ ## 1. Create an Aleo Account
92
+
93
+ The first step in operating a zero knowledge web application is creating a private key which serves as a cryptographic
94
+ identity for a user. After a private key is generated, several keys that enable specialized methods of interacting with
95
+ Aleo programs can be derived.
96
+
97
+ These keys include:
98
+ #### Private Key
99
+ The `Private Key` can be treated as the identity of a user. It is used for critical functions like authorizing zero knowledge
100
+ program execution, decrypting private data, and proving ownership of data.
101
+ ownership over user data
102
+ #### View Key
103
+ The `View Key` is derived from the private key and can be used to both decrypt encrypted data owned by a user and prove
104
+ ownership of that data.
105
+ #### Compute Key
106
+ The `Compute Key` can be used to trustlessly run applications and generate transactions on a user's behalf.
107
+ #### Address
108
+ The `Address` is a user's unique public identifier. It serves as an address for a user to receive both official Aleo
109
+ credits and data from other zero-knowledge Aleo programs.
110
+
111
+ All of these keys can be created using the account object:
112
+ ```typescript
113
+ import { Account } from '@provablehq/sdk';
114
+
115
+ const account = new Account();
116
+
117
+ // Individual keys can be then be accessed through the following methods
118
+ const privateKey = account.privateKey();
119
+ const viewKey = account.viewKey();
120
+ const address = account.address();
121
+ ```
122
+
123
+ Please note that all keys are considered sensitive information and should be stored securely.
124
+
125
+ ## 2. Execute Aleo Programs
126
+
127
+ ### 2.1 Aleo Programs
128
+
129
+ Aleo programs provide the ability for users to make any input or output of a program private and prove that the program
130
+ was run correctly. Keeping program inputs and outputs private allows developers to build privacy into their applications.
131
+
132
+ Zero-Knowledge programs are written in one of two languages:
133
+ 1. [Leo](https://developer.aleo.org/leo/language): A high level, developer friendly language for developing
134
+ zero knowledge programs.
135
+ 2. [Aleo Instructions](https://developer.aleo.org/aleo/instructions): A low level language that provides developers fine
136
+ grained control over the execution flow of zero knowledge programs. Leo programs are compiled into Aleo Instructions
137
+ under the hood.
138
+
139
+ Documentation for both languages can be found at [developer.aleo.org](https://developer.aleo.org).
140
+
141
+ #### Hello world in the Leo Language
142
+ ```
143
+ // A simple program adding two numbers together
144
+ program helloworld.aleo {
145
+ transition hello(public a: u32, b: u32) -> u32 {
146
+ let c: u32 = a + b;
147
+ return c;
148
+ }
149
+ }
150
+ ```
151
+
152
+ #### Hello world in Aleo instructions
153
+ ```
154
+ program helloworld.aleo;
155
+
156
+ // The leo code above compiles to the following Aleo instructions
157
+ function hello:
158
+ input r0 as u32.public;
159
+ input r1 as u32.private;
160
+ add r0 r1 into r2;
161
+ output r2 as u32.private;
162
+ ```
163
+
164
+ ### 2.2 Program Execution Model
165
+
166
+ The SDK provides the ability execute `Aleo Instructions` programs %100 client-side within the browser.
167
+
168
+ The `ProgramManager` object encapsulates the functionality for executing programs and making zero knowledge proofs about
169
+ them. Under the hood it uses cryptographic code compiled from [SnarkVM](https://developer.aleo.org/aleo) into WebAssembly
170
+ with JavaScript bindings that allow execution of Aleo programs fully within the browser. Users interested in lower level
171
+ details how this is achieved can visit the [aleo-wasm](https://github.com/ProvableHQ/sdk/tree/testnet3/wasm) crate.
172
+
173
+ The basic execution flow of a program is as follows:
174
+ 1. A web app is loaded with an instance of the `ProgramManager` object
175
+ 2. The SDK wasm modules are loaded into the browser's WebAssembly runtime
176
+ 2. An Aleo program in `Aleo Instructions` format is loaded into the `ProgramManager` as a wasm object
177
+ 3. The web app provides a user input form for the program
178
+ 4. The user submits the inputs and the zero knowledge execution is performed entirely within the browser via WebAssembly
179
+ 5. The result is returned to the user
180
+ 6. (Optional) A fully encrypted zero knowledge transcript of the execution is optionally sent to the Aleo network
181
+
182
+ A diagramatic representation of the program execution flow is shown below.
183
+ ```mermaid
184
+ graph LR
185
+ p1[Leo Program]
186
+ p2[Aleo Instructions]
187
+
188
+ subgraph Browser Web-App
189
+ subgraph ProgramManager
190
+ subgraph Aleo-Wasm-Module
191
+ in-memory-program
192
+ end
193
+ end
194
+ end
195
+
196
+ p1-->p2--load program--oin-memory-program-.ZK result.->user
197
+ user-.user input.->in-memory-program
198
+ in-memory-program-."ZK result (Optional)".->Aleo-Network
199
+ ```
200
+
201
+ ### 2.3 Multi-threading
202
+
203
+ You can enable multi-threading by calling the `initThreadPool` function. This will run the SDK on multiple Workers, which significantly speeds up performance:
204
+
205
+ ```typescript
206
+ import { Account, initThreadPool } from '@provablehq/sdk';
207
+
208
+ // Enables multi-threading
209
+ await initThreadPool();
210
+
211
+ // Create a new Aleo account
212
+ const account = new Account();
213
+
214
+ // Perform further program logic...
215
+ ````
216
+
217
+ ### 2.4 Local Program Execution
218
+ A simple example of running the hello world program within the web browser and capturing its outputs is shown below:
219
+ ```typescript
220
+ import { Account, Program } from '@provablehq/sdk';
221
+
222
+ /// Create the source for the "hello world" program
223
+ const program = "program helloworld.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n";
224
+ const programManager = new ProgramManager();
225
+
226
+ /// Create a temporary account for the execution of the program
227
+ const account = new Account();
228
+ programManager.setAccount(account);
229
+
230
+ /// Get the response and ensure that the program executed correctly
231
+ const executionResponse = await programManager.executeOffline(program, "hello", ["5u32", "5u32"]);
232
+ const result = executionResponse.getOutputs();
233
+ assert(result === ["10u32"]);
234
+ ```
235
+
236
+ ### 2.5 Program execution on the Aleo Network
237
+ The SDK provides the ability to execute programs and store an encrypted transcript of the execution on the Aleo
238
+ network that anyone can trustlessly verify.
239
+
240
+ This process can be thought of being executed in the following steps:
241
+ 1. A program is run locally
242
+ 2. A proof that the program was executed correctly and that the outputs follow from the inputs is generated
243
+ 3. A transcript of the proof is generated client-side containing encrypted proof data (see [Section 2.6](#4-managing-records-and-private-state))
244
+ and any public outputs or state the user of the program wishes to reveal
245
+ 4. The proof transcript is posted to the Aleo network and verified by the Aleo validator nodes in a trustless manner
246
+ 5. If the proof is valid, it is stored and anyone can later verify the proof and read the outputs the author of the
247
+ program has chosen to make public. Private inputs will remain encrypted, but the author of the proof can also choose to
248
+ retrieve this encrypted state at any point and decrypt it locally for their own use.
249
+
250
+ Posting an execution to the Aleo Network serves as a globally trustless and verifiable record of a program execution and
251
+ any resulting state changes in private or public data.
252
+
253
+ A simple example of running the hello world program on the Aleo network is shown below:
254
+ ```typescript
255
+ import { Account, AleoNetworkClient, NetworkRecordProvider, ProgramManager, KeySearchParams } from '@provablehq/sdk';
256
+
257
+ // Create a key provider that will be used to find public proving & verifying keys for Aleo programs
258
+ const keyProvider = new AleoKeyProvider();
259
+ keyProvider.useCache = true;
260
+
261
+ // Create a record provider that will be used to find records and transaction data for Aleo programs
262
+ const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
263
+ const recordProvider = new NetworkRecordProvider(account, networkClient);
264
+
265
+ // Initialize a program manager to talk to the Aleo network with the configured key and record providers
266
+ const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
267
+
268
+ // Provide a key search parameter to find the correct key for the program if they are stored in a memory cache
269
+ const keySearchParams = { "cacheKey": "hello_hello:hello" };
270
+
271
+ // Execute the program using the options provided inline
272
+ const tx_id = await programManager.execute({
273
+ programName: "hello_hello.aleo",
274
+ functionName: "hello_hello",
275
+ fee: 0.020,
276
+ privateFee: false, // Assuming a value for privateFee
277
+ inputs: ["5u32", "5u32"],
278
+ keySearchParams: keySearchParams
279
+ });
280
+ const transaction = await programManager.networkClient.getTransaction(tx_id);
281
+ ```
282
+
283
+ A reader of the above example may notice the `RecordProvider` and `KeyProvider` classes that were not present in the local
284
+ execution example. The `KeyProvider` class helps users of the SDK find `Proving Keys` for programs. `Proving Keys`
285
+ allow zero knowledge proofs that the programs were executed correctly to be created. The `RecordProvider` class helps
286
+ find `Records` which are private data associated with programs that can be changed and updated throughout time.
287
+ These two concepts are explained in more detail below.
288
+
289
+ ### 2.6 Program Proving Keys & Program Records
290
+
291
+ Executing Aleo programs in zero knowledge requires two additional pieces of information.
292
+
293
+ 1. **Function Proving & Verifying Keys:** Proving and Verifying keys are cryptographic keys that are generated when a
294
+ program function is executed. These keys are public and unique for each function in a program. The proving key allows any party to
295
+ execute the program and generate a proof that the program was executed correctly. The verifying keys allow any party
296
+ to verify that the proof was generated correctly and the execution is correct. These keys are required to create the
297
+ zero knowledge property of program execution.
298
+ 2. **Program Records:** Records are private state generated by a program belonging to a unique private keyholder. Records
299
+ are generated by a program's functions and can be changed and updated by when a user runs various functions of the
300
+ program. These records are private by default and are used to manage updatable private state. One of the most clear
301
+ usages of records is to the `credits` record in the `credits.aleo`. Credits records are one of two official ways of
302
+ representing Aleo credits on the Aleo Network and are used to pay all transaction fees on the network. More information
303
+ on Records can be found in the [Records](#41-private-state-data--records) section below.
304
+
305
+ For this reason, all programs will need proving and verifying keys to operate and many functions in Aleo programs will
306
+ require records as inputs. To simplify the process of managing keys and records, the Aleo SDK provides two abstractions
307
+ for managing these concepts:
308
+
309
+ 1. **KeyProvider:** When program functions execute, by default, they will synthesize the proving and verifying keys needed to
310
+ make a zero knowledge proof of the execution. However, these keys are large and expensive to generate. For this reason, applications may
311
+ want to store these keys and re-use them in future executions. The `KeyProvider` interface provides the ability for
312
+ users of the SDK to provide their own key storage and retrieval mechanism. The SDK provides a default implementation
313
+ of the `KeyProvider` interface via the `AleoKeyProvider` class.
314
+ 2. **RecordProvider:** When programs execute, they will often need to find records that belong to a user. The
315
+ `RecordProvider` interface allows users of the SDK to implement their own record storage and retrieval mechanism. The
316
+ SDK provides a default implementation of the `RecordProvider` interface via the `NetworkRecordProvider` class which
317
+ searches the Aleo network for records uniquely belonging to a user.
318
+
319
+ The `ProgramManager` class is capable of taking a `KeyProvider` and `RecordProvider` as arguments and will use them to
320
+ find the correct keys and records for a program execution.
321
+
322
+ ### 2.7 Deploy a new Program to the Aleo Network
323
+
324
+ The Aleo Network contains a public registry of programs that can be executed by anyone. Any user can add an Aleo program
325
+ to the network (as long as it doesn't already currently exist) by paying a deployment fee in Aleo credits. The SDK
326
+ provides a simple interface for deploying programs to the Aleo network using the program manager.
327
+
328
+ ```typescript
329
+ import { Account, AleoNetworkClient, NetworkRecordProvider, ProgramManager, KeySearchParams} from '@provablehq/sdk';
330
+
331
+ // Create a key provider that will be used to find public proving & verifying keys for Aleo programs
332
+ const keyProvider = new AleoKeyProvider();
333
+ keyProvider.useCache(true);
334
+
335
+ // Create a record provider that will be used to find records and transaction data for Aleo programs
336
+ const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
337
+
338
+ // Use existing account with funds
339
+ const account = new Account({
340
+ privateKey: "user1PrivateKey",
341
+ });
342
+
343
+ const recordProvider = new NetworkRecordProvider(account, networkClient);
344
+
345
+ // Initialize a program manager to talk to the Aleo network with the configured key and record providers
346
+ const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
347
+ programManager.setAccount(account)
348
+
349
+ // Define an Aleo program to deploy
350
+ const program = "program hello_hello.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n";
351
+
352
+ // Define a fee to pay to deploy the program
353
+ const fee = 1.8; // 1.8 Aleo credits
354
+
355
+ // Deploy the program to the Aleo network
356
+ const tx_id = await programManager.deploy(program, fee);
357
+
358
+ // Verify the transaction was successful
359
+ const transaction = await programManager.networkClient.getTransaction(tx_id);
360
+ ```
361
+
362
+ The NetworkRecordProvider will attempt to scan the network for a fee record for the account provided. Doing a recent
363
+ public transfer to the deploying account will ensure a record is found quickly, or you can provide a fee record manually
364
+ by [scanning](https://developer.aleo.org/testnet/getting_started/deploy_execute/#scan) for a record and passing it as a
365
+ string.
366
+
367
+ ```typescript
368
+ // Set fee record manually
369
+ const feeRecord = "{ owner: aleo1xxx...xxx.private, microcredits: 2000000u64.private, _nonce: 123...789group.public}";
370
+
371
+ // Deploy the program to the Aleo network
372
+ const tx_id = await programManager.deploy(program, fee, undefined, feeRecord);
373
+ ```
374
+
375
+ ### 2.8 React Example
376
+
377
+ The above concepts can be tied together in a concrete example of a React web app. This example can be installed in one
378
+ step by running:
379
+
380
+ `npm create aleo-app@latest`
381
+
382
+ #### Program Execution
383
+
384
+ Program execution is a computationally expensive process. For this reason, it is recommended to execute programs in
385
+ webworkers.
386
+
387
+ <details>
388
+ <summary>Example Web Worker Usage</summary>
389
+
390
+ A worker file that performs the execution can be created as follows:
391
+ `worker.js`
392
+ ```jsx
393
+ import * as aleo from "@provablehq/sdk";
394
+
395
+ // Threads are then initialized to execute the program in parallel using multithreading
396
+ await aleo.initThreadPool();
397
+
398
+ /// The program manager is initialized with a key provider and a record provider
399
+ const defaultHost = "https://api.explorer.aleo.org/v1";
400
+ const keyProvider = new aleo.AleoKeyProvider();
401
+ const recordProvider = new aleo.NetworkRecordProvider(new Account(), "https://api.explorer.aleo.org/v1");
402
+ const programManager = new aleo.ProgramManager(
403
+ defaultHost,
404
+ keyProvider,
405
+ recordProvider,
406
+ );
407
+
408
+ // The key provider is set to use an in-memory cache to store keys
409
+ keyProvider.useCache(true);
410
+
411
+ self.postMessage({
412
+ type: "ALEO_WORKER_READY",
413
+ });
414
+
415
+ // The program is executed when specific events are dispatched and then communicates the result to the main thread
416
+ // when execution has finished
417
+ let lastLocalProgram = null;
418
+ self.addEventListener("message", (ev) => {
419
+ if (ev.data.type === "ALEO_EXECUTE_PROGRAM_LOCAL") {
420
+ const {localProgram, aleoFunction, inputs, privateKey} = ev.data;
421
+
422
+ console.log("Web worker: Executing function locally...");
423
+ let startTime = performance.now();
424
+
425
+ (async function () {
426
+ try {
427
+ // Ensure the program is valid and that it contains the function specified
428
+ const program = programManager.createProgramFromSource(localProgram);
429
+ const program_id = program.id();
430
+ if (!program.hasFunction(aleoFunction)) {
431
+ throw `Program ${program_id} does not contain function ${aleoFunction}`;
432
+ }
433
+ const cacheKey = `${program_id}:${aleoFunction}`;
434
+
435
+ // Get the program imports
436
+ const imports =
437
+ programManager.networkClient.getProgramImports(localProgram);
438
+
439
+ // Get the proving and verifying keys for the function
440
+ if (lastLocalProgram !== localProgram) {
441
+ const keys = programManager.executionEngine.synthesizeKeypair(
442
+ localProgram,
443
+ aleoFunction,
444
+ );
445
+ programManager.keyProvider.cacheKeys(cacheKey, [
446
+ keys.provingKey(),
447
+ keys.verifyingKey(),
448
+ ]);
449
+ lastLocalProgram = localProgram;
450
+ }
451
+
452
+ // Pass the cache key to the execute function
453
+ const keyParams = new aleo.AleoKeyProviderParams({
454
+ cacheKey: cacheKey,
455
+ });
456
+
457
+ // Execute the function locally
458
+ let response = await programManager.executeOffline(
459
+ localProgram,
460
+ aleoFunction,
461
+ inputs,
462
+ imports,
463
+ keyParams,
464
+ undefined,
465
+ undefined,
466
+ aleo.PrivateKey.from_string(privateKey),
467
+ );
468
+
469
+ // Return the outputs to the main thread
470
+ self.postMessage({
471
+ type: "OFFLINE_EXECUTION_COMPLETED",
472
+ outputs,
473
+ });
474
+ } catch (error) {
475
+ console.error(error);
476
+ self.postMessage({
477
+ type: "ERROR",
478
+ errorMessage: error.toString(),
479
+ });
480
+ }
481
+ })();
482
+ }
483
+ });
484
+ ```
485
+
486
+ The WebWorker can then be initialized in worker provider component which uses React effects
487
+
488
+ ```jsx
489
+ import { useEffect, useState } from "react";
490
+ import WorkerContext from "./WorkerContext";
491
+
492
+ const WorkerProvider = ({ children }) => {
493
+ const [worker, setWorker] = useState(null);
494
+ const [workerReady, setWorkerReady] = useState(false);
495
+
496
+ useEffect(() => {
497
+ let worker = new Worker(new URL("./worker.js", import.meta.url), {
498
+ type: "module",
499
+ });
500
+ setWorker(worker);
501
+
502
+ worker.onmessage = (event) => {
503
+ if (event.data.type === "ALEO_WORKER_READY") {
504
+ setWorkerReady(true);
505
+ }
506
+ };
507
+
508
+ return () => {
509
+ worker.terminate();
510
+ };
511
+ }, []);
512
+
513
+ if (!workerReady) {
514
+ return (
515
+ <>
516
+ <div className="spinner">
517
+ <div className="dot1"></div>
518
+ </div>
519
+ </>
520
+ );
521
+ }
522
+
523
+ return (
524
+ <WorkerContext.Provider value={worker}>
525
+ {children}
526
+ </WorkerContext.Provider>
527
+ );
528
+ };
529
+
530
+ export default WorkerProvider;
531
+ ```
532
+
533
+ </details>
534
+
535
+ Using both webworkers and a wasm initialization in a React hook, a single page app can be created that executes
536
+ Aleo zero knowledge programs.
537
+
538
+ <details>
539
+ <summary>Example App.jsx Implementing Zero Knowledge Program Execution</summary>
540
+
541
+ ```jsx
542
+ import { useEffect, useState } from "react";
543
+ import reactLogo from "./assets/react.svg";
544
+ import aleoLogo from "./assets/aleo.png";
545
+ import "./App.css";
546
+ import { useAleoWASM } from "./aleo-wasm-hook";
547
+
548
+ function App() {
549
+ const [count, setCount] = useState(0);
550
+ const aleo = useAleoWASM();
551
+ const [account, setAccount] = useState(null);
552
+ const [loading, setLoading] = useState(false);
553
+
554
+ const generateAccount = () => {
555
+ setAccount(new aleo.PrivateKey());
556
+ };
557
+
558
+ const [worker, setWorker] = useState(null);
559
+
560
+ useEffect(() => {
561
+ if (worker === null) {
562
+ const spawnedWorker = spawnWorker();
563
+ setWorker(spawnedWorker);
564
+ return () => {
565
+ spawnedWorker.terminate();
566
+ };
567
+ }
568
+ }, []);
569
+
570
+ function spawnWorker() {
571
+ return new Worker(new URL("workers/worker.js", import.meta.url), {
572
+ type: "module",
573
+ });
574
+ }
575
+
576
+ function postMessagePromise(worker, message) {
577
+ return new Promise((resolve, reject) => {
578
+ worker.onmessage = (event) => {
579
+ resolve(event.data);
580
+ };
581
+ worker.onerror = (error) => {
582
+ reject(error);
583
+ };
584
+ worker.postMessage(message);
585
+ });
586
+ }
587
+
588
+ async function execute() {
589
+ const hello_hello_program =
590
+ "program hello_hello.aleo;\n" +
591
+ "\n" +
592
+ "function hello:\n" +
593
+ " input r0 as u32.public;\n" +
594
+ " input r1 as u32.private;\n" +
595
+ " add r0 r1 into r2;\n" +
596
+ " output r2 as u32.private;\n";
597
+
598
+ setLoading(true);
599
+ const result = await postMessagePromise(worker, {
600
+ type: "ALEO_EXECUTE_PROGRAM_LOCAL",
601
+ localProgram: hello_hello_program,
602
+ aleoFunction: "hello",
603
+ inputs: ["5u32", "5u32"],
604
+ privateKey: account.to_string(),
605
+ });
606
+ setLoading(false);
607
+
608
+ alert(JSON.stringify(result));
609
+ }
610
+
611
+ return (
612
+ <>
613
+ <div>
614
+ <a href="https://aleo.org" target="_blank">
615
+ <img src={aleoLogo} className="logo" alt="Aleo logo" />
616
+ </a>
617
+ <a href="https://react.dev" target="_blank">
618
+ <img src={reactLogo} className="logo react" alt="React logo" />
619
+ </a>
620
+ </div>
621
+ <h1>Aleo + React</h1>
622
+ <div className="card">
623
+ <button onClick={() => setCount((count) => count + 1)}>
624
+ count is {count}
625
+ </button>
626
+ <p>
627
+ <button onClick={generateAccount}>
628
+ {account
629
+ ? `Account is ${JSON.stringify(account.to_string())}`
630
+ : `Click to generate account`}
631
+ </button>
632
+ </p>
633
+ <p>
634
+ <button disabled={!account || loading} onClick={execute}>
635
+ {loading
636
+ ? `Executing...check console for details...`
637
+ : `Execute hello_hello.aleo`}
638
+ </button>
639
+ </p>
640
+ <p>
641
+ Edit <code>src/App.jsx</code> and save to test HMR
642
+ </p>
643
+ </div>
644
+ <p className="read-the-docs">
645
+ Click on the Aleo and React logos to learn more
646
+ </p>
647
+ </>
648
+ );
649
+ }
650
+
651
+ export default App;
652
+ ```
653
+ </details>
654
+
655
+
656
+ A full example of this implementation can be found [here](https://github.com/ProvableHQ/sdk/blob/testnet3/create-aleo-app/template-react/src/App.jsx)
657
+
658
+ ## 3. Aleo Credit Transfers
659
+
660
+ ### 3.1 Aleo Credits
661
+
662
+ The official token of operation of the Aleo Network are Aleo credits. Aleo credits are used to pay all fees for program
663
+ execution on the Aleo network.
664
+
665
+ Aleo credits are defined in the [credits.aleo](https://www.aleo.network/programs/credits.aleo) program. This program is
666
+ deployed to the Aleo Network and defines data structures representing Aleo credits and the functions used to manage them.
667
+
668
+ There are two ways to hold Aleo credits.
669
+
670
+ #### 1 - Private balances via credits.aleo records
671
+ The first method is owning a `credits` record which enables a participant in the Aleo
672
+ network to hold a private balance of Aleo credits.
673
+ ```
674
+ record credits:
675
+ owner as address.private;
676
+ microcredits as u64.private;
677
+ ```
678
+
679
+ A user's total private credits balance will consist of all unspent `credits` records owned by the user with a nonzero
680
+ `microcredits` value.
681
+
682
+ #### 2 - Public balances via credits.aleo account mapping
683
+ The second is by holding a `balance` in the `account` mapping in the `credits.aleo` program on the Aleo Network.
684
+
685
+ ```
686
+ mapping account:
687
+ key owner as address.public;
688
+ value microcredits as u64.public;
689
+ ```
690
+
691
+ The total public credits balance of a user is the value of account mapping at the user's address. Users can hold both private and public balances simultaneously.
692
+
693
+ More information about `records` and `mappings` and how they related to private and public balances are explained in the
694
+ [Managing Program Data and Private State](#4-managing-program-data-and-private-state) section.
695
+
696
+ ### 3.2 Transfer Aleo Credits
697
+ The `ProgramManager` allows transfers of aleo credits via the `transfer` method. This function executes the credits.aleo
698
+ program under the hood.
699
+
700
+ There are four transfer functions available.
701
+
702
+ #### 1. transfer_private
703
+
704
+ Takes a `credits` record of owned by the sender, subtracts an amount from it, and adds that amount
705
+ to a new record owned by the receiver. This function is %100 private and does not affect the `account` mapping.
706
+
707
+ ```mermaid
708
+ graph LR
709
+ user1--record1 \n owner: user1address \n balance: 10000u64-->t1[transfer_private]
710
+ user1--amount: 4000u64-->t1
711
+ t1-.record2 \n owner: user1address \n amount: 6000u64.->user1
712
+ t1--record3 \n owner: user2address \n balance: 4000u64-->user2
713
+
714
+ ```
715
+
716
+ #### 2. transfer_private_to_public
717
+ Takes a `credits` record of owned by the sender, subtracts an amount from it, and adds
718
+ that amount to the `account` mapping of the receiver. This function is %50 private and %50 public. It consumes a record
719
+ as a private input and generates a public balance in the `account` mapping entry belonging to the receiver.
720
+
721
+ ```mermaid
722
+ graph LR
723
+ subgraph credits.aleo
724
+ m1[account mapping \n key: user3address \n value: 3000u64]
725
+ end
726
+ user1--record3 \n owner: user2address \n balance: 4000u64-->t1[transfer_private_to_public]
727
+ t1-.record4 \n owner: user2address \n amount: 1000u64.->user1
728
+ t1--amount 3000u64-->m1
729
+ ```
730
+
731
+ #### 3. transfer_public
732
+
733
+ Subtracts an amount of `credits` stored in the `account` mapping of the `credits.aleo program`, and
734
+ adds that amount to the `account` mapping of the receiver. This function is 100% public and does not consume or generate
735
+ any records.
736
+
737
+ ```mermaid
738
+ graph LR
739
+ subgraph credits.aleo account mappings - state 2
740
+ m3[account mapping \n key: user4address \n value: 3000u64]
741
+ m4[account mapping \n key: user3address \n value: 0u64]
742
+ end
743
+
744
+ subgraph credits.aleo account mappings - state 1
745
+ m2[account mapping \n key: user3address \n value: 3000u64]--transfer_public \n recipient: user4address \n amount: 3000u64-->m3
746
+ m1[account mapping \n key: user4address \n value: N/A]
747
+ end
748
+ ```
749
+
750
+ #### 4. transfer_public_to_private
751
+ Subtracts an amount `credits` stored in the `account` mapping of the `credits.aleo program`
752
+ and adds that amount to a new private record owned by the receiver. This function is %50 private and %50 public.
753
+ It publicly consumes a balance in the `account` mapping entry belonging to the sender and generates a private record
754
+ as a private output.
755
+
756
+ ```mermaid
757
+ graph LR
758
+ subgraph credits.aleo account mappings - state 2
759
+ m2[account mapping \n key: user5address \n value: 0u64]
760
+ end
761
+
762
+ subgraph credits.aleo account mappings - state 1
763
+ m1[account mapping \n key: user5address \n value: 3000u64]
764
+ end
765
+
766
+ m1--recipient: user6address \n amount: 3000u64-->transfer_public_to_private
767
+ transfer_public_to_private--record5 \n owner: user6address \n amount: 3000u64-->user6
768
+ ```
769
+
770
+ All four of these functions can be used to transfer credits between users via the `transfer` function in the
771
+ `ProgramManager` by specifying the transfer type as the third argument.
772
+
773
+ ```typescript
774
+ import { Account, ProgramManager, AleoKeyProvider, NetworkRecordProvider, AleoNetworkClient } from '@aleo/sdk';
775
+
776
+ // Create a new NetworkClient, KeyProvider, and RecordProvider
777
+ const account = Account.from_string({privateKey: "user1PrivateKey"});
778
+ const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
779
+ const keyProvider = new AleoKeyProvider();
780
+ const recordProvider = new NetworkRecordProvider(account, networkClient);
781
+
782
+ // Initialize a program manager with the key provider to automatically fetch keys for executions
783
+ const USER_1_ADDRESS = "user1Address";
784
+ const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
785
+ programManager.setAccount(account);
786
+
787
+ // Send a private transfer to yourself
788
+ const tx_id = await programManager.transfer(1, USER_1_ADDRESS, "transfer_private", 0.2);
789
+
790
+ // Update or initialize a public balance in your own account mapping
791
+ const tx_id_2 = await programManager.transfer(1, USER_1_ADDRESS, "transfer_private_to_public", 0.2);
792
+
793
+ // Check the value of your public balance
794
+ let public_balance = programManager.networkClient.getMappingValue("credits.aleo", USER_1_ADDRESS);
795
+ assert(public_balance === 0.2*1_000_000);
796
+
797
+ /// Send public transfer to another user
798
+ const USER_2_ADDRESS = "user2Address";
799
+ const tx_id_3 = await programManager.transfer(1, USER_2_ADDRESS, "transfer_public", 0.1);
800
+
801
+ // Check the value of the public balance and assert that it has been updated
802
+ public_balance = programManager.networkClient.getMappingValue("credits.aleo", USER_1_ADDRESS);
803
+ const user2_public_balance = programManager.networkClient.getMappingValue("credits.aleo", USER_1_ADDRESS);
804
+ assert(public_balance === 0.1*1_000_000);
805
+ assert(user2_public_balance === 0.1*1_000_000);
806
+
807
+ /// Create a private record from a public balance
808
+ const tx_id_4 = await programManager.transfer(1, USER_1_ADDRESS, "transfer_public_to_private", 0.1);
809
+
810
+ // Check the value of the public balance and assert that it has been updated
811
+ public_balance = programManager.networkClient.getMappingValue("credits.aleo", USER_1_ADDRESS);
812
+ assert(public_balance === 0);
813
+ ```
814
+
815
+ ### 3.2 Checking Public Balances
816
+ As shown above, a public balance of any address can be checked with `getMappingValue` function of the `NetworkClient`.
817
+
818
+ ```typescript
819
+ const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
820
+ const USER_1_ADDRESS = "user1Address";
821
+ const public_balance = networkClient.getMappingValue("credits.aleo", USER_1_ADDRESS);
822
+ ```
823
+
824
+ ## 4. Managing Program Data and Private State
825
+
826
+ ### 4.1 Private State Data: Records
827
+ Records in are analogous to concept of [UTXOs](https://en.wikipedia.org/wiki/Unspent_transaction_output). When a record is
828
+ created by a program, it can then be consumed later by the same program as an input to a function. Once a record is used
829
+ as input, it is considered consumed and cannot be used again. In many cases a new record will be created from the output
830
+ of the function. Records are private by default and are associated with a single Aleo program and a single private key
831
+ representing a user.
832
+
833
+ ### 4.2 Record Usage Example: Private Value Transfers
834
+
835
+ A straightforward example of a usage of records in a program can be demonstrated by explaining the process of private
836
+ value transfers of official Aleo credits on the Aleo network.
837
+
838
+ Aleo credits are the official token in which all on-chain execution and deployment fees are paid. Credits can be public
839
+ or private. Private credits are represented by the `credits` record in the [credits.aleo](https://www.aleo.network/programs/credits.aleo)
840
+ program.
841
+
842
+ ```
843
+ record credits:
844
+ owner as address.private;
845
+ microcredits as u64.private;
846
+ ```
847
+
848
+ Credits records contain an `owner` field representing the address which owns the record and a `microcredits` field
849
+ representing the amount of microcredits in the record. 1 credit is equal to 1,000,000 microcredits.
850
+
851
+ An example of an Aleo function that both takes a record as input and outputs a record is the `transfer_private` function
852
+ of the `credits.aleo` program. This function takes a private `credits` record as input and outputs two new private `credits`
853
+ records as output (one that sends the credits to the recipient and one that sends the remaining credits to the sender).
854
+
855
+ The source code for the `transfer_private` is:
856
+ ```
857
+ function transfer_private:
858
+ input r0 as credits.record;
859
+ input r1 as address.private;
860
+ input r2 as u64.private;
861
+ sub r0.microcredits r2 into r3;
862
+ cast r1 r2 into r4 as credits.record;
863
+ cast r0.owner r3 into r5 as credits.record;
864
+ output r4 as credits.record;
865
+ output r5 as credits.record;
866
+ ```
867
+
868
+ The `transfer_private` function can be graphically represented by the graph below. In the graph the first record "Record 1"
869
+ is consconsumed and can never be used again. From the data in Record 1, two more records are created. One containing
870
+ the intended amount for the recipient which is now owned by the recipient and another containing the remaining credits
871
+ which is sent back to the sender.
872
+
873
+ ```mermaid
874
+ graph LR
875
+ User1[Sender Address]
876
+ i1[Input 1: Credits Record 1]-->p1
877
+ i2[Input 2: Recipient Address]-->p1
878
+ p1[Credits.aleo:transfer_private]
879
+ p1--Credits Record 2-->User1
880
+ p1--Credits Record 3-->R1[Recipient Address]
881
+ ```
882
+
883
+ This chain of ownership is tracked by the Aleo Blockchain when users choose to submit their transactions to the Aleo
884
+ Network. This is allows other users who receive records to receive the updated data and verify that this data was
885
+ provably generated by the intended program.
886
+
887
+ What this process allows is a private chain of state to be created between multiple users. In the context of value
888
+ transfers, a chain of state might look like the following:
889
+
890
+ ```mermaid
891
+ graph LR
892
+ user1--record1-->t1[transfer_private]
893
+ t1-.record2.->user1
894
+ t1--record3-->user2
895
+ user2--record3-->t2[transfer_private]
896
+ t2--record5-->user3
897
+ t2-.record4.->user2
898
+ ```
899
+
900
+ The above state chain would be executed in the following way using the SDK:
901
+ #### Step 1 - User 1 sends a private value transfer to User 2
902
+ ```typescript
903
+ // USER 1
904
+ import { Account, ProgramManager, AleoKeyProvider, NetworkRecordProvider, AleoNetworkClient } from '@aleo/sdk';
905
+
906
+ // Create a new NetworkClient, KeyProvider, and RecordProvider
907
+ const account = Account.from_string({privateKey: "user1PrivateKey"});
908
+ const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
909
+ const keyProvider = new AleoKeyProvider();
910
+ const recordProvider = new NetworkRecordProvider(account, networkClient);
911
+
912
+ // Initialize a program manager with the key provider to automatically fetch keys for executions
913
+ const USER_2_ADDRESS = "user2Address";
914
+ const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
915
+ programManager.setAccount(account);
916
+
917
+ /// Send private transfer to user 2
918
+ const tx_id = await programManager.transfer(1, USER_2_ADDRESS, "transfer_private", 0.2);
919
+ ```
920
+
921
+ #### Step 2 - User 2 receives the transaction ID and fetches the credits record they received from user 1 from the network. They then send it to user 3
922
+
923
+ ```typescript
924
+ // USER 2
925
+ import { Account, ProgramManager, AleoKeyProvider, NetworkRecordProvider, AleoNetworkClient } from '@aleo/sdk';
926
+
927
+ // Create a new NetworkClient, KeyProvider, and RecordProvider
928
+ const account = Account.from_string({privateKey: "user2PrivateKey"});
929
+ const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
930
+ const keyProvider = new AleoKeyProvider();
931
+ const recordProvider_User2 = new NetworkRecordProvider(account, networkClient);
932
+
933
+ // Initialize a program manager with the key provider to automatically fetch keys for executions
934
+ const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
935
+ programManager.setAccount(account);
936
+
937
+ // Fetch the transaction from the network that user 1 sent
938
+ const transaction = await programManager.networkClient.getTransaction(tx_id);
939
+ const record = <string>transaction.execution.transitions[0].outputs[0].value;
940
+
941
+ // Decrypt the record with the user's view key
942
+ const recordCiphertext = <RecordCiphertext>RecordCiphertext.fromString(record);
943
+ const recordPlaintext = <RecordPlaintext>recordCiphertext.decrypt(account.viewKey());
944
+
945
+ // Send a transfer to user 3 using the record found above
946
+ const USER_3_ADDRESS = "user3Address";
947
+ const tx_id = await programManager.transfer(1, USER_3_ADDRESS, "transfer_private", 0.2, undefined, recordPlaintext);
948
+ ```
949
+
950
+ When an execution such as `transfer_private` consumes or generates a record is posted on the network and encrypted transcript
951
+ of the execution is posted, containing an encrypted version of the record output and a transaction ID.
952
+
953
+ Because the records are encrypted when they're posted on the network, they do not reveal any information about the party
954
+ who executed the program, nor the contents of the record. The only information that is revealed is the program ID,
955
+ function name, encrypted function inputs, and the transaction ID of the program execution. No user except for the recipient
956
+ of the record can see the contents of the record.
957
+
958
+ Below you can see what the exact data which is posted to the Aleo Network when `transfer_private` is run. Note that the
959
+ record, the amount transferred, and both the sender & recipient addresses are all encrypted.
960
+
961
+ <details>
962
+ <summary>transfer_private Execution Transcript</summary>
963
+
964
+ ```json
965
+ "transactions": [
966
+ {
967
+ "status": "accepted",
968
+ "type": "execute",
969
+ "index": 0,
970
+ "transaction": {
971
+ "type": "execute",
972
+ "id": "at1s7dxunms8xhdzgaxrwf0yvq2dqgxtf4a3j8g878rhfr0zwhap5gqywsw8y",
973
+ "execution": {
974
+ "transitions": [
975
+ {
976
+ "id": "as1thy8fvkz0rkls5wnmfq5udrcvvzurq7mqk8pkhjf63htqjf9mugqp0mfhd",
977
+ "program": "credits.aleo",
978
+ "function": "transfer_private",
979
+ "inputs": [
980
+ {
981
+ "type": "record",
982
+ "id": "1406044754369042876058586523429806531093330762697573675195902502647806778955field",
983
+ "tag": "242626059121157295593694555515381893342956813170338731374395259242800138642field"
984
+ },
985
+ {
986
+ "type": "private",
987
+ "id": "1533599744296862879610225011439684001995294756698105572984689232395187168232field",
988
+ "value": "ciphertext1qgqgpu7m8p0rwjahwffyvm4g4n6903d6ufqty74z4504w4rn356hgp9jvpuvx8suu0pukr3sl7n8x65dz35nu4jdy4lgcguxldygufrfpyqd6xr5"
989
+ },
990
+ {
991
+ "type": "private",
992
+ "id": "4081557229261486898857101724786348855190759711760925564309233047223407640812field",
993
+ "value": "ciphertext1qyqxd9wue0qh8hs6dgevn7zleedfkzf7pft8ecked2xq3pw54pgqzyqr69sgx"
994
+ }
995
+ ],
996
+ "outputs": [
997
+ {
998
+ "type": "record",
999
+ "id": "1388064668770056715587596299070268626507043043686185311840561493640415146425field",
1000
+ "checksum": "5376939704883651492329501631722578074516322228314928758786996843926470523116field",
1001
+ "value": "record1qyqsq4r7mcd3ystjvjqda0v2a6dxnyzg9mk2daqjh0wwh359h396k7c9qyxx66trwfhkxun9v35hguerqqpqzqzshsw8dphxlzn5frh8pknsm5zlvhhee79xnhfesu68nkw75dt2qgrye03xqm4zf5xg5n6nscmmzh7ztgptlrzxq95syrzeaqaqu3vpzqf03s6"
1002
+ },
1003
+ {
1004
+ "type": "record",
1005
+ "id": "4635504195534945632234501197115926012056789160185660629718795843347495373207field",
1006
+ "checksum": "3428805926164481449334365355155755448945974546383155334133384781819684465685field",
1007
+ "value": "record1qyqsp2vsvvfulmk0q0tmxq7p9pffhfhha9h9pxsftujh57kkjuahx9s0qyxx66trwfhkxun9v35hguerqqpqzq8etfmzt2elj37hkf9fen2m2qes8564sr8k970zyud5eqmq7ztzq5r3095mkfdzqzz7yp6qfavqsl3t22t6dvgauqqt2xqk98zwmtusq5ck7fm"
1008
+ }
1009
+ ],
1010
+ "tpk": "5283803395323806407328334221689294196419052177553228331323093330938016699852group",
1011
+ "tcm": "4398026033398688325681745841147300822741685834906186660771751747897598751646field"
1012
+ }
1013
+ ],
1014
+ ```
1015
+ </details>
1016
+
1017
+
1018
+ #### Record Decryption
1019
+
1020
+ If a user receives a private record from a program execution, they can use the SDK to decrypt encrypted records with
1021
+ their view keys and view their contents. Only records that are owned by the user can be decrypted. Decryption of records
1022
+ that are not owned by the user will fail.
1023
+
1024
+ Record decryption and ownership verification can be done in the SDK using the following code:
1025
+
1026
+ ```typescript
1027
+ import { Account, RecordCiphertext, RecordPlaintext } from '@aleo/sdk';
1028
+
1029
+ // Create an account from an existing private key
1030
+ const account = Account.from_string({privateKey: "existingPrivateKey"});
1031
+
1032
+ // Record value received as a string from program output or found on the Aleo network
1033
+ const record = "record1qyqsq4r7mcd3ystjvjqda0v2a6dxnyzg9mk2daqjh0wwh359h396k7c9qyxx66trwfhkxun9v35hguerqqpqzqzshsw8dphxlzn5frh8pknsm5zlvhhee79xnhfesu68nkw75dt2qgrye03xqm4zf5xg5n6nscmmzh7ztgptlrzxq95syrzeaqaqu3vpzqf03s6";
1034
+
1035
+ const recordCiphertext = RecordCiphertext.fromString(record);
1036
+
1037
+ // Check ownership of the record. If the account is the owner, decrypt the record
1038
+ if (RecordCiphertext.is_owner(account.viewKey())) {
1039
+ // Decrypt the record with the account's view key
1040
+ const recordPlaintext = recordCiphertext.decrypt(account.viewKey());
1041
+
1042
+ // View the record data
1043
+ console.log(recordPlaintext.toString());
1044
+ }
1045
+ ```
1046
+
1047
+ ### 4.3 Public State Data: Mappings
1048
+ Mappings are simple key value stores defined in a program. They are represented by a key and a value each of a specified
1049
+ type. They are stored directly within the Aleo blockchain and can be publicly read by any participant in the Aleo network.
1050
+
1051
+ An example of a mapping usage is `account` mapping in the `credits.aleo` program.
1052
+ ```
1053
+ mapping account:
1054
+ key owner as address.public;
1055
+ value microcredits as u64.public;
1056
+ ```
1057
+
1058
+ The `account` mapping is used to store public credits balances on the Aleo network. It takes a public address as a key
1059
+ and a public u64 value representing the number of microcredits owned by the address.
1060
+
1061
+ Mappings within programs are identified by the `mapping` identifier. Any program where this keyword appears contains an
1062
+ on-chain mapping. An example of a program that uses a mapping is shown below:
1063
+ ```
1064
+ program player_mapping_example.aleo
1065
+
1066
+ // The mapping identifier representing a score
1067
+ mapping score:
1068
+ key player as address.public;
1069
+ value score as u64.public;
1070
+
1071
+ // The update score function
1072
+ function update_score:
1073
+ input r0 as address.public;
1074
+ input r1 as u64.public;
1075
+
1076
+ // The finalize code block will be executed by Aleo network nodes.
1077
+ // When it runs it will update the value of the mapping.
1078
+ finalize update_score:
1079
+ input r0 as address.public;
1080
+ input r1 as u64.public;
1081
+ get.or_use score[r0] 0u64 into r2;
1082
+ add r1 r2 into r3;
1083
+ set r3 into account[r0];
1084
+ ```
1085
+
1086
+ Note that the above function has a `finalize` identifier. This identifier is used to identify a portion of a function's
1087
+ code that should be executed by nodes on the Aleo network. Program mappings are updated exclusively by code run by nodes
1088
+ on the Aleo Network written in `finalize` blocks.
1089
+
1090
+ ### 4.4 Reading Mappings
1091
+ Any state within a program mapping is public and can be read by any participant in the Aleo network. The `NetworkClient`
1092
+ class provides the `getMapping` method to read the public mappings within an program and the `getMappingValue` method to
1093
+ read the value of a specific key within a mapping.
1094
+
1095
+ ```typescript
1096
+ import { AleoNetworkClient } from '@aleo/sdk';
1097
+
1098
+ const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
1099
+ const creditsMappings = networkClient.getMappings("credits.aleo");
1100
+ assert(creditsMappings === ["account"]);
1101
+
1102
+ const publicCredits = networkClient.getMapping("credits.aleo", "[a valid aleo account with zero balance]");
1103
+ assert(publicCredits === "0u64");
1104
+ ```
1105
+
1106
+ ### 4.5 Initializing & Updating Mappings
1107
+ Updating mappings is done by executing a program function on the Aleo network which has a finalize block that updates the
1108
+ program's mapping. For instance the `transfer_public` function in the `credits.aleo` program updates the `account`
1109
+ mapping (and thus a user's balance) when called.
1110
+
1111
+ ```
1112
+ // The public interface called by users
1113
+ function transfer_public:
1114
+ input r0 as address.public;
1115
+ input r1 as u64.public;
1116
+ finalize self.caller r0 r1;
1117
+
1118
+ // The finalize block run by nodes on the Aleo network which update a user's public balance
1119
+ finalize transfer_public:
1120
+ input r0 as address.public;
1121
+ input r1 as address.public;
1122
+ input r2 as u64.public;
1123
+ get.or_use account[r0] 0u64 into r3;
1124
+ sub r3 r2 into r4;
1125
+ set r4 into account[r0];
1126
+ get.or_use account[r1] 0u64 into r5;
1127
+ add r5 r2 into r6;
1128
+ set r6 into account[r1];
1129
+ ```
1130
+
1131
+ From the perspective of the caller of the API, this is as simple as executing a normal Aleo function. Given the inputs
1132
+ to a function with a finalize scope that updates a mapping are valid, the mapping will either be intialized or updated
1133
+ by the Aleo network. All the user of the SDK must do is ensure that the inputs to the function are valid.
1134
+
1135
+ If function inputs are Invalid, the Network will return an error, but the fee paid for the transaction will still be
1136
+ consumed. So it is important to ensure that the inputs to a function are valid before executing it.
1137
+
1138
+ A simple example of a mapping update can be shown by simply executing the 'transfer_public` as shown below.
1139
+
1140
+ ```typescript
1141
+ import { Account, ProgramManager, AleoKeyProvider, NetworkRecordProvider, AleoNetworkClient } from '@aleo/sdk';
1142
+
1143
+ // Create a new NetworkClient, KeyProvider, and RecordProvider
1144
+ const account = Account.from_string({privateKey: "user1PrivateKey"});
1145
+ const networkClient = new AleoNetworkClient("https://api.explorer.aleo.org/v1");
1146
+ const keyProvider = new AleoKeyProvider();
1147
+ const recordProvider = new NetworkRecordProvider(account, networkClient);
1148
+
1149
+ // Initialize a program manager with the key provider to automatically fetch keys for executions
1150
+ const RECIPIENT_ADDRESS = "user1Address";
1151
+ const programManager = new ProgramManager("https://api.explorer.aleo.org/v1", keyProvider, recordProvider);
1152
+ programManager.setAccount(account);
1153
+
1154
+ // Update or initialize a public balance
1155
+ const tx_id = await programManager.transfer(1, RECIPIENT_ADDRESS, "transfer_private_to_public", 0.2);
1156
+ ```
1157
+
1158
+
1159
+ ## 5. Communicating with the Aleo Network
1160
+
1161
+ Communication with the Aleo network is done through the `AleoNetworkClient` class. This class provides methods to query
1162
+ data from Aleo network nodes and submit transactions to the Aleo network.
1163
+
1164
+ A full list of methods provided by the `AleoNetworkClient` class and usage examples can be found in the
1165
+ [Network Client API documentation](https://developer.aleo.org/sdk/typescript/aleo_network_client).
1166
+
1167
+ ## Further Documentation
1168
+
1169
+ API documentation for this package, the Leo Language, and Aleo instructions can be found on the [Aleo Developer Hub](https://developer.aleo.org/sdk/typescript/overview).
1170
+
1171
+ To view the API documentation for this package locally, open `docs/index.html`.
1172
+ To regenerate the documentation, run `npx jsdoc --configure jsdoc.json --verbose`