### Start Development Server Source: https://github.com/base/sol2base/blob/main/README.md Start the Next.js development server to run the application locally. Access the app via http://localhost:3000. ```bash npm run dev ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/base/sol2base/blob/main/README.md Install the necessary Node.js dependencies for the project using npm. This command is used after cloning the repository. ```bash npm install --legacy-peer-deps ``` -------------------------------- ### Clone Repository with Git Source: https://github.com/base/sol2base/blob/main/README.md Clone the Terminally Onchain repository to your local machine. Ensure you have Git installed. ```bash git clone https://github.com/Jnix2007/terminally-onchain.git cd terminally-onchain ``` -------------------------------- ### Copy Environment Template Source: https://github.com/base/sol2base/blob/main/README.md Copy the environment template file to create your local environment configuration. This is a necessary step before starting the development server. ```bash cp env.template .env.local ``` -------------------------------- ### Execute a Bridge Transfer with SolanaBridge Source: https://context7.com/base/sol2base/llms.txt Use this method to bridge SOL or SPL tokens from Solana to Base. It resolves destination addresses, validates balances, and constructs/signs the Solana transaction. Ensure you have the necessary wallet adapter setup and sufficient balances. ```typescript import { solanaBridge } from '@/lib/bridge'; import { useWallet } from '@solana/wallet-adapter-react'; import { PublicKey } from '@solana/web3.js'; // Inside a React component: const { publicKey, signTransaction } = useWallet(); // Bridge 0.05 SOL to a raw Base address try { const sig = await solanaBridge.bridge({ walletAddress: publicKey!, amount: '0.05', assetSymbol: 'sol', destinationAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', signTransaction: signTransaction!, }); console.log('Bridge tx:', `https://explorer.solana.com/tx/${sig}?cluster=devnet`); } catch (err) { console.error(err); // "Insufficient SOL balance. You have 0.01 SOL but need 0.05 SOL." } ``` ```typescript // Bridge an SPL token with a Base contract call attached const sig2 = await solanaBridge.bridge({ walletAddress: publicKey!, amount: '50', assetSymbol: 'usdc', destinationAddress: 'myname.base.eth', // Basename resolved automatically signTransaction: signTransaction!, callOptions: { type: 'call', target: '0xSomeBaseContract', value: '0', data: '0xa9059cbb000000000000000000000000recipient0000000000000000000000000000000000000000000000000000000000000064', }, }); ``` ```typescript // Bridge an arbitrary SPL token by mint address with manual overrides const sig3 = await solanaBridge.bridge({ walletAddress: publicKey!, amount: '100', assetSymbol: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU', // treated as mint address destinationAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', signTransaction: signTransaction!, overrides: { remote: '0xCace0c896714DaF7098FFD8CC54aFCFe0338b4BC', decimals: 6, }, }); ``` -------------------------------- ### Configure Mainnet Option Source: https://github.com/base/sol2base/blob/main/README.md Set NEXT_PUBLIC_ENABLE_MAINNET to 'true' in your .env.local file to enable the Solana <-> Base mainnet option in the UI. Otherwise, the app defaults to devnet/Base Sepolia. ```env NEXT_PUBLIC_ENABLE_MAINNET=true ``` -------------------------------- ### Add CDP API Credentials Source: https://github.com/base/sol2base/blob/main/README.md Optionally, add your Coinbase Developer Platform API credentials to the .env.local file to enable faucet functionality. Ensure these are kept secure. ```env CDP_API_KEY_ID=your_cdp_api_key_id CDP_API_KEY_SECRET=your_cdp_api_key_secret ``` -------------------------------- ### Deploy SPL Token on Solana Devnet Source: https://github.com/base/sol2base/blob/main/docs/spl-to-base-erc20.md Deploys a new SPL token with the full supply sent to your connected wallet. Record the printed SPL mint address. ```bash deploySpl ``` ```bash deploySpl MyToken MYT 6 1000000 ``` -------------------------------- ### PDA Derivation Utilities Source: https://context7.com/base/sol2base/llms.txt Deterministically derive PDAs for `OutgoingMessage` and `MessageToRelay` accounts using a 32-byte salt. These PDAs are crucial for bridge transactions. ```APIDOC ## `deriveOutgoingMessagePda` / `deriveMessageToRelayPda` — PDA Derivation Utilities Deterministically derive the `OutgoingMessage` and `MessageToRelay` program derived addresses from a 32-byte salt, which are used as accounts in every bridge transaction. ```typescript import { deriveOutgoingMessagePda, deriveMessageToRelayPda, normalizeSalt } from '@/lib/pdas'; import { PublicKey } from '@solana/web3.js'; const BRIDGE_PROGRAM = new PublicKey('7c6mteAcTXaQ1MFBCrnuzoZVTTAEfZwa6wgy4bqX3KXC'); const RELAYER_PROGRAM = new PublicKey('56MBBEYAtQAdjT4e1NzHD8XaoyRSTvfgbSVVcEcHj51H'); // Generate a random 32-byte salt const salt32 = new Uint8Array(32); crypto.getRandomValues(salt32); // Or from a hex string const saltFromHex = normalizeSalt('0xdeadbeef' + '00'.repeat(28)); // Derive PDAs const outgoingMsgPda = deriveOutgoingMessagePda(salt32, BRIDGE_PROGRAM); const messageToRelayPda = deriveMessageToRelayPda(salt32, RELAYER_PROGRAM); console.log('OutgoingMessage PDA:', outgoingMsgPda.toBase58()); console.log('MessageToRelay PDA:', messageToRelayPda.toBase58()); // OutgoingMessage PDA: 9xT4... // MessageToRelay PDA: 3pQ8... // Error: wrong salt length try { normalizeSalt(new Uint8Array(16)); // throws } catch (e) { console.error(e.message); // 'salt must be 32 bytes. got 16' } ``` ``` -------------------------------- ### Switch Network Environment with SolanaBridge Source: https://context7.com/base/sol2base/llms.txt Allows switching the bridge between 'devnet' and 'mainnet' environments. This updates RPC connections and program IDs. Use 'mainnet' only if NEXT_PUBLIC_ENABLE_MAINNET is true. ```typescript import { solanaBridge } from '@/lib/bridge'; // Switch to mainnet (requires NEXT_PUBLIC_ENABLE_MAINNET=true in env) solanaBridge.setEnvironment('mainnet'); console.log(solanaBridge.getEnvironment()); // 'mainnet' const config = solanaBridge.getEnvironmentConfig(); console.log(config.base.bridge); // '0x3eff766C76a1be2Ce1aCF2B69c78bCae257D5188' (Base Mainnet bridge contract) // Switch back to devnet solanaBridge.setEnvironment('devnet'); console.log(solanaBridge.getEnvironmentConfig().base.chainId); // 84532 (Base Sepolia) // Get supported assets for current environment const assets = solanaBridge.getSupportedAssets(); console.log(assets.map(a => a.symbol)); // devnet: ['sol', 'usdc'] // mainnet: ['sol'] ``` -------------------------------- ### POST /api/faucet/sol Source: https://context7.com/base/sol2base/llms.txt A Next.js API route that acts as a proxy for CDP faucet requests from the browser. It provides mock responses if CDP credentials are not configured. ```APIDOC ## `POST /api/faucet/sol` — SOL Faucet API Route Next.js API route that proxies CDP faucet requests from the browser. Returns a mock response when CDP credentials are absent, making local development work without an API key. ### Method POST ### Endpoint `/api/faucet/sol` ### Parameters #### Request Body - **address** (string) - Required - The Solana Devnet address to receive the SOL airdrop. ### Request Example ```bash curl -X POST http://localhost:3000/api/faucet/sol \ -H "Content-Type: application/json" \ -d '{"address": "8YzMz6HkEQHQEXrDvX3LDnj1vJa4VXbqTBr3kgWNp5ab"}' ``` ### Response #### Success Response (200) - **success** (boolean) - Indicates if the request was successful. - **transactionHash** (string) - The hash of the SOL transaction (or mock hash). - **amount** (number) - The amount of SOL airdropped. - **network** (string) - The network where the SOL was airdropped. - **token** (string) - The token symbol. - **explorerUrl** (string) - URL to the transaction on the network explorer. - **note** (string, optional) - A note indicating mock mode if CDP credentials are not configured. #### Error Response (400) - **error** (string) - "Address is required" #### Error Response (500) - **error** (string) - "Faucet rate limit exceeded. Please try again later (24 hour limit)." ``` -------------------------------- ### Proxy SOL Faucet API Route (Next.js) Source: https://context7.com/base/sol2base/llms.txt A Next.js API route that proxies SOL faucet requests from the browser to the CDP Faucet API. It provides mock responses for local development when CDP credentials are not configured. ```bash # Request SOL for a Solana Devnet address curl -X POST http://localhost:3000/api/faucet/sol \ -H "Content-Type: application/json" \ -d '{"address": "8YzMz6HkEQHQEXrDvX3LDnj1vJa4VXbqTBr3kgWNp5ab"}' # Success response (real CDP configured): # { # "success": true, # "transactionHash": "5j7Kwhatever...", # "amount": 0.00125, # "network": "solana-devnet", # "token": "SOL", # "explorerUrl": "https://explorer.solana.com/tx/5j7K...?cluster=devnet" # } # Success response (no CDP credentials — mock mode): # { # "success": true, # "transactionHash": "mock_sol_faucet_1712345678901", # "amount": 0.00125, # "network": "solana-devnet", # "token": "SOL", # "explorerUrl": "https://explorer.solana.com/tx/mock_sol_faucet_1712345678901?cluster=devnet", # "note": "Mock SOL faucet - CDP not configured. Add your CDP credentials to .env.local" # } # Missing address: # HTTP 400 { "error": "Address is required" } # Rate limit exceeded: # HTTP 500 { "error": "Faucet rate limit exceeded. Please try again later (24 hour limit)." } ``` -------------------------------- ### Request Devnet SOL with CdpFaucetService Source: https://context7.com/base/sol2base/llms.txt Requests a SOL airdrop to a Solana Devnet address using the Coinbase Developer Platform Faucet API. Ensure CDP_API_KEY_ID and CDP_API_KEY_SECRET are set in your environment variables. ```typescript import { cdpFaucet } from '@/lib/cdpFaucet'; // Check configuration before calling const configured = await cdpFaucet.isConfigured(); if (!configured) { console.error('Set CDP_API_KEY_ID and CDP_API_KEY_SECRET in .env.local'); } // Request SOL airdrop try { const result = await cdpFaucet.requestSol('8YzMz6HkEQHQEXrDvX3LDnj1vJa4VXbqTBr3kgWNp5ab'); console.log('Transaction hash:', result.transactionHash); console.log('Amount received:', result.amount, 'SOL'); // Transaction hash: 5j7K... // Amount received: 0.00125 SOL } catch (err) { // 'Faucet rate limit exceeded. Please try again later (24 hour limit).' // 'CDP API credentials not configured. Please check your environment variables.' console.error(err.message); } // Faucet metadata const info = cdpFaucet.getFaucetInfo(); // { network: 'Solana Devnet', token: 'SOL', amount: 0.00125, dailyLimit: '10 claims per 24 hours', ... } ``` -------------------------------- ### CdpFaucetService.requestSol(address) Source: https://context7.com/base/sol2base/llms.txt Requests a devnet SOL airdrop to a specified Solana Devnet address using the Coinbase Developer Platform Faucet API. Requires CDP API credentials. ```APIDOC ## `CdpFaucetService.requestSol(address)` — Request Devnet SOL via CDP Calls the Coinbase Developer Platform Faucet API to airdrop `0.00125 SOL` to a Solana Devnet address. Requires `CDP_API_KEY_ID` and `CDP_API_KEY_SECRET` environment variables. ### Parameters #### Path Parameters - **address** (string) - Required - The Solana Devnet address to receive the SOL airdrop. ### Request Example ```typescript import { cdpFaucet } from '@/lib/cdpFaucet'; const configured = await cdpFaucet.isConfigured(); if (!configured) { console.error('Set CDP_API_KEY_ID and CDP_API_KEY_SECRET in .env.local'); } try { const result = await cdpFaucet.requestSol('8YzMz6HkEQHQEXrDvX3LDnj1vJa4VXbqTBr3kgWNp5ab'); console.log('Transaction hash:', result.transactionHash); console.log('Amount received:', result.amount, 'SOL'); } catch (err) { console.error(err.message); } const info = cdpFaucet.getFaucetInfo(); // { network: 'Solana Devnet', token: 'SOL', amount: 0.00125, dailyLimit: '10 claims per 24 hours', ... } ``` ### Response #### Success Response - **transactionHash** (string) - The hash of the SOL transaction. - **amount** (number) - The amount of SOL airdropped. - **network** (string) - The network where the SOL was airdropped (e.g., 'Solana Devnet'). - **token** (string) - The token symbol (e.g., 'SOL'). #### Error Response - **error** (string) - An error message, e.g., 'Faucet rate limit exceeded' or 'CDP API credentials not configured'. ``` -------------------------------- ### SolanaBridge.setEnvironment Source: https://context7.com/base/sol2base/llms.txt Switches the bridge between network environments ('devnet' or 'mainnet'), updating internal RPC connections and program IDs. ```APIDOC ## `SolanaBridge.setEnvironment(env)` — Switch Network Environment Switches the bridge between `"devnet"` (Solana Devnet → Base Sepolia) and `"mainnet"` (Solana Mainnet → Base Mainnet), updating the internal RPC connection and all program IDs atomically. ### Parameters - **env** (string) - The target environment, either 'devnet' or 'mainnet'. ### Request Example ```typescript import { solanaBridge } from '@/lib/bridge'; // Switch to mainnet (requires NEXT_PUBLIC_ENABLE_MAINNET=true in env) solanaBridge.setEnvironment('mainnet'); console.log(solanaBridge.getEnvironment()); // 'mainnet' const config = solanaBridge.getEnvironmentConfig(); console.log(config.base.bridge); // '0x3eff766C76a1be2Ce1aCF2B69c78bCae257D5188' (Base Mainnet bridge contract) // Switch back to devnet solanaBridge.setEnvironment('devnet'); console.log(solanaBridge.getEnvironmentConfig().base.chainId); // 84532 (Base Sepolia) // Get supported assets for current environment const assets = solanaBridge.getSupportedAssets(); console.log(assets.map(a => a.symbol)); // devnet: ['sol', 'usdc'] // mainnet: ['sol'] ``` ### Response This method does not return a value but modifies the internal state of the bridge. ``` -------------------------------- ### Deploy ERC-20 Twin on Base Network Source: https://github.com/base/sol2base/blob/main/docs/spl-to-base-erc20.md Deploys the ERC-20 contract on Base Sepolia or Mainnet using the CrossChainERC20Factory. Requires the derived remoteToken, token name, symbol, and decimals. ```solidity deploy(remoteToken,name,symbol,decimals) ``` -------------------------------- ### Derive Solana PDAs for Bridge Transactions Source: https://context7.com/base/sol2base/llms.txt Use these functions to deterministically derive PDAs for `OutgoingMessage` and `MessageToRelay` accounts. Ensure the salt is a 32-byte array or a hex string. The `normalizeSalt` function validates the salt length. ```typescript import { deriveOutgoingMessagePda, deriveMessageToRelayPda, normalizeSalt } from '@/lib/pdas'; import { PublicKey } from '@solana/web3.js'; const BRIDGE_PROGRAM = new PublicKey('7c6mteAcTXaQ1MFBCrnuzoZVTTAEfZwa6wgy4bqX3KXC'); const RELAYER_PROGRAM = new PublicKey('56MBBEYAtQAdjT4e1NzHD8XaoyRSTvfgbSVVcEcHj51H'); // Generate a random 32-byte salt const salt32 = new Uint8Array(32); crypto.getRandomValues(salt32); // Or from a hex string const saltFromHex = normalizeSalt('0xdeadbeef' + '00'.repeat(28)); // Derive PDAs const outgoingMsgPda = deriveOutgoingMessagePda(salt32, BRIDGE_PROGRAM); const messageToRelayPda = deriveMessageToRelayPda(salt32, RELAYER_PROGRAM); console.log('OutgoingMessage PDA:', outgoingMsgPda.toBase58()); console.log('MessageToRelay PDA:', messageToRelayPda.toBase58()); // OutgoingMessage PDA: 9xT4... // MessageToRelay PDA: 3pQ8... // Error: wrong salt length try { normalizeSalt(new Uint8Array(16)); // throws } catch (e) { console.error(e.message); // 'salt must be 32 bytes. got 16' } ``` -------------------------------- ### AddressResolver.resolveAddress(input) Source: https://context7.com/base/sol2base/llms.txt Resolves a destination string to a checksum Ethereum address. It supports raw Ethereum addresses, ENS names (e.g., vitalik.eth), and Basenames (e.g., jesse.base.eth or jesse.base). ```APIDOC ## `AddressResolver.resolveAddress(input)` — Resolve ENS / Basename / Raw Address Resolves a destination string to a checksum Ethereum address. Accepts raw `0x...` addresses (returned as-is), `.eth` ENS names (resolved via `api.ensdata.net`), and `.base` / `.base.eth` Basenames (resolved via ENS or the Base name service API). ### Parameters #### Path Parameters - **input** (string) - Required - The string to resolve (raw address, ENS name, or Basename). ### Request Example ```typescript import { addressResolver } from '@/lib/addressResolver'; // Raw address const raw = await addressResolver.resolveAddress('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'); // ENS name resolution const ens = await addressResolver.resolveAddress('vitalik.eth'); // Basename resolution const basename = await addressResolver.resolveAddress('jesse.base.eth'); const basename2 = await addressResolver.resolveAddress('coinbase.base'); // Validation helper console.log(addressResolver.isValidInput('vitalik.eth')); // true console.log(addressResolver.getInputType('jesse.base')); // 'Basename' // Error handling try { await addressResolver.resolveAddress('random-string'); } catch (e) { console.error(e.message); } ``` ### Response #### Success Response - **resolvedAddress** (string) - The checksummed Ethereum address. #### Error Response - **error** (string) - Message indicating an invalid address format. ``` -------------------------------- ### Create Feature Branch Source: https://github.com/base/sol2base/blob/main/README.md When contributing, create a new branch for your feature using Git. This helps in organizing changes and managing pull requests. ```bash git checkout -b feature/amazing-feature ``` -------------------------------- ### SolanaBridge.getSolBalance Source: https://context7.com/base/sol2base/llms.txt Reads the native SOL balance for a given Solana public key. Returns the balance in SOL (not lamports) against the configured RPC endpoint. ```APIDOC ## `SolanaBridge.getSolBalance(walletAddress)` — Read SOL Balance Returns the native SOL balance (in SOL, not lamports) for the given Solana public key against the currently configured RPC endpoint. ### Parameters - **walletAddress** (PublicKey) - The public key of the Solana wallet. ### Request Example ```typescript import { solanaBridge } from '@/lib/bridge'; import { PublicKey } from '@solana/web3.js'; const wallet = new PublicKey('8YzMz6HkEQHQEXrDvX3LDnj1vJa4VXbqTBr3kgWNp5ab'); const balance = await solanaBridge.getSolBalance(wallet); console.log(`Balance: ${balance} SOL`); // Balance: 1.23456789 SOL // Handle failure gracefully (returns 0 on error) const emptyBalance = await solanaBridge.getSolBalance(new PublicKey('11111111111111111111111111111111')); // 0 ``` ### Response - **string** - The SOL balance as a string, or '0' if an error occurs. ``` -------------------------------- ### useNetwork() Hook Source: https://context7.com/base/sol2base/llms.txt A React hook that provides access to the current bridge environment, its configuration, and a function to switch environments. It must be used within a `NetworkProvider`. ```APIDOC ## `useNetwork()` — React Network Context Hook React hook that provides the current bridge environment, its full configuration object, and a setter for switching environments. Must be used inside ``. ```tsx import { NetworkProvider, useNetwork } from '@/contexts/NetworkContext'; // Wrap your app export default function RootLayout({ children }) { return {children}; } // Inside any component function BridgeForm() { const { environment, config, setEnvironment } = useNetwork(); return (

