@gibs/bridge-sdk 1.13.0 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +244 -18
- package/abis/package.json +6 -0
- package/bridge-limits/package.json +6 -0
- package/chain-info/package.json +6 -0
- package/chain-names/package.json +6 -0
- package/chains/package.json +6 -0
- package/claims/package.json +6 -0
- package/config/package.json +6 -0
- package/consolidated-quote/package.json +6 -0
- package/destination-calldata/package.json +6 -0
- package/dist/chain-info.d.ts +1 -1
- package/dist/chain-info.js +11 -12
- package/dist/chains.d.ts +25 -0
- package/dist/chains.js +55 -20
- package/dist/cjs/abis.d.ts +1 -0
- package/dist/cjs/abis.js +19 -0
- package/dist/cjs/bridge-limits.d.ts +103 -0
- package/dist/cjs/bridge-limits.js +89 -0
- package/dist/cjs/chain-info.d.ts +169 -0
- package/dist/cjs/chain-info.js +452 -0
- package/dist/cjs/chain-names.d.ts +160 -0
- package/dist/cjs/chain-names.js +207 -0
- package/dist/cjs/chains.d.ts +90 -0
- package/dist/cjs/chains.js +357 -0
- package/dist/cjs/claims.d.ts +198 -0
- package/dist/cjs/claims.js +182 -0
- package/dist/cjs/config.d.ts +240 -0
- package/dist/cjs/config.js +537 -0
- package/dist/cjs/consolidated-quote.d.ts +648 -0
- package/dist/cjs/consolidated-quote.js +1048 -0
- package/dist/cjs/destination-calldata.d.ts +118 -0
- package/dist/cjs/destination-calldata.js +156 -0
- package/dist/cjs/ecosystems.d.ts +217 -0
- package/dist/cjs/ecosystems.js +298 -0
- package/dist/cjs/execution.d.ts +346 -0
- package/dist/cjs/execution.js +468 -0
- package/dist/cjs/fee-type.d.ts +10 -0
- package/dist/cjs/fee-type.js +10 -0
- package/dist/cjs/hyperliquid-execution.d.ts +152 -0
- package/dist/cjs/hyperliquid-execution.js +175 -0
- package/dist/cjs/image-links.d.ts +117 -0
- package/dist/cjs/image-links.js +153 -0
- package/dist/cjs/index.d.ts +23 -0
- package/dist/cjs/index.js +39 -0
- package/dist/cjs/lifi-execution-guard.d.ts +210 -0
- package/dist/cjs/lifi-execution-guard.js +409 -0
- package/dist/cjs/near-intents-conformance.d.ts +85 -0
- package/dist/cjs/near-intents-conformance.js +337 -0
- package/dist/cjs/near-intents-route.d.ts +47 -0
- package/dist/cjs/near-intents-route.js +303 -0
- package/dist/cjs/near-intents.d.ts +524 -0
- package/dist/cjs/near-intents.js +1071 -0
- package/dist/cjs/origin-deposit.d.ts +326 -0
- package/dist/cjs/origin-deposit.js +82 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/pre-quote.d.ts +198 -0
- package/dist/cjs/pre-quote.js +180 -0
- package/dist/cjs/prices.d.ts +107 -0
- package/dist/cjs/prices.js +172 -0
- package/dist/cjs/providers.d.ts +238 -0
- package/dist/cjs/providers.js +171 -0
- package/dist/cjs/quote-fees.d.ts +102 -0
- package/dist/cjs/quote-fees.js +201 -0
- package/dist/cjs/referral.d.ts +85 -0
- package/dist/cjs/referral.js +85 -0
- package/dist/cjs/relay-currencies.d.ts +47 -0
- package/dist/cjs/relay-currencies.js +95 -0
- package/dist/cjs/relay-depository.d.ts +2 -0
- package/dist/cjs/relay-depository.js +85 -0
- package/dist/cjs/relay-quote.d.ts +301 -0
- package/dist/cjs/relay-quote.js +996 -0
- package/dist/cjs/route-steps.d.ts +138 -0
- package/dist/cjs/route-steps.js +310 -0
- package/dist/cjs/routing/amounts.d.ts +80 -0
- package/dist/cjs/routing/amounts.js +126 -0
- package/dist/cjs/routing/candidate-route.d.ts +43 -0
- package/dist/cjs/routing/candidate-route.js +50 -0
- package/dist/cjs/routing/candidate.d.ts +237 -0
- package/dist/cjs/routing/candidate.js +100 -0
- package/dist/cjs/routing/carriers/ask-answer.d.ts +77 -0
- package/dist/cjs/routing/carriers/ask-answer.js +2 -0
- package/dist/cjs/routing/carriers/omnibridge.d.ts +137 -0
- package/dist/cjs/routing/carriers/omnibridge.js +459 -0
- package/dist/cjs/routing/carriers/pulsex-paths.d.ts +80 -0
- package/dist/cjs/routing/carriers/pulsex-paths.js +97 -0
- package/dist/cjs/routing/carriers/pulsex-split.d.ts +175 -0
- package/dist/cjs/routing/carriers/pulsex-split.js +193 -0
- package/dist/cjs/routing/carriers/pulsex.d.ts +159 -0
- package/dist/cjs/routing/carriers/pulsex.js +565 -0
- package/dist/cjs/routing/carriers/wrap.d.ts +25 -0
- package/dist/cjs/routing/carriers/wrap.js +119 -0
- package/dist/cjs/routing/composed-route-quality.d.ts +125 -0
- package/dist/cjs/routing/composed-route-quality.js +144 -0
- package/dist/cjs/routing/entry-chain-anchor.d.ts +88 -0
- package/dist/cjs/routing/entry-chain-anchor.js +59 -0
- package/dist/cjs/routing/format.d.ts +31 -0
- package/dist/cjs/routing/format.js +64 -0
- package/dist/cjs/routing/index.d.ts +38 -0
- package/dist/cjs/routing/index.js +134 -0
- package/dist/cjs/routing/producers.d.ts +770 -0
- package/dist/cjs/routing/producers.js +1617 -0
- package/dist/cjs/routing/providers.d.ts +31 -0
- package/dist/cjs/routing/providers.js +48 -0
- package/dist/cjs/routing/route-data.d.ts +355 -0
- package/dist/cjs/routing/route-data.js +2 -0
- package/dist/cjs/routing/search/compose.d.ts +168 -0
- package/dist/cjs/routing/search/compose.js +104 -0
- package/dist/cjs/routing/search/graph.d.ts +668 -0
- package/dist/cjs/routing/search/graph.js +461 -0
- package/dist/cjs/routing/search/plan-route-data.d.ts +269 -0
- package/dist/cjs/routing/search/plan-route-data.js +848 -0
- package/dist/cjs/routing/search/score.d.ts +356 -0
- package/dist/cjs/routing/search/score.js +445 -0
- package/dist/cjs/routing/swap-transactions.d.ts +91 -0
- package/dist/cjs/routing/swap-transactions.js +131 -0
- package/dist/cjs/routing/usd-value.d.ts +17 -0
- package/dist/cjs/routing/usd-value.js +29 -0
- package/dist/cjs/settings.d.ts +785 -0
- package/dist/cjs/settings.js +1074 -0
- package/dist/cjs/ton-connect.d.ts +98 -0
- package/dist/cjs/ton-connect.js +206 -0
- package/dist/cjs/ton-execution.d.ts +7 -0
- package/dist/cjs/ton-execution.js +23 -0
- package/dist/cjs/ton.d.ts +37 -0
- package/dist/cjs/ton.js +83 -0
- package/dist/cjs/tron-execution.d.ts +146 -0
- package/dist/cjs/tron-execution.js +248 -0
- package/dist/cjs/types.d.ts +51 -0
- package/dist/cjs/types.js +2 -0
- package/dist/claims.d.ts +198 -0
- package/dist/claims.js +140 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.js +39 -5
- package/dist/consolidated-quote.d.ts +109 -15
- package/dist/consolidated-quote.js +310 -52
- package/dist/execution.d.ts +346 -0
- package/dist/execution.js +428 -0
- package/dist/hyperliquid-execution.js +2 -3
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/lifi-execution-guard.d.ts +13 -2
- package/dist/lifi-execution-guard.js +4 -0
- package/dist/near-intents.js +2 -3
- package/dist/pre-quote.d.ts +6 -6
- package/dist/pre-quote.js +10 -14
- package/dist/providers.d.ts +17 -0
- package/dist/providers.js +6 -0
- package/dist/referral.d.ts +12 -4
- package/dist/referral.js +12 -4
- package/dist/relay-depository.d.ts +2 -0
- package/dist/relay-depository.js +82 -0
- package/dist/relay-quote.js +2 -3
- package/dist/routing/candidate.d.ts +3 -3
- package/dist/routing/candidate.js +3 -3
- package/dist/routing/carriers/ask-answer.d.ts +19 -0
- package/dist/routing/carriers/omnibridge.js +23 -21
- package/dist/routing/carriers/pulsex-paths.d.ts +80 -0
- package/dist/routing/carriers/pulsex-paths.js +92 -0
- package/dist/routing/carriers/pulsex-split.d.ts +175 -0
- package/dist/routing/carriers/pulsex-split.js +185 -0
- package/dist/routing/carriers/pulsex.d.ts +69 -21
- package/dist/routing/carriers/pulsex.js +184 -65
- package/dist/routing/composed-route-quality.d.ts +28 -6
- package/dist/routing/composed-route-quality.js +36 -5
- package/dist/routing/entry-chain-anchor.d.ts +1 -1
- package/dist/routing/entry-chain-anchor.js +1 -1
- package/dist/routing/index.d.ts +7 -3
- package/dist/routing/index.js +7 -3
- package/dist/routing/producers.js +1 -1
- package/dist/routing/providers.d.ts +5 -0
- package/dist/routing/providers.js +5 -0
- package/dist/routing/search/graph.d.ts +29 -0
- package/dist/routing/search/plan-route-data.d.ts +25 -0
- package/dist/routing/search/plan-route-data.js +43 -7
- package/dist/routing/search/score.d.ts +33 -1
- package/dist/routing/search/score.js +41 -6
- package/dist/routing/swap-transactions.d.ts +91 -0
- package/dist/routing/swap-transactions.js +125 -0
- package/dist/settings.d.ts +94 -1
- package/dist/settings.js +95 -3
- package/dist/ton-connect.d.ts +98 -0
- package/dist/ton-connect.js +200 -0
- package/dist/ton-execution.d.ts +4 -114
- package/dist/ton-execution.js +4 -244
- package/dist/ton.d.ts +37 -0
- package/dist/ton.js +65 -0
- package/docs/examples/example-a-ether-to-pulse.ts +300 -0
- package/docs/examples/example-b-token-pulsechain-to-ethereum.ts +270 -0
- package/docs/examples/shared.ts +261 -0
- package/docs/examples/tsconfig.json +18 -0
- package/docs/integration-guide.md +617 -0
- package/ecosystems/package.json +6 -0
- package/execution/package.json +6 -0
- package/fee-type/package.json +6 -0
- package/hyperliquid-execution/package.json +6 -0
- package/image-links/package.json +6 -0
- package/lifi-execution-guard/package.json +6 -0
- package/llms.txt +234 -0
- package/near-intents/package.json +6 -0
- package/near-intents-route/package.json +6 -0
- package/origin-deposit/package.json +6 -0
- package/package.json +818 -10
- package/pre-quote/package.json +6 -0
- package/prices/package.json +6 -0
- package/providers/package.json +6 -0
- package/quote-fees/package.json +6 -0
- package/referral/package.json +6 -0
- package/relay-currencies/package.json +6 -0
- package/relay-quote/package.json +6 -0
- package/route-steps/package.json +6 -0
- package/routing/package.json +6 -0
- package/settings/package.json +6 -0
- package/ton/package.json +6 -0
- package/ton-connect/package.json +6 -0
- package/ton-execution/package.json +6 -0
- package/tron-execution/package.json +6 -0
- package/types/package.json +6 -0
|
@@ -0,0 +1,1074 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.assetOut = exports.assetOutKey = exports.transactionInputs = exports.pulseXSwapTransactionInputs = exports.assertCandidatePickAgrees = exports.candidatePickRefusal = exports.assertSwapAgrees = exports.swapRefusal = exports.assertCrossingAgrees = exports.crossingRefusal = exports.isUndercompensated = exports.availableCompensationMaximum = exports.desiredCompensationRatio = exports.reasonablePercentOnTopOfGasFee = exports.destinationDataParam = exports.feeDirectorStructEncoded = exports.interactingWithBridgeToken = exports.reasonablePercentFee = exports.reasonablePercentOnGasLimit = exports.reasonableFixedFee = exports.omnibridgeApproval = exports.approvalAmounts = exports.approveCall = exports.feeTypeSettings = exports.deliveryFee = exports.desiredExcessCompensationBasisPoints = exports.networkSwitchAssetOutAddress = exports.limit = exports.oneTokenInt = exports.estimatedTokenNetworkCost = exports.estimatedNativeNetworkCost = exports.estimatedFee = exports.estimatedAmountOut = exports.amountAfterBridgeFee = exports.bridgeCost = exports.amountToBridge = exports.bridgePathway = exports.basisPoints = exports.oneEther = void 0;
|
|
37
|
+
const viem_1 = require("viem");
|
|
38
|
+
const abis = __importStar(require("./abis.js"));
|
|
39
|
+
const config_js_1 = require("./config.js");
|
|
40
|
+
const fee_type_js_1 = require("./fee-type.js");
|
|
41
|
+
exports.oneEther = 10n ** 18n;
|
|
42
|
+
exports.basisPoints = 10000n;
|
|
43
|
+
/**
|
|
44
|
+
* Returns the bridge pathway (configuration) for a given bridge key, asset in, and whether to use the production pathway
|
|
45
|
+
* @param bridgeKey - the bridge key to use
|
|
46
|
+
* @param isProd - whether to use the production pathway
|
|
47
|
+
* @param assetIn - the asset in to bridge
|
|
48
|
+
* @returns the bridge pathway
|
|
49
|
+
*/
|
|
50
|
+
const bridgePathway = ({ bridgeKey, isProd, assetIn, }) => (0, config_js_1.pathway)(bridgeKey, isProd, assetIn?.address) ?? null;
|
|
51
|
+
exports.bridgePathway = bridgePathway;
|
|
52
|
+
/**
|
|
53
|
+
* Retrieves the amount to bridge from the amount and asset in. If either of them is nil, returns 0n
|
|
54
|
+
* @param amountIn - the amount to bridge
|
|
55
|
+
* @param assetIn - the asset in to bridge
|
|
56
|
+
* @returns the amount to bridge
|
|
57
|
+
*/
|
|
58
|
+
const amountToBridge = ({ amountIn, assetIn, }) => {
|
|
59
|
+
if (!amountIn || amountIn === 0n || !assetIn) {
|
|
60
|
+
return 0n;
|
|
61
|
+
}
|
|
62
|
+
return amountIn;
|
|
63
|
+
};
|
|
64
|
+
exports.amountToBridge = amountToBridge;
|
|
65
|
+
/**
|
|
66
|
+
* Calculates the bridge cost from the amount to bridge and bridge fee
|
|
67
|
+
* @param amountToBridge - the amount to bridge
|
|
68
|
+
* @param bridgeFee - the bridge fee
|
|
69
|
+
* @returns the bridge cost
|
|
70
|
+
*/
|
|
71
|
+
const bridgeCost = ({ amountToBridge, bridgeFee, }) => {
|
|
72
|
+
if (bridgeFee === null)
|
|
73
|
+
return null;
|
|
74
|
+
return (amountToBridge * bridgeFee) / exports.oneEther;
|
|
75
|
+
};
|
|
76
|
+
exports.bridgeCost = bridgeCost;
|
|
77
|
+
/**
|
|
78
|
+
* Calculates the amount after bridge fee from the amount to bridge and bridge cost
|
|
79
|
+
* @param amountToBridge - the amount to bridge
|
|
80
|
+
* @param bridgeCost - the bridge cost
|
|
81
|
+
* @returns the amount after bridge fee
|
|
82
|
+
*/
|
|
83
|
+
const amountAfterBridgeFee = ({ amountToBridge, bridgeCost, }) => {
|
|
84
|
+
if (bridgeCost === null)
|
|
85
|
+
return null;
|
|
86
|
+
const afterFee = amountToBridge - bridgeCost;
|
|
87
|
+
if (afterFee < 0n)
|
|
88
|
+
return 0n;
|
|
89
|
+
return afterFee;
|
|
90
|
+
};
|
|
91
|
+
exports.amountAfterBridgeFee = amountAfterBridgeFee;
|
|
92
|
+
/**
|
|
93
|
+
* Calculates the estimated amount out from the amount after bridge fee and fee
|
|
94
|
+
* @param amountAfterBridgeFee - the amount after bridge fee
|
|
95
|
+
* @param fee - the fee
|
|
96
|
+
* @returns the estimated amount out
|
|
97
|
+
*/
|
|
98
|
+
const estimatedAmountOut = ({ amountAfterBridgeFee, fee, }) => {
|
|
99
|
+
if (typeof fee !== 'bigint')
|
|
100
|
+
return null;
|
|
101
|
+
if (amountAfterBridgeFee === null)
|
|
102
|
+
return null;
|
|
103
|
+
if (fee > amountAfterBridgeFee)
|
|
104
|
+
return 0n;
|
|
105
|
+
return amountAfterBridgeFee - fee;
|
|
106
|
+
};
|
|
107
|
+
exports.estimatedAmountOut = estimatedAmountOut;
|
|
108
|
+
/**
|
|
109
|
+
* Calculates the estimated fee from the amount after bridge fee, fee, percent fee, fee type, limit, and whether to deliver the costs
|
|
110
|
+
* @param amountAfterBridgeFee - the amount after bridge fee
|
|
111
|
+
* @param fee - the fee
|
|
112
|
+
* @param percentFee - the percent fee
|
|
113
|
+
* @param feeType - the fee type
|
|
114
|
+
* @param limit - the limit
|
|
115
|
+
* @param costsToDeliver - whether to deliver the costs
|
|
116
|
+
* @returns the estimated fee
|
|
117
|
+
*/
|
|
118
|
+
const estimatedFee = ({ amountAfterBridgeFee, fee, percentFee, feeType, limit, costsToDeliver, }) => {
|
|
119
|
+
const fixedFee = amountAfterBridgeFee ? (amountAfterBridgeFee * percentFee) / exports.oneEther : null;
|
|
120
|
+
if (!costsToDeliver) {
|
|
121
|
+
return 0n;
|
|
122
|
+
}
|
|
123
|
+
if (feeType === fee_type_js_1.FeeType.FIXED) {
|
|
124
|
+
return fee;
|
|
125
|
+
}
|
|
126
|
+
else if (feeType === fee_type_js_1.FeeType.PERCENT) {
|
|
127
|
+
if (amountAfterBridgeFee === null)
|
|
128
|
+
return null;
|
|
129
|
+
return fixedFee;
|
|
130
|
+
}
|
|
131
|
+
else if (feeType === fee_type_js_1.FeeType.GAS_TIP) {
|
|
132
|
+
return limit;
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
};
|
|
136
|
+
exports.estimatedFee = estimatedFee;
|
|
137
|
+
/**
|
|
138
|
+
* Calculates the estimated native network cost from the estimated gas and latest base fee per gas
|
|
139
|
+
* @param estimatedGas - the estimated gas
|
|
140
|
+
* @param latestBaseFeePerGas - the latest base fee per gas
|
|
141
|
+
* @param requiresDelivery - whether to deliver the costs
|
|
142
|
+
* @returns the estimated native network cost
|
|
143
|
+
*/
|
|
144
|
+
const estimatedNativeNetworkCost = ({ estimatedGas, latestBaseFeePerGas, requiresDelivery, }) => {
|
|
145
|
+
if (!estimatedGas || !latestBaseFeePerGas || !requiresDelivery) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
return BigInt(estimatedGas * latestBaseFeePerGas);
|
|
149
|
+
};
|
|
150
|
+
exports.estimatedNativeNetworkCost = estimatedNativeNetworkCost;
|
|
151
|
+
/**
|
|
152
|
+
* Calculates the estimated token network cost from the estimated native
|
|
153
|
+
* network cost, price corrective, decimals, and one token int
|
|
154
|
+
* @param estimatedNativeNetworkCost - the estimated native network cost
|
|
155
|
+
* @param priceCorrective - the price corrective
|
|
156
|
+
* @param decimals - the decimals
|
|
157
|
+
* @param oneTokenInt - the one token int
|
|
158
|
+
* @returns the estimated token network cost
|
|
159
|
+
*/
|
|
160
|
+
const estimatedTokenNetworkCost = ({ estimatedNativeNetworkCost, priceCorrective, decimals, oneTokenInt, }) => {
|
|
161
|
+
if (!priceCorrective || !oneTokenInt || !estimatedNativeNetworkCost || !decimals) {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
const tokenCost = (estimatedNativeNetworkCost * oneTokenInt) / priceCorrective;
|
|
165
|
+
return tokenCost;
|
|
166
|
+
};
|
|
167
|
+
exports.estimatedTokenNetworkCost = estimatedTokenNetworkCost;
|
|
168
|
+
/**
|
|
169
|
+
* Calculates one token of the asset in as an int
|
|
170
|
+
* @param assetIn - the asset in to bridge
|
|
171
|
+
* @returns the one token int
|
|
172
|
+
*/
|
|
173
|
+
const oneTokenInt = ({ assetIn }) => {
|
|
174
|
+
if (!assetIn)
|
|
175
|
+
return 1n;
|
|
176
|
+
return 10n ** BigInt(assetIn.decimals);
|
|
177
|
+
};
|
|
178
|
+
exports.oneTokenInt = oneTokenInt;
|
|
179
|
+
/**
|
|
180
|
+
* Returns the limit as a bigint. Nil uses 0n
|
|
181
|
+
* @param lim - the limit
|
|
182
|
+
* @returns the limit
|
|
183
|
+
*/
|
|
184
|
+
const limit = (lim) => {
|
|
185
|
+
if (!lim) {
|
|
186
|
+
return 0n;
|
|
187
|
+
}
|
|
188
|
+
return lim;
|
|
189
|
+
};
|
|
190
|
+
exports.limit = limit;
|
|
191
|
+
/**
|
|
192
|
+
* Returns the network switch asset out address from the asset out, unwrap, and to chain
|
|
193
|
+
* @param assetOut - the asset out
|
|
194
|
+
* @param unwrap - whether to unwrap
|
|
195
|
+
* @param toChain - the chain to switch to
|
|
196
|
+
* @returns the network switch asset out address
|
|
197
|
+
*/
|
|
198
|
+
const networkSwitchAssetOutAddress = ({ assetOut, unwrap, toChain, }) => {
|
|
199
|
+
if (!assetOut)
|
|
200
|
+
return null;
|
|
201
|
+
if (!unwrap)
|
|
202
|
+
return assetOut.address;
|
|
203
|
+
const wrappedNative = config_js_1.nativeAssetOut[toChain];
|
|
204
|
+
// Addresses arrive in whatever case their source used (a checksummed literal
|
|
205
|
+
// here, a lower-cased list entry there), so equality must ignore case.
|
|
206
|
+
const isWrappedNative = !!wrappedNative && (0, viem_1.isAddress)(assetOut.address, { strict: false }) && (0, viem_1.isAddressEqual)(wrappedNative, assetOut.address);
|
|
207
|
+
return isWrappedNative ? viem_1.zeroAddress : assetOut.address;
|
|
208
|
+
};
|
|
209
|
+
exports.networkSwitchAssetOutAddress = networkSwitchAssetOutAddress;
|
|
210
|
+
/**
|
|
211
|
+
* Calculates the desired excess compensation basis points from the path, asset in, asset out, bridge key, fee type, list, and asset out address
|
|
212
|
+
* @param path - the path
|
|
213
|
+
* @param assetIn - the asset in to bridge
|
|
214
|
+
* @param assetOut - the asset out
|
|
215
|
+
* @param bridgeKey - the bridge key
|
|
216
|
+
* @param feeType - the fee type
|
|
217
|
+
* @param list - the list
|
|
218
|
+
* @param assetOutAddress - the asset out address
|
|
219
|
+
* @returns the desired excess compensation basis points
|
|
220
|
+
*/
|
|
221
|
+
const desiredExcessCompensationBasisPoints = ({ path, assetIn, assetOut, bridgeKey, feeType, list, assetOutAddress, }) => {
|
|
222
|
+
if (!path?.requiresDelivery) {
|
|
223
|
+
return 0n;
|
|
224
|
+
}
|
|
225
|
+
return !assetIn
|
|
226
|
+
? 0n
|
|
227
|
+
: feeType === fee_type_js_1.FeeType.PERCENT
|
|
228
|
+
? 1000n
|
|
229
|
+
: (0, config_js_1.isNative)(assetIn, bridgeKey) || (0, config_js_1.isNative)(assetOut, bridgeKey)
|
|
230
|
+
? 1000n
|
|
231
|
+
: list.has((0, viem_1.getAddress)(assetIn?.address ?? '')) ||
|
|
232
|
+
list.has(assetOutAddress ? (0, viem_1.getAddress)(assetOutAddress) : '0x')
|
|
233
|
+
? 5000n
|
|
234
|
+
: 10000n;
|
|
235
|
+
};
|
|
236
|
+
exports.desiredExcessCompensationBasisPoints = desiredExcessCompensationBasisPoints;
|
|
237
|
+
/**
|
|
238
|
+
* Works out the Gibs delivery fee for a transfer, as a {@link DeliveryFee}.
|
|
239
|
+
*
|
|
240
|
+
* Each mode reads the SAME figure the delivered estimate subtracts
|
|
241
|
+
* ({@link estimatedFee}), so a route's cost and its delivered value reconcile:
|
|
242
|
+
*
|
|
243
|
+
* - percent: the arriving value times the rate. The router computes
|
|
244
|
+
* `value * multiplier / 1 ether`.
|
|
245
|
+
* - fixed: the fixed amount. The router takes `limit` as the fee.
|
|
246
|
+
* - gas: the limit. The router takes the gas cost, capped at the limit, so the
|
|
247
|
+
* limit is the most the reader pays and the figure the delivered estimate
|
|
248
|
+
* already assumes.
|
|
249
|
+
*
|
|
250
|
+
* `percentFee` must be null when the rate is not known. Passing a zero stand-in
|
|
251
|
+
* would state a free delivery.
|
|
252
|
+
*
|
|
253
|
+
* @param options.shouldDeliver - whether the reader asked for delivery
|
|
254
|
+
* @param options.routeOffersDelivery - whether this pathway delivers for a fee at all
|
|
255
|
+
* @param options.feeType - the delivery fee mode
|
|
256
|
+
* @param options.amountAfterBridgeFee - the value that reaches the destination router, or null
|
|
257
|
+
* @param options.percentFee - the percent rate as a fraction of one ether, or null when unknown
|
|
258
|
+
* @param options.fixedFee - the fixed fee in base units, or null when unknown
|
|
259
|
+
* @param options.limit - the gas mode cap in base units, or null when unknown
|
|
260
|
+
* @returns the delivery fee
|
|
261
|
+
*/
|
|
262
|
+
const deliveryFee = ({ shouldDeliver, routeOffersDelivery, feeType, amountAfterBridgeFee, percentFee, fixedFee, limit, }) => {
|
|
263
|
+
if (!shouldDeliver || !routeOffersDelivery) {
|
|
264
|
+
return { status: 'not-requested' };
|
|
265
|
+
}
|
|
266
|
+
if (feeType === fee_type_js_1.FeeType.FIXED) {
|
|
267
|
+
return { status: 'requested', amount: fixedFee, rate: null };
|
|
268
|
+
}
|
|
269
|
+
if (feeType === fee_type_js_1.FeeType.GAS_TIP) {
|
|
270
|
+
return { status: 'requested', amount: limit, rate: null };
|
|
271
|
+
}
|
|
272
|
+
if (amountAfterBridgeFee === null || percentFee === null) {
|
|
273
|
+
return { status: 'requested', amount: null, rate: percentFee };
|
|
274
|
+
}
|
|
275
|
+
return {
|
|
276
|
+
status: 'requested',
|
|
277
|
+
amount: (amountAfterBridgeFee * percentFee) / exports.oneEther,
|
|
278
|
+
rate: percentFee,
|
|
279
|
+
};
|
|
280
|
+
};
|
|
281
|
+
exports.deliveryFee = deliveryFee;
|
|
282
|
+
/**
|
|
283
|
+
* The four-bit fee-type settings word a fee director carries.
|
|
284
|
+
*
|
|
285
|
+
* - bit 0: fixed fee mode.
|
|
286
|
+
* - bit 1: unwrap the delivered token to the native coin.
|
|
287
|
+
* - bit 2: exclude the priority fee from the delivery cost. Always set.
|
|
288
|
+
* - bit 3: percent fee mode.
|
|
289
|
+
*
|
|
290
|
+
* @param options.feeType - the delivery fee mode
|
|
291
|
+
* @param options.unwrap - whether the delivery unwraps to the native coin
|
|
292
|
+
* @returns the settings word for {@link feeDirectorStructEncoded}
|
|
293
|
+
*/
|
|
294
|
+
const feeTypeSettings = ({ feeType, unwrap }) => {
|
|
295
|
+
const fixedBit = feeType === fee_type_js_1.FeeType.FIXED ? 1n : 0n;
|
|
296
|
+
const unwrapBit = unwrap ? 1n : 0n;
|
|
297
|
+
const excludePriorityBit = 1n;
|
|
298
|
+
const percentBit = feeType === fee_type_js_1.FeeType.PERCENT ? 1n : 0n;
|
|
299
|
+
return (percentBit << 3n) | (excludePriorityBit << 2n) | (unwrapBit << 1n) | fixedBit;
|
|
300
|
+
};
|
|
301
|
+
exports.feeTypeSettings = feeTypeSettings;
|
|
302
|
+
/**
|
|
303
|
+
* The ERC-20 `approve` call, as a target, a value and calldata. The
|
|
304
|
+
* interface's approval broadcast and the SDK's execution planner both build it
|
|
305
|
+
* here.
|
|
306
|
+
*
|
|
307
|
+
* @param options.token - the token to approve
|
|
308
|
+
* @param options.spender - the address allowed to pull it
|
|
309
|
+
* @param options.amount - the allowance to set
|
|
310
|
+
* @returns the call
|
|
311
|
+
*/
|
|
312
|
+
const approveCall = ({ token, spender, amount, }) => ({
|
|
313
|
+
to: token,
|
|
314
|
+
value: 0n,
|
|
315
|
+
data: (0, viem_1.encodeFunctionData)({ abi: viem_1.erc20Abi, functionName: 'approve', args: [spender, amount] }),
|
|
316
|
+
});
|
|
317
|
+
exports.approveCall = approveCall;
|
|
318
|
+
/**
|
|
319
|
+
* The `approve` amounts to send, in order, so the spender may pull exactly
|
|
320
|
+
* `minimum`. Empty when the allowance on chain already covers it.
|
|
321
|
+
*
|
|
322
|
+
* EXACT, NEVER UNLIMITED. An unlimited approval lets the spender pull the
|
|
323
|
+
* reader's whole balance for as long as the approval stands, so a later fault
|
|
324
|
+
* in that contract, or a spender a compromised quote named, costs everything
|
|
325
|
+
* rather than one transfer. The owner chose exact approvals everywhere
|
|
326
|
+
* (2026-10-07); the interface and the SDK's execution planner both decide
|
|
327
|
+
* here.
|
|
328
|
+
*
|
|
329
|
+
* A SHORT, NON-ZERO ALLOWANCE IS RESET TO ZERO FIRST. Some tokens (Tether on
|
|
330
|
+
* Ethereum is the known one) revert an `approve` that changes one non-zero
|
|
331
|
+
* allowance into another. Exact approvals leave such remainders more often,
|
|
332
|
+
* because an aggregator may spend less than it was allowed. A reset first
|
|
333
|
+
* works for every token, at the cost of one extra transaction in that case.
|
|
334
|
+
*
|
|
335
|
+
* @param options.allowance - the allowance on chain now
|
|
336
|
+
* @param options.minimum - the amount the next transaction pulls
|
|
337
|
+
* @returns the amounts to approve, in order: none, `[minimum]`, or `[0n, minimum]`
|
|
338
|
+
*/
|
|
339
|
+
const approvalAmounts = ({ allowance, minimum, }) => {
|
|
340
|
+
if (allowance >= minimum)
|
|
341
|
+
return [];
|
|
342
|
+
if (allowance === 0n)
|
|
343
|
+
return [minimum];
|
|
344
|
+
return [0n, minimum];
|
|
345
|
+
};
|
|
346
|
+
exports.approvalAmounts = approvalAmounts;
|
|
347
|
+
/**
|
|
348
|
+
* The allowance a direct omnibridge crossing needs, or null when it needs none.
|
|
349
|
+
*
|
|
350
|
+
* Reads the SAME predicate {@link transactionInputs} uses to pick the call: a
|
|
351
|
+
* token the bridge minted ({@link interactingWithBridgeToken}) is burned by
|
|
352
|
+
* `transferAndCall` and needs no allowance, and the native coin is sent as
|
|
353
|
+
* value. Every other token is pulled by the pathway's `from` mediator through
|
|
354
|
+
* `relayTokens` or `relayTokensAndCall`.
|
|
355
|
+
*
|
|
356
|
+
* @param options.bridgePathway - the crossing's pathway
|
|
357
|
+
* @param options.assetIn - the token the crossing spends
|
|
358
|
+
* @param options.assetLink - the token's bridge link
|
|
359
|
+
* @param options.amountToBridge - the amount the crossing pulls
|
|
360
|
+
* @returns the approval the crossing needs, or null
|
|
361
|
+
*/
|
|
362
|
+
const omnibridgeApproval = ({ bridgePathway, assetIn, assetLink, amountToBridge, }) => {
|
|
363
|
+
if (assetIn.address === viem_1.zeroAddress)
|
|
364
|
+
return null;
|
|
365
|
+
if ((0, exports.interactingWithBridgeToken)({ assetLink, assetInAddress: assetIn.address }))
|
|
366
|
+
return null;
|
|
367
|
+
return {
|
|
368
|
+
chainId: assetIn.chainId,
|
|
369
|
+
token: assetIn.address,
|
|
370
|
+
spender: bridgePathway.from,
|
|
371
|
+
minimum: amountToBridge,
|
|
372
|
+
};
|
|
373
|
+
};
|
|
374
|
+
exports.omnibridgeApproval = omnibridgeApproval;
|
|
375
|
+
/**
|
|
376
|
+
* Calculates the reasonable fixed fee from the estimated token network cost and desired excess compensation basis points
|
|
377
|
+
* @param estimatedTokenNetworkCost - the estimated token network cost
|
|
378
|
+
* @param desiredExcessCompensationBasisPoints - the desired excess compensation basis points
|
|
379
|
+
* @returns the reasonable fixed fee
|
|
380
|
+
*/
|
|
381
|
+
const reasonableFixedFee = ({ estimatedTokenNetworkCost, desiredExcessCompensationBasisPoints, }) => {
|
|
382
|
+
if (!estimatedTokenNetworkCost) {
|
|
383
|
+
return null;
|
|
384
|
+
}
|
|
385
|
+
return ((estimatedTokenNetworkCost * (25000n + desiredExcessCompensationBasisPoints)) / exports.basisPoints);
|
|
386
|
+
};
|
|
387
|
+
exports.reasonableFixedFee = reasonableFixedFee;
|
|
388
|
+
/**
|
|
389
|
+
* Calculates the reasonable percent on gas limit from the gas tip fee and estimated token network cost
|
|
390
|
+
* @param gasTipFee - the gas tip fee
|
|
391
|
+
* @param estimatedTokenNetworkCost - the estimated token network cost
|
|
392
|
+
* @returns the reasonable percent on gas limit
|
|
393
|
+
*/
|
|
394
|
+
const reasonablePercentOnGasLimit = ({ gasTipFee, estimatedTokenNetworkCost, }) => {
|
|
395
|
+
return ((25000n * ((exports.oneEther + (gasTipFee ?? 0n)) * (estimatedTokenNetworkCost ?? 0n))) /
|
|
396
|
+
(exports.oneEther * exports.basisPoints));
|
|
397
|
+
};
|
|
398
|
+
exports.reasonablePercentOnGasLimit = reasonablePercentOnGasLimit;
|
|
399
|
+
/**
|
|
400
|
+
* Calculates the reasonable percent fee from the reasonable fixed fee and amount after bridge fee
|
|
401
|
+
* @param reasonableFixedFee - the reasonable fixed fee
|
|
402
|
+
* @param amountAfterBridgeFee - the amount after bridge fee
|
|
403
|
+
* @returns the reasonable percent fee
|
|
404
|
+
*/
|
|
405
|
+
const reasonablePercentFee = ({ reasonableFixedFee, amountAfterBridgeFee, }) => {
|
|
406
|
+
if (!reasonableFixedFee) {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
if (!amountAfterBridgeFee) {
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
const highFee = amountAfterBridgeFee / 10n;
|
|
413
|
+
const basisFeeTruncator = 10n ** 14n;
|
|
414
|
+
const max = 1000n * basisFeeTruncator;
|
|
415
|
+
const min = 5n * basisFeeTruncator;
|
|
416
|
+
if (highFee < reasonableFixedFee) {
|
|
417
|
+
return max; // 10%
|
|
418
|
+
}
|
|
419
|
+
const highResPercent = (reasonableFixedFee * exports.oneEther) / amountAfterBridgeFee;
|
|
420
|
+
if (highResPercent < min) {
|
|
421
|
+
return min;
|
|
422
|
+
}
|
|
423
|
+
else if (highResPercent > max) {
|
|
424
|
+
return max;
|
|
425
|
+
}
|
|
426
|
+
const basisPoint = highResPercent / basisFeeTruncator;
|
|
427
|
+
return basisPoint * basisFeeTruncator;
|
|
428
|
+
};
|
|
429
|
+
exports.reasonablePercentFee = reasonablePercentFee;
|
|
430
|
+
/**
|
|
431
|
+
* Returns whether the asset in address is interacting with a bridge token
|
|
432
|
+
* @param assetLink - the asset link
|
|
433
|
+
* @param assetInAddress - the asset in address
|
|
434
|
+
* @returns whether the asset in address is interacting with a bridge token
|
|
435
|
+
*/
|
|
436
|
+
const interactingWithBridgeToken = ({ assetLink, assetInAddress, }) => {
|
|
437
|
+
const { toForeign, toHome } = assetLink || {};
|
|
438
|
+
const { foreign } = toForeign || {};
|
|
439
|
+
const { home } = toHome || {};
|
|
440
|
+
if (!assetInAddress)
|
|
441
|
+
return false;
|
|
442
|
+
return !!((foreign && (0, viem_1.getAddress)(foreign) === (0, viem_1.getAddress)(assetInAddress)) ||
|
|
443
|
+
(home && (0, viem_1.getAddress)(home) === (0, viem_1.getAddress)(assetInAddress)));
|
|
444
|
+
};
|
|
445
|
+
exports.interactingWithBridgeToken = interactingWithBridgeToken;
|
|
446
|
+
/**
|
|
447
|
+
* Calculates the fee director struct encoded from the recipient, bridge pathway, fee type, price corrective, gas tip fee, percent fee, fee type settings, limit, and asset out
|
|
448
|
+
* @param recipient - the recipient
|
|
449
|
+
* @param bridgePathway - the bridge pathway
|
|
450
|
+
* @param feeType - the fee type
|
|
451
|
+
* @param priceCorrective - the price corrective
|
|
452
|
+
* @param gasTipFee - the gas tip fee
|
|
453
|
+
* @param percentFee - the percent fee
|
|
454
|
+
* @param feeTypeSettings - the fee type settings
|
|
455
|
+
* @param limit - the limit
|
|
456
|
+
* @param assetOut - the asset out
|
|
457
|
+
* @returns the fee director struct encoded
|
|
458
|
+
*/
|
|
459
|
+
const feeDirectorStructEncoded = ({ recipient, bridgePathway, feeType, priceCorrective, gasTipFee, percentFee, feeTypeSettings, limit, assetOut, }) => {
|
|
460
|
+
if (!assetOut || !bridgePathway) {
|
|
461
|
+
return null;
|
|
462
|
+
}
|
|
463
|
+
if (!bridgePathway.requiresDelivery) {
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
if (!priceCorrective) {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
let multiplier = 0n;
|
|
470
|
+
if (feeType === fee_type_js_1.FeeType.GAS_TIP && priceCorrective > 0n) {
|
|
471
|
+
multiplier =
|
|
472
|
+
((exports.oneEther + (gasTipFee ?? 0n)) * 10n ** BigInt(assetOut.decimals)) / priceCorrective;
|
|
473
|
+
}
|
|
474
|
+
else if (feeType === fee_type_js_1.FeeType.PERCENT) {
|
|
475
|
+
multiplier = percentFee ?? 0n;
|
|
476
|
+
}
|
|
477
|
+
if (!recipient || !(0, viem_1.isAddress)(recipient)) {
|
|
478
|
+
return null;
|
|
479
|
+
}
|
|
480
|
+
return (0, viem_1.encodeAbiParameters)(abis.feeDeliveryStruct, [
|
|
481
|
+
[recipient, feeTypeSettings, limit, multiplier],
|
|
482
|
+
]);
|
|
483
|
+
};
|
|
484
|
+
exports.feeDirectorStructEncoded = feeDirectorStructEncoded;
|
|
485
|
+
/**
|
|
486
|
+
* Calculates the destination data param from the recipient, bridge pathway, asset in, destination router, fee director struct encoded, asset link, should deliver, and unwrap
|
|
487
|
+
* @param recipient - the recipient
|
|
488
|
+
* @param bridgePathway - the bridge pathway
|
|
489
|
+
* @param assetIn - the asset in to bridge
|
|
490
|
+
* @param destinationRouter - the destination router
|
|
491
|
+
* @param feeDirectorStructEncoded - the fee director struct encoded
|
|
492
|
+
* @param assetLink - the asset link
|
|
493
|
+
* @param shouldDeliver - whether to deliver the costs
|
|
494
|
+
* @param unwrap - whether to unwrap
|
|
495
|
+
* @returns the destination data param
|
|
496
|
+
*/
|
|
497
|
+
const destinationDataParam = ({ recipient, bridgePathway, assetIn, destinationRouter, feeDirectorStructEncoded, assetLink, shouldDeliver, unwrap, }) => {
|
|
498
|
+
// const recipient = input.recipient.value
|
|
499
|
+
if (!recipient) {
|
|
500
|
+
return null;
|
|
501
|
+
}
|
|
502
|
+
if (!bridgePathway || !assetIn) {
|
|
503
|
+
return null;
|
|
504
|
+
}
|
|
505
|
+
if (!destinationRouter) {
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
// Only a delivery needs the fee director. A crossing without delivery sends
|
|
509
|
+
// to the recipient, whatever the fee director would have said.
|
|
510
|
+
if (bridgePathway.requiresDelivery && shouldDeliver && !feeDirectorStructEncoded) {
|
|
511
|
+
return null;
|
|
512
|
+
}
|
|
513
|
+
if (!assetLink) {
|
|
514
|
+
return null;
|
|
515
|
+
}
|
|
516
|
+
if (bridgePathway.requiresDelivery) {
|
|
517
|
+
// going from home to foreign
|
|
518
|
+
if (!shouldDeliver) {
|
|
519
|
+
// act like a regular bridge
|
|
520
|
+
return recipient;
|
|
521
|
+
}
|
|
522
|
+
// going from foreign to home
|
|
523
|
+
if (feeDirectorStructEncoded) {
|
|
524
|
+
return (0, viem_1.concatHex)([destinationRouter, feeDirectorStructEncoded]);
|
|
525
|
+
}
|
|
526
|
+
return recipient;
|
|
527
|
+
}
|
|
528
|
+
if (!unwrap) {
|
|
529
|
+
return recipient;
|
|
530
|
+
}
|
|
531
|
+
// unwrap wpls->pls
|
|
532
|
+
return (0, viem_1.concatHex)([destinationRouter, recipient]);
|
|
533
|
+
};
|
|
534
|
+
exports.destinationDataParam = destinationDataParam;
|
|
535
|
+
/**
|
|
536
|
+
* Converts a desired excess compensation basis point value into a percentage as an integer, with the denominator assumed to be 1e18
|
|
537
|
+
* @param desiredExcessCompensationBasisPoints - the desired excess compensation basis points
|
|
538
|
+
* @returns the reasonable percent on top of gas fee
|
|
539
|
+
*/
|
|
540
|
+
const reasonablePercentOnTopOfGasFee = ({ desiredExcessCompensationBasisPoints, }) => {
|
|
541
|
+
return desiredExcessCompensationBasisPoints * (exports.oneEther / exports.basisPoints);
|
|
542
|
+
};
|
|
543
|
+
exports.reasonablePercentOnTopOfGasFee = reasonablePercentOnTopOfGasFee;
|
|
544
|
+
/**
|
|
545
|
+
* Calculates the desired compensation ratio from the desired excess compensation basis points
|
|
546
|
+
* @param desiredExcessCompensationBasisPoints - the desired excess compensation basis points
|
|
547
|
+
* @returns the desired compensation ratio
|
|
548
|
+
*/
|
|
549
|
+
const desiredCompensationRatio = ({ desiredExcessCompensationBasisPoints, }) => {
|
|
550
|
+
return exports.oneEther + (desiredExcessCompensationBasisPoints * exports.oneEther) / exports.basisPoints;
|
|
551
|
+
};
|
|
552
|
+
exports.desiredCompensationRatio = desiredCompensationRatio;
|
|
553
|
+
/**
|
|
554
|
+
* Calculates the available compensation maximum from the amount after bridge fee, percent fee, fee type, fixed fee, and limit
|
|
555
|
+
* @param amountAfterBridgeFee - the amount after bridge fee
|
|
556
|
+
* @param percentFee - the percent fee
|
|
557
|
+
* @param feeType - the fee type
|
|
558
|
+
* @param fixedFee - the fixed fee
|
|
559
|
+
* @param limit - the limit
|
|
560
|
+
* @returns the available compensation maximum
|
|
561
|
+
*/
|
|
562
|
+
const availableCompensationMaximum = ({ amountAfterBridgeFee, percentFee, feeType, fixedFee, limit, }) => {
|
|
563
|
+
if (feeType === fee_type_js_1.FeeType.PERCENT) {
|
|
564
|
+
if (amountAfterBridgeFee === null)
|
|
565
|
+
return null;
|
|
566
|
+
return (amountAfterBridgeFee * (percentFee ?? 0n)) / exports.oneEther;
|
|
567
|
+
}
|
|
568
|
+
else if (feeType === fee_type_js_1.FeeType.GAS_TIP) {
|
|
569
|
+
return limit;
|
|
570
|
+
}
|
|
571
|
+
else if (feeType === fee_type_js_1.FeeType.FIXED) {
|
|
572
|
+
return fixedFee ?? 0n;
|
|
573
|
+
}
|
|
574
|
+
return 0n;
|
|
575
|
+
};
|
|
576
|
+
exports.availableCompensationMaximum = availableCompensationMaximum;
|
|
577
|
+
/**
|
|
578
|
+
* Determines if the bridge is undercompensated based on network costs vs compensation limit using desired compensation rate
|
|
579
|
+
* @param estimatedTokenNetworkCost - the estimated token network cost
|
|
580
|
+
* @param feeType - the fee type
|
|
581
|
+
* @param limit - the maximum compensation limit
|
|
582
|
+
* @param amountAfterBridgeFee - the amount after bridge fee
|
|
583
|
+
* @param desiredExcessCompensationBasisPoints - the desired excess compensation basis points
|
|
584
|
+
* @returns whether the bridge is undercompensated
|
|
585
|
+
*/
|
|
586
|
+
const isUndercompensated = ({ estimatedTokenNetworkCost, feeType, limit, amountAfterBridgeFee, desiredExcessCompensationBasisPoints, }) => {
|
|
587
|
+
// No undercompensation if no amount to bridge
|
|
588
|
+
if (!amountAfterBridgeFee || amountAfterBridgeFee <= 0n) {
|
|
589
|
+
return false;
|
|
590
|
+
}
|
|
591
|
+
// GAS_TIP fee type doesn't have undercompensation issues
|
|
592
|
+
if (feeType === fee_type_js_1.FeeType.GAS_TIP) {
|
|
593
|
+
return false;
|
|
594
|
+
}
|
|
595
|
+
// No network cost estimate means we can't determine undercompensation
|
|
596
|
+
if (!estimatedTokenNetworkCost) {
|
|
597
|
+
return false;
|
|
598
|
+
}
|
|
599
|
+
// Calculate desired compensation using the actual desired compensation ratio
|
|
600
|
+
const desiredCompensationRatio = exports.oneEther + (desiredExcessCompensationBasisPoints * exports.oneEther) / exports.basisPoints;
|
|
601
|
+
const desiredCompensationForNetworkCost = (estimatedTokenNetworkCost * desiredCompensationRatio) / exports.oneEther;
|
|
602
|
+
// Undercompensated if desired compensation exceeds the limit
|
|
603
|
+
return desiredCompensationForNetworkCost > limit;
|
|
604
|
+
};
|
|
605
|
+
exports.isUndercompensated = isUndercompensated;
|
|
606
|
+
/**
|
|
607
|
+
* Why a bridge key must not be built into a transaction for the pair on screen,
|
|
608
|
+
* or null when the two agree.
|
|
609
|
+
*
|
|
610
|
+
* WHY THIS EXISTS, in the reader's words: "i just tried to swap from weth from
|
|
611
|
+
* ethereum on pls, to pls, and the calldata that i must have signed was to
|
|
612
|
+
* bridge back from pls to eth". A selection of PulseChain on BOTH sides is a
|
|
613
|
+
* swap; it has no pathway, so the bridge key kept whatever crossing it last
|
|
614
|
+
* held — or the address bar was repaired to a crossing — and the settings
|
|
615
|
+
* cascade went on building a real, signable transfer of the reader's bridged
|
|
616
|
+
* wrapped ether to Ethereum while the screen still named PulseChain.
|
|
617
|
+
*
|
|
618
|
+
* Three refusals, and each one is a separate way the two can part company:
|
|
619
|
+
*
|
|
620
|
+
* - A SAME-CHAIN SELECTION IS NEVER A CROSSING. Origin and destination on one
|
|
621
|
+
* chain describes a swap. No omnibridge pathway can serve it, so any pathway
|
|
622
|
+
* reached for here belongs to some other journey.
|
|
623
|
+
* - THE PATHWAY MUST LEAVE THE CHAIN THE READER'S FUNDS ARE ON. A key whose
|
|
624
|
+
* source chain differs spends a token the reader is not looking at.
|
|
625
|
+
* - THE PATHWAY MUST LAND WHERE THE READER ASKED. This is the reported defect:
|
|
626
|
+
* the destination silently became Ethereum.
|
|
627
|
+
*
|
|
628
|
+
* `signedCrossing` is `null` for a call no reader composed — the aggregator's
|
|
629
|
+
* executor call built by `buildDestinationCalldata`, where the chain pair IS
|
|
630
|
+
* the pathway and there is no screen to disagree with. Nullable rather than
|
|
631
|
+
* optional so every caller has to decide, and the decision is visible at the
|
|
632
|
+
* call site.
|
|
633
|
+
*
|
|
634
|
+
* @param bridgeKey - the key the pathway was resolved from
|
|
635
|
+
* @param signedCrossing - the pair on screen, or null when no surface composed it
|
|
636
|
+
* @returns the reason to refuse, or null when the two agree
|
|
637
|
+
*/
|
|
638
|
+
const crossingRefusal = ({ bridgeKey, signedCrossing, }) => {
|
|
639
|
+
// `undefined` is treated as `null` here, and only here. The field is REQUIRED
|
|
640
|
+
// by the type, so no compiled caller can omit it — but a test double that
|
|
641
|
+
// returns a partial object can, and a crash inside the settings cascade blanks
|
|
642
|
+
// the page rather than refusing a transaction.
|
|
643
|
+
if (signedCrossing === null || signedCrossing === undefined) {
|
|
644
|
+
return null;
|
|
645
|
+
}
|
|
646
|
+
const { originChainId, destinationChainId } = signedCrossing;
|
|
647
|
+
if (originChainId === destinationChainId) {
|
|
648
|
+
return `Refusing to build a crossing for a selection that stays on chain ${originChainId}. Origin and destination are the same chain, which is a swap, not a bridge.`;
|
|
649
|
+
}
|
|
650
|
+
if (!bridgeKey) {
|
|
651
|
+
return `Refusing to build a crossing from chain ${originChainId} to chain ${destinationChainId}: no bridge key was resolved for it.`;
|
|
652
|
+
}
|
|
653
|
+
const pathwayOriginChainId = Number(bridgeKey[1]);
|
|
654
|
+
const pathwayDestinationChainId = Number(bridgeKey[2]);
|
|
655
|
+
if (pathwayOriginChainId !== originChainId) {
|
|
656
|
+
return `Refusing to build a crossing that leaves chain ${pathwayOriginChainId} while the selection starts on chain ${originChainId}.`;
|
|
657
|
+
}
|
|
658
|
+
if (pathwayDestinationChainId !== destinationChainId) {
|
|
659
|
+
return `Refusing to build a crossing that delivers on chain ${pathwayDestinationChainId} while the selection asks for chain ${destinationChainId}.`;
|
|
660
|
+
}
|
|
661
|
+
return null;
|
|
662
|
+
};
|
|
663
|
+
exports.crossingRefusal = crossingRefusal;
|
|
664
|
+
/**
|
|
665
|
+
* Throws when the bridge key and the pair on screen describe different journeys.
|
|
666
|
+
*
|
|
667
|
+
* The LOUD half of {@link crossingRefusal}. {@link transactionInputs} runs
|
|
668
|
+
* during render, where a throw would blank the application, so it refuses
|
|
669
|
+
* quietly by returning null and the button it feeds stays inert. This is for
|
|
670
|
+
* the broadcast funnel, where a disagreement means something reconstructed the
|
|
671
|
+
* call another way and the reader is one signature from a transfer they never
|
|
672
|
+
* asked for — there, silence is the worse failure.
|
|
673
|
+
*
|
|
674
|
+
* @param bridgeKey - the key the pathway was resolved from
|
|
675
|
+
* @param signedCrossing - the pair on screen, or null when no surface composed it
|
|
676
|
+
* @throws when the two describe different journeys
|
|
677
|
+
*/
|
|
678
|
+
const assertCrossingAgrees = ({ bridgeKey, signedCrossing, }) => {
|
|
679
|
+
const refusal = (0, exports.crossingRefusal)({ bridgeKey, signedCrossing });
|
|
680
|
+
if (refusal !== null) {
|
|
681
|
+
throw new Error(refusal);
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
exports.assertCrossingAgrees = assertCrossingAgrees;
|
|
685
|
+
/**
|
|
686
|
+
* Why a same-chain PulseX swap transaction must not be built for the leg on
|
|
687
|
+
* screen, or null when they agree. The swap-side sibling of
|
|
688
|
+
* {@link crossingRefusal}.
|
|
689
|
+
*
|
|
690
|
+
* Two refusals, each a separate way the two can part company:
|
|
691
|
+
*
|
|
692
|
+
* - THE LEG ON SCREEN NAMES A CROSSING. A caller building a swap transaction
|
|
693
|
+
* while the reader is looking at a two-chain crossing would sign the wrong
|
|
694
|
+
* kind of thing for what is on screen.
|
|
695
|
+
* - THE SWAP DOES NOT EXECUTE ON THE CHAIN THE READER IS LOOKING AT. A stale
|
|
696
|
+
* candidate built for a chain the address bar has since left.
|
|
697
|
+
*
|
|
698
|
+
* @param signedLeg - what the surface believes this signature does, or null
|
|
699
|
+
* when no surface composed it
|
|
700
|
+
* @param chainId - the chain the candidate swap transaction actually executes on
|
|
701
|
+
* @returns the reason to refuse, or null when the two agree
|
|
702
|
+
*/
|
|
703
|
+
const swapRefusal = ({ signedLeg, chainId, }) => {
|
|
704
|
+
// `undefined` treated as `null`, matching `crossingRefusal`'s own guard: the
|
|
705
|
+
// field is required by the type, so only a test double or a crash inside the
|
|
706
|
+
// cascade could omit it.
|
|
707
|
+
if (signedLeg === null || signedLeg === undefined) {
|
|
708
|
+
return null;
|
|
709
|
+
}
|
|
710
|
+
if (signedLeg.kind !== 'swap') {
|
|
711
|
+
return `Refusing to build a same-chain swap for a selection that names a ${signedLeg.kind} (chain ${signedLeg.originChainId} to chain ${signedLeg.destinationChainId}).`;
|
|
712
|
+
}
|
|
713
|
+
if (chainId === null) {
|
|
714
|
+
return `Refusing to build a same-chain swap: no chain was resolved for it.`;
|
|
715
|
+
}
|
|
716
|
+
if (signedLeg.chainId !== chainId) {
|
|
717
|
+
return `Refusing to build a swap on chain ${chainId} while the selection names chain ${signedLeg.chainId}.`;
|
|
718
|
+
}
|
|
719
|
+
return null;
|
|
720
|
+
};
|
|
721
|
+
exports.swapRefusal = swapRefusal;
|
|
722
|
+
/**
|
|
723
|
+
* Throws when the leg on screen and the candidate swap transaction describe
|
|
724
|
+
* different journeys. The swap-side sibling of {@link assertCrossingAgrees} —
|
|
725
|
+
* loud where {@link swapRefusal} is quiet, for the same reason: this runs one
|
|
726
|
+
* step before the wallet, where silence is what lets a reader sign.
|
|
727
|
+
*
|
|
728
|
+
* @param signedLeg - what the surface believes this signature does, or null
|
|
729
|
+
* @param chainId - the chain the candidate swap transaction actually executes on
|
|
730
|
+
* @throws when the two describe different journeys
|
|
731
|
+
*/
|
|
732
|
+
const assertSwapAgrees = ({ signedLeg, chainId, }) => {
|
|
733
|
+
const refusal = (0, exports.swapRefusal)({ signedLeg, chainId });
|
|
734
|
+
if (refusal !== null) {
|
|
735
|
+
throw new Error(refusal);
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
exports.assertSwapAgrees = assertSwapAgrees;
|
|
739
|
+
/**
|
|
740
|
+
* Why a candidate must not be signed for the leg and section a caller is
|
|
741
|
+
* about to build calldata for, or null when they agree. The candidate-pick
|
|
742
|
+
* sibling of {@link crossingRefusal}/{@link swapRefusal}.
|
|
743
|
+
*
|
|
744
|
+
* UNLIKE THOSE TWO, A MISSING PICK IS ITSELF A REFUSAL. `crossingRefusal` and
|
|
745
|
+
* `swapRefusal` let a null leg through because some calls compose no screen at
|
|
746
|
+
* all (the aggregator's own executor call). A candidate-signing sender always
|
|
747
|
+
* has a screen — the route the reader picked — so a candidate id with no
|
|
748
|
+
* recorded leg is exactly the gap this type exists to close: `candidateId`
|
|
749
|
+
* alone used to be treated as sufficient identity, and this function is what
|
|
750
|
+
* stops it from being treated that way again.
|
|
751
|
+
*
|
|
752
|
+
* @param pick - what the route recorded it picked, or null/undefined when the
|
|
753
|
+
* producer that built the route never set one
|
|
754
|
+
* @param leg - the leg the caller is about to build calldata for
|
|
755
|
+
* @param sectionIndex - the route section the caller is about to build
|
|
756
|
+
* calldata for
|
|
757
|
+
* @returns the reason to refuse, or null when they agree
|
|
758
|
+
*/
|
|
759
|
+
const candidatePickRefusal = ({ pick, leg, sectionIndex, }) => {
|
|
760
|
+
if (pick === null || pick === undefined) {
|
|
761
|
+
return `Refusing to sign a ${leg} at section ${sectionIndex}: the route named no candidate to sign.`;
|
|
762
|
+
}
|
|
763
|
+
if (pick.leg !== leg) {
|
|
764
|
+
return `Refusing to sign candidate ${pick.candidateId}'s ${pick.leg} leg as a ${leg}: the route picked a different kind of leg.`;
|
|
765
|
+
}
|
|
766
|
+
if (pick.sectionIndex !== sectionIndex) {
|
|
767
|
+
return `Refusing to sign candidate ${pick.candidateId} for section ${sectionIndex}: the route picked it for section ${pick.sectionIndex}.`;
|
|
768
|
+
}
|
|
769
|
+
return null;
|
|
770
|
+
};
|
|
771
|
+
exports.candidatePickRefusal = candidatePickRefusal;
|
|
772
|
+
/**
|
|
773
|
+
* Throws when a candidate pick and the leg/section a caller is about to build
|
|
774
|
+
* calldata for describe different signatures. The candidate-pick sibling of
|
|
775
|
+
* {@link assertCrossingAgrees}/{@link assertSwapAgrees} — loud where {@link
|
|
776
|
+
* candidatePickRefusal} is quiet, for the same reason: this runs one step
|
|
777
|
+
* before the wallet, where silence is what lets a reader sign the wrong thing.
|
|
778
|
+
*
|
|
779
|
+
* @param pick - what the route recorded it picked, or null
|
|
780
|
+
* @param leg - the leg the caller is about to build calldata for
|
|
781
|
+
* @param sectionIndex - the route section the caller is about to build
|
|
782
|
+
* calldata for
|
|
783
|
+
* @throws when the pick and the leg/section being built describe different
|
|
784
|
+
* signatures
|
|
785
|
+
*/
|
|
786
|
+
const assertCandidatePickAgrees = ({ pick, leg, sectionIndex, }) => {
|
|
787
|
+
const refusal = (0, exports.candidatePickRefusal)({ pick, leg, sectionIndex });
|
|
788
|
+
if (refusal !== null) {
|
|
789
|
+
throw new Error(refusal);
|
|
790
|
+
}
|
|
791
|
+
};
|
|
792
|
+
exports.assertCandidatePickAgrees = assertCandidatePickAgrees;
|
|
793
|
+
/**
|
|
794
|
+
* Calculates the same-chain PulseX swap transaction inputs, or null when the
|
|
795
|
+
* inputs cannot form a call — including when the leg on screen and the swap's
|
|
796
|
+
* own chain disagree. The swap-side sibling of {@link transactionInputs}.
|
|
797
|
+
*
|
|
798
|
+
* SAME SHAPE AS `transactionInputs`, deliberately: `{ to, value, data } | null`,
|
|
799
|
+
* so a caller can dispatch either builder's result through one `sendTransaction`
|
|
800
|
+
* without a second shape to handle.
|
|
801
|
+
*
|
|
802
|
+
* WRAPPING AND UNWRAPPING THE NATIVE COIN USE THE ROUTER'S OWN NATIVE-COIN
|
|
803
|
+
* FUNCTIONS, not a separate deposit/withdraw step — one router contract wraps
|
|
804
|
+
* on the way in (`swapExactETHForTokens`) and unwraps on the way out
|
|
805
|
+
* (`swapExactTokensForETH`), the same contract `swapExactTokensForTokens`
|
|
806
|
+
* already targets when neither side is native.
|
|
807
|
+
*
|
|
808
|
+
* @param signedLeg - what the surface believes this signature does, or null
|
|
809
|
+
* @param chainId - the chain the swap actually executes on
|
|
810
|
+
* @param routerAddress - the PulseX router this swap is sent to, or null when
|
|
811
|
+
* none is deployed for this chain
|
|
812
|
+
* @param fromTokenAddress - the input token address, or the zero address for
|
|
813
|
+
* the chain's native coin
|
|
814
|
+
* @param toTokenAddress - the output token address, or the zero address for
|
|
815
|
+
* the chain's native coin
|
|
816
|
+
* @param swapPath - the ordered swap path — for a route-search hop, the one
|
|
817
|
+
* its quote was priced along (`pulseXSwapPathForHop`),
|
|
818
|
+
* already expressed in the router's own token addresses — the wrapped-native
|
|
819
|
+
* token stands in for either native end
|
|
820
|
+
* @param amountIn - the amount to swap, in the input token's base units
|
|
821
|
+
* @param minAmountOut - the minimum acceptable output after slippage, in the
|
|
822
|
+
* output token's base units
|
|
823
|
+
* @param recipient - the address the swap delivers to
|
|
824
|
+
* @param deadline - the unix-seconds deadline the router enforces
|
|
825
|
+
* @returns the transaction inputs, or null when the inputs cannot form a call
|
|
826
|
+
*/
|
|
827
|
+
const pulseXSwapTransactionInputs = ({ signedLeg, chainId, routerAddress, fromTokenAddress, toTokenAddress, swapPath, amountIn, minAmountOut, recipient, deadline, }) => {
|
|
828
|
+
// FIRST, BEFORE ANY ENCODING — see `transactionInputs`'s identical note.
|
|
829
|
+
if ((0, exports.swapRefusal)({ signedLeg, chainId }) !== null) {
|
|
830
|
+
return null;
|
|
831
|
+
}
|
|
832
|
+
if (!routerAddress) {
|
|
833
|
+
return null;
|
|
834
|
+
}
|
|
835
|
+
if (!recipient || !(0, viem_1.isAddress)(recipient) || recipient === viem_1.zeroAddress) {
|
|
836
|
+
return null;
|
|
837
|
+
}
|
|
838
|
+
if (swapPath.length < 2) {
|
|
839
|
+
return null;
|
|
840
|
+
}
|
|
841
|
+
if (amountIn <= 0n) {
|
|
842
|
+
return null;
|
|
843
|
+
}
|
|
844
|
+
const fromIsNative = fromTokenAddress === viem_1.zeroAddress;
|
|
845
|
+
const toIsNative = toTokenAddress === viem_1.zeroAddress;
|
|
846
|
+
// Native-to-native names no real swap — there is nothing for the router to do.
|
|
847
|
+
if (fromIsNative && toIsNative) {
|
|
848
|
+
return null;
|
|
849
|
+
}
|
|
850
|
+
if (fromIsNative) {
|
|
851
|
+
return {
|
|
852
|
+
to: routerAddress,
|
|
853
|
+
value: amountIn,
|
|
854
|
+
data: (0, viem_1.encodeFunctionData)({
|
|
855
|
+
abi: abis.univ2Router,
|
|
856
|
+
functionName: 'swapExactETHForTokens',
|
|
857
|
+
args: [minAmountOut, swapPath, recipient, deadline],
|
|
858
|
+
}),
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
if (toIsNative) {
|
|
862
|
+
return {
|
|
863
|
+
to: routerAddress,
|
|
864
|
+
value: 0n,
|
|
865
|
+
data: (0, viem_1.encodeFunctionData)({
|
|
866
|
+
abi: abis.univ2Router,
|
|
867
|
+
functionName: 'swapExactTokensForETH',
|
|
868
|
+
args: [amountIn, minAmountOut, swapPath, recipient, deadline],
|
|
869
|
+
}),
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
return {
|
|
873
|
+
to: routerAddress,
|
|
874
|
+
value: 0n,
|
|
875
|
+
data: (0, viem_1.encodeFunctionData)({
|
|
876
|
+
abi: abis.univ2Router,
|
|
877
|
+
functionName: 'swapExactTokensForTokens',
|
|
878
|
+
args: [amountIn, minAmountOut, swapPath, recipient, deadline],
|
|
879
|
+
}),
|
|
880
|
+
};
|
|
881
|
+
};
|
|
882
|
+
exports.pulseXSwapTransactionInputs = pulseXSwapTransactionInputs;
|
|
883
|
+
/**
|
|
884
|
+
* Calculates the transaction inputs from the bridge pathway, asset in, recipient, account, asset link, destination data param, amount to bridge, fee director struct encoded, and should deliver
|
|
885
|
+
* @param bridgeKey - the key the pathway was resolved from, for {@link crossingRefusal}
|
|
886
|
+
* @param signedCrossing - the chain pair on screen, or null when no surface composed it
|
|
887
|
+
* @param bridgePathway - the bridge pathway to use
|
|
888
|
+
* @param assetIn - the asset in to bridge
|
|
889
|
+
* @param recipient - the recipient of the bridge
|
|
890
|
+
* @param account - the account to bridge from
|
|
891
|
+
* @param assetLink - the asset link to use
|
|
892
|
+
* @param destinationDataParam - the destination data param to use
|
|
893
|
+
* @param amountToBridge - the amount to bridge
|
|
894
|
+
* @param feeDirectorStructEncoded - the fee director struct encoded to use
|
|
895
|
+
* @param shouldDeliver - whether to deliver the tokens to the recipient
|
|
896
|
+
* @returns the transaction inputs, or null when the inputs cannot form a call —
|
|
897
|
+
* including when the pathway crosses somewhere other than the pair on screen
|
|
898
|
+
*/
|
|
899
|
+
const transactionInputs = ({ bridgeKey, signedCrossing, bridgePathway, assetIn, recipient, account, assetLink, destinationDataParam, amountToBridge, feeDirectorStructEncoded, shouldDeliver, }) => {
|
|
900
|
+
// FIRST, BEFORE ANY ENCODING. Every branch below writes a real mediator call;
|
|
901
|
+
// by the time one is chosen the disagreement is already encoded.
|
|
902
|
+
if ((0, exports.crossingRefusal)({ bridgeKey, signedCrossing }) !== null) {
|
|
903
|
+
return null;
|
|
904
|
+
}
|
|
905
|
+
if (!bridgePathway) {
|
|
906
|
+
return null;
|
|
907
|
+
}
|
|
908
|
+
// check that recipient is valid
|
|
909
|
+
if (!recipient || !(0, viem_1.isAddress)(recipient) || recipient === viem_1.zeroAddress) {
|
|
910
|
+
return null;
|
|
911
|
+
}
|
|
912
|
+
// check that wallet account is valid
|
|
913
|
+
if (!account || !(0, viem_1.isAddress)(account) || account === viem_1.zeroAddress) {
|
|
914
|
+
return null;
|
|
915
|
+
}
|
|
916
|
+
// check that asset in is valid
|
|
917
|
+
if (!assetIn) {
|
|
918
|
+
return null;
|
|
919
|
+
}
|
|
920
|
+
// check that asset link is valid
|
|
921
|
+
if (!assetLink) {
|
|
922
|
+
return null;
|
|
923
|
+
}
|
|
924
|
+
let value = 0n;
|
|
925
|
+
// we are moving "from" this side, so we need to call a function on the "from" address
|
|
926
|
+
// only relevant for the relayTokens(AndCall) pathway outside of native tokens
|
|
927
|
+
let toAddress = bridgePathway.from;
|
|
928
|
+
let data = '0x';
|
|
929
|
+
const inputIsBridgeToken = (0, exports.interactingWithBridgeToken)({
|
|
930
|
+
assetLink,
|
|
931
|
+
assetInAddress: assetIn.address,
|
|
932
|
+
});
|
|
933
|
+
if (inputIsBridgeToken) {
|
|
934
|
+
// when interacting with a bridged token, we need to call the token address directly
|
|
935
|
+
toAddress = assetIn.address;
|
|
936
|
+
value = 0n;
|
|
937
|
+
// if we want delivery of the tokens (going from home to foreign) then we need to have the foreign data param
|
|
938
|
+
// and it needs to start with the destination router
|
|
939
|
+
if (!destinationDataParam) {
|
|
940
|
+
return null;
|
|
941
|
+
}
|
|
942
|
+
data = bridgePathway.usesExtraParam
|
|
943
|
+
? (0, viem_1.encodeFunctionData)({
|
|
944
|
+
abi: abis.erc677ExtraInput,
|
|
945
|
+
functionName: 'transferAndCall',
|
|
946
|
+
args: [bridgePathway.from, amountToBridge, destinationDataParam, account],
|
|
947
|
+
})
|
|
948
|
+
: (0, viem_1.encodeFunctionData)({
|
|
949
|
+
abi: abis.erc677,
|
|
950
|
+
functionName: 'transferAndCall',
|
|
951
|
+
args: [bridgePathway.from, amountToBridge, destinationDataParam],
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
else if (assetIn.address === viem_1.zeroAddress) {
|
|
955
|
+
value = amountToBridge;
|
|
956
|
+
toAddress = bridgePathway.nativeRouter;
|
|
957
|
+
if (bridgePathway.feeManager === 'from' && shouldDeliver) {
|
|
958
|
+
// transferring native to foreign
|
|
959
|
+
if (!feeDirectorStructEncoded)
|
|
960
|
+
return null;
|
|
961
|
+
if (!bridgePathway.destinationRouter)
|
|
962
|
+
return null;
|
|
963
|
+
data = bridgePathway.usesExtraParam
|
|
964
|
+
? (0, viem_1.encodeFunctionData)({
|
|
965
|
+
abi: abis.nativeRouterExtraInput,
|
|
966
|
+
functionName: 'relayTokensAndCall',
|
|
967
|
+
args: [bridgePathway.destinationRouter, feeDirectorStructEncoded, account],
|
|
968
|
+
})
|
|
969
|
+
: (0, viem_1.encodeFunctionData)({
|
|
970
|
+
abi: abis.nativeRouter,
|
|
971
|
+
functionName: 'relayTokensAndCall',
|
|
972
|
+
args: [bridgePathway.destinationRouter, feeDirectorStructEncoded],
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
else {
|
|
976
|
+
// delivery always occurs when moving from foreign to home
|
|
977
|
+
data = bridgePathway.usesExtraParam
|
|
978
|
+
? (0, viem_1.encodeFunctionData)({
|
|
979
|
+
abi: abis.nativeRouterExtraInput,
|
|
980
|
+
functionName: 'wrapAndRelayTokens',
|
|
981
|
+
args: [recipient, account],
|
|
982
|
+
})
|
|
983
|
+
: (0, viem_1.encodeFunctionData)({
|
|
984
|
+
abi: abis.nativeRouter,
|
|
985
|
+
functionName: 'wrapAndRelayTokens',
|
|
986
|
+
args: [recipient],
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
else {
|
|
991
|
+
// tokens native to this side, entering the bridge
|
|
992
|
+
if (shouldDeliver && bridgePathway.requiresDelivery) {
|
|
993
|
+
if (!feeDirectorStructEncoded)
|
|
994
|
+
return null;
|
|
995
|
+
if (!bridgePathway.destinationRouter)
|
|
996
|
+
return null;
|
|
997
|
+
data = bridgePathway.usesExtraParam
|
|
998
|
+
? (0, viem_1.encodeFunctionData)({
|
|
999
|
+
abi: abis.inputBridgeExtraInput,
|
|
1000
|
+
functionName: 'relayTokensAndCall',
|
|
1001
|
+
args: [
|
|
1002
|
+
assetIn.address,
|
|
1003
|
+
bridgePathway.destinationRouter,
|
|
1004
|
+
amountToBridge,
|
|
1005
|
+
feeDirectorStructEncoded,
|
|
1006
|
+
account,
|
|
1007
|
+
],
|
|
1008
|
+
})
|
|
1009
|
+
: (0, viem_1.encodeFunctionData)({
|
|
1010
|
+
abi: abis.inputBridge,
|
|
1011
|
+
functionName: 'relayTokensAndCall',
|
|
1012
|
+
args: [
|
|
1013
|
+
assetIn.address,
|
|
1014
|
+
bridgePathway.destinationRouter,
|
|
1015
|
+
amountToBridge,
|
|
1016
|
+
feeDirectorStructEncoded,
|
|
1017
|
+
],
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
else {
|
|
1021
|
+
data = bridgePathway.usesExtraParam
|
|
1022
|
+
? (0, viem_1.encodeFunctionData)({
|
|
1023
|
+
abi: abis.inputBridgeExtraInput,
|
|
1024
|
+
functionName: 'relayTokens',
|
|
1025
|
+
args: [assetIn.address, recipient, amountToBridge, account],
|
|
1026
|
+
})
|
|
1027
|
+
: (0, viem_1.encodeFunctionData)({
|
|
1028
|
+
abi: abis.inputBridge,
|
|
1029
|
+
functionName: 'relayTokens',
|
|
1030
|
+
args: [assetIn.address, recipient, amountToBridge],
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
return {
|
|
1035
|
+
to: toAddress,
|
|
1036
|
+
value,
|
|
1037
|
+
data,
|
|
1038
|
+
};
|
|
1039
|
+
};
|
|
1040
|
+
exports.transactionInputs = transactionInputs;
|
|
1041
|
+
/**
|
|
1042
|
+
* Calculates the asset out key from the bridge key path, asset in address, and unwrap
|
|
1043
|
+
* @param bridgeKeyPath - the bridge key path
|
|
1044
|
+
* @param assetInAddress - the asset in address
|
|
1045
|
+
* @param unwrap - whether to unwrap
|
|
1046
|
+
* @returns the asset out key
|
|
1047
|
+
*/
|
|
1048
|
+
const assetOutKey = ({ bridgeKeyPath, assetInAddress, unwrap, }) => {
|
|
1049
|
+
if (!bridgeKeyPath || !assetInAddress)
|
|
1050
|
+
return null;
|
|
1051
|
+
return `${bridgeKeyPath}/${unwrap ? 'native' : 'erc20'}/${assetInAddress.toLowerCase()}`;
|
|
1052
|
+
};
|
|
1053
|
+
exports.assetOutKey = assetOutKey;
|
|
1054
|
+
/**
|
|
1055
|
+
* Returns the asset out from the asset in address, assets out, bridge key path, and unwrap
|
|
1056
|
+
* @param assetInAddress - the asset in address
|
|
1057
|
+
* @param assetsOut - the assets out
|
|
1058
|
+
* @param bridgeKeyPath - the bridge key path
|
|
1059
|
+
* @param unwrap - whether to unwrap
|
|
1060
|
+
* @returns the asset out
|
|
1061
|
+
*/
|
|
1062
|
+
const assetOut = ({ assetInAddress, assetsOut, bridgeKeyPath, unwrap, }) => {
|
|
1063
|
+
if (!assetInAddress)
|
|
1064
|
+
return null;
|
|
1065
|
+
const key = (0, exports.assetOutKey)({
|
|
1066
|
+
bridgeKeyPath,
|
|
1067
|
+
assetInAddress,
|
|
1068
|
+
unwrap,
|
|
1069
|
+
});
|
|
1070
|
+
if (!key)
|
|
1071
|
+
return null;
|
|
1072
|
+
return assetsOut.get(key) ?? null;
|
|
1073
|
+
};
|
|
1074
|
+
exports.assetOut = assetOut;
|