Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -197,74 +197,65 @@ export class SquidRouterPayPhaseHandler extends BasePhaseHandler {
* @param txHash The swap (bridgeCall) transaction hash
*/
private async checkBridgeStatus(state: RampState, swapHash: string, quote: QuoteTicket): Promise<void> {
try {
let isExecuted = false;
let payTxHash: string | undefined = state.state.squidRouterPayTxHash; // in case of recovery, we may have already paid.
// initial delay to allow for API indexing.
await new Promise(resolve => setTimeout(resolve, SQUIDROUTER_INITIAL_DELAY_MS));
while (!isExecuted) {
let isExecuted = false;
let payTxHash: string | undefined = state.state.squidRouterPayTxHash;

await new Promise(resolve => setTimeout(resolve, SQUIDROUTER_INITIAL_DELAY_MS));

while (!isExecuted) {
try {
const squidRouterStatus = await this.getSquidrouterStatus(swapHash, state, quote);

if (squidRouterStatus.status === "success") {
isExecuted = true;
logger.info(`SquidRouterPayPhaseHandler: Transaction ${swapHash} successfully executed on Squidrouter.`);
break;
}
if (!squidRouterStatus) {
logger.warn(`SquidRouterPayPhaseHandler: No squidRouter status found for swap hash ${swapHash}.`);
throw this.createRecoverableError("No squidRouter status found for swap hash.");
}

// If route is on the same chain, we must skip the Axelar check.
if (!squidRouterStatus.isGMPTransaction) {
await new Promise(resolve => setTimeout(resolve, AXELAR_POLLING_INTERVAL_MS));
}

const axelarScanStatus = await getStatusAxelarScan(swapHash);

//no status found is considered a recoverable error.
if (!axelarScanStatus) {
logger.warn(`SquidRouterPayPhaseHandler: No status found for swap hash ${swapHash}.`);
throw this.createRecoverableError("No status found for swap hash.");
}
if (axelarScanStatus.status === "executed" || axelarScanStatus.status === "express_executed") {
} else if (squidRouterStatus.status === "success") {
logger.info(`SquidRouterPayPhaseHandler: Transaction ${swapHash} successfully executed on Squidrouter.`);
isExecuted = true;
logger.info(`SquidRouterPayPhaseHandler: Transaction ${swapHash} successfully executed on Axelar.`);
break;
}

if (!payTxHash) {
const nativeToFundRaw = this.calculateGasFeeInUnits(axelarScanStatus.fees, DEFAULT_SQUIDROUTER_GAS_ESTIMATE);
const logIndex = Number(axelarScanStatus.id.split("_")[2]);
const isGmp = squidRouterStatus ? squidRouterStatus.isGMPTransaction : true;

payTxHash = await this.executeFundTransaction(nativeToFundRaw, swapHash as `0x${string}`, logIndex, state, quote);
if (isGmp) {
const axelarScanStatus = await getStatusAxelarScan(swapHash);

const isPolygon = quote.inputCurrency !== FiatToken.BRL;
const subsidyToken = isPolygon ? SubsidyToken.MATIC : SubsidyToken.GLMR;
const subsidyAmount = nativeToDecimal(nativeToFundRaw, 18).toNumber(); // Both MATIC and GLMR have 18 decimals
const payerAccount = isPolygon
? this.polygonWalletClient.account?.address
: this.moonbeamWalletClient.account?.address;
if (!axelarScanStatus) {
logger.info(`SquidRouterPayPhaseHandler: Axelar status not found yet for hash ${swapHash}.`);
} else if (axelarScanStatus.status === "executed" || axelarScanStatus.status === "express_executed") {
logger.info(`SquidRouterPayPhaseHandler: Transaction ${swapHash} successfully executed on Axelar.`);
isExecuted = true;
break;
} else if (!payTxHash) {
logger.info(`SquidRouterPayPhaseHandler: Bridge transaction detected on Axelar. Proceeding to fund gas.`);

if (payerAccount) {
await this.createSubsidy(state, subsidyAmount, subsidyToken, payerAccount, payTxHash);
}
const nativeToFundRaw = this.calculateGasFeeInUnits(axelarScanStatus.fees, DEFAULT_SQUIDROUTER_GAS_ESTIMATE);
const logIndex = Number(axelarScanStatus.id.split("_")[2]);

await state.update({
state: {
...state.state,
squidRouterPayTxHash: payTxHash
payTxHash = await this.executeFundTransaction(nativeToFundRaw, swapHash as `0x${string}`, logIndex, state, quote);

const isPolygon = quote.inputCurrency !== FiatToken.BRL;
const subsidyToken = isPolygon ? SubsidyToken.MATIC : SubsidyToken.GLMR;
const subsidyAmount = nativeToDecimal(nativeToFundRaw, 18).toNumber();
const payerAccount = isPolygon
? this.polygonWalletClient.account?.address
: this.moonbeamWalletClient.account?.address;

if (payerAccount) {
await this.createSubsidy(state, subsidyAmount, subsidyToken, payerAccount, payTxHash);
}
});
}

await new Promise(resolve => setTimeout(resolve, AXELAR_POLLING_INTERVAL_MS));
}
} catch (error) {
if (error && error instanceof PhaseError && error.isRecoverable) {
throw error;
await state.update({
state: { ...state.state, squidRouterPayTxHash: payTxHash }
});
}
} else {
logger.info(`SquidRouterPayPhaseHandler: Same-chain transaction detected. Skipping Axelar check.`);
}
} catch (error) {
logger.error(`SquidRouterPayPhaseHandler: Error in bridge status loop for ${swapHash}:`, error);
}
throw new Error(`SquidRouterPayPhaseHandler: Error waiting checking for Axelar bridge transaction: ${error}`);

await new Promise(resolve => setTimeout(resolve, AXELAR_POLLING_INTERVAL_MS));
}
}

Expand Down