Socket
Socket
Sign inDemoInstall

@wormhole-foundation/sdk-connect

Package Overview
Dependencies
Maintainers
6
Versions
117
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@wormhole-foundation/sdk-connect - npm Package Compare versions

Comparing version 0.7.2 to 0.7.3-beta.0

22

dist/cjs/protocols/tokenBridge/tokenTransfer.js

@@ -432,4 +432,8 @@ "use strict";

const feeAmountDest = sdk_base_1.amount.scale(sdk_base_1.amount.truncate(sdk_base_1.amount.fromBaseUnits(fee, srcDecimals), TokenTransfer.MAX_DECIMALS), dstDecimals);
const dstNativeGasAmountRequested = transfer.nativeGas ?? 0n;
// The expected destination gas can be pulled from the destination token bridge
// nativeGas is in source chain decimals
const srcNativeGasAmountRequested = transfer.nativeGas ?? 0n;
// convert to destination chain decimals
const dstNativeGasAmountRequested = sdk_base_1.amount.units(sdk_base_1.amount.scale(sdk_base_1.amount.truncate(sdk_base_1.amount.fromBaseUnits(srcNativeGasAmountRequested, srcDecimals), TokenTransfer.MAX_DECIMALS), dstDecimals));
// TODO: consider moving these solana specific checks to its protocol implementation
const solanaMinBalanceForRentExemptAccount = 890880n;
let destinationNativeGas = 0n;

