@wormhole-foundation/connect-sdk
Advanced tools
Comparing version 0.4.3 to 0.4.4-beta.0
@@ -1,3 +0,3 @@ | ||
import { Network } from "@wormhole-foundation/sdk-base"; | ||
import { AttestationId, GatewayTransferDetails, IbcTransferInfo, Signer, TokenBridge, TransactionId, TxHash, WormholeMessageId } from "@wormhole-foundation/sdk-definitions"; | ||
import { Chain, Network } from "@wormhole-foundation/sdk-base"; | ||
import { AttestationId, ChainContext, GatewayTransferDetails, IbcTransferInfo, Signer, TokenBridge, TokenId, TransactionId, TxHash, WormholeMessageId } from "@wormhole-foundation/sdk-definitions"; | ||
import { TransferState } from "../types"; | ||
@@ -35,2 +35,4 @@ import { Wormhole } from "../wormhole"; | ||
static getTransferVaa<N extends Network>(wh: Wormhole<N>, whm: WormholeMessageId, timeout?: number): Promise<TokenBridge.TransferVAA>; | ||
static destinationOverrides<N extends Network>(srcChain: ChainContext<N>, dstChain: ChainContext<N>, gatewayChain: ChainContext<N, "Wormchain">, transfer: GatewayTransferDetails): Promise<GatewayTransferDetails>; | ||
static lookupDestinationToken<N extends Network, SC extends Chain, DC extends Chain>(srcChain: ChainContext<N, SC>, dstChain: ChainContext<N, DC>, gatewayChain: ChainContext<N, "Wormchain">, token: TokenId<SC>): Promise<TokenId<DC>>; | ||
private fromGateway; | ||
@@ -37,0 +39,0 @@ private toGateway; |
@@ -59,2 +59,7 @@ "use strict"; | ||
if ((0, sdk_definitions_1.isGatewayTransferDetails)(from)) { | ||
const fromChain = wh.getChain(from.from.chain); | ||
const toChain = wh.getChain(from.to.chain); | ||
const overrides = await GatewayTransfer.destinationOverrides(fromChain, toChain, wc, from); | ||
// Override transfer params if necessary | ||
from = { ...from, ...overrides }; | ||
return new GatewayTransfer(wh, from, wc, wcibc); | ||
@@ -135,34 +140,26 @@ } | ||
const originChain = wh.getChain(chain); | ||
// If its origin chain is Cosmos, it should be an IBC message | ||
// but its not all the time so do this differently? | ||
// TODO: check if the chain supports Gateway protocol? | ||
if ((0, sdk_base_1.chainToPlatform)(chain) === "Cosmwasm") { | ||
// If its origin chain supports IBC, it should be an IBC message | ||
if (originChain.supportsIbcBridge()) { | ||
// Get the ibc tx info from the origin | ||
const ibcBridge = await originChain.getIbcBridge(); | ||
const xfer = await ibcBridge.lookupTransferFromTx(from.txid); | ||
const [xfer] = await ibcBridge.lookupTransferFromTx(from.txid); | ||
return GatewayTransfer.ibcTransfertoGatewayTransfer(xfer); | ||
} | ||
// Otherwise grab the vaa details from the origin tx | ||
const [whMsgId] = await originChain.parseTransaction(txid); | ||
return await GatewayTransfer._fromMsgId(wh, whMsgId, timeout); | ||
const msgs = await wormhole_1.Wormhole.parseMessageFromTx(originChain, txid); | ||
if (!msgs) | ||
throw new Error("No messages found in transaction"); | ||
return await GatewayTransfer._fromMsgId(wh, msgs[0], timeout); | ||
} | ||
// Recover transfer info the first step in the transfer | ||
static ibcTransfertoGatewayTransfer(xfer) { | ||
const token = { | ||
chain: xfer.id.chain, | ||
address: (0, sdk_definitions_1.toNative)(xfer.id.chain, xfer.data.denom), | ||
}; | ||
const token = wormhole_1.Wormhole.tokenId(xfer.id.chain, xfer.data.denom); | ||
const msg = (0, sdk_definitions_1.toGatewayMsg)(xfer.data.memo); | ||
const destChain = (0, sdk_base_1.toChain)(msg.chain); | ||
const _recip = sdk_base_1.encoding.b64.valid(msg.recipient) | ||
? sdk_base_1.encoding.bytes.decode(sdk_base_1.encoding.b64.decode(msg.recipient)) | ||
: msg.recipient; | ||
const _recip = sdk_base_1.encoding.b64.decode(msg.recipient); | ||
const recipient = (0, sdk_base_1.chainToPlatform)(destChain) === "Cosmwasm" | ||
? { | ||
chain: destChain, | ||
address: (0, sdk_definitions_1.toNative)(destChain, _recip.toString()), | ||
} | ||
? wormhole_1.Wormhole.chainAddress(destChain, sdk_base_1.encoding.bytes.decode(_recip)) | ||
: { | ||
chain: destChain, | ||
address: (0, sdk_definitions_1.toNative)(destChain, new sdk_definitions_1.UniversalAddress(_recip)), | ||
address: new sdk_definitions_1.UniversalAddress(_recip).toNative(destChain), | ||
}; | ||
@@ -217,4 +214,2 @@ const payload = msg.payload ? sdk_base_1.encoding.bytes.encode(msg.payload) : undefined; | ||
} | ||
// TODO: track the time elapsed and subtract it from the timeout passed with | ||
// successive updates | ||
// wait for the Attestations to be ready | ||
@@ -256,6 +251,15 @@ async fetchAttestation(timeout) { | ||
// Otherwise we need to get the transfer on the destination chain | ||
// using the transfer from wormchain | ||
const gatewayTransferTask = () => (0, tasks_1.fetchIbcXfer)(this.gatewayIbcBridge, xfer.id); | ||
const gatewayIbcTransfers = await (0, tasks_1.retry)(gatewayTransferTask, 5000, timeout, "Gateway:IbcBridge:LookupWormchainIbcTransfer"); | ||
if (gatewayIbcTransfers === null) | ||
throw new Error("Gateway IBC transfer not found after retries exhausted"); | ||
const toDestChainIbcTransfer = gatewayIbcTransfers[1]; | ||
const dstChain = this.wh.getChain(this.transfer.to.chain); | ||
const dstIbcBridge = await dstChain.getIbcBridge(); | ||
const ibcXfer = await dstIbcBridge.lookupTransferFromIbcMsgId(xfer.id); | ||
this.ibcTransfers.push(ibcXfer); | ||
const dstMsgTask = () => (0, tasks_1.fetchIbcXfer)(dstIbcBridge, toDestChainIbcTransfer.id); | ||
const dstIbcTransfers = await (0, tasks_1.retry)(dstMsgTask, 5000, timeout, "Gateway:IbcBridge:LookupDestinationIbcTransfer"); | ||
if (!dstIbcTransfers) | ||
throw new Error("Destination IBC transfer not found after retries exhausted"); | ||
this.ibcTransfers.push(dstIbcTransfers[0]); | ||
} | ||
@@ -290,5 +294,6 @@ } | ||
const wcTransferTask = () => (0, tasks_1.fetchIbcXfer)(this.gatewayIbcBridge, this.msg); | ||
const wcTransfer = await (0, tasks_1.retry)(wcTransferTask, vaaRedeemedRetryInterval, timeout, "Gateway:IbcBridge:WormchainTransferInitiated"); | ||
if (!wcTransfer) | ||
const wcTransfers = await (0, tasks_1.retry)(wcTransferTask, vaaRedeemedRetryInterval, timeout, "Gateway:IbcBridge:WormchainTransferInitiated"); | ||
if (!wcTransfers) | ||
throw new Error("Wormchain transfer not found after retries exhausted"); | ||
const [wcTransfer] = wcTransfers; | ||
if (wcTransfer.pending) { | ||
@@ -301,3 +306,2 @@ // TODO: check if pending and bail(?) if so | ||
const destIbcBridge = await destChain.getIbcBridge(); | ||
//@ts-ignore | ||
const destTransferTask = () => (0, tasks_1.fetchIbcXfer)(destIbcBridge, wcTransfer.id); | ||
@@ -307,4 +311,4 @@ const destTransfer = await (0, tasks_1.retry)(destTransferTask, transferCompleteInterval, timeout, "Destination:IbcBridge:WormchainTransferCompleted"); | ||
throw new Error("IBC Transfer into destination not found after retries exhausted" + | ||
JSON.stringify(wcTransfer.id)); | ||
this.ibcTransfers.push(destTransfer); | ||
JSON.stringify(wcTransfer)); | ||
this.ibcTransfers.push(destTransfer[0]); | ||
} | ||
@@ -335,7 +339,4 @@ // Add transfers to attestations we return | ||
throw new Error("Expected 1 vaa"); | ||
const { chain, address } = this.transfer.to; | ||
const toChain = this.wh.getChain(chain); | ||
// TODO: these could be different, but when? | ||
//const signerAddress = toNative(signer.chain(), signer.address()); | ||
const toAddress = address.toUniversalAddress(); | ||
const toChain = this.wh.getChain(signer.chain()); | ||
const toAddress = (0, sdk_definitions_1.toNative)(signer.chain(), signer.address()); | ||
const tb = await toChain.getTokenBridge(); | ||
@@ -357,2 +358,47 @@ const { vaa } = this.vaas[0]; | ||
} | ||
static async destinationOverrides(srcChain, dstChain, gatewayChain, transfer) { | ||
const _transfer = { ...transfer }; | ||
// Bit of (temporary) hackery until solana contracts support being | ||
// sent a VAA with the primary address | ||
if (transfer.to.chain === "Solana") { | ||
const destinationToken = await GatewayTransfer.lookupDestinationToken(srcChain, dstChain, gatewayChain, _transfer.token); | ||
_transfer.to = await dstChain.getTokenAccount(_transfer.to.address, destinationToken.address); | ||
} | ||
return _transfer; | ||
} | ||
// Lookup the token id for the destination chain given the source chain | ||
// and token id | ||
static async lookupDestinationToken(srcChain, dstChain, gatewayChain, token) { | ||
// that will be minted when the transfer is redeemed | ||
let lookup; | ||
if ((0, sdk_definitions_1.isNative)(token.address)) { | ||
// if native, get the wrapped asset id | ||
lookup = await srcChain.getNativeWrappedTokenId(); | ||
} | ||
else { | ||
try { | ||
// otherwise, check to see if it is a wrapped token locally | ||
const tb = await srcChain.getTokenBridge(); | ||
lookup = await tb.getOriginalAsset(token.address); | ||
} | ||
catch (e) { | ||
// not a from-chain native token, check the gateway chain | ||
try { | ||
const gtb = await gatewayChain.getTokenBridge(); | ||
lookup = await gtb.getOriginalAsset(token.address); | ||
} | ||
catch (e) { | ||
lookup = token; | ||
} | ||
} | ||
} | ||
// if the token id is actually native to the destination, return it | ||
if (lookup.chain === dstChain.chain) { | ||
return lookup; | ||
} | ||
// otherwise, figure out what the token address representing the wormhole-wrapped token we're transferring | ||
const dstTb = await dstChain.getTokenBridge(); | ||
const dstAddress = await dstTb.getWrappedAsset(lookup); | ||
return { chain: dstChain.chain, address: dstAddress }; | ||
} | ||
// Implicitly determine if the chain is Gateway enabled by | ||
@@ -359,0 +405,0 @@ // checking to see if the Gateway IBC bridge has a transfer channel setup |
@@ -35,3 +35,3 @@ import { Chain, Network } from "@wormhole-foundation/sdk-base"; | ||
static validateTransferDetails<N extends Network>(wh: Wormhole<N>, transfer: TokenTransferDetails, fromChain?: ChainContext<N, Chain>, toChain?: ChainContext<N, Chain>): void; | ||
static quoteTransfer<N extends Network>(srcChain: ChainContext<N, Chain>, dstChain: ChainContext<N, Chain>, transfer: TokenTransferDetails): Promise<TransferQuote>; | ||
static quoteTransfer<N extends Network>(wh: Wormhole<N>, srcChain: ChainContext<N, Chain>, dstChain: ChainContext<N, Chain>, transfer: TokenTransferDetails): Promise<TransferQuote>; | ||
static destinationOverrides<N extends Network>(srcChain: ChainContext<N, Chain>, dstChain: ChainContext<N, Chain>, transfer: TokenTransferDetails): Promise<TokenTransferDetails>; | ||
@@ -38,0 +38,0 @@ static getReceipt<N extends Network>(xfer: TokenTransfer<N>): TokenTransferReceipt; |
@@ -9,2 +9,3 @@ "use strict"; | ||
const types_1 = require("../types"); | ||
const whscan_api_1 = require("../whscan-api"); | ||
const wormhole_1 = require("../wormhole"); | ||
@@ -257,11 +258,30 @@ // 8 is maximum precision supported by the token bridge VAA | ||
} | ||
static async quoteTransfer(srcChain, dstChain, transfer) { | ||
const dstToken = await this.lookupDestinationToken(srcChain, dstChain, transfer.token); | ||
static async quoteTransfer(wh, srcChain, dstChain, transfer) { | ||
const srcDecimals = await srcChain.getDecimals(transfer.token.address); | ||
const srcAmount = sdk_base_1.amount.fromBaseUnits(transfer.amount, srcDecimals); | ||
const srcAmountTruncated = sdk_base_1.amount.truncate(srcAmount, TOKEN_BRIDGE_MAX_DECIMALS); | ||
const srcToken = (0, sdk_definitions_1.isNative)(transfer.token.address) | ||
? await srcChain.getNativeWrappedTokenId() | ||
: transfer.token; | ||
const srcDecimals = await srcChain.getDecimals(srcToken.address); | ||
const srcTokenUniversalAddress = (0, sdk_definitions_1.universalAddress)(srcToken); | ||
// Ensure the transfer would not violate governor transfer limits | ||
const [tokens, limits] = await Promise.all([ | ||
(0, whscan_api_1.getGovernedTokens)(wh.config.api), | ||
(0, whscan_api_1.getGovernorLimits)(wh.config.api), | ||
]); | ||
if (limits !== null && | ||
srcChain.chain in limits && | ||
tokens !== null && | ||
srcChain.chain in tokens && | ||
srcTokenUniversalAddress in tokens[srcChain.chain]) { | ||
const limit = limits[srcChain.chain]; | ||
const tokenPrice = tokens[srcChain.chain][srcTokenUniversalAddress]; | ||
const notionalTransferAmt = tokenPrice * sdk_base_1.amount.whole(srcAmountTruncated); | ||
if (limit.maxSize && notionalTransferAmt > limit.maxSize) | ||
throw new Error(`Transfer amount exceeds maximum size: ${notionalTransferAmt} > ${limit.maxSize}`); | ||
if (notionalTransferAmt > limit.available) | ||
throw new Error(`Transfer amount exceeds available governed amount: ${notionalTransferAmt} > ${limit.available}`); | ||
} | ||
const dstToken = await this.lookupDestinationToken(srcChain, dstChain, transfer.token); | ||
const dstDecimals = await dstChain.getDecimals(dstToken.address); | ||
const srcAmount = sdk_base_1.amount.fromBaseUnits(transfer.amount, srcDecimals); | ||
const srcAmountTruncated = sdk_base_1.amount.truncate(srcAmount, TOKEN_BRIDGE_MAX_DECIMALS); | ||
const dstAmountReceivable = sdk_base_1.amount.scale(srcAmountTruncated, dstDecimals); | ||
@@ -280,3 +300,3 @@ if (!transfer.automatic) { | ||
const feeAmountDest = sdk_base_1.amount.scale(sdk_base_1.amount.truncate(sdk_base_1.amount.fromBaseUnits(fee, srcDecimals), TOKEN_BRIDGE_MAX_DECIMALS), dstDecimals); | ||
let dstNativeGasAmountRequested = transfer.nativeGas ?? 0n; | ||
const dstNativeGasAmountRequested = transfer.nativeGas ?? 0n; | ||
// The expected destination gas can be pulled from the destination token bridge | ||
@@ -288,9 +308,10 @@ let destinationNativeGas = 0n; | ||
// token that may be swapped for native gas on the destination | ||
const maxNativeAmountIn = await dtb.maxSwapAmount(dstToken.address); | ||
dstNativeGasAmountRequested = | ||
dstNativeGasAmountRequested > maxNativeAmountIn | ||
? maxNativeAmountIn | ||
: dstNativeGasAmountRequested; | ||
// Get the actual amount we should receive | ||
destinationNativeGas = await dtb.nativeTokenAmount(dstToken.address, dstNativeGasAmountRequested); | ||
const [maxNativeAmountIn, _destinationNativeGas] = await Promise.all([ | ||
dtb.maxSwapAmount(dstToken.address), | ||
// Get the actual amount we should receive | ||
dtb.nativeTokenAmount(dstToken.address, dstNativeGasAmountRequested), | ||
]); | ||
if (dstNativeGasAmountRequested > maxNativeAmountIn) | ||
throw new Error(`Native gas amount exceeds maximum swap amount: ${sdk_base_1.amount.fmt(dstNativeGasAmountRequested, dstDecimals)}>${sdk_base_1.amount.fmt(maxNativeAmountIn, dstDecimals)}`); | ||
destinationNativeGas = _destinationNativeGas; | ||
} | ||
@@ -297,0 +318,0 @@ const destAmountLessFee = sdk_base_1.amount.units(dstAmountReceivable) - dstNativeGasAmountRequested - sdk_base_1.amount.units(feeAmountDest); |
@@ -43,5 +43,5 @@ import { Chain, Network, amount } from "@wormhole-foundation/sdk-base"; | ||
initiate(signer: Signer, quote: Q): Promise<R>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/cctpTransfer").CircleTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/cctpTransfer").CircleTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
} | ||
export {}; | ||
//# sourceMappingURL=automatic.d.ts.map |
@@ -39,3 +39,3 @@ import { Chain, Network, amount } from "@wormhole-foundation/sdk-base"; | ||
complete(signer: Signer, receipt: R): Promise<TransactionId[]>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/cctpTransfer").CircleTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/cctpTransfer").CircleTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
private toTransferDetails; | ||
@@ -42,0 +42,0 @@ } |
@@ -5,3 +5,10 @@ import { Network } from "@wormhole-foundation/sdk-base"; | ||
import { Route } from "./route"; | ||
export declare function checkAndCompleteTransfer<N extends Network>(route: Route<N>, receipt: Receipt, destinationSigner: Signer<N>): Promise<void>; | ||
/** | ||
* track the transfer until the destination is initiated | ||
* | ||
* @param route The route that can be used to track the receipt | ||
* @param receipt The receipt to track | ||
* @param destinationSigner The signer for the destination chain if | ||
*/ | ||
export declare function checkAndCompleteTransfer<N extends Network>(route: Route<N>, receipt: Receipt, destinationSigner?: Signer<N>, timeout?: number, log?: typeof console.log): Promise<import("../types").CreatedTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"> | import("../types").SourceInitiatedTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"> | import("../types").FailedTransferReceipt<import("../types").AttestationReceipt, "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"> | import("../types").SourceFinalizedTransferReceipt<import("../types").AttestationReceipt, "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"> | import("../types").AttestedTransferReceipt<import("../types").AttestationReceipt, "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"> | import("../types").CompletedTransferReceipt<import("../types").AttestationReceipt, "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">>; | ||
//# sourceMappingURL=common.d.ts.map |
@@ -6,25 +6,41 @@ "use strict"; | ||
const types_1 = require("../types"); | ||
// TODO: take out logs | ||
// track the transfer until the destination is initiated | ||
async function checkAndCompleteTransfer(route, receipt, destinationSigner) { | ||
console.log("Checking transfer state..."); | ||
/** | ||
* track the transfer until the destination is initiated | ||
* | ||
* @param route The route that can be used to track the receipt | ||
* @param receipt The receipt to track | ||
* @param destinationSigner The signer for the destination chain if | ||
*/ | ||
async function checkAndCompleteTransfer(route, receipt, destinationSigner, timeout = 120 * 1000, | ||
// byo logger but im dumping to console rn 🙃 | ||
log = console.log) { | ||
const start = Date.now(); | ||
log("Checking transfer state..."); | ||
// overwrite receipt var as we receive updates, will return when it's complete | ||
// but can be called again if the destination is not finalized | ||
// this construct is to drain an async generator and return the last value | ||
for await (receipt of route.track(receipt, 120 * 1000)) { | ||
console.log("Transfer State:", types_1.TransferState[receipt.state]); | ||
log("Current Transfer State: ", types_1.TransferState[receipt.state]); | ||
} | ||
// gucci | ||
if ((0, types_1.isCompleted)(receipt)) | ||
return; | ||
return receipt; | ||
// if the route is one we need to complete, do it | ||
if ((0, route_1.isManual)(route) && (0, types_1.isAttested)(receipt)) { | ||
if ((0, route_1.isManual)(route) && (0, types_1.isAttested)(receipt) && destinationSigner) { | ||
const completedTxids = await route.complete(destinationSigner, receipt); | ||
console.log("Completed transfer with txids: ", completedTxids); | ||
log("Completed transfer with txids: ", completedTxids); | ||
// Note: do not return receipt yet, there may be further steps to track, this only completes the bridge transfer | ||
} | ||
// give it time to breath and try again | ||
const wait = 2 * 1000; | ||
console.log(`Transfer not complete, trying again in a ${wait}ms...`); | ||
setTimeout(() => checkAndCompleteTransfer(route, receipt, destinationSigner), wait); | ||
const leftover = timeout - (Date.now() - start); | ||
// do we still have time? | ||
if (leftover > 0) { | ||
// give it a second, computers need to rest sometimes | ||
const wait = 2 * 1000; | ||
log(`Transfer not complete, trying again in a ${wait}ms...`); | ||
await Promise.resolve(setTimeout(() => { }, wait)); | ||
return checkAndCompleteTransfer(route, receipt, destinationSigner, leftover); | ||
} | ||
return receipt; | ||
} | ||
exports.checkAndCompleteTransfer = checkAndCompleteTransfer; | ||
//# sourceMappingURL=common.js.map |
@@ -41,3 +41,3 @@ import { AttestationReceipt, Chain, ChainContext, Network, PorticoBridge, Signer, SourceInitiatedTransferReceipt, TokenId, TransactionId, TransferState, amount } from "../.."; | ||
quote(params: VP): Promise<QR>; | ||
initiate(sender: Signer<N>, quote: Q): Promise<SourceInitiatedTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">>; | ||
initiate(sender: Signer<N>, quote: Q): Promise<SourceInitiatedTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<{ | ||
@@ -61,5 +61,5 @@ vaa: import("@wormhole-foundation/sdk-definitions/dist/esm/vaa/vaa").VAA<"TokenBridge:TransferWithPayload">; | ||
state: TransferState.SourceInitiated; | ||
originTxs: TransactionId<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">[]; | ||
from: "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"; | ||
to: "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"; | ||
originTxs: TransactionId<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">[]; | ||
from: "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"; | ||
to: "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"; | ||
}, void, unknown>; | ||
@@ -66,0 +66,0 @@ complete(signer: Signer<N>, receipt: R): Promise<TransactionId[]>; |
@@ -42,3 +42,3 @@ import { Chain, Network, amount } from "@wormhole-foundation/sdk-base"; | ||
initiate(signer: Signer, quote: Q): Promise<R>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/tokenTransfer").TokenTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/tokenTransfer").TokenTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
private toTransferDetails; | ||
@@ -45,0 +45,0 @@ } |
@@ -103,3 +103,3 @@ "use strict"; | ||
try { | ||
let quote = await tokenTransfer_1.TokenTransfer.quoteTransfer(this.request.fromChain, this.request.toChain, this.toTransferDetails(params)); | ||
let quote = await tokenTransfer_1.TokenTransfer.quoteTransfer(this.wh, this.request.fromChain, this.request.toChain, this.toTransferDetails(params)); | ||
return this.request.displayQuote(quote, params); | ||
@@ -106,0 +106,0 @@ } |
@@ -38,3 +38,3 @@ import { Chain, Network, amount } from "@wormhole-foundation/sdk-base"; | ||
complete(signer: Signer, receipt: R): Promise<TransactionId[]>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/tokenTransfer").TokenTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/tokenTransfer").TokenTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
private toTransferDetails; | ||
@@ -41,0 +41,0 @@ } |
@@ -46,3 +46,3 @@ "use strict"; | ||
try { | ||
return this.request.displayQuote(await tokenTransfer_1.TokenTransfer.quoteTransfer(this.request.fromChain, this.request.toChain, this.toTransferDetails(params)), params); | ||
return this.request.displayQuote(await tokenTransfer_1.TokenTransfer.quoteTransfer(this.wh, this.request.fromChain, this.request.toChain, this.toTransferDetails(params)), params); | ||
} | ||
@@ -49,0 +49,0 @@ catch (e) { |
@@ -1,7 +0,7 @@ | ||
import { Chain, Network, Platform, PlatformToChains } from "@wormhole-foundation/sdk-base"; | ||
import { Chain, Network } from "@wormhole-foundation/sdk-base"; | ||
import { GatewayTransferMsg, GatewayTransferWithPayloadMsg, IbcBridge, IbcMessageId, IbcTransferInfo, TokenBridge, TransactionId, TxHash } from "@wormhole-foundation/sdk-definitions"; | ||
export type Task<T> = () => Promise<T | null>; | ||
export declare function retry<T>(task: Task<T>, interval: number, timeout?: number, title?: string): Promise<T | null>; | ||
export declare function isTokenBridgeVaaRedeemed<N extends Network, P extends Platform, C extends Chain>(tb: TokenBridge<N, C>, vaa: TokenBridge.TransferVAA): Promise<boolean | null>; | ||
export declare function fetchIbcXfer<N extends Network, C extends PlatformToChains<"Cosmwasm">>(wcIbc: IbcBridge<N, C>, msg: TxHash | TransactionId | IbcMessageId | GatewayTransferMsg | GatewayTransferWithPayloadMsg): Promise<IbcTransferInfo | null>; | ||
export declare function isTokenBridgeVaaRedeemed<N extends Network, C extends Chain>(tb: TokenBridge<N, C>, vaa: TokenBridge.TransferVAA): Promise<boolean | null>; | ||
export declare function fetchIbcXfer<N extends Network, C extends Chain>(wcIbc: IbcBridge<N, C>, msg: TxHash | TransactionId | IbcMessageId | GatewayTransferMsg | GatewayTransferWithPayloadMsg): Promise<IbcTransferInfo[] | null>; | ||
//# sourceMappingURL=tasks.d.ts.map |
@@ -0,1 +1,2 @@ | ||
import { Chain } from "@wormhole-foundation/sdk-base"; | ||
import { PayloadDiscriminator, PayloadLiteral, TxHash, WormholeMessageId, deserialize } from "@wormhole-foundation/sdk-definitions"; | ||
@@ -157,2 +158,16 @@ export declare const WHSCAN_RETRY_INTERVAL = 2000; | ||
export declare function getGuardianHeartbeats(rpcUrl: string): Promise<GuardianHeartbeat[] | null>; | ||
export type GovernedTokens = { | ||
[chain in Chain]?: Record<string, number>; | ||
}; | ||
export declare function getGovernedTokens(rpcUrl: string): Promise<GovernedTokens | null>; | ||
export type GovernorChainLimit = { | ||
available: number; | ||
limit: number; | ||
maxSize?: number; | ||
}; | ||
export type GovernorLimits = { | ||
[chain in Chain]?: GovernorChainLimit; | ||
}; | ||
export declare function getGovernorLimits(rpcUrl: string): Promise<GovernorLimits | null>; | ||
export declare function getIsVaaEnqueued(rpcUrl: string, whm: WormholeMessageId): Promise<boolean | null>; | ||
//# sourceMappingURL=whscan-api.d.ts.map |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getGuardianHeartbeats = exports.getTxsByAddress = exports.getVaaByTxHashWithRetry = exports.getVaaByTxHash = exports.getRelayStatusWithRetry = exports.getRelayStatus = exports.getTransactionStatusWithRetry = exports.getTransactionStatus = exports.getVaaWithRetry = exports.getVaa = exports.getVaaBytesWithRetry = exports.getVaaBytes = exports.WHSCAN_RETRY_INTERVAL = void 0; | ||
exports.getIsVaaEnqueued = exports.getGovernorLimits = exports.getGovernedTokens = exports.getGuardianHeartbeats = exports.getTxsByAddress = exports.getVaaByTxHashWithRetry = exports.getVaaByTxHash = exports.getRelayStatusWithRetry = exports.getRelayStatus = exports.getTransactionStatusWithRetry = exports.getTransactionStatus = exports.getVaaWithRetry = exports.getVaa = exports.getVaaBytesWithRetry = exports.getVaaBytes = exports.WHSCAN_RETRY_INTERVAL = void 0; | ||
const sdk_base_1 = require("@wormhole-foundation/sdk-base"); | ||
@@ -190,2 +190,56 @@ const sdk_definitions_1 = require("@wormhole-foundation/sdk-definitions"); | ||
exports.getGuardianHeartbeats = getGuardianHeartbeats; | ||
async function getGovernedTokens(rpcUrl) { | ||
const url = `${rpcUrl}/v1/governor/token_list`; | ||
try { | ||
const response = await axios_1.default.get(url); | ||
if (response.data && response.data.entries.length > 0) { | ||
return response.data.entries.reduce((acc, entry) => { | ||
const chain = (0, sdk_base_1.toChain)(entry.originChainId); | ||
acc[chain] = acc[chain] || {}; | ||
acc[chain][entry.originAddress] = entry.price; | ||
return acc; | ||
}, {}); | ||
} | ||
} | ||
catch { } | ||
return null; | ||
} | ||
exports.getGovernedTokens = getGovernedTokens; | ||
async function getGovernorLimits(rpcUrl) { | ||
const url = `${rpcUrl}/v1/governor/available_notional_by_chain`; | ||
try { | ||
const response = await axios_1.default.get(url); | ||
if (response.data && response.data.entries.length > 0) { | ||
return response.data.entries.reduce((acc, entry) => { | ||
// if 0 consider it no limit | ||
const maxSize = entry.bigTransactionSize === "0" | ||
? undefined | ||
: sdk_base_1.amount.whole(sdk_base_1.amount.parse(entry.bigTransactionSize, 2)); | ||
acc[(0, sdk_base_1.toChain)(entry.chainId)] = { | ||
available: sdk_base_1.amount.whole(sdk_base_1.amount.parse(entry.remainingAvailableNotional, 2)), | ||
limit: sdk_base_1.amount.whole(sdk_base_1.amount.parse(entry.notionalLimit, 2)), | ||
maxSize, | ||
}; | ||
return acc; | ||
}, {}); | ||
} | ||
} | ||
catch { } | ||
return null; | ||
} | ||
exports.getGovernorLimits = getGovernorLimits; | ||
// TODO: returning bool or null is asking for trouble | ||
async function getIsVaaEnqueued(rpcUrl, whm) { | ||
const { chain, emitter, sequence } = whm; | ||
const chainId = (0, sdk_base_1.toChainId)(chain); | ||
const emitterAddress = emitter.toUniversalAddress().toString(); | ||
const url = `${rpcUrl}/v1/governor/is_vaa_enqueued/${chainId}/${emitterAddress}/${sequence}`; | ||
try { | ||
const response = await axios_1.default.get(url); | ||
return response.data.isEnqueued; | ||
} | ||
catch { } | ||
return null; | ||
} | ||
exports.getIsVaaEnqueued = getIsVaaEnqueued; | ||
//# sourceMappingURL=whscan-api.js.map |
@@ -304,8 +304,14 @@ "use strict"; | ||
const task = async () => { | ||
const msgs = await chain.parseTransaction(txid); | ||
// possible the node we hit does not have this data yet | ||
// return null to signal retry | ||
if (msgs.length === 0) | ||
try { | ||
const msgs = await chain.parseTransaction(txid); | ||
// possible the node we hit does not have this data yet | ||
// return null to signal retry | ||
if (msgs.length === 0) | ||
return null; | ||
return msgs; | ||
} | ||
catch (e) { | ||
console.error(e); | ||
return null; | ||
return msgs; | ||
} | ||
}; | ||
@@ -312,0 +318,0 @@ const parsed = await (0, tasks_1.retry)(task, chain.config.blockTime, timeout, "WormholeCore:ParseMessageFromTransaction"); |
@@ -1,3 +0,3 @@ | ||
import { Network } from "@wormhole-foundation/sdk-base"; | ||
import { AttestationId, GatewayTransferDetails, IbcTransferInfo, Signer, TokenBridge, TransactionId, TxHash, WormholeMessageId } from "@wormhole-foundation/sdk-definitions"; | ||
import { Chain, Network } from "@wormhole-foundation/sdk-base"; | ||
import { AttestationId, ChainContext, GatewayTransferDetails, IbcTransferInfo, Signer, TokenBridge, TokenId, TransactionId, TxHash, WormholeMessageId } from "@wormhole-foundation/sdk-definitions"; | ||
import { TransferState } from "../types"; | ||
@@ -35,2 +35,4 @@ import { Wormhole } from "../wormhole"; | ||
static getTransferVaa<N extends Network>(wh: Wormhole<N>, whm: WormholeMessageId, timeout?: number): Promise<TokenBridge.TransferVAA>; | ||
static destinationOverrides<N extends Network>(srcChain: ChainContext<N>, dstChain: ChainContext<N>, gatewayChain: ChainContext<N, "Wormchain">, transfer: GatewayTransferDetails): Promise<GatewayTransferDetails>; | ||
static lookupDestinationToken<N extends Network, SC extends Chain, DC extends Chain>(srcChain: ChainContext<N, SC>, dstChain: ChainContext<N, DC>, gatewayChain: ChainContext<N, "Wormchain">, token: TokenId<SC>): Promise<TokenId<DC>>; | ||
private fromGateway; | ||
@@ -37,0 +39,0 @@ private toGateway; |
@@ -56,2 +56,7 @@ import { chainToPlatform, encoding, toChain, } from "@wormhole-foundation/sdk-base"; | ||
if (isGatewayTransferDetails(from)) { | ||
const fromChain = wh.getChain(from.from.chain); | ||
const toChain = wh.getChain(from.to.chain); | ||
const overrides = await GatewayTransfer.destinationOverrides(fromChain, toChain, wc, from); | ||
// Override transfer params if necessary | ||
from = { ...from, ...overrides }; | ||
return new GatewayTransfer(wh, from, wc, wcibc); | ||
@@ -132,34 +137,26 @@ } | ||
const originChain = wh.getChain(chain); | ||
// If its origin chain is Cosmos, it should be an IBC message | ||
// but its not all the time so do this differently? | ||
// TODO: check if the chain supports Gateway protocol? | ||
if (chainToPlatform(chain) === "Cosmwasm") { | ||
// If its origin chain supports IBC, it should be an IBC message | ||
if (originChain.supportsIbcBridge()) { | ||
// Get the ibc tx info from the origin | ||
const ibcBridge = await originChain.getIbcBridge(); | ||
const xfer = await ibcBridge.lookupTransferFromTx(from.txid); | ||
const [xfer] = await ibcBridge.lookupTransferFromTx(from.txid); | ||
return GatewayTransfer.ibcTransfertoGatewayTransfer(xfer); | ||
} | ||
// Otherwise grab the vaa details from the origin tx | ||
const [whMsgId] = await originChain.parseTransaction(txid); | ||
return await GatewayTransfer._fromMsgId(wh, whMsgId, timeout); | ||
const msgs = await Wormhole.parseMessageFromTx(originChain, txid); | ||
if (!msgs) | ||
throw new Error("No messages found in transaction"); | ||
return await GatewayTransfer._fromMsgId(wh, msgs[0], timeout); | ||
} | ||
// Recover transfer info the first step in the transfer | ||
static ibcTransfertoGatewayTransfer(xfer) { | ||
const token = { | ||
chain: xfer.id.chain, | ||
address: toNative(xfer.id.chain, xfer.data.denom), | ||
}; | ||
const token = Wormhole.tokenId(xfer.id.chain, xfer.data.denom); | ||
const msg = toGatewayMsg(xfer.data.memo); | ||
const destChain = toChain(msg.chain); | ||
const _recip = encoding.b64.valid(msg.recipient) | ||
? encoding.bytes.decode(encoding.b64.decode(msg.recipient)) | ||
: msg.recipient; | ||
const _recip = encoding.b64.decode(msg.recipient); | ||
const recipient = chainToPlatform(destChain) === "Cosmwasm" | ||
? { | ||
chain: destChain, | ||
address: toNative(destChain, _recip.toString()), | ||
} | ||
? Wormhole.chainAddress(destChain, encoding.bytes.decode(_recip)) | ||
: { | ||
chain: destChain, | ||
address: toNative(destChain, new UniversalAddress(_recip)), | ||
address: new UniversalAddress(_recip).toNative(destChain), | ||
}; | ||
@@ -214,4 +211,2 @@ const payload = msg.payload ? encoding.bytes.encode(msg.payload) : undefined; | ||
} | ||
// TODO: track the time elapsed and subtract it from the timeout passed with | ||
// successive updates | ||
// wait for the Attestations to be ready | ||
@@ -253,6 +248,15 @@ async fetchAttestation(timeout) { | ||
// Otherwise we need to get the transfer on the destination chain | ||
// using the transfer from wormchain | ||
const gatewayTransferTask = () => fetchIbcXfer(this.gatewayIbcBridge, xfer.id); | ||
const gatewayIbcTransfers = await retry(gatewayTransferTask, 5000, timeout, "Gateway:IbcBridge:LookupWormchainIbcTransfer"); | ||
if (gatewayIbcTransfers === null) | ||
throw new Error("Gateway IBC transfer not found after retries exhausted"); | ||
const toDestChainIbcTransfer = gatewayIbcTransfers[1]; | ||
const dstChain = this.wh.getChain(this.transfer.to.chain); | ||
const dstIbcBridge = await dstChain.getIbcBridge(); | ||
const ibcXfer = await dstIbcBridge.lookupTransferFromIbcMsgId(xfer.id); | ||
this.ibcTransfers.push(ibcXfer); | ||
const dstMsgTask = () => fetchIbcXfer(dstIbcBridge, toDestChainIbcTransfer.id); | ||
const dstIbcTransfers = await retry(dstMsgTask, 5000, timeout, "Gateway:IbcBridge:LookupDestinationIbcTransfer"); | ||
if (!dstIbcTransfers) | ||
throw new Error("Destination IBC transfer not found after retries exhausted"); | ||
this.ibcTransfers.push(dstIbcTransfers[0]); | ||
} | ||
@@ -287,5 +291,6 @@ } | ||
const wcTransferTask = () => fetchIbcXfer(this.gatewayIbcBridge, this.msg); | ||
const wcTransfer = await retry(wcTransferTask, vaaRedeemedRetryInterval, timeout, "Gateway:IbcBridge:WormchainTransferInitiated"); | ||
if (!wcTransfer) | ||
const wcTransfers = await retry(wcTransferTask, vaaRedeemedRetryInterval, timeout, "Gateway:IbcBridge:WormchainTransferInitiated"); | ||
if (!wcTransfers) | ||
throw new Error("Wormchain transfer not found after retries exhausted"); | ||
const [wcTransfer] = wcTransfers; | ||
if (wcTransfer.pending) { | ||
@@ -298,3 +303,2 @@ // TODO: check if pending and bail(?) if so | ||
const destIbcBridge = await destChain.getIbcBridge(); | ||
//@ts-ignore | ||
const destTransferTask = () => fetchIbcXfer(destIbcBridge, wcTransfer.id); | ||
@@ -304,4 +308,4 @@ const destTransfer = await retry(destTransferTask, transferCompleteInterval, timeout, "Destination:IbcBridge:WormchainTransferCompleted"); | ||
throw new Error("IBC Transfer into destination not found after retries exhausted" + | ||
JSON.stringify(wcTransfer.id)); | ||
this.ibcTransfers.push(destTransfer); | ||
JSON.stringify(wcTransfer)); | ||
this.ibcTransfers.push(destTransfer[0]); | ||
} | ||
@@ -332,7 +336,4 @@ // Add transfers to attestations we return | ||
throw new Error("Expected 1 vaa"); | ||
const { chain, address } = this.transfer.to; | ||
const toChain = this.wh.getChain(chain); | ||
// TODO: these could be different, but when? | ||
//const signerAddress = toNative(signer.chain(), signer.address()); | ||
const toAddress = address.toUniversalAddress(); | ||
const toChain = this.wh.getChain(signer.chain()); | ||
const toAddress = toNative(signer.chain(), signer.address()); | ||
const tb = await toChain.getTokenBridge(); | ||
@@ -354,2 +355,47 @@ const { vaa } = this.vaas[0]; | ||
} | ||
static async destinationOverrides(srcChain, dstChain, gatewayChain, transfer) { | ||
const _transfer = { ...transfer }; | ||
// Bit of (temporary) hackery until solana contracts support being | ||
// sent a VAA with the primary address | ||
if (transfer.to.chain === "Solana") { | ||
const destinationToken = await GatewayTransfer.lookupDestinationToken(srcChain, dstChain, gatewayChain, _transfer.token); | ||
_transfer.to = await dstChain.getTokenAccount(_transfer.to.address, destinationToken.address); | ||
} | ||
return _transfer; | ||
} | ||
// Lookup the token id for the destination chain given the source chain | ||
// and token id | ||
static async lookupDestinationToken(srcChain, dstChain, gatewayChain, token) { | ||
// that will be minted when the transfer is redeemed | ||
let lookup; | ||
if (isNative(token.address)) { | ||
// if native, get the wrapped asset id | ||
lookup = await srcChain.getNativeWrappedTokenId(); | ||
} | ||
else { | ||
try { | ||
// otherwise, check to see if it is a wrapped token locally | ||
const tb = await srcChain.getTokenBridge(); | ||
lookup = await tb.getOriginalAsset(token.address); | ||
} | ||
catch (e) { | ||
// not a from-chain native token, check the gateway chain | ||
try { | ||
const gtb = await gatewayChain.getTokenBridge(); | ||
lookup = await gtb.getOriginalAsset(token.address); | ||
} | ||
catch (e) { | ||
lookup = token; | ||
} | ||
} | ||
} | ||
// if the token id is actually native to the destination, return it | ||
if (lookup.chain === dstChain.chain) { | ||
return lookup; | ||
} | ||
// otherwise, figure out what the token address representing the wormhole-wrapped token we're transferring | ||
const dstTb = await dstChain.getTokenBridge(); | ||
const dstAddress = await dstTb.getWrappedAsset(lookup); | ||
return { chain: dstChain.chain, address: dstAddress }; | ||
} | ||
// Implicitly determine if the chain is Gateway enabled by | ||
@@ -356,0 +402,0 @@ // checking to see if the Gateway IBC bridge has a transfer channel setup |
@@ -35,3 +35,3 @@ import { Chain, Network } from "@wormhole-foundation/sdk-base"; | ||
static validateTransferDetails<N extends Network>(wh: Wormhole<N>, transfer: TokenTransferDetails, fromChain?: ChainContext<N, Chain>, toChain?: ChainContext<N, Chain>): void; | ||
static quoteTransfer<N extends Network>(srcChain: ChainContext<N, Chain>, dstChain: ChainContext<N, Chain>, transfer: TokenTransferDetails): Promise<TransferQuote>; | ||
static quoteTransfer<N extends Network>(wh: Wormhole<N>, srcChain: ChainContext<N, Chain>, dstChain: ChainContext<N, Chain>, transfer: TokenTransferDetails): Promise<TransferQuote>; | ||
static destinationOverrides<N extends Network>(srcChain: ChainContext<N, Chain>, dstChain: ChainContext<N, Chain>, transfer: TokenTransferDetails): Promise<TokenTransferDetails>; | ||
@@ -38,0 +38,0 @@ static getReceipt<N extends Network>(xfer: TokenTransfer<N>): TokenTransferReceipt; |
import { amount, encoding, toChain as toChainName, } from "@wormhole-foundation/sdk-base"; | ||
import { TokenBridge, deserialize, isNative, isTokenId, isTokenTransferDetails, isTransactionIdentifier, isWormholeMessageId, serialize, toNative, toUniversal, } from "@wormhole-foundation/sdk-definitions"; | ||
import { TokenBridge, deserialize, isNative, isTokenId, isTokenTransferDetails, isTransactionIdentifier, isWormholeMessageId, serialize, toNative, toUniversal, universalAddress, } from "@wormhole-foundation/sdk-definitions"; | ||
import { signSendWait } from "../common"; | ||
import { DEFAULT_TASK_TIMEOUT } from "../config"; | ||
import { TransferState, isAttested, isSourceFinalized, isSourceInitiated, } from "../types"; | ||
import { getGovernedTokens, getGovernorLimits } from "../whscan-api"; | ||
import { Wormhole } from "../wormhole"; | ||
@@ -253,11 +254,30 @@ // 8 is maximum precision supported by the token bridge VAA | ||
} | ||
static async quoteTransfer(srcChain, dstChain, transfer) { | ||
const dstToken = await this.lookupDestinationToken(srcChain, dstChain, transfer.token); | ||
static async quoteTransfer(wh, srcChain, dstChain, transfer) { | ||
const srcDecimals = await srcChain.getDecimals(transfer.token.address); | ||
const srcAmount = amount.fromBaseUnits(transfer.amount, srcDecimals); | ||
const srcAmountTruncated = amount.truncate(srcAmount, TOKEN_BRIDGE_MAX_DECIMALS); | ||
const srcToken = isNative(transfer.token.address) | ||
? await srcChain.getNativeWrappedTokenId() | ||
: transfer.token; | ||
const srcDecimals = await srcChain.getDecimals(srcToken.address); | ||
const srcTokenUniversalAddress = universalAddress(srcToken); | ||
// Ensure the transfer would not violate governor transfer limits | ||
const [tokens, limits] = await Promise.all([ | ||
getGovernedTokens(wh.config.api), | ||
getGovernorLimits(wh.config.api), | ||
]); | ||
if (limits !== null && | ||
srcChain.chain in limits && | ||
tokens !== null && | ||
srcChain.chain in tokens && | ||
srcTokenUniversalAddress in tokens[srcChain.chain]) { | ||
const limit = limits[srcChain.chain]; | ||
const tokenPrice = tokens[srcChain.chain][srcTokenUniversalAddress]; | ||
const notionalTransferAmt = tokenPrice * amount.whole(srcAmountTruncated); | ||
if (limit.maxSize && notionalTransferAmt > limit.maxSize) | ||
throw new Error(`Transfer amount exceeds maximum size: ${notionalTransferAmt} > ${limit.maxSize}`); | ||
if (notionalTransferAmt > limit.available) | ||
throw new Error(`Transfer amount exceeds available governed amount: ${notionalTransferAmt} > ${limit.available}`); | ||
} | ||
const dstToken = await this.lookupDestinationToken(srcChain, dstChain, transfer.token); | ||
const dstDecimals = await dstChain.getDecimals(dstToken.address); | ||
const srcAmount = amount.fromBaseUnits(transfer.amount, srcDecimals); | ||
const srcAmountTruncated = amount.truncate(srcAmount, TOKEN_BRIDGE_MAX_DECIMALS); | ||
const dstAmountReceivable = amount.scale(srcAmountTruncated, dstDecimals); | ||
@@ -276,3 +296,3 @@ if (!transfer.automatic) { | ||
const feeAmountDest = amount.scale(amount.truncate(amount.fromBaseUnits(fee, srcDecimals), TOKEN_BRIDGE_MAX_DECIMALS), dstDecimals); | ||
let dstNativeGasAmountRequested = transfer.nativeGas ?? 0n; | ||
const dstNativeGasAmountRequested = transfer.nativeGas ?? 0n; | ||
// The expected destination gas can be pulled from the destination token bridge | ||
@@ -284,9 +304,10 @@ let destinationNativeGas = 0n; | ||
// token that may be swapped for native gas on the destination | ||
const maxNativeAmountIn = await dtb.maxSwapAmount(dstToken.address); | ||
dstNativeGasAmountRequested = | ||
dstNativeGasAmountRequested > maxNativeAmountIn | ||
? maxNativeAmountIn | ||
: dstNativeGasAmountRequested; | ||
// Get the actual amount we should receive | ||
destinationNativeGas = await dtb.nativeTokenAmount(dstToken.address, dstNativeGasAmountRequested); | ||
const [maxNativeAmountIn, _destinationNativeGas] = await Promise.all([ | ||
dtb.maxSwapAmount(dstToken.address), | ||
// Get the actual amount we should receive | ||
dtb.nativeTokenAmount(dstToken.address, dstNativeGasAmountRequested), | ||
]); | ||
if (dstNativeGasAmountRequested > maxNativeAmountIn) | ||
throw new Error(`Native gas amount exceeds maximum swap amount: ${amount.fmt(dstNativeGasAmountRequested, dstDecimals)}>${amount.fmt(maxNativeAmountIn, dstDecimals)}`); | ||
destinationNativeGas = _destinationNativeGas; | ||
} | ||
@@ -293,0 +314,0 @@ const destAmountLessFee = amount.units(dstAmountReceivable) - dstNativeGasAmountRequested - amount.units(feeAmountDest); |
@@ -43,5 +43,5 @@ import { Chain, Network, amount } from "@wormhole-foundation/sdk-base"; | ||
initiate(signer: Signer, quote: Q): Promise<R>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/cctpTransfer").CircleTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/cctpTransfer").CircleTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
} | ||
export {}; | ||
//# sourceMappingURL=automatic.d.ts.map |
@@ -39,3 +39,3 @@ import { Chain, Network, amount } from "@wormhole-foundation/sdk-base"; | ||
complete(signer: Signer, receipt: R): Promise<TransactionId[]>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/cctpTransfer").CircleTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/cctpTransfer").CircleTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
private toTransferDetails; | ||
@@ -42,0 +42,0 @@ } |
@@ -5,3 +5,10 @@ import { Network } from "@wormhole-foundation/sdk-base"; | ||
import { Route } from "./route"; | ||
export declare function checkAndCompleteTransfer<N extends Network>(route: Route<N>, receipt: Receipt, destinationSigner: Signer<N>): Promise<void>; | ||
/** | ||
* track the transfer until the destination is initiated | ||
* | ||
* @param route The route that can be used to track the receipt | ||
* @param receipt The receipt to track | ||
* @param destinationSigner The signer for the destination chain if | ||
*/ | ||
export declare function checkAndCompleteTransfer<N extends Network>(route: Route<N>, receipt: Receipt, destinationSigner?: Signer<N>, timeout?: number, log?: typeof console.log): Promise<import("../types").CreatedTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"> | import("../types").SourceInitiatedTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"> | import("../types").FailedTransferReceipt<import("../types").AttestationReceipt, "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"> | import("../types").SourceFinalizedTransferReceipt<import("../types").AttestationReceipt, "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"> | import("../types").AttestedTransferReceipt<import("../types").AttestationReceipt, "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"> | import("../types").CompletedTransferReceipt<import("../types").AttestationReceipt, "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">>; | ||
//# sourceMappingURL=common.d.ts.map |
import { isManual } from "./route"; | ||
import { TransferState, isAttested, isCompleted } from "../types"; | ||
// TODO: take out logs | ||
// track the transfer until the destination is initiated | ||
export async function checkAndCompleteTransfer(route, receipt, destinationSigner) { | ||
console.log("Checking transfer state..."); | ||
/** | ||
* track the transfer until the destination is initiated | ||
* | ||
* @param route The route that can be used to track the receipt | ||
* @param receipt The receipt to track | ||
* @param destinationSigner The signer for the destination chain if | ||
*/ | ||
export async function checkAndCompleteTransfer(route, receipt, destinationSigner, timeout = 120 * 1000, | ||
// byo logger but im dumping to console rn 🙃 | ||
log = console.log) { | ||
const start = Date.now(); | ||
log("Checking transfer state..."); | ||
// overwrite receipt var as we receive updates, will return when it's complete | ||
// but can be called again if the destination is not finalized | ||
// this construct is to drain an async generator and return the last value | ||
for await (receipt of route.track(receipt, 120 * 1000)) { | ||
console.log("Transfer State:", TransferState[receipt.state]); | ||
log("Current Transfer State: ", TransferState[receipt.state]); | ||
} | ||
// gucci | ||
if (isCompleted(receipt)) | ||
return; | ||
return receipt; | ||
// if the route is one we need to complete, do it | ||
if (isManual(route) && isAttested(receipt)) { | ||
if (isManual(route) && isAttested(receipt) && destinationSigner) { | ||
const completedTxids = await route.complete(destinationSigner, receipt); | ||
console.log("Completed transfer with txids: ", completedTxids); | ||
log("Completed transfer with txids: ", completedTxids); | ||
// Note: do not return receipt yet, there may be further steps to track, this only completes the bridge transfer | ||
} | ||
// give it time to breath and try again | ||
const wait = 2 * 1000; | ||
console.log(`Transfer not complete, trying again in a ${wait}ms...`); | ||
setTimeout(() => checkAndCompleteTransfer(route, receipt, destinationSigner), wait); | ||
const leftover = timeout - (Date.now() - start); | ||
// do we still have time? | ||
if (leftover > 0) { | ||
// give it a second, computers need to rest sometimes | ||
const wait = 2 * 1000; | ||
log(`Transfer not complete, trying again in a ${wait}ms...`); | ||
await Promise.resolve(setTimeout(() => { }, wait)); | ||
return checkAndCompleteTransfer(route, receipt, destinationSigner, leftover); | ||
} | ||
return receipt; | ||
} | ||
//# sourceMappingURL=common.js.map |
@@ -41,3 +41,3 @@ import { AttestationReceipt, Chain, ChainContext, Network, PorticoBridge, Signer, SourceInitiatedTransferReceipt, TokenId, TransactionId, TransferState, amount } from "../.."; | ||
quote(params: VP): Promise<QR>; | ||
initiate(sender: Signer<N>, quote: Q): Promise<SourceInitiatedTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">>; | ||
initiate(sender: Signer<N>, quote: Q): Promise<SourceInitiatedTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<{ | ||
@@ -61,5 +61,5 @@ vaa: import("@wormhole-foundation/sdk-definitions/dist/esm/vaa/vaa").VAA<"TokenBridge:TransferWithPayload">; | ||
state: TransferState.SourceInitiated; | ||
originTxs: TransactionId<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">[]; | ||
from: "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"; | ||
to: "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"; | ||
originTxs: TransactionId<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">[]; | ||
from: "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"; | ||
to: "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky"; | ||
}, void, unknown>; | ||
@@ -66,0 +66,0 @@ complete(signer: Signer<N>, receipt: R): Promise<TransactionId[]>; |
@@ -42,3 +42,3 @@ import { Chain, Network, amount } from "@wormhole-foundation/sdk-base"; | ||
initiate(signer: Signer, quote: Q): Promise<R>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/tokenTransfer").TokenTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/tokenTransfer").TokenTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
private toTransferDetails; | ||
@@ -45,0 +45,0 @@ } |
@@ -100,3 +100,3 @@ import { amount, contracts } from "@wormhole-foundation/sdk-base"; | ||
try { | ||
let quote = await TokenTransfer.quoteTransfer(this.request.fromChain, this.request.toChain, this.toTransferDetails(params)); | ||
let quote = await TokenTransfer.quoteTransfer(this.wh, this.request.fromChain, this.request.toChain, this.toTransferDetails(params)); | ||
return this.request.displayQuote(quote, params); | ||
@@ -103,0 +103,0 @@ } |
@@ -38,3 +38,3 @@ import { Chain, Network, amount } from "@wormhole-foundation/sdk-base"; | ||
complete(signer: Signer, receipt: R): Promise<TransactionId[]>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/tokenTransfer").TokenTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
track(receipt: R, timeout?: number): AsyncGenerator<import("../../protocols/tokenTransfer").TokenTransferReceipt<"Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky", "Solana" | "Ethereum" | "Terra" | "Bsc" | "Polygon" | "Avalanche" | "Oasis" | "Algorand" | "Aurora" | "Fantom" | "Karura" | "Acala" | "Klaytn" | "Celo" | "Near" | "Moonbeam" | "Neon" | "Terra2" | "Injective" | "Osmosis" | "Sui" | "Aptos" | "Arbitrum" | "Optimism" | "Gnosis" | "Pythnet" | "Xpla" | "Btc" | "Base" | "Sei" | "Rootstock" | "Wormchain" | "Cosmoshub" | "Evmos" | "Kujira" | "Neutron" | "Celestia" | "Stargaze" | "Dymension" | "Sepolia" | "ArbitrumSepolia" | "BaseSepolia" | "OptimismSepolia" | "Holesky">, void, unknown>; | ||
private toTransferDetails; | ||
@@ -41,0 +41,0 @@ } |
@@ -43,3 +43,3 @@ import { amount, contracts } from "@wormhole-foundation/sdk-base"; | ||
try { | ||
return this.request.displayQuote(await TokenTransfer.quoteTransfer(this.request.fromChain, this.request.toChain, this.toTransferDetails(params)), params); | ||
return this.request.displayQuote(await TokenTransfer.quoteTransfer(this.wh, this.request.fromChain, this.request.toChain, this.toTransferDetails(params)), params); | ||
} | ||
@@ -46,0 +46,0 @@ catch (e) { |
@@ -1,7 +0,7 @@ | ||
import { Chain, Network, Platform, PlatformToChains } from "@wormhole-foundation/sdk-base"; | ||
import { Chain, Network } from "@wormhole-foundation/sdk-base"; | ||
import { GatewayTransferMsg, GatewayTransferWithPayloadMsg, IbcBridge, IbcMessageId, IbcTransferInfo, TokenBridge, TransactionId, TxHash } from "@wormhole-foundation/sdk-definitions"; | ||
export type Task<T> = () => Promise<T | null>; | ||
export declare function retry<T>(task: Task<T>, interval: number, timeout?: number, title?: string): Promise<T | null>; | ||
export declare function isTokenBridgeVaaRedeemed<N extends Network, P extends Platform, C extends Chain>(tb: TokenBridge<N, C>, vaa: TokenBridge.TransferVAA): Promise<boolean | null>; | ||
export declare function fetchIbcXfer<N extends Network, C extends PlatformToChains<"Cosmwasm">>(wcIbc: IbcBridge<N, C>, msg: TxHash | TransactionId | IbcMessageId | GatewayTransferMsg | GatewayTransferWithPayloadMsg): Promise<IbcTransferInfo | null>; | ||
export declare function isTokenBridgeVaaRedeemed<N extends Network, C extends Chain>(tb: TokenBridge<N, C>, vaa: TokenBridge.TransferVAA): Promise<boolean | null>; | ||
export declare function fetchIbcXfer<N extends Network, C extends Chain>(wcIbc: IbcBridge<N, C>, msg: TxHash | TransactionId | IbcMessageId | GatewayTransferMsg | GatewayTransferWithPayloadMsg): Promise<IbcTransferInfo[] | null>; | ||
//# sourceMappingURL=tasks.d.ts.map |
@@ -0,1 +1,2 @@ | ||
import { Chain } from "@wormhole-foundation/sdk-base"; | ||
import { PayloadDiscriminator, PayloadLiteral, TxHash, WormholeMessageId, deserialize } from "@wormhole-foundation/sdk-definitions"; | ||
@@ -157,2 +158,16 @@ export declare const WHSCAN_RETRY_INTERVAL = 2000; | ||
export declare function getGuardianHeartbeats(rpcUrl: string): Promise<GuardianHeartbeat[] | null>; | ||
export type GovernedTokens = { | ||
[chain in Chain]?: Record<string, number>; | ||
}; | ||
export declare function getGovernedTokens(rpcUrl: string): Promise<GovernedTokens | null>; | ||
export type GovernorChainLimit = { | ||
available: number; | ||
limit: number; | ||
maxSize?: number; | ||
}; | ||
export type GovernorLimits = { | ||
[chain in Chain]?: GovernorChainLimit; | ||
}; | ||
export declare function getGovernorLimits(rpcUrl: string): Promise<GovernorLimits | null>; | ||
export declare function getIsVaaEnqueued(rpcUrl: string, whm: WormholeMessageId): Promise<boolean | null>; | ||
//# sourceMappingURL=whscan-api.d.ts.map |
@@ -1,2 +0,2 @@ | ||
import { encoding, toChainId } from "@wormhole-foundation/sdk-base"; | ||
import { amount, encoding, toChain, toChainId } from "@wormhole-foundation/sdk-base"; | ||
import { deserialize, } from "@wormhole-foundation/sdk-definitions"; | ||
@@ -171,2 +171,53 @@ import axios from "axios"; | ||
} | ||
export async function getGovernedTokens(rpcUrl) { | ||
const url = `${rpcUrl}/v1/governor/token_list`; | ||
try { | ||
const response = await axios.get(url); | ||
if (response.data && response.data.entries.length > 0) { | ||
return response.data.entries.reduce((acc, entry) => { | ||
const chain = toChain(entry.originChainId); | ||
acc[chain] = acc[chain] || {}; | ||
acc[chain][entry.originAddress] = entry.price; | ||
return acc; | ||
}, {}); | ||
} | ||
} | ||
catch { } | ||
return null; | ||
} | ||
export async function getGovernorLimits(rpcUrl) { | ||
const url = `${rpcUrl}/v1/governor/available_notional_by_chain`; | ||
try { | ||
const response = await axios.get(url); | ||
if (response.data && response.data.entries.length > 0) { | ||
return response.data.entries.reduce((acc, entry) => { | ||
// if 0 consider it no limit | ||
const maxSize = entry.bigTransactionSize === "0" | ||
? undefined | ||
: amount.whole(amount.parse(entry.bigTransactionSize, 2)); | ||
acc[toChain(entry.chainId)] = { | ||
available: amount.whole(amount.parse(entry.remainingAvailableNotional, 2)), | ||
limit: amount.whole(amount.parse(entry.notionalLimit, 2)), | ||
maxSize, | ||
}; | ||
return acc; | ||
}, {}); | ||
} | ||
} | ||
catch { } | ||
return null; | ||
} | ||
// TODO: returning bool or null is asking for trouble | ||
export async function getIsVaaEnqueued(rpcUrl, whm) { | ||
const { chain, emitter, sequence } = whm; | ||
const chainId = toChainId(chain); | ||
const emitterAddress = emitter.toUniversalAddress().toString(); | ||
const url = `${rpcUrl}/v1/governor/is_vaa_enqueued/${chainId}/${emitterAddress}/${sequence}`; | ||
try { | ||
const response = await axios.get(url); | ||
return response.data.isEnqueued; | ||
} | ||
catch { } | ||
return null; | ||
} | ||
//# sourceMappingURL=whscan-api.js.map |
@@ -301,8 +301,14 @@ import { chainToPlatform, circle } from "@wormhole-foundation/sdk-base"; | ||
const task = async () => { | ||
const msgs = await chain.parseTransaction(txid); | ||
// possible the node we hit does not have this data yet | ||
// return null to signal retry | ||
if (msgs.length === 0) | ||
try { | ||
const msgs = await chain.parseTransaction(txid); | ||
// possible the node we hit does not have this data yet | ||
// return null to signal retry | ||
if (msgs.length === 0) | ||
return null; | ||
return msgs; | ||
} | ||
catch (e) { | ||
console.error(e); | ||
return null; | ||
return msgs; | ||
} | ||
}; | ||
@@ -309,0 +315,0 @@ const parsed = await retry(task, chain.config.blockTime, timeout, "WormholeCore:ParseMessageFromTransaction"); |
{ | ||
"name": "@wormhole-foundation/connect-sdk", | ||
"version": "0.4.3", | ||
"version": "0.4.4-beta.0", | ||
"repository": { | ||
@@ -48,5 +48,5 @@ "type": "git", | ||
"axios": "^1.4.0", | ||
"@wormhole-foundation/sdk-base": "^0.4.3", | ||
"@wormhole-foundation/sdk-definitions": "^0.4.3" | ||
"@wormhole-foundation/sdk-base": "0.4.4-beta.0", | ||
"@wormhole-foundation/sdk-definitions": "0.4.4-beta.0" | ||
} | ||
} |
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
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1440100
14817
+ Added@wormhole-foundation/sdk-base@0.4.4-beta.0(transitive)
+ Added@wormhole-foundation/sdk-definitions@0.4.4-beta.0(transitive)
- Removed@wormhole-foundation/sdk-base@0.4.6(transitive)
- Removed@wormhole-foundation/sdk-definitions@0.4.6(transitive)