### Install Project Dependencies Source: https://github.com/meshjs/mesh/blob/main/README.md Run this command in your terminal to install all necessary project dependencies. ```bash npm install ``` -------------------------------- ### Initialize a New Project with Mesh CLI Source: https://github.com/meshjs/mesh/blob/main/README.md Use this command to quickly set up a new project with the Mesh CLI. This is the recommended way to start building applications with Mesh. ```bash npx meshjs your-app-name ``` -------------------------------- ### Install Mesh Core Package Source: https://github.com/meshjs/mesh/blob/main/README.md Install the core Mesh SDK package using npm. This package provides the fundamental APIs for building web3 applications. ```bash npm install @meshsdk/core ``` -------------------------------- ### Configure Aiken Project Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/plutus-nft/aiken-workspace/README.md Configure your Aiken project by setting network-specific parameters in the `aiken.toml` file. This example sets the default network ID. ```toml [config.default] network_id = 41 ``` -------------------------------- ### Build and Test On-Chain Code Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/payment-splitter/readme.md Navigates to the 'onchain' directory and executes Aiken commands to test and build the smart contract. Requires Aiken to be installed. ```bash cd onchain aiken test aiken build ``` -------------------------------- ### Install Dependencies for Off-Chain Code Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/payment-splitter/readme.md Installs Node.js dependencies for the off-chain JavaScript code. Requires Node.js and Yarn. ```bash cd offchain yarn install ``` -------------------------------- ### Onchain Variable Fee Calculation Example Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/royalties/cip102.md Illustrates the calculation for storing and retrieving variable royalty fees. This method minimizes resource consumption in Plutus. ```cddl ; Given a royalty fee of 1.6% (0.016) ; To store this in the royalty datum 1 / (0.016 / 10) => 625 ; To read it back 10 / 625 => 0.016 ``` -------------------------------- ### Write a Test in Aiken Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/escrow/aiken-workspace-v1/readme.md Tests can be written in any module using the `test` keyword. This example shows a basic arithmetic test. ```gleam test foo() { 1 + 1 == 2 } ``` -------------------------------- ### Write and Run Aiken Tests Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/plutus-nft/aiken-workspace/README.md Write tests within any module using the `test` keyword. This example checks if the configured network ID plus one equals 42. Use `aiken check` to run all tests or `aiken check -m ` to run specific tests. ```aiken use config test foo() { config.network_id + 1 == 42 } ``` -------------------------------- ### Write a Validator in Aiken Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/escrow/aiken-workspace-v1/readme.md Validators are written in the `validators` folder using the `.ak` file extension. This example shows a simple validator that always returns true. ```gleam validator { fn spend(_datum: Data, _redeemer: Data, _context: Data) -> Bool { True } } ``` -------------------------------- ### Type Definition with `any` Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Illustrates how explicitly setting a type to `any` can lead to downstream types also resolving to `any`. This example shows `InferWithParams`, `JsonRpcRequest`, and `JsonRpcResponse` types becoming `any` due to a single `any` definition. ```typescript export declare type InferWithParams< Type extends Struct, Params extends JsonRpcParams, > = any; export declare type JsonRpcRequest< Params extends JsonRpcParams = JsonRpcParams, > = InferWithParams; // Resolves to 'any' export declare type JsonRpcResponse = | JsonRpcSuccess | JsonRpcFailure; // Resolves to 'any' ``` -------------------------------- ### Downstream `any` Pollution Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Shows how `any` types in a package (`@meshsdk/utils`) can pollute downstream code, suppressing valid TypeScript errors. This example highlights how properties like `origin` and `res.result` are treated as `any`, leading to potential runtime errors. ```typescript import type { JsonRpcRequest, JsonRpcResponse } from '@meshsdk/utils' function sendMetadataHandler( req: JsonRpcRequest // any, res: JsonRpcResponse // any, _next: JsonRpcEngineNextCallback, end: JsonRpcEngineEndCallback, { addSubjectMetadata, subjectType }: SendMetadataOptionsType, ): void { // Error: Property 'origin' does not exist on type 'JsonRpcRequest'.ts(2339) const { origin, params } = req; // 'any' , 'any' if (params && typeof params === 'object' && !Array.isArray(params)) { const { icon = null, name = null, ...remainingParams } = params; addSubjectMetadata({ ...remainingParams // 'any', iconUrl: icon // 'any', name, subjectType, origin, }); } else { return end(ethErrors.rpc.invalidParams({ data: params })); // 'any' } // Error: Property 'result' does not exist on type 'JsonRpcResponse'. // Property 'result' does not exist on type '{ error: JsonRpcError; id: string | number; jsonrpc: "2.0"; }'.ts(2339) res.result = true; // `res`, `res.result` are both 'any' return end(); } ``` -------------------------------- ### Conditional Omission with `Omit` Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Illustrates conditional property omission using `Omit` based on type conditions, though this specific example might be complex for direct application. ```typescript interface CartItem { productId: number; quantity: number; color?: string; // Optional color // Omit color if quantity is 1 const singleItemPayload = Omit; // Omit color for all items if quantity is always 1 const cartPayload: singleItemPayload[] = []; ``` -------------------------------- ### Define a Plutus Spend Validator in Aiken Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/plutus-nft/aiken-workspace/README.md Write Plutus validators in the `validators` folder using the `.ak` file extension. This example shows a basic validator that always returns True. ```aiken validator my_first_validator { spend(_datum: Option, _redeemer: Data, _output_reference: Data, _context: Data) { True } } ``` -------------------------------- ### Use Verb Phrase for Boolean Function/Method Names Source: https://github.com/meshjs/mesh/blob/main/docs/javascript.md For functions or methods returning a boolean, start the name with a descriptive verb like 'getNOUN' instead of 'isSTATE' to avoid potential naming collisions with variables and ESLint's 'no-shadow' rule. ```javascript function isEIP1559Compatible() { // ... } const isEIP1559Compatible = isEIP1559Compatible(); ``` ```javascript function getEIP1559Compatibility() { // ... } const isEIP1559Compatible = getEIP1559Compatibility(); ``` -------------------------------- ### Create Mesh App CLI Usage Source: https://github.com/meshjs/mesh/blob/main/scripts/mesh-cli/README.md Use this command to quickly bootstrap a new Web3 application with Mesh. Specify the app name and optionally choose a template, stack, and language. ```sh Usage: create-mesh-app [options] A quick and easy way to bootstrap your Web3 app using Mesh. Arguments: name Set a name for your app. Options: -V, --version output the version number -t, --template The template to start your project from. (choices: "starter", "minting", "marketplace") -s, --stack The tech stack you want to build on. (choices: "next", "remix") -l, --language The language you want to use. (choices: "js", "ts") -h, --help display help for command ``` -------------------------------- ### Run Project Apps and Packages Source: https://github.com/meshjs/mesh/blob/main/README.md Use this command to run all applications and packages in development mode. ```bash npm run dev ``` -------------------------------- ### Build Project Apps and Packages Source: https://github.com/meshjs/mesh/blob/main/README.md Execute this command to build all applications and packages within the Mesh project. ```bash npm run build ``` -------------------------------- ### Prepare Wallets for Payment Splitter Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/payment-splitter/readme.md Prepares a specified number of wallets for interacting with the payment splitter. This command generates wallet addresses. ```bash node use-payment-splitter.js prepare 5 ``` -------------------------------- ### Build Aiken Project Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/escrow/aiken-workspace-v1/readme.md Use the `aiken build` command to compile your Aiken project. ```sh aiken build ``` -------------------------------- ### Initialize MeshGiftCardContract Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/giftcard/readme.md Initialize the necessary components including provider, MeshTxBuilder, and MeshGiftCardContract. Ensure you have the wallet connected and API key configured. ```typescript import { BlockfrostProvider, MeshTxBuilder } from '@meshsdk/core'; import { MeshGiftCardContract } from '@meshsdk/contracts'; import { useWallet } from '@meshsdk/react'; const { connected, wallet } = useWallet(); const provider = new BlockfrostProvider(APIKEY); const meshTxBuilder = new MeshTxBuilder({ fetcher: provider, submitter: provider, }); const contract = new MeshGiftCardContract({ mesh: meshTxBuilder, fetcher: provider, wallet: wallet, networkId: 0, }); ``` -------------------------------- ### POST /meshjs/mesh Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/hello-world/aiken-workspace-v2/README.md Submits a 'Hello, World!' message to the MeshJS network. ```APIDOC ## POST /meshjs/mesh ### Description This endpoint allows you to send a 'Hello, World!' message, associated with an owner's public key hash, to the MeshJS network. ### Method POST ### Endpoint /meshjs/mesh ### Parameters #### Request Body - **owner** (string) - Required - Owner's pub key hash. - **message** (string) - Required - The message to be sent. Must be a string, e.g., "Hello, World!" ### Request Example { "owner": "", "message": "Hello, World!" } ### Response #### Success Response (200) This endpoint does not specify a success response body in the provided documentation. #### Response Example (No example provided) ``` -------------------------------- ### Initialize MeshVestingContract Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/vesting/readme.md Initializes the vesting contract by setting up the provider, MeshTxBuilder, and MeshVestingContract instances. Ensure you have the necessary API key and wallet connection. ```javascript import { BlockfrostProvider, MeshTxBuilder } from '@meshsdk/core'; import { MeshVestingContract } from '@meshsdk/contracts'; import { useWallet } from '@meshsdk/react'; const { connected, wallet } = useWallet(); const provider = new BlockfrostProvider(APIKEY); const meshTxBuilder = new MeshTxBuilder({ fetcher: provider, submitter: provider, }); const contract = new MeshVestingContract({ mesh: meshTxBuilder, fetcher: provider, wallet: wallet, networkId: 0, }); ``` -------------------------------- ### Type Assertion for External Contract Map Schema Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md This example shows a type assertion used to align an imported `contractMap` object with a known `LegacyToken` schema. The assertion is considered safe because the required properties are validated at runtime. ```typescript import contractMap from '@meshsdk/contract'; type LegacyToken = { name: string; logo: `${string}.svg`; symbol: string; decimals: number; erc20?: boolean; erc721?: boolean; }; export const STATIC_MAINNET_TOKEN_LIST = Object.entries( // This type assertion is to the known schema of the JSON object `contractMap`. contractMap as Record, ).reduce((acc, [base, contract]) => { const { name, symbol, decimals, logo, erc20, erc721 } = contract; // The required properties are validated at runtime if ([name, symbol, decimals, logo].some((e) => !e)) { return; } ... }, {}); ``` -------------------------------- ### Risks of Type Assertions in TypeScript Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Type assertions in TypeScript should be used cautiously as they bypass type checking and can lead to silent runtime failures. This example demonstrates how multiple, unnecessary type assertions can obscure errors and make code brittle. ```typescript enum Direction { Up = 'up', Down = 'down', Left = 'left', Right = 'right', } const directions = Object.values(Direction); // Error: Element implicitly has an 'any' type because index expression is not of type 'number'.(7015) // Only one of the two `as` assertions necessary to fix error, but neither are flagged as redundant. for (const key of Object.keys(directions) as (keyof typeof directions)[]) { const direction = directions[key as keyof typeof directions]; } ``` -------------------------------- ### Avoid Type Inference and `satisfies` for Extensible Types Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md When typing extensible data types, explicit type annotations are preferred over type inference or the `satisfies` operator to ensure all properties and elements are included. This example shows how `satisfies` can lead to type errors when checking against a union type. ```typescript // const SUPPORTED_CHAIN_IDS: ("0x1" | "0x38" | "0xa" | "0x2105" | "0x89" | "0xa86a" | "0xa4b1" | "0xaa36a7" | "0xe708")[] export const SUPPORTED_CHAIN_IDS = [ CHAIN_IDS.ARBITRUM, CHAIN_IDS.AVALANCHE, ... CHAIN_IDS.SEPOLIA, ]; export const SUPPORTED_CHAIN_IDS = [ ... ] satisfies `0x${string}`[]; const { chainId } = networkController.state.providerConfig // Type of 'chainId': '`0x${string}`'; SUPPORTED_CHAIN_IDS.includes(chainId) // Argument of type '`0x${string}`' is not assignable to parameter of type "0x1" | "0x38" | "0xa" | "0x2105" | "0x89" | "0xa86a" | "0xa4b1" | "0xaa36a7" | "0xe708".ts(2345) ``` -------------------------------- ### Initialize Payment Splitter Contract Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/payment-splitter/readme.md Initializes the MeshPaymentSplitterContract with necessary providers, wallet, and network configurations. Ensure APIKEY is defined and the wallet is connected. ```typescript import { MeshPaymentSplitterContract } from "@meshsdk/contracts"; import { BlockfrostProvider, MeshTxBuilder } from "@meshsdk/core"; import { useWallet } from "@meshsdk/react"; const { connected, wallet } = useWallet(); const provider = new BlockfrostProvider(APIKEY); const meshTxBuilder = new MeshTxBuilder({ fetcher: provider, submitter: provider, }); const contract = new MeshPaymentSplitterContract( { mesh: meshTxBuilder, fetcher: provider, wallet: wallet, networkId: 0, }, [ "addr_test1vpg334d6skwu6xxq0r4lqrnsjd5293n8s3d80em60kf6guc7afx8k", "addr_test1vp4l2kk0encl7t7972ngepgm0044fu8695prkgh5vjj5l6sxu0l3p", "addr_test1vqqnfs2vt42nq4htq460wd6gjxaj05jg9vzg76ur6ws4sngs55pwr", "addr_test1vqv2qhqddxmf87pzky2nkd9wm4y5599mhp62mu4atuss5dgdja5pw", ], ); ``` -------------------------------- ### Initialize Escrow Contract with Mesh.js Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/escrow/readme.md Initializes the necessary components for interacting with the Escrow smart contract, including the provider, transaction builder, and the contract itself. Ensure APIKEY is replaced with your actual Blockfrost API key. ```javascript import { BlockfrostProvider, MeshTxBuilder } from '@meshsdk/core'; import { MeshEscrowContract } from '@meshsdk/contracts'; import { useWallet } from '@meshsdk/react'; const { connected, wallet } = useWallet(); const provider = new BlockfrostProvider(APIKEY); const meshTxBuilder = new MeshTxBuilder({ fetcher: provider, submitter: provider, }); const contract = new MeshEscrowContract({ mesh: meshTxBuilder, fetcher: provider, wallet: wallet, networkId: 0, }); ``` -------------------------------- ### Making Network Request and Returning JSON (Without Await) Source: https://github.com/meshjs/mesh/blob/main/docs/javascript.md This snippet demonstrates a common pattern for fetching data and parsing its JSON response. However, it may lead to incomplete stack traces if the `response.json()` promise rejects. ```javascript async function makeRequest() { const response = await fetch('https://some/url'); return response.json(); } ``` -------------------------------- ### Generate Aiken Documentation Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/escrow/aiken-workspace-v1/readme.md Generate HTML documentation for your Aiken library using the `aiken docs` command. ```sh aiken docs ``` -------------------------------- ### Initialize Swap Contract Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/swap/readme.md Initializes the necessary components for interacting with the Mesh Swap Contract, including the provider, transaction builder, and the contract instance itself. Ensure APIKEY is replaced with your actual Blockfrost API key. ```typescript import { MeshSwapContract } from "@meshsdk/contracts"; import { BlockfrostProvider, MeshTxBuilder } from "@meshsdk/core"; import { useWallet } from "@meshsdk/react"; const { connected, wallet } = useWallet(); const provider = new BlockfrostProvider(APIKEY); const meshTxBuilder = new MeshTxBuilder({ fetcher: provider, submitter: provider, }); const contract = new MeshSwapContract({ mesh: meshTxBuilder, fetcher: provider, wallet: wallet, networkId: 0, }); ``` -------------------------------- ### Using `any` in Generic Constraints Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Demonstrates how `any` can be used within generic constraints without polluting the messenger type. Prefer more specific constraints when possible. ```typescript class BaseController< ..., // eslint-disable-next-line @typescript-eslint/no-explicit-any messenger extends RestrictedControllerMessenger > ... ``` ```typescript export class ComposableController< // eslint-disable-next-line @typescript-eslint/no-explicit-any ComposableControllerState extends { [name: string]: Record }, > extends BaseController< typeof controllerName, // (type parameter) ComposableControllerState in ComposableController ComposableControllerState, ComposableControllerMessenger > ``` -------------------------------- ### Check Aiken Project Tests Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/escrow/aiken-workspace-v1/readme.md Run all tests in your Aiken project using `aiken check`. To run tests matching a specific string, use the `-m` flag. ```sh aiken check ``` ```sh aiken check -m foo ``` -------------------------------- ### Initialize Mesh Marketplace Contract Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/marketplace/readme.md Initializes the MeshMarketplaceContract with a blockchain provider, wallet, network ID, owner address, and fee percentage. Ensure you have a blockchain provider and a connected browser wallet set up. ```typescript import { MeshMarketplaceContract } from '@meshsdk/contracts'; import { BlockfrostProvider, MeshTxBuilder } from '@meshsdk/core'; const provider = new BlockfrostProvider(APIKEY); const meshTxBuilder = new MeshTxBuilder({ fetcher: provider, submitter: provider, }); const contract = new MeshMarketplaceContract( { mesh: meshTxBuilder, fetcher: provider, wallet: wallet, networkId: 0, }, 'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv06fwlvuacpyv59g3a3w2fhk7daa8aepvacnpamyhyyxrgnscrfpsa', 200 ); ``` -------------------------------- ### Use async/await for Asynchronous Operations Source: https://github.com/meshjs/mesh/blob/main/docs/javascript.md Employ `async`/`await` syntax for handling asynchronous operations instead of `.then`/`.catch`. This approach results in cleaner, more readable code and provides better stack traces in Node.js and Chromium environments. ```javascript function makeRequest() { return fetch('https://google.com').then((response) => { return response.json().then((json) => { return json['page_views']; }); }); } ``` ```javascript async function makeRequest() { const response = await fetch('https://google.com'); const json = await response.json(); return json['page_views']; } ``` -------------------------------- ### Making Network Request and Returning JSON (With Await) Source: https://github.com/meshjs/mesh/blob/main/docs/javascript.md This improved snippet ensures that the `response.json()` promise is awaited before returning. This guarantees that the full stack trace is available if any errors occur during JSON parsing, aiding in debugging. ```javascript async function makeRequest() { const response = await fetch('https://some/url'); return await response.json(); } ``` -------------------------------- ### Run All Tests in Aiken Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/escrow/aiken-workspace-v2/readme.md Execute this command to run all tests within your Aiken project. It checks the correctness of your validators and functions. ```sh aiken check ``` -------------------------------- ### TypeScript Mapped Type with Key Remapping using `as` Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Illustrates the use of the `as` keyword within a mapped type in TypeScript for key remapping. This allows for the transformation of keys from the original type to new keys in the resulting type. ```typescript type MappedTypeWithNewProperties = { [Properties in keyof Type as NewKeyType]: Type[Properties]; }; ``` -------------------------------- ### Trigger Payout from Payment Splitter Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/payment-splitter/readme.md Calculates and distributes the total available Lovelace from the contract UTXOs among the registered payees. This action triggers the payout process. ```bash node use-payment-splitter.js unlock ``` -------------------------------- ### Use Verb Phrase for Function/Method Names Source: https://github.com/meshjs/mesh/blob/main/docs/javascript.md When naming functions or methods, use a verb phrase to describe the action being performed, not the outcome. This promotes clarity in code intent. ```javascript function formattedChangelog() { // ... } ``` ```javascript function formatChangelog() { // ... } ``` -------------------------------- ### Aiken Hello World Validator Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/hello-world/aiken-workspace-v1/contract.md This validator checks if a transaction message is 'Hello, World!' and if the owner has signed the transaction. Ensure the correct imports are present. ```aiken use aiken/hash.{Blake2b_224, Hash} use aiken/list use aiken/transaction.{ScriptContext} use aiken/transaction/credential.{VerificationKey} type Datum { owner: Hash, } type Redeemer { msg: ByteArray, } validator { fn hello_world(datum: Datum, redeemer: Redeemer, context: ScriptContext) -> Bool { let must_say_hello = redeemer.msg == "Hello, World!" let must_be_signed = list.has(context.transaction.extra_signatories, datum.owner) must_say_hello && must_be_signed } } ``` -------------------------------- ### Run Specific Tests in Aiken Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/escrow/aiken-workspace-v2/readme.md Filter and run tests matching a specific string using the `-m` flag. This is useful for targeted testing. ```sh aiken check -m foo ``` -------------------------------- ### Highlight Non-Blocking Comments in Code Reviews Source: https://github.com/meshjs/mesh/blob/main/docs/pull-requests.md Use prefixes like 'Nitpick:' or 'Nit:' to indicate comments that are stylistic suggestions and not blocking the merge. This helps the author prioritize feedback. ```text Nit: Jest has a `jest.mocked` function you could use here instead of `jest.MockFunction`. That should let you clean this up a bit if you wanted. ``` -------------------------------- ### Vulnerable Value Check in Aiken Script Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/marketplace/insufficient-stake-control/README.md This script demonstrates the vulnerable implementation where value is checked against a recipient's public key hash. This can be exploited by sending funds to an address controlled by the attacker's stake key. ```rust # In scripts let is_proceed_paid = get_all_value_to(tx.outputs, datum.seller) |> value_geq( from_lovelace(datum.price + lovelace_of(own_input.output.value)), ) let is_fee_paid = get_all_value_to_key_hash(tx.outputs, owner) |> value_geq( from_lovelace(datum.price * fee_percentage_basis_point / 10000), ) pub fn get_all_value_to_key_hash( outputs: List, recipient: VerificationKeyHash, ) -> Value { list.foldr( outputs, zero, fn(output, acc_value) { expect Some(pub_key) = address_pub_key(output.address) if pub_key == recipient { merge(acc_value, output.value) } else { acc_value } }, ) } ``` -------------------------------- ### Define and Implement Interface Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Use the `implements` keyword to enforce contracts defined by interfaces. Interfaces can be defined as type aliases. ```typescript export type IPollingController = { ... } export function AbstractPollingControllerBaseMixin( Base: TBase, ) { abstract class AbstractPollingControllerBase extends Base implements IPollingController { ... } return AbstractPollingControllerBase } ``` -------------------------------- ### GitHub Suggestion Feature for Code Reviews Source: https://github.com/meshjs/mesh/blob/main/docs/pull-requests.md Use GitHub's suggestion feature to propose code changes directly within a review. This allows authors to easily incorporate feedback. ```text ... add your suggestion here ... ``` -------------------------------- ### Fixed Value Check in Aiken Script Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/marketplace/insufficient-stake-control/README.md This script shows the corrected implementation that validates value transfers by checking against the full recipient address, mitigating the insufficient stake control vulnerability. ```rust # In scripts let is_proceed_paid = get_all_value_to(tx.outputs, datum.seller) |> value_geq( from_lovelace(datum.price + lovelace_of(own_input.output.value)), ) let is_fee_paid = get_all_value_to(tx.outputs, owner) |> value_geq( from_lovelace(datum.price * fee_percentage_basis_point / 10000), ) ``` -------------------------------- ### Create Content Transaction Body Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/content-ownership/aiken-workspace/specs/user_actions.md Defines the structure for a transaction that creates new content. It specifies inputs, reference inputs, outputs, extra signatories, and redeemers for ownership and content records. ```js - inputs: [ownership_registry_input, content_registry_input], - reference_inputs: [oracle_ref_utxo], - outputs: [ownership_registry_output, content_registry_output], - extra_signatories: List>, - redeemers: { Spend(ownership_registry_input_utxo): CreateOwnershipRecord, Spend(content_registry_input_utxo): CreateContent { content_hash: ByteArray, owner: (PolicyId, AssetName) } } ``` -------------------------------- ### TypeScript Type Declarations vs. Inferences Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Demonstrates how explicit type declarations can sometimes widen types, losing specific information, while type inferences capture more precise types. Use type inferences when possible to maintain type safety. ```typescript const name: string = 'MESH'; // Type 'string' const chainId: string = this.messagingSystem( 'NetworkController:getProviderConfig', ).chainId; // Type 'string' const BUILT_IN_NETWORKS = new Map([ ['mainnet', '0x1'], ['sepolia', '0xaa36a7'], ]); // Type 'Map' ``` ```typescript const name = 'MESH'; // Type 'MESH' const chainId = this.messagingSystem( 'NetworkController:getProviderConfig', ).chainId; // Type '`0x${string}`' const BUILT_IN_NETWORKS = { mainnet: '0x1', sepolia: '0xaa36a7', } as const; // Type { readonly mainnet: '0x1'; readonly sepolia: '0xaa36a7'; } ``` -------------------------------- ### Reference Commit Updates in Code Reviews Source: https://github.com/meshjs/mesh/blob/main/docs/pull-requests.md When responding to feedback by making changes, link to the specific commit that contains the updates. This allows reviewers to easily verify the changes and helps move the discussion towards a resolution. ```text Good catch! Updated in abc1234. ``` -------------------------------- ### Lock Funds in Payment Splitter Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/payment-splitter/readme.md Locks a specified amount of Lovelace into the payment splitter contract. The amount should be in Lovelace (e.g., 10000000 for 10 tAda). ```bash node use-payment-splitter.js lock 10000000 ``` -------------------------------- ### Avoiding `any` as Generic Argument Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Illustrates a scenario where using `any` directly as a generic argument is discouraged. ```typescript // eslint-disable-next-line @typescript-eslint/no-explicit-any const controllerMessenger = ControllerMessenger; ``` -------------------------------- ### Vulnerable Minting Logic in Aiken Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/giftcard/infinite-mint/README.md This code snippet demonstrates the vulnerable part of a minting policy where it only checks for the existence of a specific token without restricting the total minting amount. Use this to understand how the vulnerability arises. ```aiken # No check in output value length expect Some(Pair(asset_name, amount)) = mint |> assets.tokens(policy_id) |> dict.to_pairs() |> list.find(fn(Pair(asset_name, _)) { asset_name == token_name }) ``` -------------------------------- ### Provide Explicit Function Return Types Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Always provide explicit return types for functions and methods to improve API clarity and prevent unexpected changes. ```typescript async function removeAccount(address: Hex) { const keyring = await this.getKeyringForAccount(address); if (!keyring.removeAccount) { throw new Error(KeyringControllerError.UnsupportedRemoveAccount); } keyring.removeAccount(address); this.emit('removedAccount', address); await this.persistAllKeyrings(); return this.fullUpdate(); } ``` ```typescript async function removeAccount(address: Hex): Promise { const keyring = await this.getKeyringForAccount(address); if (!keyring.removeAccount) { throw new Error(KeyringControllerError.UnsupportedRemoveAccount); } keyring.removeAccount(address); this.emit('removedAccount', address); await this.persistAllKeyrings(); return this.fullUpdate(); } ``` -------------------------------- ### Type Inference with `any` Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Demonstrates how `any` affects type inference in union types and function return values. When `any` is involved, surrounding types can become `any` as well, leading to a loss of type information. ```typescript const handler: | ((payload_0: ComposableControllerState, payload_1: Patch[]) => void) | ((payload_0: any, payload_1: Patch[]) => void); function returnsAny(): any { return { a: 1, b: true, c: 'c' }; } // Types of a, b, c are all `any` const { a, b, c } = returnsAny(); ``` -------------------------------- ### Fixing Double Satisfaction Vulnerability Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/swap/double-satisfaction/README.md This code snippet demonstrates the fix for the double satisfaction vulnerability by ensuring only one input originates from a script. This is crucial for preventing unintended multiple UTXO unlocks. ```rust # In scripts let is_only_one_input_from_script = when inputs_from_script is { [_] -> True _ -> False } ``` -------------------------------- ### Using `unknown` as an Assignee Type Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md When `any` is used as the assignee type, `unknown` can be a safer alternative. `unknown` is the universal supertype and is assignable to every type, making it interchangeable with `any` when typing the assignee. ```typescript type ExampleFunction = () => any; const exampleArray: any[] = ['a', 1, true]; ``` ```typescript type ExampleFunction = () => unknown; const exampleArray: unknown[] = ['a', 1, true]; ``` -------------------------------- ### Using `Omit` to Reduce Requirements Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Demonstrates using the `Omit` utility type to create new types by excluding specific properties from an existing type, useful for API payloads. ```typescript interface User { username: string; email?: string; phoneNumber?: string; } // Type for API call payload type ApiPayload = Omit; const payload: ApiPayload = { username: 'johndoe' }; // Now `payload` only has the `username` property, satisfying the API requirements. ``` -------------------------------- ### TypeScript Overload Signatures for `handle` Function Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md These are the overload signatures for a generic `handle` function in TypeScript, defining its behavior with different parameter and return types. ```typescript handle( request: JsonRpcRequest, callback: (error: unknown, response: JsonRpcResponse) => void, ): void; handle( requests: (JsonRpcRequest | JsonRpcNotification)[], callback: (error: unknown, responses: JsonRpcResponse[]) => void, ): void; handle( requests: (JsonRpcRequest | JsonRpcNotification)[], ): Promise[]>; ``` -------------------------------- ### Constraining Generic Types Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Shows how to constrain generic types using `extends` to ensure they meet specific requirements, such as extending `JsonRpcParams` or `Json`. ```typescript // before function createExampleMiddleware(exampleParam); // after function createExampleMiddleware< Params extends JsonRpcParams, Result extends Json, >(exampleParam); ``` -------------------------------- ### Async Function Returning Awaited Promise Source: https://github.com/meshjs/mesh/blob/main/docs/javascript.md By awaiting the promise returned by another async function, you ensure that the full stack trace, including the calling function, is preserved when the promise rejects. This is crucial for effective debugging. ```javascript async function foo() { return await bar(); } async function bar() { await Promise.resolve(); throw new Error('BEEP BEEP'); } foo().catch((error) => console.log(error.stack)); ``` -------------------------------- ### Missing Input Check for Double Satisfaction Source: https://github.com/meshjs/mesh/blob/main/packages/mesh-contract/src/swap/double-satisfaction/README.md This code snippet illustrates the missing check that allows a double satisfaction vulnerability. It should verify that only one input originates from a script. ```rust # Missing this line // let is_only_one_input_from_script = // when inputs_from_script is { // [_] -> True // _ -> False // } ``` -------------------------------- ### Force Type Assertion with 'as unknown as' Source: https://github.com/meshjs/mesh/blob/main/docs/typescript.md Use `as unknown as` to assert a type to a structurally incompatible type or to resolve type errors related to runtime property access, assignment, or deletion. Use this cautiously as a last resort. ```typescript for (const key of getKnownPropertyNames(this.internalConfig)) { (this as unknown as typeof this.internalConfig)[key] = this.internalConfig[key]; } delete addressBook[chainId as unknown as `0x${string}`]; ```