@f5i23q999d/cow-sdk
Version:
<p align="center"> <img width="400" src="https://github.com/cowprotocol/cow-sdk/raw/main/docs/images/CoW.png" /> </p>
141 lines • 6.62 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getQuoteWithBridge = void 0;
const app_data_1 = require("@cowprotocol/app-data");
const utils_1 = require("../../hooks/utils.js");
const units_1 = require("@ethersproject/units");
const trading_1 = require("../../trading/index.js");
const wallet_1 = require("../../common/utils/wallet.js");
const log_1 = require("../../common/utils/log.js");
const serialize_1 = require("../../common/utils/serialize.js");
async function getQuoteWithBridge(params) {
const { provider, swapAndBridgeRequest, advancedSettings, getErc20Decimals, tradingSdk } = params;
const { kind, sellTokenChainId, sellTokenAddress, buyTokenChainId, buyTokenAddress, amount, signer: signerLike, ...rest } = swapAndBridgeRequest;
const signer = (0, wallet_1.getSigner)(signerLike);
(0, log_1.log)(`Cross-chain ${kind} ${amount} ${sellTokenAddress} (source chain ${sellTokenChainId}) for ${buyTokenAddress} (target chain ${buyTokenChainId})`);
// Get the mocked hook (for estimating the additional swap costs)
const bridgeRequestWithoutAmount = await getBaseBridgeQuoteRequest({
swapAndBridgeRequest: swapAndBridgeRequest,
provider,
getErc20Decimals,
});
// Get the hook mock for cost estimation
const gasLimit = provider.getGasLimitEstimationForHook(bridgeRequestWithoutAmount);
const mockedHook = (0, utils_1.getHookMockForCostEstimation)(gasLimit);
(0, log_1.log)(`Using mocked hook for swap gas estimation: ${JSON.stringify(mockedHook)}`);
const { sellTokenAddress: intermediateToken, sellTokenDecimals: intermediaryTokenDecimals } = bridgeRequestWithoutAmount;
// Estimate the expected amount of intermediate tokens received in CoW Protocol's swap
const swapParams = {
...rest,
kind,
chainId: sellTokenChainId,
sellToken: sellTokenAddress,
buyToken: intermediateToken,
buyTokenDecimals: intermediaryTokenDecimals,
amount: amount.toString(),
signer,
};
(0, log_1.log)(`Getting a quote for the swap (sell token to buy intermediate token). Delegate to trading SDK with params: ${JSON.stringify(swapParams, serialize_1.jsonWithBigintReplacer)}`);
const { result: swapResult, orderBookApi } = await tradingSdk.getQuoteResults(swapParams, {
...advancedSettings,
appData: {
metadata: {
hooks: mockedHook,
},
},
});
const intermediateTokenAmount = swapResult.amountsAndCosts.afterSlippage.buyAmount; // Estimated, as it will likely have surplus
(0, log_1.log)(`Expected to receive ${intermediateTokenAmount} of the intermediate token (${(0, units_1.parseUnits)(intermediateTokenAmount.toString(), intermediaryTokenDecimals).toString()})`);
// Get the bridge result
const { bridgeResult, bridgeHook, appData } = await getBridgeResult({
swapAndBridgeRequest,
swapResult,
bridgeRequestWithoutAmount,
provider,
intermediateTokenAmount,
signer,
});
(0, log_1.log)(`Bridge hook for swap: ${JSON.stringify(bridgeHook)}`);
// Update the receiver and appData (both were mocked before we had the bridge hook)
swapResult.tradeParameters.receiver = bridgeHook.recipient;
const { fullAppData, appDataKeccak256 } = await (0, trading_1.generateAppDataFromDoc)(appData);
(0, log_1.log)(`App data for swap: appDataKeccak256=${appDataKeccak256}, fullAppData="${fullAppData}"`);
swapResult.appDataInfo = {
fullAppData,
appDataKeccak256,
doc: appData,
};
// Return the quote results with the post swap order function
return {
swap: swapResult,
bridge: bridgeResult,
async postSwapOrderFromQuote() {
const quoteResults = {
result: {
...swapResult,
signer,
},
orderBookApi,
};
return (0, trading_1.postSwapOrderFromQuote)(quoteResults, { ...advancedSettings, appData });
},
};
}
exports.getQuoteWithBridge = getQuoteWithBridge;
/**
* Ge the base params (without the amount) for the bridge quote request
*/
async function getBaseBridgeQuoteRequest(params) {
const { provider, getErc20Decimals, swapAndBridgeRequest: quoteBridgeRequest } = params;
const { sellTokenChainId } = quoteBridgeRequest;
const intermediateTokens = await provider.getIntermediateTokens(quoteBridgeRequest);
if (intermediateTokens.length === 0) {
throw new Error('No path found (not intermediate token for bridging)');
}
// We just pick the first intermediate token for now
const intermediateTokenAddress = intermediateTokens[0];
(0, log_1.log)(`Using ${intermediateTokenAddress} as intermediate tokens`);
// Get intermediate token decimals
const intermediaryTokenDecimals = await getErc20Decimals(sellTokenChainId, intermediateTokenAddress);
// Get the gas limit estimation for the hook
return {
...quoteBridgeRequest,
sellTokenAddress: intermediateTokenAddress,
sellTokenDecimals: intermediaryTokenDecimals,
};
}
async function getBridgeResult(params) {
const { swapResult, bridgeRequestWithoutAmount, provider, intermediateTokenAmount, signer } = params;
const bridgeRequest = {
...bridgeRequestWithoutAmount,
amount: intermediateTokenAmount,
};
// Get the quote for the bridging of the intermediate token to the final token
const bridgingQuote = await provider.getQuote(bridgeRequest);
// Get the bridging call
const unsignedBridgeCall = await provider.getUnsignedBridgeCall(bridgeRequest, bridgingQuote);
// Get the pre-authorized hook
const bridgeHook = await provider.getSignedHook(bridgeRequest.sellTokenChainId, unsignedBridgeCall, signer);
// Generate the app data for the hook
const metadataApi = new app_data_1.MetadataApi();
const appData = await metadataApi.generateAppDataDoc({
...swapResult.appDataInfo.doc,
metadata: {
hooks: {
post: [bridgeHook.postHook],
},
},
});
// Prepare the bridge result
const bridgeResult = {
...bridgingQuote,
providerInfo: provider.info,
tradeParameters: bridgeRequest,
bridgeCallDetails: {
unsignedBridgeCall: unsignedBridgeCall,
preAuthorizedBridgingHook: bridgeHook,
},
};
return { bridgeResult, bridgeHook, appData };
}
//# sourceMappingURL=getQuoteWithBridging.js.map