### Project Setup and Dependency Installation Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/setup Clones the Inco Lightning Rod Solana repository, installs project dependencies using Yarn, and builds the Anchor programs. ```bash # Clone the repository git clone https://github.com/Inco-fhevm/lightning-rod-solana.git cd lightning-rod-solana # Install dependencies yarn install # Build the programs anchor build ``` -------------------------------- ### Remappings for Node Modules Setup Source: https://docs.inco.org/tutorials/confidential-token/foundry/setup This is an example of a 'remappings.txt' file tailored for a setup where dependencies are installed in 'node_modules' one directory above the contracts folder. It correctly maps library prefixes to their locations within 'node_modules'. ```txt @openzeppelin/=../node_modules/@openzeppelin/ forge-std/=../node_modules/forge-std/src/ ds-test/=../node_modules/ds-test/src/ @inco/=../node_modules/@inco/ ``` -------------------------------- ### Clone and Install Lightning-Rod Template Source: https://docs.inco.org/tutorials/confidential-token/foundry This snippet shows how to clone the Inco 'lightning-rod' template repository and install its dependencies using 'bun'. This is the recommended approach for a quick setup. ```bash git clone git@github.com:Inco-fhevm/lightning-rod.git cd lightning-rod bun install ``` -------------------------------- ### Install Dependencies with Bun (Shell) Source: https://docs.inco.org/quickstart Installs project dependencies using the Bun package manager. This command should be run after cloning the repository and navigating into the project directory. ```sh bun install ``` -------------------------------- ### Example Solidity Remappings Configuration Source: https://docs.inco.org/tutorials/confidential-token/foundry/setup This is an example of the content for the 'remappings.txt' file. It specifies how to map common library prefixes like 'forge-std/', 'ds-test/', '@inco/', and '@openzeppelin/' to their respective local paths or node_modules locations. ```txt forge-std/=your/path/to/forge-std/src/ ds-test/=your/path/to/ds-test/src/ @inco/=path/to/your/node_modules/@inco/ @openzeppelin/=path/to/your/node_modules/@openzeppelin/ ``` -------------------------------- ### Create and Configure Remappings.txt Source: https://docs.inco.org/tutorials/confidential-token/foundry These commands demonstrate creating a 'remappings.txt' file and providing example configurations for Solidity import paths. Proper remapping is crucial for compiling projects that use Inco and other common libraries. ```bash touch remappings.txt ``` ```plaintext forge-std/=your/path/to/forge-std/src/ ds-test/=your/path/to/ds-test/src/ @inco/=path/to/your/node_modules/@inco/ @openzeppelin/=path/to/your/node_modules/@openzeppelin/ ``` -------------------------------- ### Example Remappings for Node Modules Setup Source: https://docs.inco.org/tutorials/confidential-token/foundry This remapping configuration is suitable when your 'node_modules' directory is located one level above your contracts directory. It ensures that Solidity can correctly resolve imports for Inco, Forge, and OpenZeppelin. ```plaintext @openzeppelin/=../node_modules/@openzeppelin/ forge-std/=../node_modules/forge-std/src/ ds-test/=../node_modules/ds-test/src/ @inco/=../node_modules/@inco/ ``` -------------------------------- ### Clone and Setup Hardhat Project Source: https://docs.inco.org/tutorials/confidential-token/hardhat Clones the Inco Lite Hardhat template repository, navigates into the project directory, and installs project dependencies using pnpm. ```bash git clone https://github.com/Inco-fhevm/inco-lite-template.git cd inco-lite-template pnpm install ``` -------------------------------- ### Instruction Setup Source: https://docs.inco.org/svm/guide/accounts Guides on setting up instruction accounts for interacting with the Inco Lightning program, including general setup, access control, and signature verification. ```APIDOC ## Setting Up Your Instruction ### General Instruction Setup To interact with the Inco Lightning program, your instruction's account struct must include the Inco Lightning program ID. ```rust use inco_lightning::ID as INCO_LIGHTNING_ID; #[derive(Accounts)] pub struct MyInstruction<'info> { #[account(mut)] pub authority: Signer<'info>, #[account(mut)] pub my_account: Account<'info, MyAccount>, /// CHECK: Inco Lightning program #[account(address = INCO_LIGHTNING_ID)] pub inco_lightning_program: AccountInfo<'info>, } ``` ### Grant Access Instruction Setup For access control operations, include additional accounts like the allowance account and the address being granted access. ```rust #[derive(Accounts)] pub struct GrantAccess<'info> { #[account(mut)] pub authority: Signer<'info>, /// CHECK: Allowance PDA #[account(mut)] pub allowance_account: AccountInfo<'info>, /// CHECK: Address being granted access pub allowed_address: AccountInfo<'info>, /// CHECK: Inco Lightning program #[account(address = INCO_LIGHTNING_ID)] pub inco_lightning_program: AccountInfo<'info>, pub system_program: Program<'info, System>, } ``` ### Verify Decryption Instruction Setup For signature verification related to decryption, include the instructions sysvar. ```rust use solana_program::sysvar::instructions::ID as SYSVAR_INSTRUCTIONS_ID; #[derive(Accounts)] pub struct VerifyDecryption<'info> { #[account(mut)] pub authority: Signer<'info>, /// CHECK: Instructions sysvar #[account(address = SYSVAR_INSTRUCTIONS_ID)] pub instructions: AccountInfo<'info>, /// CHECK: Inco Lightning program #[account(address = INCO_LIGHTNING_ID)] pub inco_lightning_program: AccountInfo<'info>, } ``` ``` -------------------------------- ### Setup Inco Solana SDK Connection Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/deploy-and-test Establishes a connection to the Solana devnet and initializes the Anchor provider and IncoToken program. This is a prerequisite for all subsequent operations. ```typescript import * as anchor from "@coral-xyz/anchor"; import { Program } from "@coral-xyz/anchor"; import type { IncoToken } from "../target/types/inco_token"; import { PublicKey, Keypair, SystemProgram, Connection, } from "@solana/web3.js"; import { encryptValue } from "@inco/solana-sdk/encryption"; import { decrypt } from "@inco/solana-sdk/attested-decrypt"; import { hexToBuffer } from "@inco/solana-sdk/utils"; // Connection setup const connection = new Connection("https://api.devnet.solana.com", "confirmed"); const provider = anchor.AnchorProvider.env(); anchor.setProvider(provider); const program = anchor.workspace.IncoToken as Program; const wallet = provider.wallet.payer as Keypair; ``` -------------------------------- ### Build and Deploy Solana Programs Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/setup Commands to build all Anchor programs, retrieve the program ID, update configurations, and deploy the program to the Solana devnet. ```bash # Build all programs anchor build # Get your program ID solana address -k target/deploy/inco_token-keypair.json # Update the program ID in Anchor.toml and lib.rs declare_id! (replace ) # Then rebuild anchor build # Deploy to devnet anchor deploy --provider.cluster devnet # Verify deployment solana program show ``` -------------------------------- ### Running Project Tests using Bash Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/deploy-and-test Commands to build the Solana program and run tests on the devnet cluster using the Anchor framework. Ensure Anchor is installed and configured. ```bash # Build the program anchor build # Run tests on devnet anchor test --provider.cluster devnet ``` -------------------------------- ### Add Inco Lightning Package using Bun Source: https://docs.inco.org/tutorials/confidential-token/foundry This command adds the core Inco Solidity library, '@inco/lightning', to your project dependencies using the 'bun add' command. This is part of the manual setup process. ```bash bun add @inco/lightning ``` -------------------------------- ### Install Node.js and pnpm Source: https://docs.inco.org/tutorials/confidential-token/hardhat Installs the latest version of Node.js using nvm and globally installs the pnpm package manager. ```bash nvm install node npm install -g pnpm ``` -------------------------------- ### Add Multiple Dependencies with Bun Source: https://docs.inco.org/tutorials/confidential-token/foundry This command efficiently adds Inco, testing libraries, and OpenZeppelin contracts as project dependencies using 'bun'. It simplifies the process of acquiring all necessary components for a project. ```bash bun add @inco/lightning https://github.com/dapphub/ds-test https://github.com/foundry-rs/forge-std @openzeppelin/contracts ``` -------------------------------- ### Stop Docker Containers (Shell) Source: https://docs.inco.org/quickstart Stops any Docker containers that were started as part of the testing process. This command helps in cleaning up resources after running tests. ```sh docker compose down ``` -------------------------------- ### Initialize with Zero Example Source: https://docs.inco.org/svm/guide/input Example of initializing an account with an encrypted zero value using trivial encryption. ```APIDOC ## POST /initialize_with_zero ### Description Initializes an account with an encrypted zero value using trivial encryption. ### Method POST ### Endpoint /initialize_with_zero ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```json {} ``` ### Response #### Success Response (200) - **balance** (Euint128) - The encrypted zero value stored in the account. #### Response Example ```json { "balance": "encrypted_zero_value" } ``` ``` -------------------------------- ### Mint with Auto-Allow Example (TypeScript) Source: https://docs.inco.org/svm/guide/access-control Demonstrates a four-step process for minting tokens with an auto-allow mechanism. It involves building a transaction for simulation, simulating to get a handle, deriving an allowance PDA, and finally executing the real transaction with the necessary accounts. ```typescript // Step 1: Build transaction for simulation (without allowance accounts) const txForSim = await program.methods .mintTo(hexToBuffer(encryptedAmount), inputType) .accounts({ mint: mintKeypair.publicKey, account: ownerAccountKp.publicKey, mintAuthority: walletKeypair.publicKey, incoLightningProgram: INCO_LIGHTNING_PROGRAM_ID, systemProgram: SystemProgram.programId, }) .transaction(); // Step 2: Simulate to get the new handle const newHandle = await simulateAndGetHandle(connection, txForSim, ownerAccountKp.publicKey, walletKeypair); // Step 3: Derive allowance PDA from the simulated handle const [allowancePda] = getAllowancePda(newHandle!, walletKeypair.publicKey); // Step 4: Execute real transaction with allowance accounts const tx = await program.methods .mintTo(hexToBuffer(encryptedAmount), inputType) .accounts({ mint: mintKeypair.publicKey, account: ownerAccountKp.publicKey, mintAuthority: walletKeypair.publicKey, incoLightningProgram: INCO_LIGHTNING_PROGRAM_ID, systemProgram: SystemProgram.programId, }) .remainingAccounts([ { pubkey: allowancePda, isSigner: false, isWritable: true }, { pubkey: walletKeypair.publicKey, isSigner: false, isWritable: false }, ]) .rpc(); ``` -------------------------------- ### Configure Solana CLI for Devnet Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/setup Configures the Solana CLI to use the devnet cluster, generates a new keypair if needed, and performs an airdrop to fund the wallet for testing. ```bash # Set Solana to use devnet solana config set --url devnet # Verify configuration solana config get # Create a new wallet (if you don't have one) solana-keygen new --outfile ~/.config/solana/id.json # Get some devnet SOL for testing solana airdrop 2 # Check your balance solana balance ``` -------------------------------- ### Compile Contracts and Run Tests with Bun (Shell) Source: https://docs.inco.org/quickstart Compiles smart contracts and executes tests using the Bun test runner. This command verifies the functionality of the project's smart contracts. ```sh bun run test ``` -------------------------------- ### Install Dependencies using Package Managers Source: https://docs.inco.org/guide/preview/intro These commands demonstrate how to install project dependencies after updating package.json. Supported package managers include npm, yarn, and bun. ```bash npm install ``` ```bash yarn install ``` ```bash bun install ``` -------------------------------- ### package.json for Solana Project Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/setup Defines project metadata, dependencies, and scripts for a Solana project using Anchor and TypeScript. Includes dependencies for web3.js, Inco SDK, and testing tools. ```json { "name": "lightning-rod-solana", "version": "0.1.0", "description": "Encrypted Token Program for Solana using Inco Lightning", "type": "module", "dependencies": { "@coral-xyz/anchor": "^0.31.0", "@inco/solana-sdk": "latest", "@noble/ed25519": "^2.3.0", "@solana/web3.js": "^1.98.0" }, "devDependencies": { "@types/bn.js": "^5.1.6", "@types/chai": "^5.2.1", "@types/mocha": "^10.0.10", "chai": "^5.2.0", "dotenv": "^16.4.7", "mocha": "^11.1.0", "ts-mocha": "^11.1.0", "typescript": "^5.8.3" }, "scripts": { "build": "anchor build", "test": "anchor test", "test:token": "ts-mocha -p ./tsconfig.json -t 1000000 tests/inco-token.ts" } } ``` -------------------------------- ### Cloning the Raffle Example Source Code (Bash) Source: https://docs.inco.org/svm/tutorials/private-raffle/overview Provides the command to clone the source code repository for the private raffle example on Solana from GitHub. ```bash git clone https://github.com/Inco-fhevm/raffle-example-solana.git ``` -------------------------------- ### Install @inco/lightning with npm, yarn, or bun Source: https://docs.inco.org/quickstart/lib-reference Instructions for installing the @inco/lightning package using popular JavaScript package managers: npm, yarn, and bun. This is the first step to using the Inco library in your project. ```bash npm install @inco/lightning ``` ```bash yarn add @inco/lightning ``` ```bash bun add @inco/lightning ``` -------------------------------- ### Clone Inco Lightning Repository (Shell) Source: https://docs.inco.org/quickstart Clones the Inco Lightning template repository from GitHub. Supports both SSH and HTTPS protocols. Navigate into the cloned directory after cloning. ```sh git clone git@github.com:Inco-fhevm/lightning-rod.git cd lightning-rod ``` ```sh git clone https://github.com/Inco-fhevm/lightning-rod cd lightning-rod ``` -------------------------------- ### Common Setup for incoJS Encryption Source: https://docs.inco.org/js-sdk/encryption This snippet demonstrates the common setup required for encrypting values with incoJS. It includes importing necessary modules, initializing the incoJS lightning instance, and creating a viem wallet client. Ensure you replace placeholder values for account and transport with your specific implementation. ```typescript import { handleTypes, getViemChain, supportedChains } from '@inco/js'; import { createWalletClient, type Address } from 'viem'; import { Lightning } from '@inco/js/lite' // Do this once at initialization const chainId = supportedChains.baseSepolia; const zap = Lightning.latest('testnet', chainId); const walletClient = createWalletClient({ chain: getViemChain(chainId), account: /* Choose your account, e.g. from window.ethereum */, transport: /* Choose your transport, e.g. from Alchemy */, }); const dappAddress = '0x00000000000000000000000000000000deadbeef'; // Your contract ``` -------------------------------- ### Run Local Node with Docker Source: https://docs.inco.org/tutorials/confidential-token/hardhat Starts a local development node and a local covalidator using Docker Compose. This step can be skipped if deploying to a different network. ```bash docker compose up ``` -------------------------------- ### Install IncoJS SDK using bun Source: https://docs.inco.org/js-sdk/existing-project Installs the IncoJS SDK using the bun package manager. This provides another option for integrating IncoJS into your project. ```bash bun add @inco/js ``` -------------------------------- ### Create Remappings File Source: https://docs.inco.org/tutorials/confidential-token/foundry/setup This command creates an empty 'remappings.txt' file at the root of your contracts directory. This file is crucial for configuring how Solidity imports are resolved when using Inco. ```bash touch remappings.txt ``` -------------------------------- ### Install IncoJS SDK using npm Source: https://docs.inco.org/js-sdk/existing-project Installs the IncoJS SDK using the npm package manager. This is the first step to integrating IncoJS into your project. ```bash npm install @inco/js ``` -------------------------------- ### Account Operations Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/deploy-and-test Endpoints for initializing and closing token accounts. ```APIDOC ## POST /initialize_account ### Description Initializes a new Inco token account. ### Method POST ### Endpoint /initialize_account ### Parameters #### Path Parameters - **tokenAccountKeypair** (Keypair) - Required - The keypair for the new token account. - **mintKeypair** (PublicKey) - Required - The public key of the mint. - **wallet** (PublicKey) - Required - The public key of the wallet acting as owner and payer. ### Request Example ```typescript const tokenAccountKeypair = Keypair.generate(); await program.methods .initializeAccount() .accounts({ account: tokenAccountKeypair.publicKey, mint: mintKeypair.publicKey, owner: wallet.publicKey, payer: wallet.publicKey, systemProgram: SystemProgram.programId, }) .signers([tokenAccountKeypair]) .rpc(); ``` ### Response #### Success Response (200) - **owner** (string) - The base58 encoded public key of the account owner. - **state** (string) - The state of the account. #### Response Example ```json { "owner": "", "state": "" } ``` ## POST /close_account ### Description Closes an existing Inco token account, returning any remaining lamports to the destination. ### Method POST ### Endpoint /close_account ### Parameters #### Path Parameters - **tokenAccountKeypair** (PublicKey) - Required - The public key of the token account to close. - **wallet** (PublicKey) - Required - The public key of the wallet receiving remaining lamports and acting as authority. ### Request Example ```typescript await program.methods .closeAccount() .accounts({ account: tokenAccountKeypair.publicKey, destination: wallet.publicKey, authority: wallet.publicKey, }) .rpc(); ``` ### Response #### Success Response (200) (No specific response body documented, assumes success confirmation) #### Response Example (No example provided) ``` -------------------------------- ### Mint Operations Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/deploy-and-test Endpoints for minting new tokens, either with a specified amount or using an existing handle. ```APIDOC ## POST /mint_to ### Description Mints a specified amount of tokens to an account. The amount is encrypted before being processed. ### Method POST ### Endpoint /mint_to ### Parameters #### Query Parameters - **mintAmount** (BigInt) - Required - The amount of tokens to mint, with 9 decimals. - **encryptedAmount** (Buffer) - Required - The encrypted representation of the mint amount. - **mintKeypair** (PublicKey) - Required - The public key of the mint. - **tokenAccountKeypair** (Keypair) - Required - The keypair for the token account. - **wallet** (PublicKey) - Required - The public key of the wallet acting as mint authority. ### Request Example ```typescript const mintAmount = BigInt(1_000_000_000); const encryptedAmount = await encryptValue(mintAmount); await program.methods .mintTo(hexToBuffer(encryptedAmount), 0) .accounts({ mint: mintKeypair.publicKey, account: tokenAccountKeypair.publicKey, mintAuthority: wallet.publicKey, }) .rpc(); ``` ### Response #### Success Response (200) - **balance** (string) - The decrypted balance of the token account after minting. #### Response Example ```json { "balance": "1000000000 tokens" } ``` ## POST /mint_to_with_handle ### Description Mints tokens to an account using an existing encrypted handle, typically transferring the entire balance from a source account. ### Method POST ### Endpoint /mint_to_with_handle ### Parameters #### Query Parameters - **amountHandle** (Buffer) - Required - The encrypted amount handle from a source account. - **mintKeypair** (PublicKey) - Required - The public key of the mint. - **tokenAccountKeypair** (Keypair) - Required - The keypair for the token account. - **wallet** (PublicKey) - Required - The public key of the wallet acting as mint authority. - **sourceAccountPubkey** (PublicKey) - Required - The public key of the source account. ### Request Example ```typescript const sourceAccount = await program.account.incoAccount.fetch(sourceAccountPubkey); const amountHandle = sourceAccount.amount; await program.methods .mintToWithHandle(amountHandle) .accounts({ mint: mintKeypair.publicKey, account: tokenAccountKeypair.publicKey, mintAuthority: wallet.publicKey, }) .rpc(); ``` ### Response #### Success Response (200) (No specific response body documented, assumes success confirmation) #### Response Example (No example provided) ``` -------------------------------- ### Freeze/Thaw Operations Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/deploy-and-test Endpoints for freezing and thawing token accounts. ```APIDOC ## POST /freeze_account ### Description Freezes a token account, preventing further transfers or operations. ### Method POST ### Endpoint /freeze_account ### Parameters #### Path Parameters - **tokenAccountPubkey** (PublicKey) - Required - The public key of the token account to freeze. - **mintPubkey** (PublicKey) - Required - The public key of the mint. - **authority** (PublicKey) - Required - The public key of the authority. ### Request Example ```typescript // Assuming program, tokenAccountPubkey, mintPubkey, and wallet are defined await program.methods .freezeAccount() .accounts({ account: tokenAccountPubkey, mint: mintPubkey, authority: wallet.publicKey, }) .rpc(); ``` ### Response #### Success Response (200) (No specific response body documented, assumes success confirmation) #### Response Example (No example provided) ## POST /thaw_account ### Description Thaws a previously frozen token account, allowing normal operations to resume. ### Method POST ### Endpoint /thaw_account ### Parameters #### Path Parameters - **tokenAccountPubkey** (PublicKey) - Required - The public key of the token account to thaw. - **mintPubkey** (PublicKey) - Required - The public key of the mint. - **authority** (PublicKey) - Required - The public key of the authority. ### Request Example ```typescript // Assuming program, tokenAccountPubkey, mintPubkey, and wallet are defined await program.methods .thawAccount() .accounts({ account: tokenAccountPubkey, mint: mintPubkey, authority: wallet.publicKey, }) .rpc(); ``` ### Response #### Success Response (200) (No specific response body documented, assumes success confirmation) #### Response Example (No example provided) ``` -------------------------------- ### Install JavaScript SDK using npm, yarn, or pnpm Source: https://docs.inco.org/svm/js-sdk/overview Installs the Inco Solana SDK, a client-side library for interacting with confidential Solana programs. It handles encryption and decryption workflows. ```bash npm install @inco/solana-sdk ``` ```bash yarn add @inco/solana-sdk ``` ```bash pnpm add @inco/solana-sdk ``` -------------------------------- ### Delegation Operations Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/deploy-and-test Endpoints for approving and revoking token delegation. ```APIDOC ## POST /approve ### Description Approves a delegate to spend a specified amount of tokens from the source account. ### Method POST ### Endpoint /approve ### Parameters #### Path Parameters - **approveAmount** (BigInt) - Required - The amount of tokens to approve for delegation. - **encryptedAmount** (Buffer) - Required - The encrypted representation of the approval amount. - **tokenAccountPubkey** (PublicKey) - Required - The public key of the token account. - **delegatePubkey** (PublicKey) - Required - The public key of the delegate. - **wallet** (PublicKey) - Required - The public key of the wallet acting as the owner. ### Request Example ```typescript const approveAmount = BigInt(100_000_000); const encryptedAmount = await encryptValue(approveAmount); await program.methods .approve(hexToBuffer(encryptedAmount), 0) .accounts({ source: tokenAccountPubkey, delegate: delegatePubkey, owner: wallet.publicKey, }) .rpc(); ``` ### Response #### Success Response (200) - **delegate** (string) - The public key of the approved delegate. #### Response Example ```json { "delegate": "" } ``` ## POST /revoke ### Description Revokes the delegation for a token account, removing any previously approved delegate. ### Method POST ### Endpoint /revoke ### Parameters #### Path Parameters - **tokenAccountPubkey** (PublicKey) - Required - The public key of the token account. - **wallet** (PublicKey) - Required - The public key of the wallet acting as the owner. ### Request Example ```typescript await program.methods .revoke() .accounts({ source: tokenAccountPubkey, owner: wallet.publicKey, }) .rpc(); ``` ### Response #### Success Response (200) - **delegate** (object) - Indicates the delegate has been removed (e.g., `{ none: {} }`). #### Response Example ```json { "delegate": {"none": {}} } ``` ``` -------------------------------- ### Setup Solana Connection and Program Instance (TypeScript) Source: https://docs.inco.org/svm/tutorials/private-raffle/client Initializes the Solana connection, Anchor provider, and the Private Lottery program instance. It imports necessary libraries from `@coral-xyz/anchor` and `@solana/web3.js`, along with Inco SDK utilities for encryption and decryption. This setup is crucial for all subsequent interactions with the blockchain. ```typescript import * as anchor from "@coral-xyz/anchor"; import { Program } from "@coral-xyz/anchor"; import { PrivateLottery } from "../target/types/private_lottery"; import { PublicKey, Keypair, SystemProgram, Connection, SYSVAR_INSTRUCTIONS_PUBKEY, Transaction } from "@solana/web3.js"; import nacl from "tweetnacl"; import { encryptValue } from "@inco/solana-sdk/encryption"; import { decrypt } from "@inco/solana-sdk/attested-decrypt"; import { hexToBuffer, handleToBuffer, plaintextToBuffer } from "@inco/solana-sdk/utils"; const INCO_LIGHTNING_PROGRAM_ID = new PublicKey( "5sjEbPiqgZrYwR31ahR6Uk9wf5awoX61YGg7jExQSwaj" ); const connection = new Connection("https://api.devnet.solana.com", "confirmed"); const provider = anchor.AnchorProvider.env(); anchor.setProvider(provider); const program = anchor.workspace.privateLottery as Program; const wallet = (provider.wallet as any).payer as Keypair; ``` -------------------------------- ### Minimal Permissions Example - Rust Source: https://docs.inco.org/svm/guide/access-control Demonstrates the best practice of granting minimal decryption permissions by allowing only the account owner to decrypt their balance. This ensures enhanced security and privacy. ```rust // Only allow the account owner to decrypt their balance allow(ctx, balance_handle, true, owner_pubkey)?; ``` -------------------------------- ### Cargo.toml for Inco Token Program Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/setup Specifies the dependencies and features for the 'inco-token' Solana program, including Anchor, Inco Lightning, and standard Rust configurations. ```toml [package] name = "inco-token" version = "0.1.0" description = "Encrypted Token Program for Solana using Inco Lightning" edition = "2021" [lib] crate-type = ["cdylib", "lib"] name = "inco_token" [features] default = [] cpi = ["no-entrypoint"] no-entrypoint = [] no-idl = [] no-log-ix-name = [] idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build"] [dependencies] anchor-lang = { version = "0.31.1", features = ["init-if-needed"] } anchor-spl = "0.31.1" inco-lightning = { version = "0.1.4", features = ["cpi"] } ``` -------------------------------- ### Anchor.toml Configuration for Devnet Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/setup Configures the Anchor build tool for deployment to the Solana devnet, specifying the cluster, wallet, and program ID for the Inco token. ```toml [features] resolution = true skip-lint = false [programs.devnet] inco_token = "" [registry] url = "https://api.apr.dev" [provider] cluster = "devnet" wallet = "~/.config/solana/id.json" [scripts] test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" ``` -------------------------------- ### Compile and Test Hardhat Contracts Source: https://docs.inco.org/tutorials/confidential-token/hardhat Compiles the smart contracts using Hardhat and runs tests against the local 'anvil' network. ```bash pnpm hardhat compile pnpm hardhat test --network anvil ``` -------------------------------- ### Cargo.toml Workspace Configuration Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/setup Defines the workspace members and build profiles for a Rust project, typically used in multi-crate repositories. Includes release profile settings for optimization. ```toml [workspace] members = [ "programs/*" ] resolver = "2" [profile.release] overflow-checks = true lto = "fat" codegen-units = 1 [profile.release.build-override] opt-level = 3 incremental = false codegen-units = 1 ``` -------------------------------- ### Configure Environment Variables for Hardhat Source: https://docs.inco.org/tutorials/confidential-token/hardhat Sets up the .env file with necessary private keys, seed phrases, and RPC URLs for local development and deployment to networks like Base Sepolia. ```bash # This should be a private key funded with native tokens. PRIVATE_KEY_ANVIL="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" PRIVATE_KEY_BASE_SEPOLIA="" # This should be a seed phrase used to test functionalities with different accounts. # You can send funds from the main wallet to this whenever needed. SEED_PHRASE="garden cage click scene crystal fat message twice rubber club choice cool" # This should be an RPC URL provided by a proper provider # that supports the eth_getLogs() and eth_getFilteredLogs() methods. LOCAL_CHAIN_RPC_URL="http://localhost:8545" BASE_SEPOLIA_RPC_URL="https://base-sepolia-rpc.publicnode.com" ``` -------------------------------- ### Initialize Account - TypeScript Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/deploy-and-test Initializes a new Inco account. This involves generating a new keypair for the account and setting its initial state, including owner and mint details. It requires the `Keypair` class and system program information. ```typescript const tokenAccountKeypair = Keypair.generate(); await program.methods .initializeAccount() .accounts({ account: tokenAccountKeypair.publicKey, mint: mintKeypair.publicKey, owner: wallet.publicKey, payer: wallet.publicKey, systemProgram: SystemProgram.programId, }) .signers([tokenAccountKeypair]) .rpc(); // Verify const tokenAccount = await program.account.incoAccount.fetch(tokenAccountKeypair.publicKey); console.log("Owner:", tokenAccount.owner.toBase58()); console.log("State:", tokenAccount.state); ``` -------------------------------- ### Environment Variables for Inco SPL Tokens Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/setup Defines essential environment variables for interacting with Inco's Confidential SPL Token features, including co-validator details and Solana cluster configuration. ```bash # Co-validator public key for encryption SERVER_PUBLIC_KEY=0486ca2bbf34bea44c6043f23ebc5b67ca7ccefc3710498385ecc161460a1f8729db2a361cb0d7f40847a99a75572bc10e36a365218f4bae450dc61348330bb717 # Co-validator endpoint for decryption requests COVALIDATOR_ENDPOINT=https://grpc.solana-devnet.alpha.devnet.inco.org # Your Solana cluster RPC_URL=https://api.devnet.solana.com # Path to your wallet keypair SOLANA_WALLET=~/.config/solana/id.json ``` -------------------------------- ### Decrypt Balance Helper Function Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/deploy-and-test Combines handle extraction and decryption to provide a user-friendly way to get the decrypted balance of a token account. It handles potential errors during decryption and formats the output based on specified decimals. ```typescript async function decryptBalance( accountData: any, decimals: number = 9 ): Promise { try { const handle = getHandleFromAccount(accountData.amount); if (handle === "0") return 0; const result = await decrypt([handle]); const rawAmount = parseInt(result.plaintexts[0], 10); return rawAmount / Math.pow(10, decimals); } catch (error) { console.error("Decryption error:", error); return null; } } // Usage const tokenAccount = await program.account.incoAccount.fetch(tokenAccountPubkey); const balance = await decryptBalance(tokenAccount); console.log("Balance:", balance, "tokens"); ``` -------------------------------- ### Deploy and Test on Base Sepolia Source: https://docs.inco.org/tutorials/confidential-token/hardhat Deploys the ConfidentialToken contract to the Base Sepolia network using Hardhat Ignition and then runs tests against the deployed contract on the same network. ```bash pnpm hardhat ignition deploy ./ignition/modules/ConfidentialToken.ts --network baseSepolia pnpm hardhat test --network baseSepolia ``` -------------------------------- ### Get Encrypted Handle from Transaction Logs Source: https://docs.inco.org/svm/tutorials/confidential-spl-token/deploy-and-test Retrieves an encrypted handle from transaction logs after an operation. It waits for transaction confirmation, parses logs, and extracts a numeric handle using a provided prefix. This handle can then be used for decryption. ```typescript async function getHandleFromTx( txSignature: string, logPrefix: string ): Promise { // Wait for transaction to be confirmed await new Promise(resolve => setTimeout(resolve, 2000)); const txDetails = await connection.getTransaction(txSignature, { commitment: "confirmed", maxSupportedTransactionVersion: 0, }); const logs = txDetails?.meta?.logMessages || []; for (const log of logs) { if (log.includes(logPrefix)) { const match = log.match(/(\d+)/); if (match) return match[1]; } } throw new Error(`Handle not found in logs for prefix: ${logPrefix}`); } // Usage const handle = await getHandleFromTx(txSignature, "Balance handle:"); const result = await decrypt([handle]); ``` -------------------------------- ### Initialize Mint Account with Solana SDK Source: https://docs.inco.org/svm/tutorials/nextjs-template/components Initializes a new mint account for tokens using the Solana SDK. This involves generating a new keypair for the mint, setting initial parameters like decimals and owner, and adding the instruction to a transaction. Requires the public key of the payer and the system program ID. ```tsx // Create mint const mintKp = Keypair.generate(); tx.add( await program.methods .initializeMint(6, publicKey, publicKey) .accounts({ mint: mintKp.publicKey, payer: publicKey, systemProgram: SystemProgram.programId, }) .instruction() ); ``` -------------------------------- ### Slice Elist by Start and End Indices in Solidity Source: https://docs.inco.org/guide/preview/elist The `slice` function extracts a portion of an elist based on provided start and end indices. It returns a new elist containing elements from the start index (inclusive) to the end index (exclusive). If indices are out of bounds or the end index is not greater than the start index, the operation will revert. ```solidity elist myList = ePreview.newEList(ETypes.Uint256); elist myNewList1 = ePreview.append(myList, e.asEuint256(5)); elist myNewList2 = ePreview.append(myNewList1, e.asEuint256(10)); elist myNewList3 = ePreview.append(myNewList2, e.asEuint256(15)); elist slicedList = ePreview.slice(myNewList3, 1, 3); // [5, 10, 15].slice(1, 3) == [10, 15] ``` -------------------------------- ### Deposit Function Example Source: https://docs.inco.org/svm/guide/input Example of a deposit function that creates an encrypted value from client-provided ciphertext. ```APIDOC ## POST /deposit ### Description Creates an encrypted handle from client-provided ciphertext and stores it. ### Method POST ### Endpoint /deposit ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **ciphertext** (Vec) - Required - Client-encrypted amount. ### Request Example ```json { "ciphertext": "0x..." } ``` ### Response #### Success Response (200) - **balance** (Euint128) - The encrypted amount stored in the vault. #### Response Example ```json { "balance": "encrypted_value" } ``` ``` -------------------------------- ### Slice Elist by Start Index and Length in Solidity Source: https://docs.inco.org/guide/preview/elist The `sliceLen` function provides an alternative way to slice an elist using an encrypted start index and a desired length. If the encrypted start position is out of bounds, the resulting list is padded with a specified default value. This function requires fee payment. ```solidity function listSlice(bytes memory ctStart, uint16 len, bytes memory ctDefaultValue) public payable returns (elist) { require(msg.value >= inco.getFee() * 2, "Fee not paid"); euint256 start = e.newEuint256(ctStart, msg.sender); euint256 defaultValue = e.newEuint256(ctDefaultValue, msg.sender); list = ePreview.sliceLen(list, start, len, defaultValue); inco.allow(elist.unwrap(list), address(this)); inco.allow(elist.unwrap(list), msg.sender); return list; } // [5, 10, 15].sliceLen(1, 2, 0) == [10, 15] ``` -------------------------------- ### Install IncoJS SDK using yarn Source: https://docs.inco.org/js-sdk/existing-project Installs the IncoJS SDK using the yarn package manager. This is an alternative to npm for adding IncoJS to your project. ```bash yarn add @inco/js ``` -------------------------------- ### Test Fee Requirements in Foundry (Solidity) Source: https://docs.inco.org/quickstart/fees Demonstrates how to set up test environments using Foundry to simulate fee scenarios. It covers setting user ETH balances for user-paid fees and contract ETH balances for contract-paid fees. ```solidity // For user-paid fees in Foundry tests vim.deal(user, inco.getFee() * 2); // User needs ETH for fees // For contract-paid fees in Foundry tests vim.deal(address(contract), inco.getFee() * 10); // Contract needs ETH balance ``` -------------------------------- ### Import Libraries for Confidential ERC20 Setup (Solidity) Source: https://docs.inco.org/tutorials/confidential-token/hardhat/contract-setup Imports essential contracts and libraries required for building a confidential ERC20 token. This includes Inco's core library, type utility functions, decryption attestation types, and OpenZeppelin's Ownable2Step for access control. ```Solidity pragma solidity ^0.8.28; import {inco, e, ebool, euint256} from "@inco/lightning/src/Lib.sol"; import {asBool} from "@inco/lightning/src/shared/TypeUtils.sol"; import {DecryptionAttestation} from "@inco/lightning/src/lightning-parts/DecryptionAttester.types.sol"; import "@openzeppelin/contracts/access/Ownable2Step.sol"; ``` -------------------------------- ### JavaScript SDK Client and Inco Initialization Source: https://docs.inco.org/guide/verifying-attestations Sets up the viem wallet client and initializes the Inco SDK for use with a specific chain and network. This code is essential for establishing communication with the blockchain and the Inco network. ```typescript import { createWalletClient, http } from "viem"; import { baseSepolia } from "viem/chains"; import { Lightning, supportedChains } from "@inco/js"; export const walletClient = createWalletClient({ chain: baseSepolia, transport: http(), }); export const zap = await Lightning.latest( "testnet", supportedChains.baseSepolia ); ``` -------------------------------- ### Create Range List in Solidity Source: https://docs.inco.org/guide/preview/elist The `range` function generates a new elist populated with ordered integer values between a specified start (inclusive) and end (exclusive) value. The length of the generated list is determined by the difference between the end and start values. ```solidity elist myList = ePreview.range(0, 5); // myList = E([0, 1, 2, 3, 4]) ``` -------------------------------- ### Account Size Example with Encrypted Handles (Rust) Source: https://docs.inco.org/svm/guide/handles Provides an example of an Anchor account struct `Vault` that includes an encrypted handle (`Euint128`) for its balance. This illustrates how handles contribute to the overall account size, with the handle itself being only 16 bytes. ```rust #[account] pub struct Vault { pub owner: Pubkey, // 32 bytes pub balance: Euint128, // 16 bytes (handle only!) pub bump: u8, // 1 byte } // Total: 49 bytes + 8 bytes discriminator = 57 bytes ``` -------------------------------- ### Import Preview and Lightning Libraries in Solidity Source: https://docs.inco.org/guide/preview/intro This Solidity code snippet shows how to import necessary libraries from the Inco Lightning Preview and core Lightning SDK. It includes imports for EList functionalities and basic data types. ```solidity import {ePreview, elist, ETypes} from "@inco/lightning-preview/src/Preview.Lib.sol"; import {euint256, ebool, e, inco} from "@inco/lightning/src/Lib.sol"; ``` -------------------------------- ### Set Up MyInstruction Account Structure (Rust) Source: https://docs.inco.org/svm/guide/accounts Defines the account structure for a custom instruction that includes the Inco Lightning program. This is a prerequisite for interacting with the Inco Lightning program. ```rust use inco_lightning::ID as INCO_LIGHTNING_ID; #[derive(Accounts)] pub struct MyInstruction<'info> { #[account(mut)] pub authority: Signer<'info>, #[account(mut)] pub my_account: Account<'info, MyAccount>, /// CHECK: Inco Lightning program #[account(address = INCO_LIGHTNING_ID)] pub inco_lightning_program: AccountInfo<'info>, } ```