solana-bridges — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited solana-bridges (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Cross-chain liquidity is the single biggest piece of friction on Solana today. Mert Mumtaz (Helius CEO) put "making bridges more robust" in his top-5 priority list for the ecosystem, and for good reason — most "Solana is down" reports from end users are really "the bridge I used got stuck." If you are building anything that touches another chain (a wallet, an exchange, a payments app, an agent that moves funds), bridging is the layer most likely to fail and the layer that determines whether users come back.
The Solana bridge landscape in May 2026 sorts into three architectural buckets, and you pick a bridge based on which bucket fits your use case:
1. Lock-and-mint / burn-and-mint (canonical bridges) The source chain locks (or burns) the asset and the destination chain mints a representation (or releases the canonical asset). Slow but conceptually clean.
*.wh wrapped tokens on the destination. Now the canonical pathway for non-stablecoin assets thanks to Sunrise (Nov 2025 launch with MON, expanding through 2026).2. Liquidity-network bridges Liquidity pools on each chain; a swap on the source pool plus a withdrawal on the destination pool. Fast but priced like an AMM (slippage, fee tier).
3. Intent-based / solver bridges User signs an intent ("I want X on chain B for Y on chain A"); a solver fronts the destination funds and is repaid on the source. Fastest user experience because the solver doesn't wait for source finality, they take that risk.
Rough decision matrix:
| If you want… | Use |
|---|---|
| Native USDC, lowest trust assumption | Circle CCTP v2 |
| Fastest EVM→Solana for arbitrary tokens | Mayan Swift |
| Programmatic / API-first cross-chain orders | deBridge DLN |
| Bridge a token you issue and keep it canonical | Wormhole NTT |
| Stablecoin route that doesn't depend on a single solver | Allbridge Core |
| You're a wallet/integrator and just want one drop-in UI | Wormhole Connect |
Trigger this skill when the user says any of:
Do not use this skill for same-chain swaps on Solana — that is the jupiter-swap skill.
@solana/web3.js v1.95+ (or the new modular v2 packages) for Solana signing and RPCethers v6 or viem v2 for the EVM source chain — pick one and stay consistentapi.mainnet-beta.solana.com for bridge claim steps, it rate-limits aggressivelyEPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB480x833589fCD6eDb6E08f4c7C32D4f71b54bdA029130xaf88d065e77c8cC2239327C5EDb3A432268e5831Install for the two providers in this skill:
npm i @mayanfinance/swap-sdk @solana/web3.js ethers
# deBridge uses HTTP API directly — no SDK install needed
npm i node-fetch # if on Node <22 without global fetchLock-and-mint vs liquidity-network vs intent-based — these three architectures have very different failure modes:
redeem/claim. If you forget this step, the user thinks the bridge ate their money. Always surface the claim step in your UI or auto-claim it server-side.slippageBps and have a refund path.The universal flow:
permit so you sign a message instead of a separate on-chain tx; prefer permit when supported.Finality times (May 2026, realistic):
| Bridge | EVM→Solana | Solana→EVM | Notes |
|---|---|---|---|
| Mayan Swift v2 | ~12 sec | ~30 sec | Solver-funded; can take longer if no solver bids |
| deBridge DLN | ~30 sec – 2 min | ~30 sec – 2 min | Solver-funded |
| Across | ~2 sec – 1 min | ~30 sec | Limited routes (mostly USDC) |
| CCTP v2 fast | ~20 sec | ~20 sec | Fast lane has a small fee; slow lane is free but ~13 min on EVM |
| Wormhole WTT | ~15 min | ~3 min | Manual relay; longer if you wait for "finalized" on Ethereum |
| Wormhole NTT | ~3–15 min | ~3 min | Configurable threshold per integration |
| Allbridge Core | ~3 min | ~3 min | Stablecoin pool dependent |
USDC vs wrapped tokens — this is the single biggest user-facing footgun. On Solana you may see:
EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v — native USDC (Circle, what you almost always want)A9mUU4qviSctJVPJdBJWkb28deg915LYJKrzQ19ji3FM — USDCet (Wormhole-wrapped USDC from Ethereum, legacy)Bn113WT6rbdgwrm12UJtnmNqGqZjY4it2WoUQuQopFVn — USDCpo (Wormhole-wrapped USDC from Polygon, legacy)Mybi... — countless other wrapped variants from older bridgesA user who bridges via Wormhole WTT pre-CCTP ends up with USDCet, not the native USDC their wallet/exchange/DEX expects. CCTP gives them real EPjFW.... If you build a wallet UI, label these as completely different tokens (because they are) or surface a "convert to native USDC" step.
CCTP for native USDC — for any USDC movement, default to CCTP unless you have a reason not to. The user gets the real Circle USDC, not a wrapped IOU, and the trust assumption is "Circle's attestation service" — which they already trust to mint the USDC in the first place. No new bridge risk.
#### Provider 1 — Mayan Swap (intent-based, fastest EVM→Solana)
Use Mayan when the user is moving any token (not just USDC) from an EVM chain to Solana and speed matters more than absolute lowest fee. Mayan's "Swift" route uses a solver network — a solver fronts SOL/SPL on Solana the moment your EVM tx confirms, and gets repaid on Ethereum later. From the user's perspective it feels like ~12 seconds.
Flow:
import { fetchQuote, swapFromEvm } from '@mayanfinance/swap-sdk';
import { Wallet, JsonRpcProvider } from 'ethers';
// 1. Quote
const quotes = await fetchQuote({
amount: 100, // human units, not wei
fromChain: 'ethereum', // ChainName literal
fromToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // Ethereum USDC
toChain: 'solana',
toToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // Solana USDC
slippageBps: 'auto',
});
const quote = quotes[0]; // Mayan returns multiple route options, [0] is cheapest
// 2. Approve / permit (handled inside swapFromEvm via permit if supported,
// else you must call ERC-20 approve to addresses.MAYAN_FORWARDER_CONTRACT first)
// 3. Bridge
const provider = new JsonRpcProvider(process.env.EVM_RPC_URL);
const signer = new Wallet(process.env.EVM_PRIVATE_KEY!, provider);
const result = await swapFromEvm(
quote,
await signer.getAddress(),
destSolanaAddress,
null, // referrer
signer,
undefined, // permit object — passed when permit was signed off-chain
null,
null,
);
const txHash = (result as any).hash;
// 4. Wait — poll Mayan explorer API
// https://explorer-api.mayan.finance/v3/swap/trx/{txHash}
// Status fields: clientStatus, status — wait for 'COMPLETED'See scripts/bridge-via-mayan.ts for a full runnable example with polling.
#### Provider 2 — deBridge DLN (intent-based, programmatic / API-first)
Use deBridge when you need an HTTP API rather than an SDK — perfect for agents, server-side workflows, or non-JS languages. The flow is "build a tx by calling our API, sign it with whatever wallet you have, broadcast." deBridge's solver network ("takers") fills orders on the destination side.
Internal chain IDs (these are NOT standard EVM chain IDs):
| Chain | deBridge chainId |
|---|---|
| Ethereum | 1 |
| BSC | 56 |
| Polygon | 137 |
| Optimism | 10 |
| Arbitrum | 42161 |
| Avalanche | 43114 |
| Base | 8453 |
| Linea | 59144 |
| Solana | 7565164 |
Flow:
// 1. Quote + build tx in one call
const url = new URL('https://dln.debridge.finance/v1.0/dln/order/create-tx');
url.searchParams.set('srcChainId', '1');
url.searchParams.set('srcChainTokenIn', '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48');
url.searchParams.set('srcChainTokenInAmount', '100000000'); // 100 USDC, 6 decimals
url.searchParams.set('dstChainId', '7565164'); // Solana
url.searchParams.set('dstChainTokenOut', 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');
url.searchParams.set('dstChainTokenOutAmount', 'auto'); // let solver price it
url.searchParams.set('dstChainTokenOutRecipient', solanaWallet);
url.searchParams.set('srcChainOrderAuthorityAddress', evmWallet); // can cancel/patch order
url.searchParams.set('dstChainOrderAuthorityAddress', solanaWallet);
const { tx, estimation, orderId } = await (await fetch(url)).json();
// 2. Approve (ERC-20 approve to tx.to before broadcasting)
// 3. Broadcast tx.data / tx.to / tx.value with your signer
// 4. Poll order status:
// https://dln-api.debridge.finance/v1.0/dln/order/{orderId}
// status flows: Created → Fulfilled → ClaimedUnlockSee scripts/bridge-via-debridge.ts for a full example.
#### Provider 3 — Circle CCTP v2 (canonical USDC)
Default choice for any USDC movement. Burns USDC on the source chain via depositForBurn, Circle's IRIS service attests, and you mint on Solana via the TokenMessengerMinter program. No third-party bridge trust.
// EVM source: call depositForBurn on the TokenMessenger contract
// Solana destination: PDAs derived from the message, call receiveMessage on MessageTransmitter
// IRIS attestation (poll after the source tx is mined):
const attestationUrl =
`https://iris-api.circle.com/v2/messages/${sourceDomain}?transactionHash=${txHash}`;The full CCTP flow is more code than the intent-based bridges because you handle four explicit steps (approve, burn, attest, mint). Use @coral-xyz/anchor + @solana/web3.js for the Solana side. Circle publishes a reference repo at circlefin/solana-cctp-contracts. If you want a simpler API surface, Wormhole's CCTP route wraps these steps in their SDK.
USDCet (A9mU...) on Solana, then Jupiter routes it through obscure pools at a 5% spread. Fix: prefer CCTP for USDC; if you must use WTT, surface the wrapped mint clearly and offer to swap to native via Jupiter.redeemOnSolana yourself. Have a "stuck transfers" recovery flow.slippageBps: 'auto' on Mayan is usually fine; on Allbridge set it explicitly and check pool TVL against your transfer size.getSignatureStatus with commitment: 'confirmed' and a 60s confirm window before retry. Bridge claim txs are not Jupiter swaps — they are not time-sensitive, give them room.gasDrop (Mayan supports this — set gasDrop: 0.01 in the quote params to give the user starter SOL).EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v as a constant named USDC_MINT in your codebase. If a function ever accepts a "USDC mint" parameter, it's a bug waiting to happen.create-tx responses are ~30s. If the user clicks "confirm" 2 minutes after seeing the quote, you must re-quote before signing. Otherwise the solver rejects the order and the user sees a confusing revert.scripts/bridge-via-mayan.ts — full Mayan Swift bridge ETH→SOL USDC with status pollingscripts/bridge-via-debridge.ts — full deBridge DLN bridge ETH→SOL USDC via HTTP APIreferences/bridge-comparison.md — fee, finality, security model side-by-side~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.