Current network: {config.label}

{/* "Solana Devnet → Base Sepolia" */}

Bridge contract: {config.base.bridge}

{/* "0x01824a90d32A69022DdAEcC6C5C14Ed08dB4EB9B" */}

Supported assets: {config.assets.map(a => a.symbol).join(', ')}

{/* "sol, usdc" */} {/* Toggle to mainnet (only visible when NEXT_PUBLIC_ENABLE_MAINNET=true) */}
); } ``` ``` -------------------------------- ### Read SPL Token Balance with SolanaBridge Source: https://context7.com/base/sol2base/llms.txt Fetches the balance of a specific SPL token for a given wallet address. Assumes 6 decimals by default and returns 0 if the token account does not exist. ```typescript import { solanaBridge } from '@/lib/bridge'; import { PublicKey } from '@solana/web3.js'; const wallet = new PublicKey('8YzMz6HkEQHQEXrDvX3LDnj1vJa4VXbqTBr3kgWNp5ab'); const usdcMint = new PublicKey('4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU'); const usdcBalance = await solanaBridge.getTokenBalance(wallet, usdcMint); console.log(`USDC Balance: ${usdcBalance}`); // USDC Balance: 250.5 // Returns 0 if the token account does not exist const unknownMint = new PublicKey('11111111111111111111111111111111'); const zeroBalance = await solanaBridge.getTokenBalance(wallet, unknownMint); // 0 ``` -------------------------------- ### Bridge SPL Tokens to Base Network Source: https://github.com/base/sol2base/blob/main/docs/spl-to-base-erc20.md Initiates the bridging of SPL tokens from Solana to Base. Specify the amount, SPL mint address, destination address on Base, the remote ERC-20 address, and token decimals. ```bash bridge --remote --decimals ``` ```bash bridge 100 MYT_SPL_MINT 0xYourBaseAddress --remote 0xDeployedErc20 --decimals 6 ``` -------------------------------- ### Read SOL Balance with SolanaBridge Source: https://context7.com/base/sol2base/llms.txt Retrieves the native SOL balance for a given Solana public key. Returns 0 if an error occurs or the address is invalid. ```typescript import { solanaBridge } from '@/lib/bridge'; import { PublicKey } from '@solana/web3.js'; const wallet = new PublicKey('8YzMz6HkEQHQEXrDvX3LDnj1vJa4VXbqTBr3kgWNp5ab'); const balance = await solanaBridge.getSolBalance(wallet); console.log(`Balance: ${balance} SOL`); // Balance: 1.23456789 SOL // Handle failure gracefully (returns 0 on error) const emptyBalance = await solanaBridge.getSolBalance(new PublicKey('11111111111111111111111111111111')); // 0 ``` -------------------------------- ### Resolve ENS / Basename / Raw Address with AddressResolver Source: https://context7.com/base/sol2base/llms.txt Resolves various address formats including raw hex, ENS names, and Basenames. Use this to standardize address inputs. Validation helpers are also available. ```typescript import { addressResolver } from '@/lib/addressResolver'; // Raw address — returned immediately without network call const raw = await addressResolver.resolveAddress('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'); // '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045' // ENS name resolution const ens = await addressResolver.resolveAddress('vitalik.eth'); // '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045' // Basename resolution const basename = await addressResolver.resolveAddress('jesse.base.eth'); // '0x...resolvedAddress' // Basename with short-form suffix const basename2 = await addressResolver.resolveAddress('coinbase.base'); // '0x...resolvedAddress' // Validation helper — no network call console.log(addressResolver.isValidInput('vitalik.eth')); // true console.log(addressResolver.isValidInput('not-valid')); // false console.log(addressResolver.getInputType('jesse.base')); // 'Basename' console.log(addressResolver.getInputType('vitalik.eth')); // 'ENS Name' console.log(addressResolver.getInputType('0xAbc...')); // 'Ethereum Address' // Error on unrecognized format try { await addressResolver.resolveAddress('random-string'); } catch (e) { console.error(e.message); // 'Invalid address format. Please enter a valid Ethereum address (0x...), ENS name (.eth), or basename (.base)' } ``` -------------------------------- ### React Hook for Network Context Source: https://context7.com/base/sol2base/llms.txt Use the `useNetwork` hook within a `NetworkProvider` to access the current bridge environment, its configuration, and a function to switch environments. This hook simplifies state management for network-specific data in React components. ```tsx import { NetworkProvider, useNetwork } from '@/contexts/NetworkContext'; // Wrap your app export default function RootLayout({ children }) { return {children}; } // Inside any component function BridgeForm() { const { environment, config, setEnvironment } = useNetwork(); return (

