### Initial Project Setup Source: https://github.com/endojs/endo/blob/master/CONTRIBUTING.md Clone the repository, navigate to the directory, and install dependencies using yarn. This is the first step for any contributor. ```sh git clone git@github.com:endojs/endo.git cd endo yarn ``` -------------------------------- ### Install @endo/memoize with yarn Source: https://github.com/endojs/endo/blob/master/packages/memoize/README.md Install the @endo/memoize package using yarn. ```sh yarn add @endo/memoize ``` -------------------------------- ### Install @endo/lp32 with npm Source: https://github.com/endojs/endo/blob/master/packages/lp32/README.md Installs the @endo/lp32 package using npm. ```sh npm install @endo/lp32 ``` -------------------------------- ### Install Endo CLI from Source Source: https://github.com/endojs/endo/blob/master/packages/cli/demo/README.md Clone the Endo repository, install dependencies with Yarn, and create an alias for the Endo command. ```bash > git clone https://github.com/endojs/endo.git > yarn > alias endo=$PWD/packages/cli/bin/endo.cjs ``` -------------------------------- ### Install Endo Dependencies Source: https://github.com/endojs/endo/blob/master/docs/get-started.md Installs necessary packages for demonstrating CapTP locally, including initialization, CapTP protocol, stream utilities, eventual send, exo, and patterns. ```bash npm install @endo/init npm install @endo/captp npm install @endo/stream npm install @endo/eventual-send npm install @endo/exo npm install @endo/patterns ``` -------------------------------- ### Install @endo/lp32 with yarn Source: https://github.com/endojs/endo/blob/master/packages/lp32/README.md Installs the @endo/lp32 package using yarn. ```sh yarn add @endo/lp32 ``` -------------------------------- ### Install ESLint Source: https://github.com/endojs/endo/blob/master/packages/eslint-plugin/README.md Install ESLint as a development dependency for your project. ```sh npm i eslint --save-dev ``` -------------------------------- ### Install @endo/memoize with npm Source: https://github.com/endojs/endo/blob/master/packages/memoize/README.md Install the @endo/memoize package using npm. ```sh npm install @endo/memoize ``` -------------------------------- ### Basic Usage Example Source: https://github.com/endojs/endo/blob/master/packages/promise-kit/README.md Demonstrates the basic usage of `makePromiseKit` to create a promise that is resolved or rejected after a delay. ```APIDOC ## Basic Usage of makePromiseKit ### Description This example shows how to use `makePromiseKit` to create a promise for an asynchronous operation. The promise is resolved or rejected based on a simulated success condition. ### Method N/A (Illustrative JavaScript code) ### Endpoint N/A ### Request Example ```javascript import { makePromiseKit } from '@endo/promise-kit'; function asyncOperation() { const { promise, resolve, reject } = makePromiseKit(); setTimeout(() => { const success = true; // Simulating success or failure if (success) { resolve("Operation successful!"); } else { reject("Operation failed!"); } }, 2000); return promise; } async function handleAsyncOperation() { try { const result = await asyncOperation(); console.log(result); // "Operation successful!" } catch (error) { console.error(error); // "Operation failed!" } } handleAsyncOperation(); ``` ### Response (Illustrative console output) ``` Operation successful! ``` OR ``` Operation failed! ``` ``` -------------------------------- ### Install @endo/hex Package Source: https://github.com/endojs/endo/blob/master/packages/hex/README.md Install the @endo/hex package using npm. ```sh npm install @endo/hex ``` -------------------------------- ### Install @endo/eslint-plugin Source: https://github.com/endojs/endo/blob/master/packages/eslint-plugin/README.md Install the @endo/eslint-plugin package as a development dependency. ```sh npm install @endo/eslint-plugin --save-dev ``` -------------------------------- ### Multiple Promise Kits Example Source: https://github.com/endojs/endo/blob/master/packages/promise-kit/README.md Illustrates how to create and manage multiple independent promise kits simultaneously. ```APIDOC ## Creating Multiple Promise Kits ### Description This example demonstrates the creation and management of multiple promise kits, showing how each kit can be resolved independently. ### Method N/A (Illustrative JavaScript code) ### Endpoint N/A ### Request Example ```javascript import { makePromiseKit } from '@endo/promise-kit'; const kit1 = makePromiseKit(); const kit2 = makePromiseKit(); kit1.promise.then(value => console.log('Kit 1 resolved with:', value)); kit2.promise.then(value => console.log('Kit 2 resolved with:', value)); kit1.resolve('First success'); kit2.resolve('Second success'); ``` ### Response (Illustrative console output) ``` Kit 1 resolved with: First success Kit 2 resolved with: Second success ``` ``` -------------------------------- ### Round-Trip Example Source: https://github.com/endojs/endo/blob/master/packages/lp32/README.md Demonstrates a full round-trip scenario using `makeLp32Reader` and `makeLp32Writer` with `@endo/stream`'s `makePipe`. ```APIDOC ## Round-Trip Example ### Description This example demonstrates a complete cycle of writing and reading length-prefixed messages using `makeLp32Writer` and `makeLp32Reader` in conjunction with `@endo/stream`'s `makePipe` for creating an in-memory stream. ### Code ```javascript import { makePipe } from '@endo/stream'; import { makeLp32Reader, makeLp32Writer } from '@endo/lp32'; const [input, output] = makePipe(); const writer = makeLp32Writer(output); const reader = makeLp32Reader(input); const encoder = new TextEncoder(); const decoder = new TextDecoder(); // Producer side: Write messages await writer.next(encoder.encode('message 1')); await writer.next(encoder.encode('message 2')); await writer.return(); // Consumer side: Read messages for await (const message of reader) { console.log(decoder.decode(message)); } ``` ``` -------------------------------- ### Setup Python Virtual Environment Source: https://github.com/endojs/endo/blob/master/packages/ocapn/test/python-test-suite/README.md Activate the Python virtual environment before running the test suite. This ensures dependencies are correctly managed. ```bash source ./venv/bin/activate ``` -------------------------------- ### Install Endo and SES Source: https://github.com/endojs/endo/blob/master/docs/get-started.md Set up a new Node.js project with ESM support and install the 'ses' package to begin using Endo's HardenedJS features. ```shell mkdir my-first-endo cd my-first-endo echo '{"type": "module"}' > package.json npm init --yes npm install ses ``` -------------------------------- ### Install SES Source: https://github.com/endojs/endo/blob/master/packages/ses/README.md Install the SES shim using npm. This command is used to add SES to your project's dependencies. ```sh npm install ses ``` -------------------------------- ### Clone Repository and Install Dependencies Source: https://github.com/endojs/endo/blob/master/packages/bundle-source/CONTRIBUTING.md Clone the EndoJS repository and install the necessary Node.js dependencies. ```bash git clone https://github.com/Agoric/@REPO@/ npm install ``` -------------------------------- ### Install @endo/base64 Package Source: https://github.com/endojs/endo/blob/master/packages/base64/README.md Use npm to install the @endo/base64 package. This command is for Node.js environments. ```sh npm install @endo/base64 ``` -------------------------------- ### Install @endo/trampoline Source: https://github.com/endojs/endo/blob/master/packages/trampoline/README.md Standard installation command for the @endo/trampoline package using npm. ```sh npm install @endo/trampoline ``` -------------------------------- ### Install Familiar Chat Weblet Source: https://github.com/endojs/endo/blob/master/packages/cli/demo/README.md Installs the Familiar Chat weblet, granting it agent powers and setting a listening port. This prepares the application to manage your pet store and mailbox. ```bash > endo install cat.js --listen 8920 --powers AGENT --name familiar-chat ``` -------------------------------- ### Round-Trip Message Stream Example Source: https://github.com/endojs/endo/blob/master/packages/lp32/README.md Demonstrates a full cycle of writing and reading length-prefixed messages using `makeLp32Writer` and `makeLp32Reader` in conjunction with `makePipe` from `@endo/stream`. This example shows how to produce messages and then consume them from the same stream. ```javascript import { makePipe } from '@endo/stream'; import { makeLp32Reader, makeLp32Writer } from '@endo/lp32'; const [input, output] = makePipe(); const writer = makeLp32Writer(output); const reader = makeLp32Reader(input); const encoder = new TextEncoder(); const decoder = new TextDecoder(); // Producer await writer.next(encoder.encode('message 1')); await writer.next(encoder.encode('message 2')); await writer.return(); // Consumer for await (const message of reader) { console.log(decoder.decode(message)); } ``` -------------------------------- ### Usage Example for @endo/bytes Source: https://github.com/endojs/endo/blob/master/packages/bytes/README.md Demonstrates common usage patterns including text conversion, byte concatenation, comparison, and handling immutable byte buffers. ```js import { bytesFromText } from '@endo/bytes/from-string.js'; import { bytesToText } from '@endo/bytes/to-string.js'; import { concatBytes } from '@endo/bytes/concat.js'; import { bytesEqual } from '@endo/bytes/equals.js'; import { bytesToImmutable } from '@endo/bytes/to-immutable.js'; import { bytesFromImmutable } from '@endo/bytes/from-immutable.js'; const a = bytesFromText('Hello, '); const b = bytesFromText('world!'); const greeting = concatBytes([a, b]); bytesToText(greeting); // 'Hello, world!' bytesEqual(bytesFromText('abc'), bytesFromText('abc')); // true // Wrap a Uint8Array in a passable, immutable ArrayBuffer. const passable = bytesToImmutable(greeting); // Recover a working Uint8Array from an immutable buffer received over a vat boundary. bytesToText(bytesFromImmutable(passable)); // 'Hello, world!' ``` -------------------------------- ### Markdown Style Example Source: https://github.com/endojs/endo/blob/master/CONTRIBUTING.md Example demonstrating the recommended Markdown style with lines wrapped at 80 to 100 columns and each sentence starting on a new line. ```markdown The Endo stack provides a layered solution through four packages. Each package has a specific role in enabling safe message passing. Together, they form the foundation of distributed computing. ``` -------------------------------- ### makeExo: Single Instance Greeter Source: https://github.com/endojs/endo/blob/master/packages/exo/README.md Demonstrates creating a single, stateless exo instance using makeExo. This pattern is suitable for utility objects or simple services without instance-specific state. ```javascript import { makeExo } from '@endo/exo'; import { M } from '@endo/patterns'; const GreeterI = M.interface('Greeter', { greet: M.call(M.string()).returns(M.string()) }); const greeter = makeExo('Greeter', GreeterI, { greet(name) { return `Hello, ${name}!`; } }); greeter.greet('World'); // 'Hello, World!' ``` -------------------------------- ### Quick Start: Data Validation with @endo/patterns Source: https://github.com/endojs/endo/blob/master/packages/patterns/README.md Use `mustMatch` to validate data against a pattern. This example demonstrates matching a record with required and optional properties, throwing an error if the data does not conform. ```javascript import { M, mustMatch } from '@endo/patterns'; const specimen = harden({ foo: 3, bar: 4 }); const pattern = M.splitRecord( { foo: M.number() }, // required properties { bar: M.string(), baz: M.number() } // optional properties ); mustMatch(specimen, pattern); // throws: 'bar?: number 4 - Must be a string' ``` -------------------------------- ### Bundle Source from Command Line Source: https://github.com/endojs/endo/blob/master/packages/bundle-source/README.md Use the `bundle-source` tool to create a source bundle from an entry point script. The `--cache-json` option stores the bundle in a cache. ```console > yarn bundle-source --cache-json bundles program.js program ``` -------------------------------- ### Install @endo/bytes Source: https://github.com/endojs/endo/blob/master/packages/bytes/README.md Install the @endo/bytes package using npm. ```sh npm install @endo/bytes ``` -------------------------------- ### Build and Publish Release Source: https://github.com/endojs/endo/blob/master/packages/bundle-source/CONTRIBUTING.md Build the project for release and publish the package to the registry. ```bash npm run build npm publish ``` -------------------------------- ### Create and Use a Weak Cache Source: https://github.com/endojs/endo/blob/master/packages/cache-map/README.md Demonstrates creating a cache with a size limit and using its WeakMap-compatible methods. Keys are held weakly, so they may be garbage collected. Assertions verify cache behavior including eviction. ```javascript import { makeCacheMapKit } from '@endo/cache-map'; const { cache: weakCache, getMetrics } = makeCacheMapKit(2); const entries = [ { key: Symbol('key 1'), value: Symbol('value 1') }, { key: Symbol('key 2'), value: Symbol('value 2') }, { key: Symbol('key 3'), value: Symbol('value 3') }, ]; for (const { key, value } of entries) weakCache.set(key, value); assert(!weakCache.has(entries[0].key)); assert(weakCache.has(entries[1].key)); assert(weakCache.get(entries[2].key) === entries[2].value); weakCache.delete(entries[2].key); weakCache.set(entries[1].key, entries[0]); assert(!weakCache.has(entries[0].key)); assert(!weakCache.has(entries[2].key)); assert(weakCache.get(entries[1].key) === entries[0]); assert.throws(() => weakCache.set('unweakable key', {})); ``` -------------------------------- ### Create Guest and Make Doubler Source: https://github.com/endojs/endo/blob/master/packages/cli/demo/README.md CLI commands to create a guest profile for the doubler and then instantiate the doubler agent using its JavaScript file and powers. ```bash > endo mkguest doubler-handle doubler-agent > endo make doubler.js --name doubler --powers doubler-agent ``` -------------------------------- ### Run Endo Client Against Guile-hosted Sturdyref Source: https://github.com/endojs/endo/blob/master/packages/goblin-chat/test/guile-interop/README.md Execute the Endo client to connect to a Guile-hosted chatroom sturdyref. Ensure the sturdyref URI is provided as an argument. ```bash node ./packages/goblin-chat/test/guile-interop/index.js "ocapn://.../s/..." ``` -------------------------------- ### Disable Yarn Install Scripts Source: https://github.com/endojs/endo/wiki/Mitigating-Postinstall-Attacks-like-the-Shai‐Hulud-Worm Configure Yarn to disable install scripts by adding `{"enableScripts": false}` to your project's `.yarnrc.yml` file. This prevents arbitrary code execution during installation. ```yaml enableScripts: false ``` -------------------------------- ### Initialize Compartment with ModuleSource Source: https://github.com/endojs/endo/blob/master/packages/module-source/README.md Demonstrates setting up a Compartment with custom resolve and import hooks that utilize ModuleSource. Ensure 'ses' and '@endo/module-source' are imported. ```javascript import 'ses'; import { ModuleSource } from '@endo/module-source'; const c1 = new Compartment({}, {}, { name: "first compartment", resolveHook: (moduleSpecifier, moduleReferrer) => { return resolve(moduleSpecifier, moduleReferrer); }, importHook: async moduleSpecifier => { const moduleLocation = locate(moduleSpecifier); const moduleText = await retrieve(moduleLocation); return new ModuleSource(moduleText, moduleLocation); }, }); ``` -------------------------------- ### Installing @endo/random Source: https://github.com/endojs/endo/blob/master/packages/random/README.md Install the @endo/random package using npm. This command is used to add the library to your project's dependencies. ```sh npm install @endo/random ``` -------------------------------- ### Run Endo OCapN Test Server Source: https://github.com/endojs/endo/blob/master/packages/ocapn/test/python-test-suite/README.md Start the Node.js server to act as the host for the OCapN test suite. This is the first step in setting up the test environment. ```bash node ./packages/ocapn/test/python-test-suite/index.js ``` -------------------------------- ### Direct Use of Installed harden Property Source: https://github.com/endojs/endo/blob/master/docs/spackle.md This snippet demonstrates directly accessing and using the harden function installed on Object using a registered symbol. ```javascript Object[Symbol.for('harden')](object); ``` -------------------------------- ### Initialize CapTP Connection and Bootstrap Source: https://github.com/endojs/endo/blob/master/packages/captp/README.md Sets up a CapTP connection, defines a message dispatcher, and initiates the bootstrap process. Ensure 'myconn' is a pre-established connection object and 'myBootstrap' is the remote's bootstrap object. Messages are exchanged as JSON-able objects. ```javascript import { E, makeCapTP } from '@endo/captp'; // Create a message dispatcher and bootstrap. // Messages on myconn are exchanged with JSON-able objects. const { dispatch, getBootstrap, abort } = makeCapTP('myid', myconn.send, myBootstrap); myconn.onReceive = obj => dispatch(obj); // Get the remote's bootstrap object and call a remote method. E(getBootstrap()).method(args).then(res => console.log('got res', res)); // Tear down the CapTP connection if it fails (e.g. connection is closed). abort(Error('Connection aborted by user.')); ``` -------------------------------- ### Example of a Tagged Object Source: https://github.com/endojs/endo/blob/master/docs/message-passing.md Illustrates the creation of a 'tagged' object, used as an extension point for domain-specific types. This example shows how to create a tagged 'copySet'. ```javascript makeTagged('copySet', [...]) ``` -------------------------------- ### Basic Promise Kit Usage Source: https://github.com/endojs/endo/blob/master/packages/promise-kit/README.md Demonstrates how to use `makePromiseKit` to create a promise that is resolved or rejected after a delay. Ensure the `success` variable is set appropriately to simulate different outcomes. ```javascript import { makePromiseKit } from '@endo/promise-kit'; function asyncOperation() { const { promise, resolve, reject } = makePromiseKit(); setTimeout(() => { const success = true; // Simulating success or failure if (success) { resolve("Operation successful!"); } else { reject("Operation failed!"); } }, 2000); return promise; } async function handleAsyncOperation() { try { const result = await asyncOperation(); console.log(result); // "Operation successful!" } catch (error) { console.error(error); // "Operation failed!" } } handleAsyncOperation(); ``` -------------------------------- ### Example Module with Diverse Imports and Exports Source: https://github.com/endojs/endo/blob/master/packages/module-source/DESIGN.md Illustrates a JavaScript module showcasing various import and export syntaxes, including default, namespace, named, aliased, re-exports, and default exports. ```javascript import foo from 'import-default-export-from-me.js'; import * as bar from 'import-all-from-me.js'; import { fizz, buzz } from 'import-named-exports-from-me.js'; import { color as colour } from 'import-named-export-and-rename.js'; export let quuux = null; export { qux } from 'import-and-reexport-name-from-me.js'; export * from 'import-and-export-all.js'; export default 42; export const quux = 'Hello, World!'; const aleph = 0; export { aleph as alpha }; export { grey as gray } from './reexport-name-and-rename.js'; // Late binding of an exported variable. quuux = 'Hello, World!'; ``` -------------------------------- ### Example of an Error Object Source: https://github.com/endojs/endo/blob/master/docs/message-passing.md Illustrates how to create a hardened 'error' object, which can be passed between compartments. ```javascript harden(Error('failed')) ``` -------------------------------- ### Importing and Using makeScript Source: https://github.com/endojs/endo/blob/master/packages/compartment-mapper/README.md Demonstrates how to import the makeScript function and use it to generate a JavaScript bundle. Requires fs and url modules for node environments. ```javascript import url from "node:url"; import fs from "node:fs"; import { makeScript } from "@endo/compartment-mapper/script.js"; import { makeReadPowers } from "@endo/compartment-mapper/node-powers.js"; const readPowers = makeReadPowers({ fs, url }); const options = {}; // if any const script = await makeScript(readPowers, moduleLocation, options); ``` -------------------------------- ### Install @endo/ses-ava as a Dev Dependency Source: https://github.com/endojs/endo/blob/master/packages/ses-ava/README.md Add @endo/ses-ava to your package.json's devDependencies to include it in your project. ```json { "devDependencies": { // ... "@endo/ses-ava": "...", // for the current version of @endo/ses-ava // ... }, } ``` -------------------------------- ### Create Mint and Purse with defineExoClassKit Source: https://github.com/endojs/endo/blob/master/docs/message-passing.md Defines a 'Mint' kit with 'mint' and 'purse' facets. The purse facet is stateful, starting with a balance of 0. The makePurse method on the mint facet returns the purse facet. ```javascript // Step 2: Define the Mint/Purse Kit const makeMintKit = defineExoClassKit( 'Mint', { mint: MintI, purse: PurseI }, // init: each purse starts with 0 balance () => ({ balance: 0 }), { mint: { makePurse() { // Return the purse facet, not the mint facet // This ensures the holder of a purse can't mint return this.facets.purse; } }, purse: { getBalance() { return this.state.balance; }, async deposit(amount, payment) { // amount is validated as non-negative number by guard // payment is validated as remotable by guard // Get payment's balance (eventual send) const paymentBalance = await E(payment).getBalance(); // Verify amount matches if (paymentBalance !== amount) { throw Error('Payment balance mismatch'); } // Add to our balance this.state.balance += amount; }, withdraw(amount) { // amount is validated as non-negative by guard if (amount > this.state.balance) { throw Error('Insufficient balance'); } // Deduct from balance this.state.balance -= amount; // Create a new payment return makePayment(amount); } } } ); ``` -------------------------------- ### Promise Pipelining Example Source: https://github.com/endojs/endo/blob/master/packages/eventual-send/README.md Demonstrates promise pipelining by sending messages to promises before they resolve, significantly reducing latency in distributed systems by queuing messages and delivering them in order upon resolution. ```javascript import { E } from '@endo/eventual-send'; // All of these send immediately - no waiting! const mintP = E(bootstrap).getMint(); const purseP = E(mintP).makePurse(); const paymentP = E(purseP).withdraw(100); await E(receiverPurse).deposit(100, paymentP); // Only wait at the end for the final result ``` -------------------------------- ### Configure Compartment with importNowHook Source: https://github.com/endojs/endo/blob/master/packages/ses/README.md Demonstrates setting up a Compartment with both asynchronous `importHook` and synchronous `importNowHook`. The `importNowHook` is used for platform-specific synchronous reads. ```javascript import 'ses'; import { ModuleSource } from '@endo/module-source'; const compartment = new Compartment({ name: "first compartment", modules: { c: { source: new ModuleSource(''), }, }, resolveHook: (moduleSpecifier, moduleReferrer) => { return resolve(moduleSpecifier, moduleReferrer); }, importHook: async moduleSpecifier => { const moduleLocation = locate(moduleSpecifier); const moduleText = await retrieve(moduleLocation); return { source: new ModuleSource(moduleText, moduleLocation), }; }, importNowHook: moduleSpecifier => { const moduleLocation = locate(moduleSpecifier); // Platform-specific synchronous read API can be used const moduleText = fs.readFileSync(moduleLocation); return { source: new ModuleSource(moduleText, moduleLocation), }; }, __options__: true, // temporary migration affordance }); //... | importHook | importNowHook await compartment.import('a'); //| called | not called compartment.importNow('b'); //| not called | called compartment.importNow('a'); //| not called | not called compartment.importNow('c'); //| not called | not called ``` -------------------------------- ### Prepare SES-AVA Test Environment Source: https://github.com/endojs/endo/blob/master/packages/ses-ava/README.md Replace standard AVA imports with this to initialize the SES-shim with options suitable for debugging tests. Ensure '@endo/ses-ava' is in your devDependencies. ```javascript import test from '@endo/ses-ava/prepare-endo.js'; ``` -------------------------------- ### Insecure Counter Implementation Source: https://github.com/endojs/endo/blob/master/packages/ses/docs/secure-coding-guide.md This counter example is insecure because the returned object is not hardened, allowing external modification of its methods. ```javascript // insecure function makeCounter() { let count = 0; function increment() { count += 1; } function decrement() { count -= 1; } function read() { return count; } const updown = { increment, decrement }; return { updown, read }; } ``` -------------------------------- ### Example of HTML-like comment in code Source: https://github.com/endojs/endo/blob/master/packages/ses/error-codes/SES_HTML_COMMENT_REJECTED.md This code demonstrates a scenario where an HTML-like comment might be present, which SES will reject. ```javascript a