@@ -447,5 +451,19 @@ if (transfer.nativeGas) {

throw new Error(`Native gas amount exceeds maximum swap amount: ${sdk_base_1.amount.fmt(dstNativeGasAmountRequested, dstDecimals)}>${sdk_base_1.amount.fmt(maxNativeAmountIn, dstDecimals)}`);
// when native gas is requested on solana, the amount must be at least the rent-exempt amount
// or the transaction could fail if the account does not have enough lamports
if (dstChain.chain === "Solana" && _destinationNativeGas < solanaMinBalanceForRentExemptAccount) {
throw new Error(`Native gas amount must be at least ${solanaMinBalanceForRentExemptAccount} lamports`);
}
destinationNativeGas = _destinationNativeGas;
}
const destAmountLessFee = sdk_base_1.amount.units(dstAmountReceivable) - dstNativeGasAmountRequested - sdk_base_1.amount.units(feeAmountDest);
// when sending wsol to solana, the amount must be at least the rent-exempt amount
// or the transaction could fail if the account does not have enough lamports
if (dstToken.chain === "Solana") {
const nativeWrappedTokenId = await dstChain.getNativeWrappedTokenId();
if (dstToken.address === nativeWrappedTokenId.address &&
destAmountLessFee < solanaMinBalanceForRentExemptAccount) {
throw new Error(`Destination amount must be at least ${solanaMinBalanceForRentExemptAccount} lamports`);
}
}
return {

@@ -452,0 +470,0 @@ sourceToken: {

7

dist/cjs/routes/cctp/automatic.d.ts

@@ -8,2 +8,3 @@ import type { Chain, Network } from "@wormhole-foundation/sdk-base";

import type { Quote, QuoteResult, Receipt, TransferParams, ValidatedTransferParams, ValidationResult } from "../types.js";
import type { RouteTransferRequest } from "../request.js";
export declare namespace AutomaticCCTPRoute {

@@ -41,7 +42,7 @@ type Options = {

isAvailable(): Promise<boolean>;
validate(params: Tp): Promise<Vr>;
quote(params: Vp): Promise<QR>;
validate(request: RouteTransferRequest<N>, params: Tp): Promise<Vr>;
quote(request: RouteTransferRequest<N>, params: Vp): Promise<QR>;
private normalizeTransferParams;
private toTransferDetails;
initiate(signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
initiate(request: RouteTransferRequest<N>, signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
track(receipt: R, timeout?: number): AsyncGenerator<CircleTransfer.TransferReceipt<"Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance", "Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance">, void, unknown>;

@@ -48,0 +49,0 @@ }

@@ -35,3 +35,3 @@ "use strict";

}
// get the liist of destination tokens that may be recieved on the destination chain
// get the list of destination tokens that may be received on the destination chain
static async supportedDestinationTokens(sourceToken, fromChain, toChain) {

@@ -61,6 +61,6 @@ // Ensure the source token is USDC

}
async validate(params) {
async validate(request, params) {
try {
const options = params.options ?? this.getDefaultOptions();
const normalizedParams = await this.normalizeTransferParams(params);
const normalizedParams = await this.normalizeTransferParams(request, params);
const validatedParams = {

@@ -81,5 +81,5 @@ normalizedParams,

}
async quote(params) {
async quote(request, params) {
try {
return this.request.displayQuote(await cctpTransfer_js_1.CircleTransfer.quoteTransfer(this.request.fromChain, this.request.toChain, {
return request.displayQuote(await cctpTransfer_js_1.CircleTransfer.quoteTransfer(request.fromChain, request.toChain, {
automatic: true,

@@ -97,9 +97,9 @@ amount: sdk_base_1.amount.units(params.normalizedParams.amount),

}
async normalizeTransferParams(params) {
const amt = this.request.parseAmount(params.amount);
const ctb = await this.request.fromChain.getAutomaticCircleBridge();
const fee = await ctb.getRelayerFee(this.request.toChain.chain);
async normalizeTransferParams(request, params) {
const amt = request.parseAmount(params.amount);
const ctb = await request.fromChain.getAutomaticCircleBridge();
const fee = await ctb.getRelayerFee(request.toChain.chain);
const minAmount = (fee * 105n) / 100n;
if (sdk_base_1.amount.units(amt) < minAmount) {
throw new Error(`Minimum amount is ${sdk_base_1.amount.display(this.request.amountFromBaseUnits(minAmount))}`);
throw new Error(`Minimum amount is ${sdk_base_1.amount.display(request.amountFromBaseUnits(minAmount))}`);
}

@@ -118,5 +118,5 @@ const transferableAmount = sdk_base_1.amount.units(amt) - fee;

return {
fee: this.request.amountFromBaseUnits(fee),
fee: request.amountFromBaseUnits(fee),
amount: amt,
nativeGasAmount: this.request.amountFromBaseUnits(nativeGasAmount),
nativeGasAmount: request.amountFromBaseUnits(nativeGasAmount),
};

@@ -133,7 +133,7 @@ }

}
async initiate(signer, quote, to) {
async initiate(request, signer, quote, to) {
const { params } = quote;
let transfer = this.toTransferDetails(params, wormhole_js_1.Wormhole.chainAddress(signer.chain(), signer.address()), to);
let txids = await cctpTransfer_js_1.CircleTransfer.transfer(this.request.fromChain, transfer, signer);
const msg = await cctpTransfer_js_1.CircleTransfer.getTransferMessage(this.request.fromChain, txids[txids.length - 1].txid);
let txids = await cctpTransfer_js_1.CircleTransfer.transfer(request.fromChain, transfer, signer);
const msg = await cctpTransfer_js_1.CircleTransfer.getTransferMessage(request.fromChain, txids[txids.length - 1].txid);
return {

@@ -148,3 +148,3 @@ from: transfer.from.chain,

async *track(receipt, timeout) {
yield* cctpTransfer_js_1.CircleTransfer.track(this.wh, receipt, timeout, this.request.fromChain, this.request.toChain);
yield* cctpTransfer_js_1.CircleTransfer.track(this.wh, receipt, timeout);
}

@@ -151,0 +151,0 @@ }

import type { Chain, Network } from "@wormhole-foundation/sdk-base";
import { amount } from "@wormhole-foundation/sdk-base";
import type { ChainContext, Signer, TokenId } from "@wormhole-foundation/sdk-definitions";
import type { ChainAddress, ChainContext, Signer, TokenId } from "@wormhole-foundation/sdk-definitions";
import { CircleTransfer } from "../../protocols/cctp/cctpTransfer.js";

@@ -9,3 +9,3 @@ import type { TransferReceipt } from "../../types.js";

import type { Quote, QuoteResult, TransferParams, ValidatedTransferParams, ValidationResult } from "../types.js";
import { ChainAddress } from "@wormhole-foundation/sdk-definitions";
import type { RouteTransferRequest } from "../request.js";
export declare namespace CCTPRoute {

@@ -39,5 +39,5 @@ type Options = {

getDefaultOptions(): Op;
validate(params: Tp): Promise<Vr>;
quote(params: Vp): Promise<QR>;
initiate(signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
validate(request: RouteTransferRequest<N>, params: Tp): Promise<Vr>;
quote(request: RouteTransferRequest<N>, params: Vp): Promise<QR>;
initiate(request: RouteTransferRequest<N>, signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
complete(signer: Signer, receipt: R): Promise<R>;

@@ -44,0 +44,0 @@ track(receipt: R, timeout?: number): AsyncGenerator<CircleTransfer.TransferReceipt<"Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance", "Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance">, void, unknown>;

@@ -32,3 +32,3 @@ "use strict";

}
// get the liist of destination tokens that may be recieved on the destination chain
// get the list of destination tokens that may be received on the destination chain
static async supportedDestinationTokens(sourceToken, fromChain, toChain) {

@@ -55,4 +55,4 @@ // Ensure the source token is USDC

}
async validate(params) {
const amount = this.request.parseAmount(params.amount);
async validate(request, params) {
const amount = request.parseAmount(params.amount);
const validatedParams = {

@@ -67,5 +67,5 @@ normalizedParams: {

}
async quote(params) {
async quote(request, params) {
try {
return this.request.displayQuote(await cctpTransfer_js_1.CircleTransfer.quoteTransfer(this.request.fromChain, this.request.toChain, {
return request.displayQuote(await cctpTransfer_js_1.CircleTransfer.quoteTransfer(request.fromChain, request.toChain, {
automatic: false,

@@ -83,7 +83,7 @@ amount: sdk_base_1.amount.units(params.normalizedParams.amount),

}
async initiate(signer, quote, to) {
async initiate(request, signer, quote, to) {
const { params } = quote;
const transfer = await cctpTransfer_js_1.CircleTransfer.destinationOverrides(this.request.fromChain, this.request.toChain, this.toTransferDetails(params, wormhole_js_1.Wormhole.chainAddress(signer.chain(), signer.address()), to));
const txids = await cctpTransfer_js_1.CircleTransfer.transfer(this.request.fromChain, transfer, signer);
const msg = await cctpTransfer_js_1.CircleTransfer.getTransferMessage(this.request.fromChain, txids[txids.length - 1].txid);
const transfer = await cctpTransfer_js_1.CircleTransfer.destinationOverrides(request.fromChain, request.toChain, this.toTransferDetails(params, wormhole_js_1.Wormhole.chainAddress(signer.chain(), signer.address()), to));
const txids = await cctpTransfer_js_1.CircleTransfer.transfer(request.fromChain, transfer, signer);
const msg = await cctpTransfer_js_1.CircleTransfer.getTransferMessage(request.fromChain, txids[txids.length - 1].txid);
return {

@@ -105,5 +105,6 @@ from: transfer.from.chain,

throw new Error(`No Circle attestation for ${id}`);
const cb = await this.request.toChain.getCircleBridge();
const toChain = await this.wh.getChain(receipt.to);
const cb = await toChain.getCircleBridge();
const xfer = cb.redeem(message.payload.mintRecipient, message, attestation);
const dstTxids = await (0, common_js_1.signSendWait)(this.request.toChain, xfer, signer);
const dstTxids = await (0, common_js_1.signSendWait)(toChain, xfer, signer);
return {

@@ -121,3 +122,3 @@ ...receipt,

async *track(receipt, timeout) {
yield* cctpTransfer_js_1.CircleTransfer.track(this.wh, receipt, timeout, this.request.fromChain, this.request.toChain);
yield* cctpTransfer_js_1.CircleTransfer.track(this.wh, receipt, timeout);
}

@@ -124,0 +125,0 @@ toTransferDetails(params, from, to) {

@@ -6,3 +6,4 @@ import type { StaticRouteMethods } from "../route.js";

import { PorticoBridge, TransferState, amount } from "./../../index.js";
import { ChainAddress } from "@wormhole-foundation/sdk-definitions";
import type { ChainAddress } from "@wormhole-foundation/sdk-definitions";
import type { RouteTransferRequest } from "../request.js";
export declare const SLIPPAGE_BPS = 15n;

@@ -43,5 +44,5 @@ export declare const BPS_PER_HUNDRED_PERCENT = 10000n;

getDefaultOptions(): OP;
validate(params: TP): Promise<VR>;
quote(params: VP): Promise<QR>;
initiate(sender: Signer<N>, quote: Q, to: ChainAddress): Promise<SourceInitiatedTransferReceipt<"Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance", "Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance">>;
validate(request: RouteTransferRequest<N>, params: TP): Promise<VR>;
quote(request: RouteTransferRequest<N>, params: VP): Promise<QR>;
initiate(request: RouteTransferRequest<N>, sender: Signer<N>, quote: Q, to: ChainAddress): Promise<SourceInitiatedTransferReceipt<"Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance", "Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance">>;
track(receipt: R, timeout?: number): AsyncGenerator<{

@@ -48,0 +49,0 @@ vaa: import("@wormhole-foundation/sdk-definitions").VAA<"TokenBridge:TransferWithPayload">;

@@ -76,9 +76,9 @@ "use strict";

}
async validate(params) {
async validate(request, params) {
try {
if ((0, index_js_1.chainToPlatform)(this.request.fromChain.chain) !== "Evm" ||
(0, index_js_1.chainToPlatform)(this.request.toChain.chain) !== "Evm") {
if ((0, index_js_1.chainToPlatform)(request.fromChain.chain) !== "Evm" ||
(0, index_js_1.chainToPlatform)(request.toChain.chain) !== "Evm") {
throw new Error("Only EVM chains are supported");
}
const { fromChain, toChain, source, destination } = this.request;
const { fromChain, toChain, source, destination } = request;
const { network } = fromChain;

@@ -96,3 +96,3 @@ // This may be "native" but we want the token that can actually be bridged

normalizedParams: {
amount: this.request.parseAmount(params.amount),
amount: request.parseAmount(params.amount),
canonicalSourceToken,

@@ -110,6 +110,6 @@ canonicalDestinationToken,

}
async quote(params) {
async quote(request, params) {
try {
const swapAmounts = await this.quoteUniswap(params);
const pb = await this.request.toChain.getPorticoBridge();
const swapAmounts = await this.quoteUniswap(request, params);
const pb = await request.toChain.getPorticoBridge();
const fee = await pb.quoteRelay(params.normalizedParams.canonicalDestinationToken.address, params.normalizedParams.destinationToken.address);

@@ -127,3 +127,3 @@ const details = {

}
return (await this.request.displayQuote({
return (await request.displayQuote({
sourceToken: {

@@ -150,14 +150,14 @@ token: params.normalizedParams.sourceToken,

}
async initiate(sender, quote, to) {
async initiate(request, sender, quote, to) {
const { params, details } = quote;
const sourceToken = this.request.source.id.address;
const destToken = this.request.destination.id;
const fromPorticoBridge = await this.request.fromChain.getPorticoBridge();
const sourceToken = request.source.id.address;
const destToken = request.destination.id;
const fromPorticoBridge = await request.fromChain.getPorticoBridge();
const xfer = fromPorticoBridge.transfer(index_js_1.Wormhole.parseAddress(sender.chain(), sender.address()), to, sourceToken, index_js_1.amount.units(params.normalizedParams.amount), destToken, details);
const txids = await (0, index_js_1.signSendWait)(this.request.fromChain, xfer, sender);
const txids = await (0, index_js_1.signSendWait)(request.fromChain, xfer, sender);
const receipt = {
originTxs: txids,
state: index_js_1.TransferState.SourceInitiated,
from: this.request.fromChain.chain,
to: this.request.toChain.chain,
from: request.fromChain.chain,
to: request.toChain.chain,
};

@@ -179,9 +179,10 @@ return receipt;

throw new Error("Source must be attested");
const toPorticoBridge = await this.request.toChain.getPorticoBridge();
const toChain = await this.wh.getChain(receipt.to);
const toPorticoBridge = await toChain.getPorticoBridge();
const sender = index_js_1.Wormhole.chainAddress(signer.chain(), signer.address());
const xfer = toPorticoBridge.redeem(sender.address, receipt.attestation.attestation);
return await (0, index_js_1.signSendWait)(this.request.toChain, xfer, signer);
return await (0, index_js_1.signSendWait)(toChain, xfer, signer);
}
async quoteUniswap(params) {
const fromPorticoBridge = await this.request.fromChain.getPorticoBridge();
async quoteUniswap(request, params) {
const fromPorticoBridge = await request.fromChain.getPorticoBridge();
const startQuote = await fromPorticoBridge.quoteSwap(params.normalizedParams.sourceToken.address, params.normalizedParams.canonicalSourceToken.address, index_js_1.amount.units(params.normalizedParams.amount));

@@ -191,3 +192,3 @@ const startSlippage = (startQuote * exports.SLIPPAGE_BPS) / exports.BPS_PER_HUNDRED_PERCENT;

throw new Error("Start slippage too high");
const toPorticoBridge = await this.request.toChain.getPorticoBridge();
const toPorticoBridge = await request.toChain.getPorticoBridge();
const minAmountStart = startQuote - startSlippage;

@@ -194,0 +195,0 @@ const finishQuote = await toPorticoBridge.quoteSwap(params.normalizedParams.canonicalDestinationToken.address, params.normalizedParams.destinationToken.address, minAmountStart);

@@ -70,5 +70,5 @@ "use strict";

return await Promise.all(supportedRoutes.map(async (rc) => {
const route = new rc(this.wh, request);
const route = new rc(this.wh);
try {
const available = (0, route_js_1.isAutomatic)(route) ? await route.isAvailable() : true;
const available = (0, route_js_1.isAutomatic)(route) ? await route.isAvailable(request) : true;
return [route, available];

@@ -75,0 +75,0 @@ }

@@ -9,9 +9,8 @@ import type { Chain, Network } from "@wormhole-foundation/sdk-base";

wh: Wormhole<N>;
request: RouteTransferRequest<N>;
abstract readonly NATIVE_GAS_DROPOFF_SUPPORTED: boolean;
abstract readonly IS_AUTOMATIC: boolean;
constructor(wh: Wormhole<N>, request: RouteTransferRequest<N>);
abstract validate(params: TransferParams<OP>): Promise<ValidationResult<OP>>;
abstract quote(params: ValidatedTransferParams<OP>): Promise<QuoteResult<OP, VP>>;
abstract initiate(sender: Signer, quote: Quote<OP, VP>, to: ChainAddress): Promise<R>;
constructor(wh: Wormhole<N>);
abstract validate(request: RouteTransferRequest<N>, params: TransferParams<OP>): Promise<ValidationResult<OP>>;
abstract quote(request: RouteTransferRequest<N>, params: ValidatedTransferParams<OP>): Promise<QuoteResult<OP, VP>>;
abstract initiate(request: RouteTransferRequest<N>, sender: Signer, quote: Quote<OP, VP>, to: ChainAddress): Promise<R>;
abstract track(receipt: R, timeout?: number): AsyncGenerator<R>;

@@ -28,3 +27,3 @@ transferUrl(txid: string): string;

export interface RouteConstructor<OP extends Options = Options> {
new <N extends Network>(wh: Wormhole<N>, request: RouteTransferRequest<N>): Route<N, OP>;
new <N extends Network>(wh: Wormhole<N>): Route<N, OP>;
/** Details about the route provided by the implementation */

@@ -40,3 +39,3 @@ readonly meta: RouteMeta;

supportedSourceTokens(fromChain: ChainContext<Network>): Promise<TokenId[]>;
/** get the list of destination tokens that may be recieved on the destination chain */
/** get the list of destination tokens that may be received on the destination chain */
supportedDestinationTokens<N extends Network>(token: TokenId, fromChain: ChainContext<N>, toChain: ChainContext<N>): Promise<TokenId[]>;

@@ -51,3 +50,3 @@ }

IS_AUTOMATIC: boolean;
abstract isAvailable(): Promise<boolean>;
abstract isAvailable(request: RouteTransferRequest<N>): Promise<boolean>;
}

@@ -54,0 +53,0 @@ export declare function isAutomatic<N extends Network>(route: Route<N>): route is AutomaticRoute<N>;

@@ -6,6 +6,4 @@ "use strict";

wh;
request;
constructor(wh, request) {
constructor(wh) {
this.wh = wh;
this.request = request;
}

@@ -12,0 +10,0 @@ // Get the url to view the transfer on the explorer for the route provider

import type { Chain, Network } from "@wormhole-foundation/sdk-base";
import { amount } from "@wormhole-foundation/sdk-base";
import type { ChainContext, Signer, TokenId } from "@wormhole-foundation/sdk-definitions";
import { ChainAddress } from "@wormhole-foundation/sdk-definitions";
import type { ChainAddress, ChainContext, Signer, TokenId } from "@wormhole-foundation/sdk-definitions";
import { TokenTransfer } from "../../protocols/tokenBridge/tokenTransfer.js";

@@ -10,2 +9,3 @@ import type { AttestationReceipt } from "../../types.js";

import type { Quote, QuoteResult, Receipt, TransferParams, ValidatedTransferParams, ValidationResult } from "../types.js";
import type { RouteTransferRequest } from "../request.js";
export declare namespace AutomaticTokenBridgeRoute {

@@ -42,7 +42,7 @@ type Options = {

getDefaultOptions(): Op;
isAvailable(): Promise<boolean>;
validate(params: Tp): Promise<Vr>;
isAvailable(request: RouteTransferRequest<N>): Promise<boolean>;
validate(request: RouteTransferRequest<N>, params: Tp): Promise<Vr>;
private normalizeTransferParams;
quote(params: Vp): Promise<QR>;
initiate(signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
quote(request: RouteTransferRequest<N>, params: Vp): Promise<QR>;
initiate(request: RouteTransferRequest<N>, signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
track(receipt: R, timeout?: number): AsyncGenerator<TokenTransfer.TransferReceipt<"Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance", "Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance">, void, unknown>;

@@ -49,0 +49,0 @@ private toTransferDetails;

@@ -36,3 +36,3 @@ "use strict";

}
// get the list of destination tokens that may be recieved on the destination chain
// get the list of destination tokens that may be received on the destination chain
static async supportedDestinationTokens(sourceToken, fromChain, toChain) {

@@ -59,10 +59,10 @@ try {

}
async isAvailable() {
const atb = await this.request.fromChain.getAutomaticTokenBridge();
if ((0, sdk_definitions_1.isTokenId)(this.request.source.id)) {
return await atb.isRegisteredToken(this.request.source.id.address);
async isAvailable(request) {
const atb = await request.fromChain.getAutomaticTokenBridge();
if ((0, sdk_definitions_1.isTokenId)(request.source.id)) {
return await atb.isRegisteredToken(request.source.id.address);
}
return true;
}
async validate(params) {
async validate(request, params) {
try {

@@ -72,10 +72,10 @@ const options = params.options ?? this.getDefaultOptions();

throw new Error("Native gas must be between 0.0 and 1.0 (0% and 100%)");
// If destination is native, max out the nativeGas requested
const { destination } = this.request;
// native gas drop-off when the native token is the destination should be 0
const { destination } = request;
if ((0, sdk_definitions_1.isNative)(destination.id.address) && options.nativeGas === 0.0)
options.nativeGas = 1.0;
options.nativeGas = 0;
const updatedParams = { ...params, options };
const validatedParams = {
...updatedParams,
normalizedParams: await this.normalizeTransferParams(updatedParams),
normalizedParams: await this.normalizeTransferParams(request, updatedParams),
};

@@ -88,9 +88,9 @@ return { valid: true, params: validatedParams };

}
async normalizeTransferParams(params) {
const amt = this.request.parseAmount(params.amount);
const inputToken = (0, sdk_definitions_1.isNative)(this.request.source.id.address)
? await this.request.fromChain.getNativeWrappedTokenId()
: this.request.source.id;
const atb = await this.request.fromChain.getAutomaticTokenBridge();
const fee = await atb.getRelayerFee(this.request.toChain.chain, inputToken.address);
async normalizeTransferParams(request, params) {
const amt = request.parseAmount(params.amount);
const inputToken = (0, sdk_definitions_1.isNative)(request.source.id.address)
? await request.fromChain.getNativeWrappedTokenId()
: request.source.id;
const atb = await request.fromChain.getAutomaticTokenBridge();
const fee = await atb.getRelayerFee(request.toChain.chain, inputToken.address);
// Min amount is fee + 5%

@@ -105,24 +105,33 @@ const minAmount = (fee * 105n) / 100n;

const redeemableAmount = sdk_base_1.amount.units(amt) - fee;
// Determine nativeGas
let nativeGasAmount = 0n;
let srcNativeGasAmount = sdk_base_1.amount.fromBaseUnits(0n, request.source.decimals);
if (params.options && params.options.nativeGas > 0) {
const dtb = await request.toChain.getAutomaticTokenBridge();
// the maxSwapAmount is in destination chain decimals
const maxSwapAmount = await dtb.maxSwapAmount(request.destination.id.address);
const scale = 10000;
const scaledGas = BigInt(params.options.nativeGas * scale);
nativeGasAmount = (redeemableAmount * scaledGas) / BigInt(scale);
const scaledGasPercent = BigInt(Math.floor(params.options.nativeGas * scale));
const dstNativeGasUnits = (maxSwapAmount * scaledGasPercent) / BigInt(scale);
const dstNativeGasAmount = sdk_base_1.amount.fromBaseUnits(dstNativeGasUnits, request.destination.decimals);
// convert the native gas amount to source chain decimals
srcNativeGasAmount = sdk_base_1.amount.scale(sdk_base_1.amount.truncate(dstNativeGasAmount, tokenTransfer_js_1.TokenTransfer.MAX_DECIMALS), request.source.decimals);
// can't request more gas than the redeemable amount
if (sdk_base_1.amount.units(srcNativeGasAmount) > redeemableAmount) {
srcNativeGasAmount = sdk_base_1.amount.fromBaseUnits(redeemableAmount, request.source.decimals);
}
}
return {
fee: sdk_base_1.amount.fromBaseUnits(fee, this.request.source.decimals),
fee: sdk_base_1.amount.fromBaseUnits(fee, request.source.decimals),
amount: amt,
nativeGasAmount: sdk_base_1.amount.fromBaseUnits(nativeGasAmount, this.request.source.decimals),
nativeGasAmount: srcNativeGasAmount,
};
}
async quote(params) {
async quote(request, params) {
try {
let quote = await tokenTransfer_js_1.TokenTransfer.quoteTransfer(this.wh, this.request.fromChain, this.request.toChain, {
let quote = await tokenTransfer_js_1.TokenTransfer.quoteTransfer(this.wh, request.fromChain, request.toChain, {
automatic: true,
amount: sdk_base_1.amount.units(params.normalizedParams.amount),
token: this.request.source.id,
token: request.source.id,
nativeGas: sdk_base_1.amount.units(params.normalizedParams.nativeGasAmount),
});
return this.request.displayQuote(quote, params);
return request.displayQuote(quote, params);
}

@@ -136,6 +145,6 @@ catch (e) {

}
async initiate(signer, quote, to) {
async initiate(request, signer, quote, to) {
const { params } = quote;
const transfer = this.toTransferDetails(params, wormhole_js_1.Wormhole.chainAddress(signer.chain(), signer.address()), to);
const txids = await tokenTransfer_js_1.TokenTransfer.transfer(this.request.fromChain, transfer, signer);
const transfer = this.toTransferDetails(request, params, wormhole_js_1.Wormhole.chainAddress(signer.chain(), signer.address()), to);
const txids = await tokenTransfer_js_1.TokenTransfer.transfer(request.fromChain, transfer, signer);
return {

@@ -150,3 +159,3 @@ from: transfer.from.chain,

try {
yield* tokenTransfer_js_1.TokenTransfer.track(this.wh, receipt, timeout, this.request.fromChain, this.request.toChain);
yield* tokenTransfer_js_1.TokenTransfer.track(this.wh, receipt, timeout);
}

@@ -157,3 +166,3 @@ catch (e) {

}
toTransferDetails(params, from, to) {
toTransferDetails(request, params, from, to) {
const transfer = {

@@ -164,3 +173,3 @@ from,

amount: sdk_base_1.amount.units(params.normalizedParams.amount),
token: this.request.source.id,
token: request.source.id,
nativeGas: sdk_base_1.amount.units(params.normalizedParams.nativeGasAmount),

@@ -167,0 +176,0 @@ };

import type { Chain, Network } from "@wormhole-foundation/sdk-base";
import { amount } from "@wormhole-foundation/sdk-base";
import type { ChainContext, Signer, TokenId } from "@wormhole-foundation/sdk-definitions";
import type { ChainAddress, ChainContext, Signer, TokenId } from "@wormhole-foundation/sdk-definitions";
import { TokenTransfer } from "../../protocols/tokenBridge/tokenTransfer.js";

@@ -9,3 +9,3 @@ import type { AttestationReceipt, TransferReceipt } from "../../types.js";

import type { Quote, QuoteResult, TransferParams, ValidatedTransferParams, ValidationResult } from "../types.js";
import { ChainAddress } from "@wormhole-foundation/sdk-definitions";
import type { RouteTransferRequest } from "../request.js";
export declare namespace TokenBridgeRoute {

@@ -39,5 +39,5 @@ type Options = {

getDefaultOptions(): Op;
validate(params: Tp): Promise<Vr>;
quote(params: Vp): Promise<QR>;
initiate(signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
validate(request: RouteTransferRequest<N>, params: Tp): Promise<Vr>;
quote(request: RouteTransferRequest<N>, params: Vp): Promise<QR>;
initiate(request: RouteTransferRequest<N>, signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
complete(signer: Signer, receipt: R): Promise<R>;

@@ -44,0 +44,0 @@ track(receipt: R, timeout?: number): AsyncGenerator<TokenTransfer.TransferReceipt<"Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance", "Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance">, void, unknown>;

@@ -25,3 +25,3 @@ "use strict";

}
// get the liist of destination tokens that may be recieved on the destination chain
// get the list of destination tokens that may be received on the destination chain
static async supportedDestinationTokens(sourceToken, fromChain, toChain) {

@@ -42,4 +42,4 @@ try {

}
async validate(params) {
const amt = sdk_base_1.amount.parse(params.amount, this.request.source.decimals);
async validate(request, params) {
const amt = sdk_base_1.amount.parse(params.amount, request.source.decimals);
const validatedParams = {

@@ -52,6 +52,6 @@ amount: params.amount,

}
async quote(params) {
async quote(request, params) {
try {
return this.request.displayQuote(await tokenTransfer_js_1.TokenTransfer.quoteTransfer(this.wh, this.request.fromChain, this.request.toChain, {
token: this.request.source.id,
return request.displayQuote(await tokenTransfer_js_1.TokenTransfer.quoteTransfer(this.wh, request.fromChain, request.toChain, {
token: request.source.id,
amount: sdk_base_1.amount.units(params.normalizedParams.amount),

@@ -68,6 +68,6 @@ ...params.options,

}
async initiate(signer, quote, to) {
async initiate(request, signer, quote, to) {
const { params } = quote;
const transfer = await tokenTransfer_js_1.TokenTransfer.destinationOverrides(this.request.fromChain, this.request.toChain, this.toTransferDetails(params, wormhole_js_1.Wormhole.chainAddress(signer.chain(), signer.address()), to));
const txids = await tokenTransfer_js_1.TokenTransfer.transfer(this.request.fromChain, transfer, signer);
const transfer = await tokenTransfer_js_1.TokenTransfer.destinationOverrides(request.fromChain, request.toChain, this.toTransferDetails(request, params, wormhole_js_1.Wormhole.chainAddress(signer.chain(), signer.address()), to));
const txids = await tokenTransfer_js_1.TokenTransfer.transfer(request.fromChain, transfer, signer);
return {

@@ -83,3 +83,4 @@ from: transfer.from.chain,

throw new Error("The source must be finalized in order to complete the transfer");
const dstTxIds = await tokenTransfer_js_1.TokenTransfer.redeem(this.request.toChain, receipt.attestation.attestation, signer);
const toChain = this.wh.getChain(receipt.to);
const dstTxIds = await tokenTransfer_js_1.TokenTransfer.redeem(toChain, receipt.attestation.attestation, signer);
return {

@@ -92,9 +93,9 @@ ...receipt,

async *track(receipt, timeout) {
yield* tokenTransfer_js_1.TokenTransfer.track(this.wh, receipt, timeout, this.request.fromChain, this.request.toChain);
yield* tokenTransfer_js_1.TokenTransfer.track(this.wh, receipt, timeout);
}
toTransferDetails(params, from, to) {
toTransferDetails(request, params, from, to) {
return {
from,
to,
token: this.request.source.id,
token: request.source.id,
amount: sdk_base_1.amount.units(params.normalizedParams.amount),

@@ -101,0 +102,0 @@ ...params.options,

@@ -428,4 +428,8 @@ import { amount, encoding, toChain as toChainName } from "@wormhole-foundation/sdk-base";

const feeAmountDest = amount.scale(amount.truncate(amount.fromBaseUnits(fee, srcDecimals), TokenTransfer.MAX_DECIMALS), dstDecimals);
const dstNativeGasAmountRequested = transfer.nativeGas ?? 0n;
// The expected destination gas can be pulled from the destination token bridge
// nativeGas is in source chain decimals
const srcNativeGasAmountRequested = transfer.nativeGas ?? 0n;
// convert to destination chain decimals
const dstNativeGasAmountRequested = amount.units(amount.scale(amount.truncate(amount.fromBaseUnits(srcNativeGasAmountRequested, srcDecimals), TokenTransfer.MAX_DECIMALS), dstDecimals));
// TODO: consider moving these solana specific checks to its protocol implementation
const solanaMinBalanceForRentExemptAccount = 890880n;
let destinationNativeGas = 0n;

@@ -443,5 +447,19 @@ if (transfer.nativeGas) {

throw new Error(`Native gas amount exceeds maximum swap amount: ${amount.fmt(dstNativeGasAmountRequested, dstDecimals)}>${amount.fmt(maxNativeAmountIn, dstDecimals)}`);
// when native gas is requested on solana, the amount must be at least the rent-exempt amount
// or the transaction could fail if the account does not have enough lamports
if (dstChain.chain === "Solana" && _destinationNativeGas < solanaMinBalanceForRentExemptAccount) {
throw new Error(`Native gas amount must be at least ${solanaMinBalanceForRentExemptAccount} lamports`);
}
destinationNativeGas = _destinationNativeGas;
}
const destAmountLessFee = amount.units(dstAmountReceivable) - dstNativeGasAmountRequested - amount.units(feeAmountDest);
// when sending wsol to solana, the amount must be at least the rent-exempt amount
// or the transaction could fail if the account does not have enough lamports
if (dstToken.chain === "Solana") {
const nativeWrappedTokenId = await dstChain.getNativeWrappedTokenId();
if (dstToken.address === nativeWrappedTokenId.address &&
destAmountLessFee < solanaMinBalanceForRentExemptAccount) {
throw new Error(`Destination amount must be at least ${solanaMinBalanceForRentExemptAccount} lamports`);
}
}
return {

@@ -448,0 +466,0 @@ sourceToken: {

@@ -8,2 +8,3 @@ import type { Chain, Network } from "@wormhole-foundation/sdk-base";

import type { Quote, QuoteResult, Receipt, TransferParams, ValidatedTransferParams, ValidationResult } from "../types.js";
import type { RouteTransferRequest } from "../request.js";
export declare namespace AutomaticCCTPRoute {

@@ -41,7 +42,7 @@ type Options = {

isAvailable(): Promise<boolean>;
validate(params: Tp): Promise<Vr>;
quote(params: Vp): Promise<QR>;
validate(request: RouteTransferRequest<N>, params: Tp): Promise<Vr>;
quote(request: RouteTransferRequest<N>, params: Vp): Promise<QR>;
private normalizeTransferParams;
private toTransferDetails;
initiate(signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
initiate(request: RouteTransferRequest<N>, signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
track(receipt: R, timeout?: number): AsyncGenerator<CircleTransfer.TransferReceipt<"Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance", "Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance">, void, unknown>;

@@ -48,0 +49,0 @@ }

@@ -32,3 +32,3 @@ import { amount, circle, contracts } from "@wormhole-foundation/sdk-base";

}
// get the liist of destination tokens that may be recieved on the destination chain
// get the list of destination tokens that may be received on the destination chain
static async supportedDestinationTokens(sourceToken, fromChain, toChain) {

@@ -58,6 +58,6 @@ // Ensure the source token is USDC

}
async validate(params) {
async validate(request, params) {
try {
const options = params.options ?? this.getDefaultOptions();
const normalizedParams = await this.normalizeTransferParams(params);
const normalizedParams = await this.normalizeTransferParams(request, params);
const validatedParams = {

@@ -78,5 +78,5 @@ normalizedParams,

}
async quote(params) {
async quote(request, params) {
try {
return this.request.displayQuote(await CircleTransfer.quoteTransfer(this.request.fromChain, this.request.toChain, {
return request.displayQuote(await CircleTransfer.quoteTransfer(request.fromChain, request.toChain, {
automatic: true,

@@ -94,9 +94,9 @@ amount: amount.units(params.normalizedParams.amount),

}
async normalizeTransferParams(params) {
const amt = this.request.parseAmount(params.amount);
const ctb = await this.request.fromChain.getAutomaticCircleBridge();
const fee = await ctb.getRelayerFee(this.request.toChain.chain);
async normalizeTransferParams(request, params) {
const amt = request.parseAmount(params.amount);
const ctb = await request.fromChain.getAutomaticCircleBridge();
const fee = await ctb.getRelayerFee(request.toChain.chain);
const minAmount = (fee * 105n) / 100n;
if (amount.units(amt) < minAmount) {
throw new Error(`Minimum amount is ${amount.display(this.request.amountFromBaseUnits(minAmount))}`);
throw new Error(`Minimum amount is ${amount.display(request.amountFromBaseUnits(minAmount))}`);
}

@@ -115,5 +115,5 @@ const transferableAmount = amount.units(amt) - fee;

return {
fee: this.request.amountFromBaseUnits(fee),
fee: request.amountFromBaseUnits(fee),
amount: amt,
nativeGasAmount: this.request.amountFromBaseUnits(nativeGasAmount),
nativeGasAmount: request.amountFromBaseUnits(nativeGasAmount),
};

@@ -130,7 +130,7 @@ }

}
async initiate(signer, quote, to) {
async initiate(request, signer, quote, to) {
const { params } = quote;
let transfer = this.toTransferDetails(params, Wormhole.chainAddress(signer.chain(), signer.address()), to);
let txids = await CircleTransfer.transfer(this.request.fromChain, transfer, signer);
const msg = await CircleTransfer.getTransferMessage(this.request.fromChain, txids[txids.length - 1].txid);
let txids = await CircleTransfer.transfer(request.fromChain, transfer, signer);
const msg = await CircleTransfer.getTransferMessage(request.fromChain, txids[txids.length - 1].txid);
return {

@@ -145,5 +145,5 @@ from: transfer.from.chain,

async *track(receipt, timeout) {
yield* CircleTransfer.track(this.wh, receipt, timeout, this.request.fromChain, this.request.toChain);
yield* CircleTransfer.track(this.wh, receipt, timeout);
}
}
//# sourceMappingURL=automatic.js.map
import type { Chain, Network } from "@wormhole-foundation/sdk-base";
import { amount } from "@wormhole-foundation/sdk-base";
import type { ChainContext, Signer, TokenId } from "@wormhole-foundation/sdk-definitions";
import type { ChainAddress, ChainContext, Signer, TokenId } from "@wormhole-foundation/sdk-definitions";
import { CircleTransfer } from "../../protocols/cctp/cctpTransfer.js";

@@ -9,3 +9,3 @@ import type { TransferReceipt } from "../../types.js";

import type { Quote, QuoteResult, TransferParams, ValidatedTransferParams, ValidationResult } from "../types.js";
import { ChainAddress } from "@wormhole-foundation/sdk-definitions";
import type { RouteTransferRequest } from "../request.js";
export declare namespace CCTPRoute {

@@ -39,5 +39,5 @@ type Options = {

getDefaultOptions(): Op;
validate(params: Tp): Promise<Vr>;
quote(params: Vp): Promise<QR>;
initiate(signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
validate(request: RouteTransferRequest<N>, params: Tp): Promise<Vr>;
quote(request: RouteTransferRequest<N>, params: Vp): Promise<QR>;
initiate(request: RouteTransferRequest<N>, signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
complete(signer: Signer, receipt: R): Promise<R>;

@@ -44,0 +44,0 @@ track(receipt: R, timeout?: number): AsyncGenerator<CircleTransfer.TransferReceipt<"Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance", "Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance">, void, unknown>;

@@ -29,3 +29,3 @@ import { amount, circle, contracts } from "@wormhole-foundation/sdk-base";

}
// get the liist of destination tokens that may be recieved on the destination chain
// get the list of destination tokens that may be received on the destination chain
static async supportedDestinationTokens(sourceToken, fromChain, toChain) {

@@ -52,4 +52,4 @@ // Ensure the source token is USDC

}
async validate(params) {
const amount = this.request.parseAmount(params.amount);
async validate(request, params) {
const amount = request.parseAmount(params.amount);
const validatedParams = {

@@ -64,5 +64,5 @@ normalizedParams: {

}
async quote(params) {
async quote(request, params) {
try {
return this.request.displayQuote(await CircleTransfer.quoteTransfer(this.request.fromChain, this.request.toChain, {
return request.displayQuote(await CircleTransfer.quoteTransfer(request.fromChain, request.toChain, {
automatic: false,

@@ -80,7 +80,7 @@ amount: amount.units(params.normalizedParams.amount),

}
async initiate(signer, quote, to) {
async initiate(request, signer, quote, to) {
const { params } = quote;
const transfer = await CircleTransfer.destinationOverrides(this.request.fromChain, this.request.toChain, this.toTransferDetails(params, Wormhole.chainAddress(signer.chain(), signer.address()), to));
const txids = await CircleTransfer.transfer(this.request.fromChain, transfer, signer);
const msg = await CircleTransfer.getTransferMessage(this.request.fromChain, txids[txids.length - 1].txid);
const transfer = await CircleTransfer.destinationOverrides(request.fromChain, request.toChain, this.toTransferDetails(params, Wormhole.chainAddress(signer.chain(), signer.address()), to));
const txids = await CircleTransfer.transfer(request.fromChain, transfer, signer);
const msg = await CircleTransfer.getTransferMessage(request.fromChain, txids[txids.length - 1].txid);
return {

@@ -102,5 +102,6 @@ from: transfer.from.chain,

throw new Error(`No Circle attestation for ${id}`);
const cb = await this.request.toChain.getCircleBridge();
const toChain = await this.wh.getChain(receipt.to);
const cb = await toChain.getCircleBridge();
const xfer = cb.redeem(message.payload.mintRecipient, message, attestation);
const dstTxids = await signSendWait(this.request.toChain, xfer, signer);
const dstTxids = await signSendWait(toChain, xfer, signer);
return {

@@ -118,3 +119,3 @@ ...receipt,

async *track(receipt, timeout) {
yield* CircleTransfer.track(this.wh, receipt, timeout, this.request.fromChain, this.request.toChain);
yield* CircleTransfer.track(this.wh, receipt, timeout);
}

@@ -121,0 +122,0 @@ toTransferDetails(params, from, to) {

@@ -6,3 +6,4 @@ import type { StaticRouteMethods } from "../route.js";

import { PorticoBridge, TransferState, amount } from "./../../index.js";
import { ChainAddress } from "@wormhole-foundation/sdk-definitions";
import type { ChainAddress } from "@wormhole-foundation/sdk-definitions";
import type { RouteTransferRequest } from "../request.js";
export declare const SLIPPAGE_BPS = 15n;

@@ -43,5 +44,5 @@ export declare const BPS_PER_HUNDRED_PERCENT = 10000n;

getDefaultOptions(): OP;
validate(params: TP): Promise<VR>;
quote(params: VP): Promise<QR>;
initiate(sender: Signer<N>, quote: Q, to: ChainAddress): Promise<SourceInitiatedTransferReceipt<"Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance", "Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance">>;
validate(request: RouteTransferRequest<N>, params: TP): Promise<VR>;
quote(request: RouteTransferRequest<N>, params: VP): Promise<QR>;
initiate(request: RouteTransferRequest<N>, sender: Signer<N>, quote: Q, to: ChainAddress): Promise<SourceInitiatedTransferReceipt<"Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance", "Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance">>;
track(receipt: R, timeout?: number): AsyncGenerator<{

@@ -48,0 +49,0 @@ vaa: import("@wormhole-foundation/sdk-definitions").VAA<"TokenBridge:TransferWithPayload">;

@@ -73,9 +73,9 @@ import { filters } from "@wormhole-foundation/sdk-base";

}
async validate(params) {
async validate(request, params) {
try {
if (chainToPlatform(this.request.fromChain.chain) !== "Evm" ||
chainToPlatform(this.request.toChain.chain) !== "Evm") {
if (chainToPlatform(request.fromChain.chain) !== "Evm" ||
chainToPlatform(request.toChain.chain) !== "Evm") {
throw new Error("Only EVM chains are supported");
}
const { fromChain, toChain, source, destination } = this.request;
const { fromChain, toChain, source, destination } = request;
const { network } = fromChain;

@@ -93,3 +93,3 @@ // This may be "native" but we want the token that can actually be bridged

normalizedParams: {
amount: this.request.parseAmount(params.amount),
amount: request.parseAmount(params.amount),
canonicalSourceToken,

@@ -107,6 +107,6 @@ canonicalDestinationToken,

}
async quote(params) {
async quote(request, params) {
try {
const swapAmounts = await this.quoteUniswap(params);
const pb = await this.request.toChain.getPorticoBridge();
const swapAmounts = await this.quoteUniswap(request, params);
const pb = await request.toChain.getPorticoBridge();
const fee = await pb.quoteRelay(params.normalizedParams.canonicalDestinationToken.address, params.normalizedParams.destinationToken.address);

@@ -124,3 +124,3 @@ const details = {

}
return (await this.request.displayQuote({
return (await request.displayQuote({
sourceToken: {

@@ -147,14 +147,14 @@ token: params.normalizedParams.sourceToken,

}
async initiate(sender, quote, to) {
async initiate(request, sender, quote, to) {
const { params, details } = quote;
const sourceToken = this.request.source.id.address;
const destToken = this.request.destination.id;
const fromPorticoBridge = await this.request.fromChain.getPorticoBridge();
const sourceToken = request.source.id.address;
const destToken = request.destination.id;
const fromPorticoBridge = await request.fromChain.getPorticoBridge();
const xfer = fromPorticoBridge.transfer(Wormhole.parseAddress(sender.chain(), sender.address()), to, sourceToken, amount.units(params.normalizedParams.amount), destToken, details);
const txids = await signSendWait(this.request.fromChain, xfer, sender);
const txids = await signSendWait(request.fromChain, xfer, sender);
const receipt = {
originTxs: txids,
state: TransferState.SourceInitiated,
from: this.request.fromChain.chain,
to: this.request.toChain.chain,
from: request.fromChain.chain,
to: request.toChain.chain,
};

@@ -176,9 +176,10 @@ return receipt;

throw new Error("Source must be attested");
const toPorticoBridge = await this.request.toChain.getPorticoBridge();
const toChain = await this.wh.getChain(receipt.to);
const toPorticoBridge = await toChain.getPorticoBridge();
const sender = Wormhole.chainAddress(signer.chain(), signer.address());
const xfer = toPorticoBridge.redeem(sender.address, receipt.attestation.attestation);
return await signSendWait(this.request.toChain, xfer, signer);
return await signSendWait(toChain, xfer, signer);
}
async quoteUniswap(params) {
const fromPorticoBridge = await this.request.fromChain.getPorticoBridge();
async quoteUniswap(request, params) {
const fromPorticoBridge = await request.fromChain.getPorticoBridge();
const startQuote = await fromPorticoBridge.quoteSwap(params.normalizedParams.sourceToken.address, params.normalizedParams.canonicalSourceToken.address, amount.units(params.normalizedParams.amount));

@@ -188,3 +189,3 @@ const startSlippage = (startQuote * SLIPPAGE_BPS) / BPS_PER_HUNDRED_PERCENT;

throw new Error("Start slippage too high");
const toPorticoBridge = await this.request.toChain.getPorticoBridge();
const toPorticoBridge = await request.toChain.getPorticoBridge();
const minAmountStart = startQuote - startSlippage;

@@ -191,0 +192,0 @@ const finishQuote = await toPorticoBridge.quoteSwap(params.normalizedParams.canonicalDestinationToken.address, params.normalizedParams.destinationToken.address, minAmountStart);

@@ -67,5 +67,5 @@ import { canonicalAddress, isNative, resolveWrappedToken, } from "@wormhole-foundation/sdk-definitions";

return await Promise.all(supportedRoutes.map(async (rc) => {
const route = new rc(this.wh, request);
const route = new rc(this.wh);
try {
const available = isAutomatic(route) ? await route.isAvailable() : true;
const available = isAutomatic(route) ? await route.isAvailable(request) : true;
return [route, available];

@@ -72,0 +72,0 @@ }

@@ -9,9 +9,8 @@ import type { Chain, Network } from "@wormhole-foundation/sdk-base";

wh: Wormhole<N>;
request: RouteTransferRequest<N>;
abstract readonly NATIVE_GAS_DROPOFF_SUPPORTED: boolean;
abstract readonly IS_AUTOMATIC: boolean;
constructor(wh: Wormhole<N>, request: RouteTransferRequest<N>);
abstract validate(params: TransferParams<OP>): Promise<ValidationResult<OP>>;
abstract quote(params: ValidatedTransferParams<OP>): Promise<QuoteResult<OP, VP>>;
abstract initiate(sender: Signer, quote: Quote<OP, VP>, to: ChainAddress): Promise<R>;
constructor(wh: Wormhole<N>);
abstract validate(request: RouteTransferRequest<N>, params: TransferParams<OP>): Promise<ValidationResult<OP>>;
abstract quote(request: RouteTransferRequest<N>, params: ValidatedTransferParams<OP>): Promise<QuoteResult<OP, VP>>;
abstract initiate(request: RouteTransferRequest<N>, sender: Signer, quote: Quote<OP, VP>, to: ChainAddress): Promise<R>;
abstract track(receipt: R, timeout?: number): AsyncGenerator<R>;

@@ -28,3 +27,3 @@ transferUrl(txid: string): string;

export interface RouteConstructor<OP extends Options = Options> {
new <N extends Network>(wh: Wormhole<N>, request: RouteTransferRequest<N>): Route<N, OP>;
new <N extends Network>(wh: Wormhole<N>): Route<N, OP>;
/** Details about the route provided by the implementation */

@@ -40,3 +39,3 @@ readonly meta: RouteMeta;

supportedSourceTokens(fromChain: ChainContext<Network>): Promise<TokenId[]>;
/** get the list of destination tokens that may be recieved on the destination chain */
/** get the list of destination tokens that may be received on the destination chain */
supportedDestinationTokens<N extends Network>(token: TokenId, fromChain: ChainContext<N>, toChain: ChainContext<N>): Promise<TokenId[]>;

@@ -51,3 +50,3 @@ }

IS_AUTOMATIC: boolean;
abstract isAvailable(): Promise<boolean>;
abstract isAvailable(request: RouteTransferRequest<N>): Promise<boolean>;
}

@@ -54,0 +53,0 @@ export declare function isAutomatic<N extends Network>(route: Route<N>): route is AutomaticRoute<N>;

export class Route {
wh;
request;
constructor(wh, request) {
constructor(wh) {
this.wh = wh;
this.request = request;
}

@@ -8,0 +6,0 @@ // Get the url to view the transfer on the explorer for the route provider

import type { Chain, Network } from "@wormhole-foundation/sdk-base";
import { amount } from "@wormhole-foundation/sdk-base";
import type { ChainContext, Signer, TokenId } from "@wormhole-foundation/sdk-definitions";
import { ChainAddress } from "@wormhole-foundation/sdk-definitions";
import type { ChainAddress, ChainContext, Signer, TokenId } from "@wormhole-foundation/sdk-definitions";
import { TokenTransfer } from "../../protocols/tokenBridge/tokenTransfer.js";

@@ -10,2 +9,3 @@ import type { AttestationReceipt } from "../../types.js";

import type { Quote, QuoteResult, Receipt, TransferParams, ValidatedTransferParams, ValidationResult } from "../types.js";
import type { RouteTransferRequest } from "../request.js";
export declare namespace AutomaticTokenBridgeRoute {

@@ -42,7 +42,7 @@ type Options = {

getDefaultOptions(): Op;
isAvailable(): Promise<boolean>;
validate(params: Tp): Promise<Vr>;
isAvailable(request: RouteTransferRequest<N>): Promise<boolean>;
validate(request: RouteTransferRequest<N>, params: Tp): Promise<Vr>;
private normalizeTransferParams;
quote(params: Vp): Promise<QR>;
initiate(signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
quote(request: RouteTransferRequest<N>, params: Vp): Promise<QR>;
initiate(request: RouteTransferRequest<N>, signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
track(receipt: R, timeout?: number): AsyncGenerator<TokenTransfer.TransferReceipt<"Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance", "Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance">, void, unknown>;

@@ -49,0 +49,0 @@ private toTransferDetails;

import { amount, contracts } from "@wormhole-foundation/sdk-base";
import { isNative, isTokenId, nativeTokenId, } from "@wormhole-foundation/sdk-definitions";
import { isNative, isTokenId, nativeTokenId } from "@wormhole-foundation/sdk-definitions";
import { TokenTransfer } from "../../protocols/tokenBridge/tokenTransfer.js";

@@ -33,3 +33,3 @@ import { TransferState } from "../../types.js";

}
// get the list of destination tokens that may be recieved on the destination chain
// get the list of destination tokens that may be received on the destination chain
static async supportedDestinationTokens(sourceToken, fromChain, toChain) {

@@ -56,10 +56,10 @@ try {

}
async isAvailable() {
const atb = await this.request.fromChain.getAutomaticTokenBridge();
if (isTokenId(this.request.source.id)) {
return await atb.isRegisteredToken(this.request.source.id.address);
async isAvailable(request) {
const atb = await request.fromChain.getAutomaticTokenBridge();
if (isTokenId(request.source.id)) {
return await atb.isRegisteredToken(request.source.id.address);
}
return true;
}
async validate(params) {
async validate(request, params) {
try {

@@ -69,10 +69,10 @@ const options = params.options ?? this.getDefaultOptions();

throw new Error("Native gas must be between 0.0 and 1.0 (0% and 100%)");
// If destination is native, max out the nativeGas requested
const { destination } = this.request;
// native gas drop-off when the native token is the destination should be 0
const { destination } = request;
if (isNative(destination.id.address) && options.nativeGas === 0.0)
options.nativeGas = 1.0;
options.nativeGas = 0;
const updatedParams = { ...params, options };
const validatedParams = {
...updatedParams,
normalizedParams: await this.normalizeTransferParams(updatedParams),
normalizedParams: await this.normalizeTransferParams(request, updatedParams),
};

@@ -85,9 +85,9 @@ return { valid: true, params: validatedParams };

}
async normalizeTransferParams(params) {
const amt = this.request.parseAmount(params.amount);
const inputToken = isNative(this.request.source.id.address)
? await this.request.fromChain.getNativeWrappedTokenId()
: this.request.source.id;
const atb = await this.request.fromChain.getAutomaticTokenBridge();
const fee = await atb.getRelayerFee(this.request.toChain.chain, inputToken.address);
async normalizeTransferParams(request, params) {
const amt = request.parseAmount(params.amount);
const inputToken = isNative(request.source.id.address)
? await request.fromChain.getNativeWrappedTokenId()
: request.source.id;
const atb = await request.fromChain.getAutomaticTokenBridge();
const fee = await atb.getRelayerFee(request.toChain.chain, inputToken.address);
// Min amount is fee + 5%

@@ -102,24 +102,33 @@ const minAmount = (fee * 105n) / 100n;

const redeemableAmount = amount.units(amt) - fee;
// Determine nativeGas
let nativeGasAmount = 0n;
let srcNativeGasAmount = amount.fromBaseUnits(0n, request.source.decimals);
if (params.options && params.options.nativeGas > 0) {
const dtb = await request.toChain.getAutomaticTokenBridge();
// the maxSwapAmount is in destination chain decimals
const maxSwapAmount = await dtb.maxSwapAmount(request.destination.id.address);
const scale = 10000;
const scaledGas = BigInt(params.options.nativeGas * scale);
nativeGasAmount = (redeemableAmount * scaledGas) / BigInt(scale);
const scaledGasPercent = BigInt(Math.floor(params.options.nativeGas * scale));
const dstNativeGasUnits = (maxSwapAmount * scaledGasPercent) / BigInt(scale);
const dstNativeGasAmount = amount.fromBaseUnits(dstNativeGasUnits, request.destination.decimals);
// convert the native gas amount to source chain decimals
srcNativeGasAmount = amount.scale(amount.truncate(dstNativeGasAmount, TokenTransfer.MAX_DECIMALS), request.source.decimals);
// can't request more gas than the redeemable amount
if (amount.units(srcNativeGasAmount) > redeemableAmount) {
srcNativeGasAmount = amount.fromBaseUnits(redeemableAmount, request.source.decimals);
}
}
return {
fee: amount.fromBaseUnits(fee, this.request.source.decimals),
fee: amount.fromBaseUnits(fee, request.source.decimals),
amount: amt,
nativeGasAmount: amount.fromBaseUnits(nativeGasAmount, this.request.source.decimals),
nativeGasAmount: srcNativeGasAmount,
};
}
async quote(params) {
async quote(request, params) {
try {
let quote = await TokenTransfer.quoteTransfer(this.wh, this.request.fromChain, this.request.toChain, {
let quote = await TokenTransfer.quoteTransfer(this.wh, request.fromChain, request.toChain, {
automatic: true,
amount: amount.units(params.normalizedParams.amount),
token: this.request.source.id,
token: request.source.id,
nativeGas: amount.units(params.normalizedParams.nativeGasAmount),
});
return this.request.displayQuote(quote, params);
return request.displayQuote(quote, params);
}

@@ -133,6 +142,6 @@ catch (e) {

}
async initiate(signer, quote, to) {
async initiate(request, signer, quote, to) {
const { params } = quote;
const transfer = this.toTransferDetails(params, Wormhole.chainAddress(signer.chain(), signer.address()), to);
const txids = await TokenTransfer.transfer(this.request.fromChain, transfer, signer);
const transfer = this.toTransferDetails(request, params, Wormhole.chainAddress(signer.chain(), signer.address()), to);
const txids = await TokenTransfer.transfer(request.fromChain, transfer, signer);
return {

@@ -147,3 +156,3 @@ from: transfer.from.chain,

try {
yield* TokenTransfer.track(this.wh, receipt, timeout, this.request.fromChain, this.request.toChain);
yield* TokenTransfer.track(this.wh, receipt, timeout);
}

@@ -154,3 +163,3 @@ catch (e) {

}
toTransferDetails(params, from, to) {
toTransferDetails(request, params, from, to) {
const transfer = {

@@ -161,3 +170,3 @@ from,

amount: amount.units(params.normalizedParams.amount),
token: this.request.source.id,
token: request.source.id,
nativeGas: amount.units(params.normalizedParams.nativeGasAmount),

@@ -164,0 +173,0 @@ };

import type { Chain, Network } from "@wormhole-foundation/sdk-base";
import { amount } from "@wormhole-foundation/sdk-base";
import type { ChainContext, Signer, TokenId } from "@wormhole-foundation/sdk-definitions";
import type { ChainAddress, ChainContext, Signer, TokenId } from "@wormhole-foundation/sdk-definitions";
import { TokenTransfer } from "../../protocols/tokenBridge/tokenTransfer.js";

@@ -9,3 +9,3 @@ import type { AttestationReceipt, TransferReceipt } from "../../types.js";

import type { Quote, QuoteResult, TransferParams, ValidatedTransferParams, ValidationResult } from "../types.js";
import { ChainAddress } from "@wormhole-foundation/sdk-definitions";
import type { RouteTransferRequest } from "../request.js";
export declare namespace TokenBridgeRoute {

@@ -39,5 +39,5 @@ type Options = {

getDefaultOptions(): Op;
validate(params: Tp): Promise<Vr>;
quote(params: Vp): Promise<QR>;
initiate(signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
validate(request: RouteTransferRequest<N>, params: Tp): Promise<Vr>;
quote(request: RouteTransferRequest<N>, params: Vp): Promise<QR>;
initiate(request: RouteTransferRequest<N>, signer: Signer, quote: Q, to: ChainAddress): Promise<R>;
complete(signer: Signer, receipt: R): Promise<R>;

@@ -44,0 +44,0 @@ track(receipt: R, timeout?: number): AsyncGenerator<TokenTransfer.TransferReceipt<"Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance", "Solana" | "Btc" | "Algorand" | "Sui" | "Aptos" | "Near" | "Acala" | "Arbitrum" | "Aurora" | "Avalanche" | "Base" | "Bsc" | "Celo" | "Ethereum" | "Fantom" | "Gnosis" | "Karura" | "Klaytn" | "Moonbeam" | "Neon" | "Oasis" | "Optimism" | "Polygon" | "Rootstock" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky" | "PolygonSepolia" | "Mantle" | "Scroll" | "Blast" | "Xlayer" | "Linea" | "Berachain" | "Seievm" | "Pythnet" | "Cosmoshub" | "Evmos" | "Injective" | "Kujira" | "Osmosis" | "Sei" | "Terra" | "Terra2" | "Wormchain" | "Xpla" | "Dymension" | "Neutron" | "Stargaze" | "Celestia" | "Seda" | "Provenance">, void, unknown>;

@@ -22,3 +22,3 @@ import { amount, contracts } from "@wormhole-foundation/sdk-base";

}
// get the liist of destination tokens that may be recieved on the destination chain
// get the list of destination tokens that may be received on the destination chain
static async supportedDestinationTokens(sourceToken, fromChain, toChain) {

@@ -39,4 +39,4 @@ try {

}
async validate(params) {
const amt = amount.parse(params.amount, this.request.source.decimals);
async validate(request, params) {
const amt = amount.parse(params.amount, request.source.decimals);
const validatedParams = {

@@ -49,6 +49,6 @@ amount: params.amount,

}
async quote(params) {
async quote(request, params) {
try {
return this.request.displayQuote(await TokenTransfer.quoteTransfer(this.wh, this.request.fromChain, this.request.toChain, {
token: this.request.source.id,
return request.displayQuote(await TokenTransfer.quoteTransfer(this.wh, request.fromChain, request.toChain, {
token: request.source.id,
amount: amount.units(params.normalizedParams.amount),

@@ -65,6 +65,6 @@ ...params.options,

}
async initiate(signer, quote, to) {
async initiate(request, signer, quote, to) {
const { params } = quote;
const transfer = await TokenTransfer.destinationOverrides(this.request.fromChain, this.request.toChain, this.toTransferDetails(params, Wormhole.chainAddress(signer.chain(), signer.address()), to));
const txids = await TokenTransfer.transfer(this.request.fromChain, transfer, signer);
const transfer = await TokenTransfer.destinationOverrides(request.fromChain, request.toChain, this.toTransferDetails(request, params, Wormhole.chainAddress(signer.chain(), signer.address()), to));
const txids = await TokenTransfer.transfer(request.fromChain, transfer, signer);
return {

@@ -80,3 +80,4 @@ from: transfer.from.chain,

throw new Error("The source must be finalized in order to complete the transfer");
const dstTxIds = await TokenTransfer.redeem(this.request.toChain, receipt.attestation.attestation, signer);
const toChain = this.wh.getChain(receipt.to);
const dstTxIds = await TokenTransfer.redeem(toChain, receipt.attestation.attestation, signer);
return {

@@ -89,9 +90,9 @@ ...receipt,

async *track(receipt, timeout) {
yield* TokenTransfer.track(this.wh, receipt, timeout, this.request.fromChain, this.request.toChain);
yield* TokenTransfer.track(this.wh, receipt, timeout);
}
toTransferDetails(params, from, to) {
toTransferDetails(request, params, from, to) {
return {
from,
to,
token: this.request.source.id,
token: request.source.id,
amount: amount.units(params.normalizedParams.amount),

@@ -98,0 +99,0 @@ ...params.options,

{
"name": "@wormhole-foundation/sdk-connect",
"version": "0.7.2",
"version": "0.7.3-beta.0",
"repository": {

@@ -101,6 +101,6 @@ "type": "git",

"axios": "^1.4.0",
"@wormhole-foundation/sdk-base": "0.7.2",
"@wormhole-foundation/sdk-definitions": "0.7.2"
"@wormhole-foundation/sdk-base": "0.7.3-beta.0",
"@wormhole-foundation/sdk-definitions": "0.7.3-beta.0"
},
"type": "module"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc