> ## Documentation Index
> Fetch the complete documentation index at: https://docs.layerzero.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Interactive Solana Instructions Playground

> Test LayerZero Solana programs directly from your browser. Build and send instructions without writing code. Explore key program instructions for message...

export const InteractiveSolanaInstruction = ({programName, instructionName, description = null, accounts = [], args = []}) => {
  const [solanaWeb3, setSolanaWeb3] = useState(null);
  const [isLoaded, setIsLoaded] = useState(false);
  const [isOpen, setIsOpen] = useState(false);
  const [network, setNetwork] = useState('');
  const [customRpc, setCustomRpc] = useState('');
  const [customProgramId, setCustomProgramId] = useState('');
  const [isWalletConnected, setIsWalletConnected] = useState(false);
  const [walletAddress, setWalletAddress] = useState(null);
  const [inputValues, setInputValues] = useState({});
  const [accountValues, setAccountValues] = useState({});
  const [logs, setLogs] = useState([]);
  const [status, setStatus] = useState('idle');
  const [errorMessage, setErrorMessage] = useState(null);
  const READ_INSTRUCTIONS = ['quote', 'quoteOft', 'quoteSend', 'oftVersion', 'lzReceiveTypes'];
  const isRead = READ_INSTRUCTIONS.includes(instructionName);
  const badgeText = isRead ? 'READ' : 'WRITE';
  const badgeClasses = isRead ? "bg-[#6366f1] text-white" : "bg-[#10b981] text-white";
  useEffect(() => {
    if (window.solanaWeb3) {
      setSolanaWeb3(window.solanaWeb3);
      setIsLoaded(true);
      return;
    }
    const script = document.createElement('script');
    script.src = 'https://unpkg.com/@solana/web3.js@1.91.0/lib/index.iife.min.js';
    script.async = true;
    script.onload = () => {
      setSolanaWeb3(window.solanaWeb3);
      setIsLoaded(true);
    };
    document.body.appendChild(script);
    return () => {};
  }, []);
  useEffect(() => {
    const initialArgs = {};
    args.forEach(arg => {
      initialArgs[arg.name] = '';
    });
    setInputValues(initialArgs);
    const initialAccounts = {};
    accounts.forEach(acc => {
      initialAccounts[acc.name] = '';
    });
    setAccountValues(initialAccounts);
  }, [args, accounts]);
  const connectWallet = async () => {
    try {
      const {solana} = window;
      if (solana && solana.isPhantom) {
        const response = await solana.connect();
        setWalletAddress(response.publicKey.toString());
        setIsWalletConnected(true);
      } else {
        alert('Solana object not found! Get a Phantom Wallet 👻');
      }
    } catch (err) {
      console.error(err);
      setErrorMessage(err.message);
    }
  };
  const getRpcUrl = () => {
    if (network === 'mainnet-beta') return 'https://api.mainnet-beta.solana.com';
    return 'https://api.devnet.solana.com';
  };
  const handleArgChange = (name, value) => {
    setInputValues(prev => ({
      ...prev,
      [name]: value
    }));
  };
  const handleAccountChange = (name, value) => {
    setAccountValues(prev => ({
      ...prev,
      [name]: value
    }));
  };
  const executeInstruction = async () => {
    if (!solanaWeb3 || !isWalletConnected) return;
    setStatus('loading');
    setLogs([]);
    setErrorMessage(null);
    try {
      const connection = new solanaWeb3.Connection(getRpcUrl(), 'confirmed');
      const publicKey = new solanaWeb3.PublicKey(walletAddress);
      const keys = accounts.map(acc => {
        const pubkeyStr = accountValues[acc.name];
        if (!pubkeyStr) throw new Error(`Missing account: ${acc.name}`);
        return {
          pubkey: new solanaWeb3.PublicKey(pubkeyStr),
          isSigner: acc.type === 'Signer',
          isWritable: acc.description?.toLowerCase().includes('mutable') || false
        };
      });
      const dataBuffer = Buffer.alloc(0);
      const progIdStr = "11111111111111111111111111111111";
      const transaction = new solanaWeb3.Transaction().add(new solanaWeb3.TransactionInstruction({
        keys,
        programId: new solanaWeb3.PublicKey(progIdStr),
        data: dataBuffer
      }));
      transaction.feePayer = publicKey;
      const {blockhash} = await connection.getLatestBlockhash();
      transaction.recentBlockhash = blockhash;
      const {signature} = await window.solana.signAndSendTransaction(transaction);
      setStatus('success');
      setLogs([`Transaction sent: ${signature}`]);
      const confirmation = await connection.confirmTransaction(signature);
      if (confirmation.value.err) {
        throw new Error("Transaction failed onchain");
      }
      setLogs(prev => [...prev, "Transaction confirmed!"]);
    } catch (err) {
      console.error(err);
      setStatus('error');
      setErrorMessage(err.message);
    }
  };
  if (!isLoaded) {
    return <div className="p-4 bg-gray-50 rounded-lg animate-pulse">Loading Solana Web3...</div>;
  }
  return <div className="border border-[#e0e0e0] dark:border-[#272727] rounded-lg overflow-hidden bg-[#fafafa] dark:bg-[#0a0a0a] shadow-sm my-4 text-sm font-sans">
      
      {}
      <div className="flex items-center justify-between p-4 cursor-pointer hover:bg-gray-100 dark:hover:bg-zinc-900 transition-colors" onClick={() => setIsOpen(!isOpen)}>
        <div className="flex items-center gap-3 overflow-hidden flex-1 min-w-0">
          <div className="px-2 py-[2px] rounded-[4px] min-w-[3rem] text-[0.625rem] font-semibold tracking-[0.05em] flex justify-center items-center uppercase flex-shrink-0 text-white" style={{
    backgroundColor: isRead ? '#6366f1' : '#10b981'
  }}>
            {badgeText}
          </div>
          <div className="font-mono text-[#7d7d7d] dark:text-[#757575] overflow-x-auto whitespace-nowrap scrollbar-hide text-xs" title={`${instructionName}(${accounts.map(a => `${a.name}: ${a.type}`).join(', ')}, ${args.map(a => `${a.name}: ${a.type}`).join(', ')})`}>
            <span className="text-[#0a0a0a] dark:text-[#f2f2f2] font-normal">{instructionName}</span>
            <span className="text-[#7d7d7d] dark:text-[#757575]">(</span>
             {accounts.map((acc, i) => <span key={`acc-${i}`} className="text-[#7d7d7d] dark:text-[#757575]">
                  <span className="text-[#0a0a0a] dark:text-[#f2f2f2]">{acc.name}</span>: <span className="text-[#e36209] dark:text-[#f1df38]">{acc.type}</span>
                  {i < accounts.length - 1 ? ', ' : ''}
                </span>)}
             {accounts.length > 0 && args.length > 0 && ', '}
             {args.map((arg, i) => <span key={`arg-${i}`} className="text-[#7d7d7d] dark:text-[#757575]">
                  <span className="text-[#0a0a0a] dark:text-[#f2f2f2]">{arg.name}</span>: <span className="text-[#e36209] dark:text-[#f1df38]">{arg.type}</span>
                  {i < args.length - 1 ? ', ' : ''}
                </span>)}
            <span className="text-[#7d7d7d] dark:text-[#757575]">)</span>
          </div>
        </div>
        <div className={`text-gray-400 transform transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`}>
          <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M6 9L12 15L18 9" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
          </svg>
        </div>
      </div>

      {}
      {isOpen && <div className="content_RXk0" style={{
    animation: '.2s ease-out j',
    background: 'rgba(255, 255, 255, 0.02)',
    border: '1px solid rgba(255, 255, 255, 0.08)',
    borderTop: 'none',
    borderRadius: '0 0 8px 8px',
    marginBottom: '1rem',
    padding: '1.5rem'
  }}>
          
          {description && <div className="description_UDHP text-[#7d7d7d] dark:text-[#a3a3a3] text-[0.8125rem] font-light leading-6 mb-5 p-0">
              {description}
            </div>}

          {}
          <div className="fieldGroup_Wlo7 mb-4">
            <label className="fieldLabel_kbcb block text-[0.625rem] font-semibold text-[#7d7d7d] dark:text-[#a3a3a3] uppercase tracking-wider mb-2">NETWORK</label>
            <div className="chainSelectorWrapper_JWxm max-w-[300px] relative w-full">
              <div className="chainSelectorInput_JzEF flex items-center justify-between w-full p-2 pl-3 border !border-[#d1d5db] dark:!border-[#404040] rounded-md !bg-[#f3f4f6] dark:!bg-[#1a1a1a] cursor-pointer hover:border-[#6cadf5] transition-colors" onClick={e => {}}>
                <div className="selectedChainDisplay_disp flex items-center gap-2">
                  <span className="text-[#0a0a0a] dark:text-[#f2f2f2] text-sm font-normal">
                    {!network ? 'Select Network' : network === 'devnet' ? 'Solana Devnet' : 'Solana Mainnet'}
                  </span>
                </div>
                <div className="dropdownArrow_Xh5h text-[#7d7d7d] transition-transform">
                  <svg width="10" height="6" viewBox="0 0 10 6" fill="none"><path d="M1 1L5 5L9 1" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"></path></svg>
                </div>
              </div>
              {}
              <select value={network} onChange={e => setNetwork(e.target.value)} className="absolute inset-0 opacity-0 cursor-pointer w-full h-full">
                {}
              </select>
            </div>
          </div>

          {}
          <div className="fieldGroup_Wlo7 mb-4">
            <label className="fieldLabel_kbcb block text-[0.625rem] font-semibold text-[#7d7d7d] dark:text-[#a3a3a3] uppercase tracking-wider mb-2">CUSTOM RPC URL (OPTIONAL)</label>
            <div className="inputGroup_KcB5 addressInput_VOhc mb-1">
              <input type="text" placeholder="https://mainnet.helius-rpc.com/?api-key=YOUR_KEY" value={customRpc} onChange={e => setCustomRpc(e.target.value)} className="input_Om6f w-full !bg-[#f3f4f6] dark:!bg-[#1a1a1a] border !border-[#d1d5db] dark:!border-[#404040] text-[#0a0a0a] dark:text-[#f2f2f2] rounded-md py-2 px-3 text-[0.8125rem] transition-colors focus:outline-none focus:border-[#6cadf5] focus:shadow-[0_0_0_2px_rgba(108,173,245,0.1)] placeholder-[#7d7d7d] dark:placeholder-[#525252]" />
            </div>
            <div className="fieldHint_K4uC text-xs text-[#7d7d7d] dark:text-[#757575] leading-relaxed">
              <span>Using <a href="https://solana-rpc.publicnode.com" target="_blank" rel="noopener noreferrer" className="text-[#3986dc] dark:text-[#6cadf5] hover:underline">PublicNode</a> by default.</span><br />
              For production, consider premium RPCs from <a href="https://helius.dev" target="_blank" rel="noopener noreferrer" className="text-[#3986dc] dark:text-[#6cadf5] hover:underline">Helius</a>, <a href="https://quicknode.com" target="_blank" rel="noopener noreferrer" className="text-[#3986dc] dark:text-[#6cadf5] hover:underline">QuickNode</a>, or <a href="https://alchemy.com" target="_blank" rel="noopener noreferrer" className="text-[#3986dc] dark:text-[#6cadf5] hover:underline">Alchemy</a>.
            </div>
          </div>

          {}
           <div className="fieldGroup_Wlo7 mb-4">
            <label className="fieldLabel_kbcb block text-[0.625rem] font-semibold text-[#7d7d7d] dark:text-[#a3a3a3] uppercase tracking-wider mb-2">CUSTOM PROGRAM ID</label>
            <div className="inputGroup_KcB5 addressInput_VOhc mb-1">
              <input type="text" placeholder="11111111111111111111111111111111" value={customProgramId} onChange={e => setCustomProgramId(e.target.value)} className="input_Om6f w-full !bg-[#f3f4f6] dark:!bg-[#1a1a1a] border !border-[#d1d5db] dark:!border-[#404040] text-[#0a0a0a] dark:text-[#f2f2f2] rounded-md py-2 px-3 text-[0.8125rem] transition-colors focus:outline-none focus:border-[#6cadf5] focus:shadow-[0_0_0_2px_rgba(108,173,245,0.1)] placeholder-[#7d7d7d] dark:placeholder-[#525252]" />
            </div>
            <div className="fieldHint_K4uC text-xs text-[#7d7d7d] dark:text-[#757575]">
              No default endpoint program for Select Network. Enter a custom program ID.
            </div>
          </div>

          {}
          {accounts.length > 0 && <div className="parametersSection_oilk mt-6">
              <div className="sectionTitle_EISu text-[0.625rem] font-semibold text-[#7d7d7d] dark:text-[#a3a3a3] uppercase tracking-wider mb-4 border-b border-[#e0e0e0] dark:border-[#272727] pb-2">ACCOUNTS</div>
              <div className="inputs_Yw34 space-y-4">
                {accounts.map((acc, idx) => <div key={idx} className="inputGroup_KcB5">
                    <label className="block text-[0.75rem] font-medium text-[#0a0a0a] dark:text-[#f2f2f2] mb-1.5">
                      {acc.name}
                      <span className="typeLabel_PVtY text-[#7d7d7d] dark:text-[#a3a3a3] font-normal text-[0.6875rem] ml-1">({acc.type})</span>
                      {acc.description && <div className="fieldHint_K4uC text-[0.6875rem] text-[#7d7d7d] dark:text-[#757575] font-normal mt-0.5">{acc.description}</div>}
                    </label>
                    <input type="text" placeholder={acc.name === 'systemProgram' ? '11111111111111111111111111111111' : 'value'} value={accountValues[acc.name] || ''} onChange={e => handleAccountChange(acc.name, e.target.value)} className="input_Om6f w-full !bg-[#f3f4f6] dark:!bg-[#1a1a1a] border !border-[#d1d5db] dark:!border-[#404040] text-[#0a0a0a] dark:text-[#f2f2f2] rounded-md py-2 px-3 text-[0.8125rem] transition-colors focus:outline-none focus:border-[#6cadf5] focus:shadow-[0_0_0_2px_rgba(108,173,245,0.1)] font-mono" />
                  </div>)}
              </div>
            </div>}

          {}
          {args.length > 0 && <div className="parametersSection_oilk mt-6">
              <div className="sectionTitle_EISu text-[0.625rem] font-semibold text-[#7d7d7d] dark:text-[#a3a3a3] uppercase tracking-wider mb-4 border-b border-[#e0e0e0] dark:border-[#272727] pb-2">ARGUMENTS</div>
              <div className="inputs_Yw34 space-y-4">
                {args.map((arg, idx) => <div key={idx} className="inputGroup_KcB5">
                     <label className="block text-[0.75rem] font-medium text-[#0a0a0a] dark:text-[#f2f2f2] mb-1.5">
                      {arg.name}
                      <span className="typeLabel_PVtY text-[#7d7d7d] dark:text-[#a3a3a3] font-normal text-[0.6875rem] ml-1">({arg.type})</span>
                      {arg.description && <div className="fieldHint_K4uC text-[0.6875rem] text-[#7d7d7d] dark:text-[#757575] font-normal mt-0.5">{arg.description}</div>}
                    </label>
                    <input type="text" placeholder={arg.placeholder || 'value'} value={inputValues[arg.name] || ''} onChange={e => handleArgChange(arg.name, e.target.value)} className="input_Om6f w-full !bg-[#f3f4f6] dark:!bg-[#1a1a1a] border !border-[#d1d5db] dark:!border-[#404040] text-[#0a0a0a] dark:text-[#f2f2f2] rounded-md py-2 px-3 text-[0.8125rem] transition-colors focus:outline-none focus:border-[#6cadf5] focus:shadow-[0_0_0_2px_rgba(108,173,245,0.1)]" />
                  </div>)}
              </div>
            </div>}

          {}
          <div className="actions_dJ_o mt-6">
            {!isWalletConnected ? <button onClick={connectWallet} className="actionButton_kY6_ w-full py-3 px-4 bg-transparent hover:bg-[#6b2fe6] font-medium rounded-md transition-colors shadow-sm focus:outline-none focus:ring-2 focus:ring-[#7a3dfc] focus:ring-offset-2">
                Connect Phantom Wallet
              </button> : <button onClick={executeInstruction} disabled={status === 'loading'} className={`actionButton_kY6_ w-full py-3 px-4 font-medium rounded-md transition-colors shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2
                  ${status === 'loading' ? 'bg-blue-400 cursor-wait' : 'bg-[#3986dc] hover:bg-[#3273bf] text-[#3986dc] focus:ring-[#3986dc]'}`}>
                {status === 'loading' ? 'Processing...' : 'Execute Transaction'}
              </button>}
          </div>

          {}
          {errorMessage && <div className="messageBox_hz_w mt-4">
              <div className="messageError_L5lq p-3 bg-[#ffebeb] dark:bg-[#281919] border border-[#f56868] rounded-md text-sm text-[#d84c4c]">
                Please install Phantom wallet: {errorMessage}
              </div>
            </div>}
          {logs.length > 0 && <div className="messageBox_hz_w mt-4">
               <div className="p-3 bg-[#fafafa] dark:bg-[#0a0a0a] border border-[#e0e0e0] dark:border-[#272727] rounded-md text-xs font-mono max-h-40 overflow-y-auto">
                 {logs.map((L, i) => <div key={i} className="text-[#0a0a0a] dark:text-[#f2f2f2]">&gt; {L}</div>)}
               </div>
             </div>}

        </div>}
    </div>;
};

