deBridge
  • Introduction
  • The deBridge Messaging Protocol
    • Protocol Overview
    • Fees and Supported Chains
    • 🟢Deployed Contracts
    • Development Guides
      • Building an EVM-based dApp
        • EVM smart contract interfaces
          • Interfaces
            • ICallProxy
            • IDeBridgeGate
            • IDeBridgeToken
            • IDeBridgeTokenDeployer
            • IOraclesManager
            • ISignatureVerifier
            • IWethGate
          • Libraries
            • Flags
          • Periphery
            • CallProxy
            • DeBridgeToken
            • DeBridgeTokenProxy
            • SimpleFeeProxy
          • Transfers
            • DeBridgeGate
            • DeBridgeTokenDeployer
            • OraclesManager
            • SignatureVerifier
            • WethGate
      • Sending cross-chain messages from Solana
        • On-Chain external call preparation for Solana
        • Off-chain external call preparation for Solana
      • Lifecycle of a cross-chain call
      • Gathering data for the claim
    • Development Tools
    • Security
    • Slashing and Delegated Staking
  • 🔁DLN: The deBridge Liquidity Network Protocol
    • Introduction
    • Protocol Overview
    • deBridge Hooks
    • Fees and Supported Chains
    • 🟢Deployed Contracts
    • Market and Limit Orders
    • Integration Guidelines
      • Interacting with the API
        • Authentication
        • Creating an Order
          • Quick Start
          • API Parameters
            • Estimation-Only
            • prependOperatingExpenses
          • API Response
            • JSON Example
          • Refreshing Estimates
        • Tracking Order Status
          • Order States
        • Integrating deBridge hooks
          • Creating Hook data for Solana
        • Submitting an Order Creation Transaction
        • Cancelling the Order
      • deBridge Widget
      • Interacting with smart contracts
        • Placing orders
        • Filling orders
      • Under the Hood
        • Reserve Assets
        • Bridging Reserve Assets
        • Bridging Non-Reserve Assets
        • Order Fulfillment
          • Detecting the Order
          • Fulfilling the Order
            • Pre-Fill-Swap
          • Claiming the Order
      • Affiliate fees
        • Withdrawing Affiliate Fees
      • Fees and operating expenses
    • Interacting with the deBridge App
      • Custom Linking
    • Protocol specs
      • Deterministic order ID
      • Hook data
        • Anatomy of a Hook for the EVM-based chains
        • Anatomy of a Hook for Solana
  • 💸dePort
    • Getting started
    • Transfers Flow
  • ⚡deBridge Points
    • Referrers Overview
    • Integrators Overview
  • 🌐deBridge IaaS
    • Getting started
  • 🌐Legal
    • SDK & API License Agreement
  • External Links
    • deBridge Use Cases
      • 💡Examples
    • Talks, Videos, and Articles
    • Website
    • Github
    • Twitter
    • Social channels
      • Discord
      • Facebook
      • LinkedIn
      • Medium
      • Telegram
      • YouTube
Powered by GitBook
On this page

Was this helpful?

  1. The deBridge Messaging Protocol
  2. Development Guides
  3. Sending cross-chain messages from Solana

Off-chain external call preparation for Solana

Instructions should be serialized one by one, final calldata is a concatenation of separately serialized instructions.

For the info about the rewards, substitutions, and expenses check the previous section.

Solana's TransactionInstructions could be serialized into calldata format using @debridge-finance/debridge-external-call npm package:

import * as wasm from "@debridge-finance/debridge-external-call";
import { PublicKey, TransactionInstruction } from "@solana/web3.js";

/**
 * Substitutes amount at offset with `walletBalance(accounts[account_index]) - subtraction`
 */
type AmountSubstitution = {
  /**
   * big or little endian
   */
  is_big_endian: boolean;
  /**
   * At what offset substitution should be done
   */
  offset: number;
  /**
   * index of account in TransactionInstruction.keys to get balance for
   */
  account_index: number;
  /**
   * Amount to deduct from wallet balance
   */
  subtraction: number;
};

/**
 * Since we don't know submissionAuth at the moment of calldata preparation we can prepare substitution to replace
 * account at `index` with actual ATA(submissionAuth, tokenMint) during execution
 */
type WalletSubstitution = {
  /**
   * Token mint to calculate ATA for
   */
  token_mint: string;
  /**
   * Account at this index will be replaced with ATA(submissionAuth, tokenMint) during execution
   */
  index: number;
};

/**
 * Structure required by wasm module
 */
interface IExtIx {
  keys: {
    pubkey: string;
    isSigner: boolean;
    isWritable: boolean;
  }[];
  data: Buffer;
  programId: string;
}

function ixToIExtIx(ix: TransactionInstruction): IExtIx {
  return {
    keys: ix.keys.map((meta) => ({
      pubkey: meta.pubkey.toBase58(),
      isSigner: meta.isSigner,
      isWritable: meta.isWritable,
    })),
    programId: ix.programId.toBase58(),
    data: ix.data,
  };
}

function serialize(
  instruction: TransactionInstruction,
  substitutions?: {
    amountSubstitutions?: AmountSubstitution[];
    walletSubstitutions?: WalletSubstitution[];
  },
  expense?: bigint,
  reward?: bigint,
  isInMandatoryBlock: boolean = false,
) {
  const ixWrapper = new wasm.ExternalInstructionWrapper(
    reward,
    expense,
    isInMandatoryBlock,
    substitutions?.amountSubstitutions ?? [],
    substitutions?.walletSubstitutions ?? [],
    ixToIExtIx(instruction),
  );

  return ixWrapper.serialize();
}

const ix1: TransactionInstruction;
const ix2: TransactionInstruction;

const serializedIx1 = serialize(ix1, undefined, 1000n);
const serializedIx2 = serialize(ix2, undefined, 2000n);

const calldata = Buffer.concat([serializedIx1, serializedIx2 /** rest serialized instructions if any */]);
PreviousOn-Chain external call preparation for SolanaNextLifecycle of a cross-chain call

Last updated 11 months ago

Was this helpful?