### Check Go and Rust Versions Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md Verifies the installed versions of Go and the Rust compiler. These are prerequisites for local installation. ```bash # Check Go version go version # Check Rust compiler version rustc --version ``` -------------------------------- ### Setup and Activate Python Virtual Environment Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md Creates and activates a Python virtual environment for the project. This isolates project dependencies. ```bash make python-venv source venv/bin/activate ``` -------------------------------- ### Install System Dependencies for Verulink Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md Installs necessary system packages on Ubuntu for building and running Verulink. These include development libraries and build tools. ```bash sudo apt update sudo apt install libssl-dev pkg-config build-essential ``` -------------------------------- ### Run Verulink Local Deployment Script Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md This bash script initiates the local deployment of the Verulink project. It requires paths to configuration files, secrets, and mTLS certificates. The script guides the user through prompts for installation directories and service configurations. ```bash bash scripts/deploy-local.sh --chain-config=/path/to/chainservice.yaml --sign-config=/path/to/signingservice.yaml --secrets=/path/to/secret.yaml --ca_cert=/path/to/ca.cert --attestor_cert=/path/to/attestor.cert --attestor_key=/path/to/attestor.key ``` -------------------------------- ### Clone Verulink Repository Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md Clones the Verulink project from its GitHub repository. This is the initial step for both AWS deployment and local installation. ```bash git clone https://github.com/venture23-aleo/verulink.git ``` -------------------------------- ### Build DokoJS from Source Source: https://github.com/venture23-aleo/verulink/blob/main/aleo/README.md Builds the DokoJS project from its source code. This involves cloning the repository, installing dependencies with pnpm, building the project, and finally installing the CLI. ```bash # Download the source file git clone https://github.com/venture23-aleo/doko-js.git cd doko-js # Install the dependencies pnpm install # Build the project npm run build # Install dokojs npm run install:cli ``` -------------------------------- ### Install Dependencies and Create .env Source: https://github.com/venture23-aleo/verulink/blob/main/aleo/README.md Installs project dependencies using npm and creates a .env file from a template. The .env file is crucial for configuring environment-specific settings, including default private keys for local development. ```bash cd aleo # Install the dependencies npm install # Create .env file. 4 private keys on the .env.example are the default private keys on the local devnet with aleo credits. cp .env.example .env ``` -------------------------------- ### Install DokoJS CLI Globally Source: https://github.com/venture23-aleo/verulink/blob/main/aleo/README.md Installs the DokoJS command-line interface globally on your system using npm. This makes the `dokojs` command available system-wide for compiling and managing DokoJS projects. ```bash npm install -g @doko-js/cli@latest ``` -------------------------------- ### SigningService Configuration Example Source: https://github.com/venture23-aleo/verulink/wiki/Attestor-Service-Workflow YAML configuration for the SigningService, defining the chains it supports with their respective names, types, and chain IDs. ```yaml chains: - name: aleo chain_type: aleo chain_id: 6694886634403 - name: ethereum chain_type: evm chain_id: 111550639260264 ``` -------------------------------- ### Start SnarkOS Local Devnet Source: https://github.com/venture23-aleo/verulink/blob/main/aleo/README.md Starts a local SnarkOS development network. This command is essential for running tests that require interaction with a live blockchain environment, including transition and finalize blocks. ```bash # Settings: 4 validators, clients 0 ./devnet.sh ``` -------------------------------- ### Manage Verulink Systemd Services Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md These commands demonstrate how to manage the systemd services for the Verulink attestor and chain components. This includes checking their status, viewing logs, and starting or stopping the services. The `--user` flag is used for user-level service management. ```bash systemctl status attestor-sign.service systemctl status attestor-chain.service journalctl -u attestor-sign.service journalctl -u attestor-chain.service systemctl stop attestor-sign.service systemctl start attestor-chain.service systemctl --user status attestor-sign.service systemctl --user status attestor-chain.service journalctl --user -u attestor-sign.service journalctl --user -u attestor-chain.service systemctl --user stop attestor-sign.service systemctl --user start attestor-chain.service ``` -------------------------------- ### Verulink Configuration Files Setup Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md This section details the structure and content of the `config.yaml` and `secrets.yaml` files required for Verulink deployment. These files hold critical network, wallet, and service endpoint information. ```yaml chain: ethereum: private_key: wallet_address: aleo: private_key: wallet_address: ``` -------------------------------- ### View Verulink Application Logs Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md This command shows how to access the application log file for Verulink. The log file, named `verulink.log`, is located in the `log` directory within the installation path. ```bash cat /home/ubuntu/attestor/log/verulink.log ``` -------------------------------- ### Checkout Main Branch Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md Switches the current working branch to 'main'. This ensures that you are working with the latest stable version of the project. ```bash git checkout main ``` -------------------------------- ### Clone and Navigate Verulink Repository Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md These commands are used to clone the Verulink project from GitHub and navigate into the project directory. This is the initial step for any deployment or development work on the project. ```bash git clone https://github.com/venture23-aleo/verulink.git cd verulink git checkout main ``` -------------------------------- ### Deploy Verulink to AWS Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md Initiates the deployment process to AWS using a Makefile target. This assumes Docker is being used for deployment. ```bash make deploy-to-aws ``` -------------------------------- ### Verify Running Docker Services Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md Lists the running Docker containers on the attestor machine to verify that services like 'chainService' and 'signingService' are active. ```bash docker ps ``` -------------------------------- ### End-to-End Transfer Example (TypeScript) Source: https://context7.com/venture23-aleo/verulink/llms.txt This TypeScript code demonstrates a complete end-to-end transfer of USDC from the Ethereum chain to the Aleo chain using the Verulink bridge. It covers user actions like approval and transfer on Ethereum, attestor processing including screening and signing, and the final withdrawal and minting on Aleo. The example highlights the asynchronous nature of the process and the role of attestors in validating transactions. ```typescript // User transfers USDC from Ethereum to Aleo async function transferUSDCToAleo() { // Step 1: User approves and transfers on Ethereum const tokenService = "0x28E761500e7Fd17b5B0A21a1eAD29a8E22D73170"; const usdcToken = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; const amount = 1000e6; // 1000 USDC const aleoReceiver = "aleo1receiver123..."; await usdc.approve(tokenService, amount); const tx = await tokenService.transfer(usdcToken, amount, aleoReceiver); // Transaction emits: Transfer(sender, receiver, amount, sequence: 42) // Block: 19500000, Timestamp: 2024-01-01 12:00:00 // Step 2: Wait 24 hours for attestor processing // 2024-01-02 12:00:00 - Attestors pick up packet // Step 3: Attestors screen addresses // - Check sender 0x123... against chain analysis: CLEAN // - Check receiver aleo1receiver123...: CLEAN // - Set isWhite = true // Step 4: Attestors sign packet // Attestor 1: sig1 = "0xabc..." // Attestor 2: sig2 = "0xdef..." // Attestor 3: sig3 = "0x123..." // All signatures stored in database // Step 5: User collects signatures from API const response = await fetch( `https://db.verulink.com/api/v1/signatures?sequence=42&sourceChain=1` ); const { packet, signatures } = await response.json(); // signatures = [sig1, sig2, sig3, sig4, sig5] from 5 attestors // Step 6: User submits to Aleo bridge const aleoTx = await aleoBridge.withdraw(packet, signatures); // Bridge verifies 3/5 quorum reached // All attestors voted YEA (isWhite = true) // Mints 1000 vUSDC to aleo1receiver123... console.log("Transfer complete:", { ethTxHash: tx.hash, aleoTxHash: aleoTx.id, amount: "1000 USDC → 1000 vUSDC", duration: "~24 hours", }); } ``` -------------------------------- ### Clone Verulink Repository Source: https://github.com/venture23-aleo/verulink/blob/main/aleo/README.md Clones the Verulink project repository. This is the initial step to get the project's codebase, including the test files and scripts. ```bash git clone https://github.com/venture23-aleo/verulink.git cd attestor # Change branch to update/readme-update-dokojs, after PR is merged git checkout develop git checkout update/readme-update-dokojs ``` -------------------------------- ### Deploy Ansible Playbook Using AWS EC2 Public IP Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md This command executes the Ansible playbook using the public IP address of the AWS EC2 instance directly, bypassing the need for an inventory file. Ensure you replace the example IP with the actual instance IP. ```bash ansible-playbook scripts/aws/deploy.yml -i 54.198.147.67, -u ubuntu --private-key attestor-ssh-key.pem ``` -------------------------------- ### Navigate to Project Directory Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md Changes the current directory to the root of the cloned Verulink project. This is necessary before running subsequent commands. ```bash cd verulink ``` -------------------------------- ### ChainService Configuration Example Source: https://github.com/venture23-aleo/verulink/wiki/Attestor-Service-Workflow YAML configuration for the ChainService, specifying blockchain network details such as name, chain ID, type, wallet address, bridge contract address, node URL, and the connection details for the SigningService. ```yaml chains: - name: ethereum chain_id: 111550639260264 chain_type: evm wallet_address:
bridge_contract: 0x52985628b263481360437715e701517B7DB7aE1a node_url: https://1rpc.io/holesky signing_service: host: signingservice port: 8080 endpoint: "/sign" scheme: "http" ``` -------------------------------- ### Retrieve AWS Secret Manager Keys with Ansible Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md This command attempts to retrieve keys from AWS Secret Manager during Ansible playbook execution. It requires the SSH key name as a parameter. This is useful when keys are not automatically retrievable during installation. ```bash ansible-playbook scripts/aws/deploy.yml -i inventory.txt -u ubuntu --private-key= --tags debug,retrieve_secret ``` -------------------------------- ### View Verulink Chain Service Logs Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md Accesses the logs for the Verulink chain service within its Docker container. This is useful for debugging. ```bash docker exec -it sh cd ../logs cat verulink.log ``` -------------------------------- ### Manage Docker Containers Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md These commands are used to manage Docker containers when no Docker containers are running. 'docker ps -a' lists all containers (running and stopped), and 'docker logs ' displays the logs for a specific container, aiding in debugging. ```bash docker ps -a ``` ```bash docker logs ``` -------------------------------- ### Run Ansible Playbook for Remaining Deployment Tasks Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md If an attestor deployment phase fails, this command allows you to rerun the Ansible playbook focusing only on the remaining deployment tasks. This avoids re-executing already completed steps. ```bash ansible-playbook scripts/aws/deploy.yml -i inventory.txt -u ubuntu --private-key= ``` -------------------------------- ### Set Environment Variable for Fork Safety Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md Exports an environment variable to disable certain safety initializations forked processes. This is a workaround for a known issue mentioned in the troubleshooting section. ```bash export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES ``` -------------------------------- ### SSH Access to Attestor Machine Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md Connects to the remote attestor machine via SSH using a private key file and the machine's IP address. The IP address is typically found in the 'inventory.txt' file. ```bash ssh -i ubuntu@IP_ADDRESS ``` -------------------------------- ### Configure AWS Credentials via Environment Variables (Bash) Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md This bash script snippet demonstrates how to set AWS access key, secret access key, and default region as environment variables. This is a common method for configuring the AWS CLI and SDKs for programmatic access. ```bash export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/ bPxRfiCYEXAMPLEKEY export AWS_DEFAULT_REGION=us-east-1 ``` -------------------------------- ### Generate mTLS Private Key with OpenSSL Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md This command uses OpenSSL to generate a private key for mTLS. It specifies the RSA algorithm and a key length of 4096 bits, creating a file named 'attestor.key'. ```bash openssl genpkey -algorithm RSA -out attestor.key -pkeyopt rsa_keygen_bits:4096 ``` -------------------------------- ### AWS IAM Policy for Attestor Server Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md This JSON policy grants the necessary permissions for an IAM user to deploy and manage an Attestor server on AWS. It covers EC2, IAM, KMS, Secrets Manager, S3, and CloudShell actions. ```json { "Version": "2012-10-17", "Statement": [ { "Sid": "EC2Permissions", "Effect": "Allow", "Action": [ "ec2:AssociateIamInstanceProfile", "ec2:CreateKeyPair", "ec2:DescribeImages", "ec2:CreateTags", "ec2:DescribeSecurityGroups", "ec2:CreateSecurityGroup", "ec2:AuthorizeSecurityGroupIngress", "ec2:DescribeInstances", "ec2:RunInstances", "ec2:TerminateInstances" ], "Resource": "*" }, { "Sid": "IAMPermissions", "Effect": "Allow", "Action": [ "iam:PassRole", "iam:GetAccountPasswordPolicy", "iam:GetAccountSummary", "iam:ChangePassword", "iam:GetUser", "iam:CreateAccessKey", "iam:DeleteAccessKey", "iam:ListAccessKeys", "iam:UpdateAccessKey", "iam:GetAccessKeyLastUsed", "iam:DeleteSSHPublicKey", "iam:GetSSHPublicKey", "iam:ListSSHPublicKeys", "iam:UpdateSSHPublicKey", "iam:UploadSSHPublicKey", "iam:CreateInstanceProfile", "iam:UpdateAssumeRolePolicy", "iam:PutUserPermissionsBoundary", "iam:AttachUserPolicy", "iam:CreateRole", "iam:AttachRolePolicy", "iam:PutRolePolicy", "iam:AddRoleToInstanceProfile", "iam:CreateAccessKey", "iam:CreatePolicy", "iam:DetachRolePolicy", "iam:AttachGroupPolicy", "iam:PutUserPolicy", "iam:DetachGroupPolicy", "iam:CreatePolicyVersion", "iam:DetachUserPolicy", "iam:PutGroupPolicy", "iam:SetDefaultPolicyVersion", "iam:TagRole", "iam:GetRole", "iam:GetInstanceProfile" ], "Resource": "*" }, { "Sid": "KMSAndSecretsManagerPermissions", "Effect": "Allow", "Action": [ "kms:*", "secretsmanager:DescribeSecret", "secretsmanager:GetSecretValue", "secretsmanager:CreateSecret", "secretsmanager:ListSecrets", "secretsmanager:UpdateSecret" ], "Resource": "*" }, { "Sid": "S3Permissions", "Effect": "Allow", "Action": "s3:ListAllMyBuckets", "Resource": "*" }, { "Sid": "CloudShellPermissions", "Effect": "Allow", "Action": "cloudshell:*", "Resource": "*" } ] } ``` -------------------------------- ### Create mTLS Certificate Signing Request (CSR) with OpenSSL Source: https://github.com/venture23-aleo/verulink/blob/main/scripts/aws/DEPLOYMENT.md This command generates a Certificate Signing Request (CSR) required for mTLS. It uses the previously generated private key ('attestor.key') and allows you to specify subject details for the certificate. ```bash openssl req -new -key attestor.key -out attestor.csr -subj "/C=US/ST=State/L=City/O=Organization/OU=OrgUnit/CN=example.com" ``` -------------------------------- ### Generate CA Certificate using OpenSSL Source: https://github.com/venture23-aleo/verulink/blob/main/docs/mTLS_architecture.md Generates the private key for the Certificate Authority (CA) and then creates the CA's self-signed certificate. These are fundamental for establishing trust in the mTLS setup. ```bash openssl genpkey -algorithm RSA -out /etc/secret/mtls/ca.key openssl req -new -x509 -key /etc/secret/mtls/ca.key -out /etc/secret/mtls/ca.cer ``` -------------------------------- ### Governance Functions Interface Source: https://github.com/venture23-aleo/verulink/blob/main/docs/bridge_contract.md Provides governance functions for managing the bridge contract. These include registering and removing services, setting and getting attestors, and adding/removing target chains. These operations are typically restricted to governance roles. Dependencies include `Vec` and `u32`. No explicit error types are shown for these specific functions. ```rust pub trait IBridgeContract { // ... other functions // ensure governance fn register_service(&mut self, address: String) -> Result<(), ContractError>; // ensure governance fn remove_service(&mut self, address: String) -> Result<(), ContractError>; // ensure governance fn set_attestors(&mut self, attestors: Vec); fn get_attestors(&self) -> Vec; // ensure governance fn add_target_chain(&mut self, chain_id: u32); // ensure governance fn remove_target_chain(&mut self, chain_id: u32); // ... other functions ``` -------------------------------- ### Compile Programs with DokoJS Source: https://github.com/venture23-aleo/verulink/blob/main/aleo/README.md Compiles the Aleo programs using the DokoJS CLI. This command processes the Leo source files and generates the necessary artifacts for execution and testing. ```bash dokojs compile ``` -------------------------------- ### Verulink Attestor Configuration (YAML) Source: https://context7.com/venture23-aleo/verulink/llms.txt This YAML configuration file defines the settings for the Verulink attestor service, including chain connection details for Ethereum and Aleo, signing service parameters, collector service settings, and metric configuration. It specifies node URLs, contract addresses, wallet addresses, and polling intervals for each chain, as well as mTLS configuration for the signing service. ```yaml name: "verulink-attestor" version: "1.0.0" mode: "production" chains: - name: ethereum chain_id: 1 chain_type: evm wallet_address: "0x123abc..." bridge_contract: "0x7440176A6F367D3Fad1754519bD8033EAF173133" token_service_contract: "0x28E761500e7Fd17b5B0A21a1eAD29a8E22D73170" node_url: "https://eth-mainnet.g.alchemy.com/v2/..." wait_duration: "24h" # Wait before processing polling_interval: "30s" start_height: 19500000 - name: aleo chain_id: 6694886634403 chain_type: aleo wallet_address: "aleo1attestor123..." bridge_contract: "vlink_token_bridge_v1.aleo" token_service_contract: "vlink_token_service_v1.aleo" node_url: "https://api.explorer.aleo.org/v1" wait_duration: "24h" polling_interval: "60s" start_height: 1000000 signing_service: host: "signingservice" port: 8080 endpoint: "/sign" scheme: "https" mtls_cert: "/configs/.mtls/client.crt" mtls_key: "/configs/.mtls/client.key" mtls_ca: "/configs/.mtls/ca.crt" collector_service: host: "db.verulink.com" port: 443 endpoint: "/api/v1" scheme: "https" collector_wait_duration: "5m" # Check for missed packets metric_config: push_gateway: "https://metrics.verulink.com" job_name: "attestor-1" interval: "30s" # Run attestor: # docker-compose up -d # Chain service connects to signing service via mTLS # Processes packets from both Ethereum and Aleo # Submits signatures to shared database ``` -------------------------------- ### Run Specific Program Tests Source: https://github.com/venture23-aleo/verulink/blob/main/aleo/README.md Executes tests for a specific program within the Verulink project. This command allows targeted testing by specifying the program's filename (e.g., `1_tokenBridge`). It uses npm's test runner with specific arguments for controlling test execution. ```bash npm run test --runInBand -- 1_tokenBridge ``` -------------------------------- ### Docker Compose for Verulink Services Source: https://github.com/venture23-aleo/verulink/wiki/Attestor-Service-Workflow Defines the Docker Compose configuration for the ChainService and SigningService, including dependencies, volume mounts for configuration and mTLS certificates, and environment variables for database and log paths. ```yaml services: chainservice: depends_on: [signingservice] volumes: - ./chain_config.yaml:/configs/config.yaml - ./.mtls:/configs/.mtls environment: - DB_PATH=/db - LOG_PATH=/log signingservice: expose: ["8080"] volumes: - ./sign_config.yaml:/configs/config.yaml - ./secrets.yaml:/configs/keys.yaml ``` -------------------------------- ### Initialize Verulink Contract Source: https://github.com/venture23-aleo/verulink/blob/main/docs/bridge_contract.md Initializes the Verulink contract by setting its configuration and attestors. This function can only be called once. It takes the caller's address and an InitMsg containing the self chain ID and attestors as input. ```rust fn init_contract(&mut self, caller: String, msg: InitMsg) -> Result<(), ContractError> { if self.get_config().is_some() { return Err(ContractError::AlreadyInit); } let config = Config { governance_address: caller, chain_id: msg.self_chain_id, }; self.set_attestors(msg.attestors); self.set_config(config); Ok(()) } ``` -------------------------------- ### Create Cross-Chain Message Packets and Hash in TypeScript and Solidity Source: https://context7.com/venture23-aleo/verulink/llms.txt Utility functions for creating cross-chain message packets and calculating their deterministic hash. The TypeScript code defines the packet structure and creation logic, while the Solidity code provides the hashing function. Dependencies include specific types for packet data and address formatting utilities. ```typescript // TypeScript utilities for packet creation (aleo/utils/packet.ts) import { InPacket } from "./types"; function createPacket( sender: string, receiver: string, amount: bigint, tokenId: bigint ): InPacket { // Example: Creating packet for 1000 vUSDC transfer return { version: 1, sequence: 42n, source: { chain_id: 1n, // Ethereum addr: ethereumAddressToAleoFormat("0x456..."), // [u128; 2] }, destination: { chain_id: 6694886634403n, // Aleo addr: "vlink_token_service_v1.aleo", }, message: { sender_address: ethereumAddressToAleoFormat(sender), // "0x123..." -> [u128; 2] dest_token_id: 6088188135219746443092391282916151282477828391085949070550825603498725268775n, // vUSDC amount: 1000000000n, // 1000 USDC (6 decimals) receiver_address: receiver, // "aleo1abc..." }, height: 19500000n, }; } ``` ```solidity // Solidity hashing (PacketLibrary.sol) function hash(InPacket memory packet) public pure returns (bytes32) { return keccak256(abi.encodePacked( packet.version, // 1 packet.sequence, // 42 packet.sourceTokenService.chainId, // 6694886634403 packet.sourceTokenService.addr, // "vlink_token_service_v1.aleo" packet.destTokenService.chainId, // 1 packet.destTokenService.addr, // 0x456... packet.message.senderAddress, // "aleo1xyz..." packet.message.destTokenAddress, // 0xUSDC packet.message.amount, // 1000000000 packet.message.receiverAddress, // 0x789... packet.height // 123456 )); // Returns: 0xabc123def456... (32 bytes) } // Attestor combines with screening status bytes32 combinedHash = keccak256(abi.encodePacked(packetHash, isWhite)); // If isWhite = true: 0xabc123...01 // If isWhite = false: 0xabc123...00 ``` -------------------------------- ### Attestor ChainService: Process Blockchain Packets Source: https://context7.com/venture23-aleo/verulink/llms.txt The ChainService monitors blockchain packets, screens addresses for security, and initiates the signing process. It handles packet data, calls an address screener, and then uses a signer to generate a hash and signature before submitting to a collector service. Retries are managed for failed submissions. ```go package relay import ( "context" "github.com/venture23-aleo/verulink/attestor/chainService/chain" ) type relay struct { collector collector.CollectorI // DB service client signer signer.SignI // Signing service client screener addressscreener.ScreenI // Chain analysis client } func (r *relay) processPacket(ctx context.Context, pkt *chain.Packet) { // Example: Processing packet from Ethereum // pkt = { // Source: {ChainID: "1", Address: "0x456..."}, // Destination: {ChainID: "6694886634403", Address: "vlink_token_service_v1.aleo"}, // Message: {Sender: "0x123...", Receiver: "aleo1abc...", Amount: 1000000000}, // Sequence: 42, // Height: 19500000 // } // Step 1: Screen addresses with chain analysis isWhite := r.screener.Screen(pkt) // Returns true if sender 0x123... and receiver aleo1abc... are clean // Returns false if either address is flagged/blacklisted // Step 2: Create screened packet sp := &chain.ScreenedPacket{ Packet: pkt, IsWhite: isWhite, // true or false } // Step 3: Send to signing service for hash and signature hash, signature, err := r.signer.HashAndSignScreenedPacket(ctx, sp) // For Aleo destination: BHP256 hash // For Ethereum destination: Keccak256 hash // Example output: // hash = "0xabc123..." // signature = "0xdef456..." (ECDSA for Ethereum, Schnorr for Aleo) if err != nil { // Retry queue for failed packets RegisteredRetryChannels[pkt.Source.ChainID.String()] <- pkt return } // Step 4: Submit to database service for user collection err = r.collector.SendToCollector(ctx, sp, hash, signature) // Stores: {packetHash, signature, attestorAddress, isWhite, timestamp} // Users can now collect signatures from multiple attestors if err == nil { logger.Info("Packet successfully sent", "sequence", pkt.Sequence) } } // Expected flow: // 1. Packet detected at block 19500000 // 2. Wait 24 hours (configurable) for screening // 3. Screen addresses -> isWhite: true // 4. Hash packet -> 0xabc123... // 5. Sign hash -> signature from private key // 6. Submit to DB -> available for user collection ``` -------------------------------- ### Token Service Contract Interface (Rust) Source: https://github.com/venture23-aleo/verulink/blob/main/docs/architecture_overview.md Defines the interface for the Token Service Contract in Rust, outlining functions for token transfers, withdrawals, validation, and management of supported and enabled tokens. It also includes methods for managing blacklisted addresses and adding/removing tokens. ```rust pub trait TokenServiceContract{ pub fn transfer(&self,recipient:String, token:String, amount: u64, to_chain_id: u32); pub fn withdraw(&self, packet:Packet, sigs: []); pub fn validate_blacklisted(address:String)->bool; pub fn is_supported_token(address:String)->bool; pub fn is_enabled_token(address:String)->bool; pub fn add_chain(chain_id: u32, token_service_address: String); // TODO: add details pub fn add_token(address: String, token: TokenInfo); pub fn remove_token(address: String); pub fn enable_token(address: String); pub fn disable_token(address: String); pub fn add_to_blacklist(address: String); pub fn remove_from_blacklist(address: String); } ``` -------------------------------- ### Attestor SigningService - Chain-Specific Signing Source: https://context7.com/venture23-aleo/verulink/llms.txt The SigningService handles secure cryptographic signing operations for different blockchain types (EVM and Aleo). ```APIDOC ## Attestor SigningService - Chain-Specific Signing ### Description This service provides secure cryptographic signing for different blockchain networks, including Ethereum and Aleo. It hashes packet data combined with its screening status and then signs the hash. ### Method POST ### Endpoint `/sign` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **chain_type** (string) - Required - Specifies the blockchain type. Accepts 'evm' or 'aleo'. - **packet** (object) - Required - The packet data to be signed. Structure depends on the chain type. - **is_white** (boolean) - Required - The screening status of the packet addresses (true if whitelisted, false otherwise). ### Request Example ```json { "chain_type": "evm", "packet": { "Source": {"ChainID": "1", "Address": "0x456..."}, "Destination": {"ChainID": "6694886634403", "Address": "vlink_token_service_v1.aleo"}, "Message": {"Sender": "0x123...", "Receiver": "aleo1abc...", "Amount": 1000000000}, "Sequence": 42, "Height": 19500000 }, "is_white": true } ``` ### Response #### Success Response (200) - **Hash** (string) - The computed hash of the packet and screening status, encoded as a hexadecimal string. - **Signature** (string) - The cryptographic signature generated for the hash. #### Response Example ```json { "Hash": "0xabc123...", "Signature": "0xdef456..." } ``` ``` -------------------------------- ### Initialize Contract Interface Source: https://github.com/venture23-aleo/verulink/blob/main/docs/bridge_contract.md Initializes the bridge contract with governance address and chain ID. It prevents re-initialization and sets up initial attestors. Dependencies include `Config`, `InitMsg`, and `ContractError`. Inputs are `caller` (String) and `msg` (InitMsg). Outputs are `Result<(), ContractError>`. ```rust pub trait IBridgeContract { fn init_contract(&mut self, caller: String, msg: InitMsg) -> Result<(), ContractError> { if let None = self.get_config() { let config = Config { governance_address: caller, chain_id: msg.self_chain_id, }; self.set_attestors(msg.attestors); self.set_config(config); } return Err(ContractError::AlreadyInit); } // ... other functions ``` -------------------------------- ### Clone SnarkOS Testnet Branch Source: https://github.com/venture23-aleo/verulink/blob/main/aleo/README.md Clones the testnet3 branch of SnarkOS. This command is used to obtain the specific version of SnarkOS required for testing, ensuring compatibility with the project. ```bash git clone --branch testnet3 https://github.com/AleoHQ/snarkOS.git --depth 1 ``` -------------------------------- ### Generate Client Certificate and Key using OpenSSL Source: https://github.com/venture23-aleo/verulink/blob/main/docs/mTLS_architecture.md Generates a private key and a CSR for a client (e.g., attestor). This CSR is then signed by the CA to produce the client's certificate, allowing it to authenticate with the server. ```bash openssl genpkey -algorithm RSA -out /etc/secret/mtls/attestor1.key openssl req -new -key /etc/secret/mtls/attestor1.key -out /etc/secret/mtls/attestor1.csr openssl x509 -req -in /etc/secret/mtls/attestor1.csr -CA /path/to/ca.crt -CAkey /etc/secret/mtls/ca.key -CAcreateserial -out /etc/secret/mtls/ca.cer ``` -------------------------------- ### Manage Council Governance Operations in TypeScript Source: https://context7.com/venture23-aleo/verulink/llms.txt TypeScript scripts for managing council-based governance operations, including adding attestors, updating token transfer limits, and pausing the bridge. These functions require interaction with council members to collect signatures for proposed actions. Dependencies include a CouncilUtils class and bridge/token service contracts. ```typescript // Council operations via TypeScript scripts (aleo/scripts/council/) import { CouncilUtils } from "./councilUtils"; // Add attestor to bridge contract async function addAttestor() { // Example: Add new attestor address to 5-member council const newAttestor = "aleo1newattestor123..."; // Collect signatures from 3 of 5 council members const proposal = { action: "add_attestor", address: newAttestor, nonce: 1, }; // Member 1 signs const sig1 = await member1.sign(proposal); // Member 2 signs const sig2 = await member2.sign(proposal); // Member 3 signs const sig3 = await member3.sign(proposal); // Execute with threshold signatures (3/5) await bridge.addAttestor(newAttestor, [sig1, sig2, sig3]); // New attestor activated, now 6 total attestors // Quorum still requires 3 signatures } // Update token transfer limits async function updateMaxTransfer() { // Increase USDC limit from 10,000 to 50,000 const tokenAddress = "0xUSDC..."; const newMaxTransfer = 50000000000n; // 50,000 USDC (6 decimals) // Council multisig proposes update const proposal = CouncilUtils.createProposal( "update_max_transfer", tokenAddress, newMaxTransfer ); // Collect 3/5 signatures const signatures = await CouncilUtils.collectSignatures(proposal, [ council1, council2, council3 ]); // Execute via multisig await tokenService.updateMaxTransfer(tokenAddress, newMaxTransfer, signatures); // Users can now transfer up to 50,000 USDC per transaction } // Pause bridge in emergency async function pauseBridge() { // Emergency stop: TVL draining detected await bridge.pause({ from: councilMultisig }); // All transfers and withdrawals halted // Requires council vote to unpause } ``` -------------------------------- ### Attestor ChainService - Packet Processing Source: https://context7.com/venture23-aleo/verulink/llms.txt The ChainService monitors the blockchain for packets, screens addresses for legitimacy, and facilitates the submission of signatures. ```APIDOC ## Attestor ChainService - Packet Processing ### Description Monitors blockchain for packets, screens addresses, and submits signatures. ### Method This documentation describes the internal `processPacket` method within the ChainService, not a public HTTP endpoint. ### Endpoint Internal method within `attestor/chainService/relay/relays.go` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body `pkt` (*chain.Packet) - The packet data received from the blockchain. - **Source** (*chain.ChainAddress) - The source chain and address of the packet. - **Destination** (*chain.ChainAddress) - The destination chain and address for the packet. - **Message** (*chain.Message) - The message content, including sender, receiver, and amount. - **Sequence** (int64) - The sequence number of the packet. - **Height** (int64) - The block height at which the packet was detected. ### Request Example ```json { "Source": {"ChainID": "1", "Address": "0x456..."}, "Destination": {"ChainID": "6694886634403", "Address": "vlink_token_service_v1.aleo"}, "Message": {"Sender": "0x123...", "Receiver": "aleo1abc...", "Amount": 1000000000}, "Sequence": 42, "Height": 19500000 } ``` ### Response #### Success Response (Internal) This method does not return a direct HTTP response. It processes the packet internally and interacts with other services (signer, collector). #### Response Example No direct response. Successful processing leads to data being stored in the collector and available for user collection. ``` -------------------------------- ### Attestor SigningService: Chain-Specific Cryptographic Signing Source: https://context7.com/venture23-aleo/verulink/llms.txt This service handles secure cryptographic signing operations tailored to specific blockchains like Ethereum and Aleo. It receives packet data and a screening status, computes chain-specific hashes (Keccak256 for EVM, BHP256 for Aleo), and generates digital signatures using appropriate algorithms (ECDSA for EVM, Schnorr for Aleo). ```go // Signing service in attestor/signingService/main.go package main import ( "github.com/venture23-aleo/verulink/attestor/signingService/chain/aleo" "github.com/venture23-aleo/verulink/attestor/signingService/chain/ethereum" ) // HTTP server endpoint: POST /sign // Request body: { // "chain_type": "evm" or "aleo", // "packet": {...}, // "is_white": true/false // } func handleSignRequest(w http.ResponseWriter, r *http.Request) { var req SignRequest json.NewDecoder(r.Body).Decode(&req) // Example for Ethereum packet if req.ChainType == "evm" { // Step 1: Compute Keccak256 hash of packet packetHash := ethereum.HashPacket(req.Packet) // packetHash = keccak256(version||sequence||sourceChain||destChain||...) // Step 2: Combine with screening status combinedHash := ethereum.HashWithWhiteStatus(packetHash, req.IsWhite) // combinedHash = keccak256(packetHash || isWhite) // Step 3: Sign with ECDSA private key signature, err := ethereum.Sign(combinedHash) // signature = ECDSA_sign(combinedHash, privateKey) // Returns: 0xabc123...(65 bytes: r||s||v) json.NewEncoder(w).Encode(SignResponse{ Hash: hex.EncodeToString(combinedHash), Signature: hex.EncodeToString(signature), }) } // Example for Aleo packet if req.ChainType == "aleo" { // Step 1: Compute BHP256 hash (Aleo-specific) packetHash := aleo.HashPacket(req.Packet) // Uses external Aleo hasher command // Step 2: Combine with screening status combinedHash := aleo.HashWithWhiteStatus(packetHash, req.IsWhite) // Step 3: Sign with Schnorr signature signature, err := aleo.Sign(combinedHash) // Returns Schnorr signature compatible with Aleo json.NewEncoder(w).Encode(SignResponse{ Hash: combinedHash, Signature: signature, }) } } // Configuration (secrets.yaml): // chains: // - name: ethereum // private_key: "0x123abc..." // - name: aleo // private_key: "APrivateKey1..." // mTLS authentication ensures only ChainService can call ``` -------------------------------- ### Implement IHoldingContract Interface in Rust Source: https://github.com/venture23-aleo/verulink/blob/main/docs/holding_contract.md Implements the 'IHoldingContract' trait, defining the core logic for managing financial holdings. This includes entrypoints for holding funds, unlocking, and releasing them, along with helper methods for verification and data management. It uses Rust's trait system to define a contract's behavior. ```rust pub trait IHoldingContract { // entrypoint fn hold_fund(&mut self, caller: String, msg: TokenMessage) -> Result<(), ContractError> { self.ensure_token_service(caller)?; self.verify_payment(&msg.denom, msg.amount); let mut holding = self.pop_holding(&msg.receiver_address).unwrap_or_default(); let mut fund = holding.funds.get(&msg.denom).cloned().unwrap_or(0_u128); fund = fund.checked_add(msg.amount).expect("Addition Overflow"); holding.funds.insert(msg.denom, fund); Ok(()) } fn verify_payment(&self, denom: &str, amount: u128) -> bool; fn ensure_governance(&self, caller: String) -> Result<(), ContractError> { if self.get_governance() != caller { return Err(ContractError::Unauthorized); } return Ok(()); } // entrypoint fn unlock_holding(&mut self, caller: String, address: String) -> Result<(), ContractError> { self.ensure_governance(caller)?; if let Some(mut holding) = self.pop_holding(&address) { holding.locked = false; self.insert_holding(&address, holding); } Ok(()) } // entrypoint fn release_holding(&mut self, address: String) -> Result<(), ContractError> { let holding = self .pop_holding(&address) .ok_or(ContractError::NoFundsLocked)?; if holding.locked { return Err(ContractError::FundsLocked); } holding .funds .into_iter() .map(|f| return self.refund(&address, f.0, f.1)) .collect::, ContractError>>()?; Ok(()) } fn refund(&self, address: &str, denom: String, amount: u128) -> Result<(), ContractError>; fn pop_holding(&mut self, address: &str) -> Option; fn insert_holding(&mut self, address: &str, holding: Holding) -> Option; fn ensure_token_service(&self, caller: String) -> Result<(), ContractError> { if self.get_token_service() != caller { return Err(ContractError::Unauthorized); } return Ok(()); } fn get_token_service(&self) -> String; fn get_governance(&self) -> String; } ``` -------------------------------- ### Define InitMsg Structure Source: https://github.com/venture23-aleo/verulink/blob/main/docs/bridge_contract.md Defines the `InitMsg` struct used for initializing the Verulink contract. It specifies the self-chain ID and a list of attestor addresses, setting up the initial state and participants. ```rust pub struct InitMsg { self_chain_id: u32, attestors: Vec, } ```