Test LayerZero Solana programs directly from your browser. Build and send instructions without writing code. Explore key program instructions for message fee calculation, sending, receiving, and configuration management.

<Note>
  ### Experimental Feature

  This playground is experimental and uses simplified instruction encoding. For production use, please use the official [LayerZero Solana SDK](https://www.npmjs.com/package/@layerzerolabs/lz-solana-sdk-v2) which provides proper type-safe instruction builders.

  **Current Limitations:**

  * Instruction data encoding is simplified and may not match the exact format expected by the programs
  * Some complex instructions may require specific account ordering or additional accounts not shown here
  * The actual instruction discriminators and data encoding may differ from what's shown here
  * **Simulations may fail with "InvalidAccountForFee" or other errors** - this is expected as the playground uses experimental encoding

  **For accurate interaction with LayerZero programs**, please use the official SDKs:

  * [@layerzerolabs/lz-solana-sdk-v2](https://www.npmjs.com/package/@layerzerolabs/lz-solana-sdk-v2)
  * [@layerzerolabs/oft-v2-solana-sdk](https://www.npmjs.com/package/@layerzerolabs/oft-v2-solana-sdk)
</Note>

## LayerZero Endpoint Program

The main entry point for all crosschain messaging operations on Solana. This program handles message routing, fee calculation, and configuration management.

### OApp Registration & Setup

#### registerOapp() - Register OApp

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="registerOapp"
  description="Register an OApp with the endpoint. This establishes the OApp's delegate who can manage configurations."
  accounts={[
{ name: "payer", type: "Signer", description: "Transaction fee payer" },
{ name: "oapp", type: "Signer", description: "The PDA of the OApp" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry account (mutable)" },
{ name: "systemProgram", type: "AccountInfo", description: "System program" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "delegate", type: "Pubkey", placeholder: "11111111111111111111111111111111" }
]}
/>

#### initNonce() - Initialize Nonce

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="initNonce"
  description="Initialize nonce tracking for messages between OApps. Must be called before sending messages."
  accounts={[
{ name: "delegate", type: "Signer", description: "OApp delegate (only delegate can initialize)" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry" },
{ name: "nonce", type: "AccountInfo", description: "Nonce account (mutable)" },
{ name: "pendingInboundNonce", type: "AccountInfo", description: "Pending inbound nonce (mutable)" },
{ name: "systemProgram", type: "AccountInfo", description: "System program" }
]}
  args={[
{ name: "localOapp", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "remoteEid", type: "u32", placeholder: "30101" },
{ name: "remoteOapp", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" }
]}
/>

### Message Operations

#### quote() - Get Fee Estimates

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="quote"
  description="Get a quote for the LayerZero messaging fees required to send a crosschain message from Solana. Returns the native fee and lzToken fee required."
  accounts={[
{ name: "sendLibraryProgram", type: "AccountInfo", description: "Send library program" },
{ name: "sendLibraryConfig", type: "AccountInfo", description: "Send library configuration for the OApp" },
{ name: "defaultSendLibraryConfig", type: "AccountInfo", description: "Default send library configuration" },
{ name: "sendLibraryInfo", type: "AccountInfo", description: "PDA signer to the send library" },
{ name: "endpoint", type: "AccountInfo", description: "Endpoint settings account" },
{ name: "nonce", type: "AccountInfo", description: "Nonce account" }
]}
  args={[
{ name: "sender", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "dstEid", type: "u32", placeholder: "30101" },
{ name: "receiver", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "message", type: "bytes", placeholder: "0x48656c6c6f" },
{ name: "options", type: "bytes", placeholder: "0x00030100110100000000000000000000000000030d40" },
{ name: "payInLzToken", type: "bool", placeholder: "false" }
]}
/>

#### send() - Send Crosschain Message

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="send"
  description="Send a crosschain message from Solana to another blockchain. Returns a MessagingReceipt with guid, nonce, and fee information."
  accounts={[
{ name: "sender", type: "Signer", description: "OApp sending the message" },
{ name: "sendLibraryProgram", type: "AccountInfo", description: "Send library program" },
{ name: "sendLibraryConfig", type: "AccountInfo", description: "Send library configuration" },
{ name: "defaultSendLibraryConfig", type: "AccountInfo", description: "Default send library configuration" },
{ name: "sendLibraryInfo", type: "AccountInfo", description: "PDA signer to the send library" },
{ name: "endpoint", type: "AccountInfo", description: "Endpoint settings account" },
{ name: "nonce", type: "AccountInfo", description: "Nonce account (mutable)" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority account" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "dstEid", type: "u32", placeholder: "30101" },
{ name: "receiver", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "message", type: "bytes", placeholder: "0x48656c6c6f" },
{ name: "options", type: "bytes", placeholder: "0x00030100110100000000000000000000000000030d40" },
{ name: "nativeFee", type: "u64", placeholder: "1000000" },
{ name: "lzTokenFee", type: "u64", placeholder: "0" }
]}
/>

### Message Verification

#### initVerify() - Initialize Verification

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="initVerify"
  description="Initialize the payload hash account for message verification. Must be called before verify()."
  accounts={[
{ name: "payer", type: "Signer", description: "Transaction fee payer" },
{ name: "nonce", type: "AccountInfo", description: "Nonce account" },
{ name: "payloadHash", type: "AccountInfo", description: "Payload hash account (mutable)" },
{ name: "systemProgram", type: "AccountInfo", description: "System program" }
]}
  args={[
{ name: "srcEid", type: "u32", placeholder: "30106" },
{ name: "sender", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "receiver", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "nonce", type: "u64", placeholder: "1" }
]}
/>

#### verify() - Verify Inbound Message

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="verify"
  description="Verify an inbound crosschain message. Called by the receive library to confirm message authenticity before delivery."
  accounts={[
{ name: "receiveLibrary", type: "Signer", description: "PDA of the receive library" },
{ name: "receiveLibraryConfig", type: "AccountInfo", description: "Receive library configuration" },
{ name: "defaultReceiveLibraryConfig", type: "AccountInfo", description: "Default receive library configuration" },
{ name: "nonce", type: "AccountInfo", description: "Nonce account (mutable)" },
{ name: "pendingInboundNonce", type: "AccountInfo", description: "Pending inbound nonce account (mutable)" },
{ name: "payloadHash", type: "AccountInfo", description: "Payload hash account (mutable)" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority account" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "srcEid", type: "u32", placeholder: "30106" },
{ name: "sender", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "receiver", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "nonce", type: "u64", placeholder: "1" },
{ name: "payloadHash", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" }
]}
/>

### Compose Messages

#### sendCompose() - Send Compose Message

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="sendCompose"
  description="Send a composed message for sequential execution after the primary message. Used for complex crosschain workflows."
  accounts={[
{ name: "from", type: "Signer", description: "Sender of the compose message" },
{ name: "payer", type: "Signer", description: "Transaction fee payer" },
{ name: "composeMessage", type: "AccountInfo", description: "Compose message state (mutable)" },
{ name: "systemProgram", type: "AccountInfo", description: "System program" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "to", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "guid", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "index", type: "u16", placeholder: "0" },
{ name: "message", type: "bytes", placeholder: "0x" }
]}
/>

#### clearCompose() - Clear Compose Message

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="clearCompose"
  description="Clear a compose message after it has been processed. This cleans up the compose message state."
  accounts={[
{ name: "to", type: "Signer", description: "Recipient of the compose message" },
{ name: "composeMessage", type: "AccountInfo", description: "Compose message state (mutable)" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "from", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "guid", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "index", type: "u16", placeholder: "0" },
{ name: "message", type: "bytes", placeholder: "0x" }
]}
/>

### Message Recovery & Security

#### skip() - Skip Inbound Nonce

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="skip"
  description="Skip a specific inbound message nonce. This allows the OApp to continue processing subsequent messages if one is stuck or problematic."
  accounts={[
{ name: "signer", type: "Signer", description: "OApp or delegate" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry" },
{ name: "nonce", type: "AccountInfo", description: "Nonce account (mutable)" },
{ name: "pendingInboundNonce", type: "AccountInfo", description: "Pending inbound nonce (mutable)" },
{ name: "payloadHash", type: "AccountInfo", description: "Payload hash account (mutable)" },
{ name: "endpoint", type: "AccountInfo", description: "Endpoint account (mutable)" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "receiver", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "srcEid", type: "u32", placeholder: "30106" },
{ name: "sender", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "nonce", type: "u64", placeholder: "1" }
]}
/>

#### burn() - Permanently Block Message

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="burn"
  description="Permanently marks a message as unexecutable and un-verifiable. This irreversible action prevents the message from ever being executed."
  accounts={[
{ name: "signer", type: "Signer", description: "OApp or delegate" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry" },
{ name: "nonce", type: "AccountInfo", description: "Nonce account" },
{ name: "payloadHash", type: "AccountInfo", description: "Payload hash account to burn (mutable)" },
{ name: "endpoint", type: "AccountInfo", description: "Endpoint account (mutable)" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "receiver", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "srcEid", type: "u32", placeholder: "30106" },
{ name: "sender", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "nonce", type: "u64", placeholder: "1" },
{ name: "payloadHash", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" }
]}
/>

#### nilify() - Mark Message as Nil

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="nilify"
  description="Mark a message payload as nil, allowing it to be cleared later. This is a two-step process for safely handling problematic messages."
  accounts={[
{ name: "signer", type: "Signer", description: "OApp or delegate" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry" },
{ name: "nonce", type: "AccountInfo", description: "Nonce account (mutable)" },
{ name: "pendingInboundNonce", type: "AccountInfo", description: "Pending inbound nonce (mutable)" },
{ name: "payloadHash", type: "AccountInfo", description: "Payload hash account (mutable)" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "receiver", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "srcEid", type: "u32", placeholder: "30106" },
{ name: "sender", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "nonce", type: "u64", placeholder: "1" },
{ name: "payloadHash", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" }
]}
/>

#### clear() - Clear Payload

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="clear"
  description="Clear a nilified message payload and recover the rent. Returns the original payload hash."
  accounts={[
{ name: "signer", type: "Signer", description: "OApp or delegate" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry" },
{ name: "nonce", type: "AccountInfo", description: "Nonce account" },
{ name: "payloadHash", type: "AccountInfo", description: "Payload hash account to clear (mutable)" },
{ name: "endpoint", type: "AccountInfo", description: "Endpoint account (mutable)" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "receiver", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "srcEid", type: "u32", placeholder: "30106" },
{ name: "sender", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "nonce", type: "u64", placeholder: "1" },
{ name: "guid", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "message", type: "bytes", placeholder: "0x" }
]}
/>

### Library Configuration

#### initSendLibrary() - Initialize Send Library

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="initSendLibrary"
  description="Initialize send library configuration for an OApp on a specific destination chain."
  accounts={[
{ name: "delegate", type: "Signer", description: "OApp delegate (only delegate can initialize)" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry" },
{ name: "sendLibraryConfig", type: "AccountInfo", description: "Send library config (mutable)" },
{ name: "systemProgram", type: "AccountInfo", description: "System program" }
]}
  args={[
{ name: "sender", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "eid", type: "u32", placeholder: "30101" }
]}
/>

#### setSendLibrary() - Set Send Library

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="setSendLibrary"
  description="Set the messaging library to use for sending messages to a specific destination."
  accounts={[
{ name: "signer", type: "Signer", description: "OApp or delegate" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry" },
{ name: "sendLibraryConfig", type: "AccountInfo", description: "Send library config (mutable)" },
{ name: "messageLibInfo", type: "AccountInfo?", description: "Message library info (optional)" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "sender", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "eid", type: "u32", placeholder: "30101" },
{ name: "newLib", type: "Pubkey", placeholder: "7a4WjyR8VZ7yZz5XJAKm39BUGn5iT9CKcv2pmG9tdXVH" }
]}
/>

#### initReceiveLibrary() - Initialize Receive Library

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="initReceiveLibrary"
  description="Initialize receive library configuration for an OApp on a specific source chain."
  accounts={[
{ name: "delegate", type: "Signer", description: "OApp delegate (only delegate can initialize)" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry" },
{ name: "receiveLibraryConfig", type: "AccountInfo", description: "Receive library config (mutable)" },
{ name: "systemProgram", type: "AccountInfo", description: "System program" }
]}
  args={[
{ name: "receiver", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "eid", type: "u32", placeholder: "30106" }
]}
/>

#### setReceiveLibrary() - Set Receive Library

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="setReceiveLibrary"
  description="Set the messaging library to use for receiving messages from a specific source."
  accounts={[
{ name: "signer", type: "Signer", description: "OApp or delegate" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry" },
{ name: "receiveLibraryConfig", type: "AccountInfo", description: "Receive library config (mutable)" },
{ name: "messageLibInfo", type: "AccountInfo?", description: "Message library info (optional)" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "receiver", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "eid", type: "u32", placeholder: "30106" },
{ name: "newLib", type: "Pubkey", placeholder: "7a4WjyR8VZ7yZz5XJAKm39BUGn5iT9CKcv2pmG9tdXVH" },
{ name: "gracePeriod", type: "u64", placeholder: "0" }
]}
/>

#### setReceiveLibraryTimeout() - Set Library Timeout

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="setReceiveLibraryTimeout"
  description="Set a timeout for transitioning between receive libraries. Allows graceful library upgrades."
  accounts={[
{ name: "signer", type: "Signer", description: "OApp or delegate" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry" },
{ name: "receiveLibraryConfig", type: "AccountInfo", description: "Receive library config (mutable)" },
{ name: "messageLibInfo", type: "AccountInfo", description: "Message library info" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "receiver", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "eid", type: "u32", placeholder: "30106" },
{ name: "lib", type: "Pubkey", placeholder: "7a4WjyR8VZ7yZz5XJAKm39BUGn5iT9CKcv2pmG9tdXVH" },
{ name: "expiry", type: "u64", placeholder: "1735689600" }
]}
/>

### Configuration Management

#### initConfig() - Initialize Configuration

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="initConfig"
  description="Initialize configuration accounts for message library settings (DVN, executor, etc)."
  accounts={[
{ name: "delegate", type: "Signer", description: "OApp delegate" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry" },
{ name: "messageLibInfo", type: "AccountInfo", description: "Message library info" },
{ name: "messageLib", type: "AccountInfo", description: "Message library PDA" },
{ name: "messageLibProgram", type: "AccountInfo", description: "Message library program" }
]}
  args={[
{ name: "oapp", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "eid", type: "u32", placeholder: "30101" }
]}
/>

#### setConfig() - Set Configuration

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="setConfig"
  description="Set configuration for DVNs, executors, and other protocol parameters."
  accounts={[
{ name: "signer", type: "Signer", description: "OApp or delegate" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry" },
{ name: "messageLibInfo", type: "AccountInfo", description: "Message library info" },
{ name: "messageLib", type: "AccountInfo", description: "Message library PDA" },
{ name: "messageLibProgram", type: "AccountInfo", description: "Message library program" }
]}
  args={[
{ name: "oapp", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "eid", type: "u32", placeholder: "30101" },
{ name: "configType", type: "u32", placeholder: "1", description: "Config type (e.g., 1 for executor)" },
{ name: "config", type: "bytes", placeholder: "0x", description: "Configuration data" }
]}
/>

#### setDelegate() - Set Delegate

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="setDelegate"
  description="Set the delegate address that can configure settings on behalf of the OApp."
  accounts={[
{ name: "oapp", type: "Signer", description: "OApp PDA" },
{ name: "oappRegistry", type: "AccountInfo", description: "OApp registry (mutable)" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "delegate", type: "Pubkey", placeholder: "11111111111111111111111111111111" }
]}
/>

### Admin Functions

#### withdrawRent() - Withdraw Rent

<InteractiveSolanaInstruction
  programName="endpoint"
  instructionName="withdrawRent"
  description="Admin function to withdraw accumulated rent from closed accounts."
  accounts={[
{ name: "admin", type: "Signer", description: "Endpoint admin" },
{ name: "endpoint", type: "AccountInfo", description: "Endpoint account (mutable)" },
{ name: "receiver", type: "AccountInfo", description: "Receiver account (mutable)" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "Endpoint program ID" }
]}
  args={[
{ name: "amount", type: "u64", placeholder: "1000000000" }
]}
/>

## LayerZero OFT Program

Omnichain Fungible Token (OFT) enables seamless crosschain token transfers. Deploy once and bridge your SPL tokens to any supported blockchain.

<Note>
  ### tip

  If your OFT program hasn't been deployed to a specific network, you can supply a custom program ID in the input field.
</Note>

### Token Setup

#### initOft() - Initialize OFT

<InteractiveSolanaInstruction
  programName="oft"
  instructionName="initOft"
  description="Initialize a new Omnichain Fungible Token. This sets up an SPL token to be transferable across multiple blockchains."
  accounts={[
{ name: "payer", type: "Signer", description: "Account paying for initialization" },
{ name: "oftStore", type: "AccountInfo", description: "OFT store account (PDA)" },
{ name: "lzReceiveTypesAccounts", type: "AccountInfo", description: "LZ receive types accounts" },
{ name: "tokenMint", type: "AccountInfo", description: "SPL token mint" },
{ name: "tokenEscrow", type: "Signer", description: "Token escrow account" },
{ name: "tokenProgram", type: "AccountInfo", description: "SPL token program" },
{ name: "systemProgram", type: "AccountInfo", description: "System program" }
]}
  args={[
{ name: "oftType", type: "u8", placeholder: "0", description: "0 for Native, 1 for Adapter" },
{ name: "admin", type: "Pubkey", placeholder: "11111111111111111111111111111111" },
{ name: "sharedDecimals", type: "u8", placeholder: "6", description: "Shared decimals (typically 6)" },
{ name: "endpointProgram", type: "Pubkey?", placeholder: "76y77prsiCMvXMjuoZ5VRrhG5qYBrUMYTE5WgHqgjEn6", description: "Optional endpoint program" }
]}
/>

### Crosschain Operations

#### quoteOft() - Get OFT Quote

<InteractiveSolanaInstruction
  programName="oft"
  instructionName="quoteOft"
  description="Get a detailed quote for crosschain token transfer including fees, limits, and expected amounts."
  accounts={[
{ name: "oftStore", type: "AccountInfo", description: "OFT store account" },
{ name: "peer", type: "AccountInfo", description: "Peer configuration account" },
{ name: "tokenMint", type: "AccountInfo", description: "SPL token mint" }
]}
  args={[
{ name: "dstEid", type: "u32", placeholder: "30101" },
{ name: "to", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "amountLd", type: "u64", placeholder: "1000000000" },
{ name: "minAmountLd", type: "u64", placeholder: "900000000" },
{ name: "options", type: "bytes", placeholder: "0x00030100110100000000000000000000000000030d40" },
{ name: "composeMsg", type: "bytes?", placeholder: "0x", description: "Optional compose message" },
{ name: "payInLzToken", type: "bool", placeholder: "false" }
]}
/>

#### quoteSend() - Get Send Quote

<InteractiveSolanaInstruction
  programName="oft"
  instructionName="quoteSend"
  description="Get messaging fees for sending tokens crosschain. Returns native fee and lzToken fee."
  accounts={[
{ name: "oftStore", type: "AccountInfo", description: "OFT store account" },
{ name: "peer", type: "AccountInfo", description: "Peer configuration account" },
{ name: "tokenMint", type: "AccountInfo", description: "SPL token mint" }
]}
  args={[
{ name: "dstEid", type: "u32", placeholder: "30101" },
{ name: "to", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "amountLd", type: "u64", placeholder: "1000000000" },
{ name: "minAmountLd", type: "u64", placeholder: "900000000" },
{ name: "options", type: "bytes", placeholder: "0x00030100110100000000000000000000000000030d40" },
{ name: "composeMsg", type: "bytes?", placeholder: "0x", description: "Optional compose message" },
{ name: "payInLzToken", type: "bool", placeholder: "false" }
]}
/>

#### send() - Send Tokens Crosschain

<InteractiveSolanaInstruction
  programName="oft"
  instructionName="send"
  description="Send SPL tokens from Solana to another blockchain. The tokens will be locked on Solana and minted on the destination chain."
  accounts={[
{ name: "signer", type: "Signer", description: "Account sending tokens" },
{ name: "peer", type: "AccountInfo", description: "Peer configuration (mutable)" },
{ name: "oftStore", type: "AccountInfo", description: "OFT store account (mutable)" },
{ name: "tokenSource", type: "AccountInfo", description: "Source token account (mutable)" },
{ name: "tokenEscrow", type: "AccountInfo", description: "Token escrow account (mutable)" },
{ name: "tokenMint", type: "AccountInfo", description: "SPL token mint (mutable)" },
{ name: "tokenProgram", type: "AccountInfo", description: "SPL token program" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "OFT program ID" }
]}
  args={[
{ name: "dstEid", type: "u32", placeholder: "30101" },
{ name: "to", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "amountLd", type: "u64", placeholder: "1000000000" },
{ name: "minAmountLd", type: "u64", placeholder: "900000000" },
{ name: "options", type: "bytes", placeholder: "0x00030100110100000000000000000000000000030d40" },
{ name: "composeMsg", type: "bytes?", placeholder: "0x", description: "Optional compose message" },
{ name: "nativeFee", type: "u64", placeholder: "1000000" },
{ name: "lzTokenFee", type: "u64", placeholder: "0" }
]}
/>

#### lzReceive() - Receive Tokens

<InteractiveSolanaInstruction
  programName="oft"
  instructionName="lzReceive"
  description="Receive tokens from another blockchain. This instruction is called by the executor to deliver tokens to the recipient on Solana."
  accounts={[
{ name: "payer", type: "Signer", description: "Transaction fee payer" },
{ name: "peer", type: "AccountInfo", description: "Peer configuration (mutable)" },
{ name: "oftStore", type: "AccountInfo", description: "OFT store account (mutable)" },
{ name: "tokenEscrow", type: "AccountInfo", description: "Token escrow account (mutable)" },
{ name: "toAddress", type: "AccountInfo", description: "Recipient address" },
{ name: "tokenDest", type: "AccountInfo", description: "Destination token account (mutable)" },
{ name: "tokenMint", type: "AccountInfo", description: "SPL token mint (mutable)" },
{ name: "mintAuthority", type: "AccountInfo?", description: "Mint authority (optional)" },
{ name: "tokenProgram", type: "AccountInfo", description: "SPL token program" },
{ name: "associatedTokenProgram", type: "AccountInfo", description: "Associated token program" },
{ name: "systemProgram", type: "AccountInfo", description: "System program" },
{ name: "eventAuthority", type: "AccountInfo", description: "Event authority" },
{ name: "program", type: "AccountInfo", description: "OFT program ID" }
]}
  args={[
{ name: "srcEid", type: "u32", placeholder: "30106" },
{ name: "sender", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "nonce", type: "u64", placeholder: "1" },
{ name: "guid", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "message", type: "bytes", placeholder: "0x" },
{ name: "extraData", type: "bytes", placeholder: "0x" }
]}
/>

#### lzReceiveTypes() - Get Receive Account Types

<InteractiveSolanaInstruction
  programName="oft"
  instructionName="lzReceiveTypes"
  description="Get the required account types for lzReceive instruction. Returns array of account metadata."
  accounts={[
{ name: "oftStore", type: "AccountInfo", description: "OFT store account" },
{ name: "tokenMint", type: "AccountInfo", description: "SPL token mint" }
]}
  args={[
{ name: "srcEid", type: "u32", placeholder: "30106" },
{ name: "sender", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "nonce", type: "u64", placeholder: "1" },
{ name: "guid", type: "bytes32", placeholder: "0x0000000000000000000000000000000000000000000000000000000000000000" },
{ name: "message", type: "bytes", placeholder: "0x" },
{ name: "extraData", type: "bytes", placeholder: "0x" }
]}
/>

### Token Information

#### oftVersion() - Get OFT Version

<InteractiveSolanaInstruction programName="oft" instructionName="oftVersion" description="Returns the OFT interface ID and version number. No accounts required." accounts={[]} args={[]} />

### Configuration

#### setPeerConfig() - Configure Remote Peer

<InteractiveSolanaInstruction
  programName="oft"
  instructionName="setPeerConfig"
  description="Configure the connection to an OFT on another chain. This can set the peer address, fee basis points, enforced options, and rate limits."
  accounts={[
{ name: "admin", type: "Signer", description: "OFT admin account" },
{ name: "peer", type: "AccountInfo", description: "Peer configuration account (mutable)" },
{ name: "oftStore", type: "AccountInfo", description: "OFT store account" },
{ name: "systemProgram", type: "AccountInfo", description: "System program" }
]}
  args={[
{ name: "remoteEid", type: "u32", placeholder: "30101" },
{ name: "configType", type: "u8", placeholder: "0", description: "0=PeerAddress, 1=FeeBps, 2=EnforcedOptions, 3=OutboundLimit, 4=InboundLimit" },
{ name: "configData", type: "bytes", placeholder: "0x", description: "Configuration data based on type" }
]}
/>

#### setOftConfig() - Update OFT Settings

<InteractiveSolanaInstruction
  programName="oft"
  instructionName="setOftConfig"
  description="Update various OFT configuration settings including admin, delegate, default fee, pause state, pauser, and unpauser."
  accounts={[
{ name: "admin", type: "Signer", description: "OFT admin account" },
{ name: "oftStore", type: "AccountInfo", description: "OFT store account (mutable)" }
]}
  args={[
{ name: "configType", type: "u8", placeholder: "0", description: "0=Admin, 1=Delegate, 2=DefaultFee, 3=Paused, 4=Pauser, 5=Unpauser" },
{ name: "configData", type: "bytes", placeholder: "0x", description: "Configuration data based on type" }
]}
/>

#### setPause() - Pause/Unpause OFT

<InteractiveSolanaInstruction
  programName="oft"
  instructionName="setPause"
  description="Pause or unpause the OFT. When paused, no transfers can be initiated. Only the pauser (to pause) or unpauser (to unpause) can call this."
  accounts={[
{ name: "signer", type: "Signer", description: "Pauser or unpauser account" },
{ name: "oftStore", type: "AccountInfo", description: "OFT store account (mutable)" }
]}
  args={[
{ name: "paused", type: "bool", placeholder: "true", description: "true to pause, false to unpause" }
]}
/>

#### withdrawFee() - Withdraw Collected Fees

<InteractiveSolanaInstruction
  programName="oft"
  instructionName="withdrawFee"
  description="Withdraw collected fees from the OFT. Only the admin can withdraw fees."
  accounts={[
{ name: "admin", type: "Signer", description: "OFT admin account" },
{ name: "oftStore", type: "AccountInfo", description: "OFT store account" },
{ name: "tokenMint", type: "AccountInfo", description: "SPL token mint" },
{ name: "tokenEscrow", type: "AccountInfo", description: "Token escrow account (mutable)" },
{ name: "tokenDest", type: "AccountInfo", description: "Destination token account (mutable)" },
{ name: "tokenProgram", type: "AccountInfo", description: "SPL token program" }
]}
  args={[
{ name: "feeLd", type: "u64", placeholder: "1000000", description: "Amount of fees to withdraw in local decimals" }
]}
/>

## Usage Tips

### Getting Started

1. **Connect Your Wallet**: Click "Connect Phantom Wallet" to connect your Solana wallet
2. **Select Network**: Choose between Solana Mainnet and Devnet
3. **Custom RPC (Optional)**: If you encounter rate limits (403 errors), add a custom RPC URL:
   * [Helius](https://helius.dev) - Generous free tier
   * [QuickNode](https://quicknode.com) - Free tier available
   * [Alchemy](https://alchemy.com) - Professional services

### Common Workflows

#### Sending Tokens Crosschain (OFT)

1. Initialize your OFT with `initOft()`
2. Configure peers with `setPeerConfig()`
3. Get a quote with `quoteOft()` or `quoteSend()`
4. Send tokens with `send()`

#### Setting Up Messaging (Endpoint)

1. Register your OApp with `registerOapp()`
2. Initialize nonce tracking with `initNonce()`
3. Set up libraries with `initSendLibrary()` and `initReceiveLibrary()`
4. Configure DVNs/executors with `setConfig()`
5. Get quotes with `quote()` and send messages with `send()`

### Troubleshooting

* **403 Errors**: Use a custom RPC URL instead of public endpoints
* **"Account does not exist"**: Ensure all required accounts have been initialized
* **"Invalid arguments"**: Check that byte arrays are properly formatted (0x prefix)
* **Simulation failures**: This playground uses simplified encoding - use official SDKs for production

For production applications, always use the official LayerZero SDKs which provide proper type safety and encoding.