Current network: {config.label}

{/* "Solana Devnet → Base Sepolia" */}

Bridge contract: {config.base.bridge}

{/* "0x01824a90d32A69022DdAEcC6C5C14Ed08dB4EB9B" */}

Supported assets: {config.assets.map(a => a.symbol).join(', ')}

{/* "sol, usdc" */} {/* Toggle to mainnet (only visible when NEXT_PUBLIC_ENABLE_MAINNET=true) */}
); } ``` -------------------------------- ### SolanaBridge.getTokenBalance Source: https://context7.com/base/sol2base/llms.txt Fetches the balance of a specific SPL token for the user's associated token account. The balance is returned in human-readable units, assuming 6 decimals. ```APIDOC ## `SolanaBridge.getTokenBalance(walletAddress, tokenMint)` — Read SPL Token Balance Fetches the balance of a specific SPL token (in human-readable units, assuming 6 decimals) from the user's associated token account. ### Parameters - **walletAddress** (PublicKey) - The public key of the Solana wallet. - **tokenMint** (PublicKey) - The mint address of the SPL token. ### Request Example ```typescript import { solanaBridge } from '@/lib/bridge'; import { PublicKey } from '@solana/web3.js'; const wallet = new PublicKey('8YzMz6HkEQHQEXrDvX3LDnj1vJa4VXbqTBr3kgWNp5ab'); const usdcMint = new PublicKey('4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU'); const usdcBalance = await solanaBridge.getTokenBalance(wallet, usdcMint); console.log(`USDC Balance: ${usdcBalance}`); // USDC Balance: 250.5 // Returns 0 if the token account does not exist const unknownMint = new PublicKey('11111111111111111111111111111111'); const zeroBalance = await solanaBridge.getTokenBalance(wallet, unknownMint); // 0 ``` ### Response - **string** - The token balance as a string, or '0' if the token account does not exist or an error occurs. ``` -------------------------------- ### Parse Terminal Commands with TypeScript Source: https://context7.com/base/sol2base/llms.txt Use `parseTerminalCommand` to tokenize and parse raw terminal input into a typed command object. Supports various commands like 'bridge', 'deploySpl', 'faucet', and 'remoteToken' with extensive flag parsing. ```typescript import { parseTerminalCommand } from '@/lib/terminalParser'; // Simple SOL bridge const cmd1 = parseTerminalCommand('bridge 0.01 sol 0xAbc123...def'); // { type: 'bridge', payload: { amount: '0.01', asset: 'sol', destination: '0xAbc123...def', flags: {} } } ``` ```typescript // SPL bridge with custom mint, remote ERC-20, and a Base contract call const cmd2 = parseTerminalCommand( 'bridge 100 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU vitalik.eth ' + '--remote 0xCace0c896714DaF7098FFD8CC54aFCFe0338b4BC --decimals 6 ' + '--call-contract 0xSomeContract --call-selector 0xa9059cbb ' + '--call-args 0xRecipient 1000000' ); // { // type: 'bridge', // payload: { // amount: '100', // asset: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU', // destination: 'vitalik.eth', // flags: { // remote: '0xCace0c896714DaF7098FFD8CC54aFCFe0338b4BC', // decimals: 6, // callContract: '0xSomeContract', // callSelector: '0xa9059cbb', // callArgs: ['0xRecipient', '1000000'] // } // } // } ``` ```typescript // Error case: missing required flag value const cmd3 = parseTerminalCommand('bridge 1 sol 0xDest --call-contract 0xTarget'); // { type: 'error', message: 'Specify --call-selector when adding call details.' } ``` ```typescript // Deploy SPL token const cmd4 = parseTerminalCommand('deploySpl MyToken MYT 6 1000000'); // { type: 'deploySpl', payload: { name: 'MyToken', symbol: 'MYT', decimals: 6, supply: '1000000' } } ``` ```typescript // Faucet const cmd5 = parseTerminalCommand('faucet sol'); // { type: 'faucet', asset: 'sol' } ``` ```typescript // remoteToken lookup const cmd6 = parseTerminalCommand('remoteToken 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU'); // { type: 'remoteToken', mint: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU' } ``` -------------------------------- ### Commit Changes Source: https://github.com/base/sol2base/blob/main/README.md Commit your changes to the feature branch with a descriptive message. This is part of the standard Git workflow for contributions. ```bash git commit -m 'Add amazing feature' ``` -------------------------------- ### Push to Remote Branch Source: https://github.com/base/sol2base/blob/main/README.md Push your committed changes to the remote repository on the feature branch. This makes your changes available for review. ```bash git push origin feature/amazing-feature ``` -------------------------------- ### SolanaBridge.bridge Source: https://context7.com/base/sol2base/llms.txt Executes a bridge transfer of SOL or SPL tokens from Solana to Base. It resolves the destination address, validates balances, builds and signs the Solana transaction, and returns the transaction signature. ```APIDOC ## `SolanaBridge.bridge(options)` — Execute a Bridge Transfer The primary entry point for bridging SOL or any SPL token from Solana to Base. Resolves the destination address (raw hex, ENS, or Basename), validates balances, builds the Solana transaction via `RealBridgeImplementation`, signs it through the wallet adapter, and returns the Solana transaction signature. ### Parameters - **walletAddress** (PublicKey) - The public key of the user's Solana wallet. - **amount** (string) - The amount of the asset to bridge. - **assetSymbol** (string) - The symbol of the asset to bridge (e.g., 'sol', 'usdc') or its mint address. - **destinationAddress** (string) - The destination address on the Base network (can be raw hex, ENS, or Basename). - **signTransaction** (Function) - A function to sign the Solana transaction, typically provided by a wallet adapter. - **callOptions** (object, optional) - Options for attaching a Base contract call to the transaction. - **type** (string) - Must be 'call'. - **target** (string) - The target contract address on Base. - **value** (string) - The amount of native currency to send with the call. - **data** (string) - The contract call data. - **overrides** (object, optional) - Manual overrides for token details. - **remote** (string) - The remote token address. - **decimals** (number) - The token's decimals. ### Request Example ```typescript // Bridge 0.05 SOL to a raw Base address try { const sig = await solanaBridge.bridge({ walletAddress: publicKey!, amount: '0.05', assetSymbol: 'sol', destinationAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', signTransaction: signTransaction!, }); console.log('Bridge tx:', `https://explorer.solana.com/tx/${sig}?cluster=devnet`); } catch (err) { console.error(err); } // Bridge an SPL token with a Base contract call attached const sig2 = await solanaBridge.bridge({ walletAddress: publicKey!, amount: '50', assetSymbol: 'usdc', destinationAddress: 'myname.base.eth', // Basename resolved automatically signTransaction: signTransaction!, callOptions: { type: 'call', target: '0xSomeBaseContract', value: '0', data: '0xa9059cbb000000000000000000000000recipient0000000000000000000000000000000000000000000000000000000000000064', }, }); // Bridge an arbitrary SPL token by mint address with manual overrides const sig3 = await solanaBridge.bridge({ walletAddress: publicKey!, amount: '100', assetSymbol: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU', // treated as mint address destinationAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', signTransaction: signTransaction!, overrides: { remote: '0xCace0c896714DaF7098FFD8CC54aFCFe0338b4BC', decimals: 6, }, }); ``` ### Response - **string** - The signature of the executed Solana transaction. ``` -------------------------------- ### Derive Remote Token Bytes32 from SPL Mint Address Source: https://github.com/base/sol2base/blob/main/docs/spl-to-base-erc20.md Derives the 32-byte hex representation of the SPL token's remote identifier, which is cluster-independent. ```bash remoteToken ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.