@gibs/bridge-sdk 1.7.1 → 1.7.2
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/dist/src/abis.d.ts +14 -1
- package/dist/src/abis.js +14 -1
- package/dist/src/chain-info.d.ts +52 -0
- package/dist/src/chain-info.js +51 -15
- package/dist/src/config.d.ts +61 -2
- package/dist/src/config.js +63 -92
- package/dist/src/fee-type.d.ts +3 -0
- package/dist/src/fee-type.js +2 -0
- package/dist/src/image-links.d.ts +29 -0
- package/dist/src/image-links.js +28 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/settings.d.ts +341 -0
- package/dist/src/settings.js +614 -0
- package/dist/src/types.d.ts +9 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/src/abis.ts +14 -2
- package/src/chain-info.ts +53 -15
- package/src/config.ts +66 -92
- package/src/fee-type.ts +3 -1
- package/src/image-links.ts +29 -0
- package/src/index.ts +1 -0
- package/src/settings.ts +853 -0
- package/src/types.ts +9 -0
|
@@ -0,0 +1,614 @@
|
|
|
1
|
+
import { concatHex, encodeAbiParameters, encodeFunctionData, getAddress, isAddress, zeroAddress } from "viem";
|
|
2
|
+
import { isNative, nativeAssetOut, pathway } from "./config.js";
|
|
3
|
+
import { FeeType } from "./fee-type.js";
|
|
4
|
+
import * as abis from "./abis.js";
|
|
5
|
+
export const oneEther = 10n ** 18n;
|
|
6
|
+
export const basisPoints = 10000n;
|
|
7
|
+
/**
|
|
8
|
+
* Returns the bridge pathway (configuration) for a given bridge key, asset in, and whether to use the production pathway
|
|
9
|
+
* @param bridgeKey - the bridge key to use
|
|
10
|
+
* @param isProd - whether to use the production pathway
|
|
11
|
+
* @param assetIn - the asset in to bridge
|
|
12
|
+
* @returns the bridge pathway
|
|
13
|
+
*/
|
|
14
|
+
export const bridgePathway = ({ bridgeKey, isProd, assetIn, }) => (pathway(bridgeKey, isProd, assetIn?.address) ?? null);
|
|
15
|
+
/**
|
|
16
|
+
* Retrieves the amount to bridge from the amount and asset in. If either of them is nil, returns 0n
|
|
17
|
+
* @param amountIn - the amount to bridge
|
|
18
|
+
* @param assetIn - the asset in to bridge
|
|
19
|
+
* @returns the amount to bridge
|
|
20
|
+
*/
|
|
21
|
+
export const amountToBridge = ({ amountIn, assetIn, }) => {
|
|
22
|
+
if (!amountIn || amountIn === 0n || !assetIn) {
|
|
23
|
+
return 0n;
|
|
24
|
+
}
|
|
25
|
+
return amountIn;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Calculates the bridge cost from the amount to bridge and bridge fee
|
|
29
|
+
* @param amountToBridge - the amount to bridge
|
|
30
|
+
* @param bridgeFee - the bridge fee
|
|
31
|
+
* @returns the bridge cost
|
|
32
|
+
*/
|
|
33
|
+
export const bridgeCost = ({ amountToBridge, bridgeFee, }) => {
|
|
34
|
+
if (bridgeFee === null)
|
|
35
|
+
return null;
|
|
36
|
+
return (amountToBridge * bridgeFee) / oneEther;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Calculates the amount after bridge fee from the amount to bridge and bridge cost
|
|
40
|
+
* @param amountToBridge - the amount to bridge
|
|
41
|
+
* @param bridgeCost - the bridge cost
|
|
42
|
+
* @returns the amount after bridge fee
|
|
43
|
+
*/
|
|
44
|
+
export const amountAfterBridgeFee = ({ amountToBridge, bridgeCost, }) => {
|
|
45
|
+
if (bridgeCost === null)
|
|
46
|
+
return null;
|
|
47
|
+
const afterFee = amountToBridge - bridgeCost;
|
|
48
|
+
if (afterFee < 0n)
|
|
49
|
+
return 0n;
|
|
50
|
+
return afterFee;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Calculates the estimated amount out from the amount after bridge fee and fee
|
|
54
|
+
* @param amountAfterBridgeFee - the amount after bridge fee
|
|
55
|
+
* @param fee - the fee
|
|
56
|
+
* @returns the estimated amount out
|
|
57
|
+
*/
|
|
58
|
+
export const estimatedAmountOut = ({ amountAfterBridgeFee, fee, }) => {
|
|
59
|
+
if (typeof fee !== 'bigint')
|
|
60
|
+
return null;
|
|
61
|
+
if (amountAfterBridgeFee === null)
|
|
62
|
+
return null;
|
|
63
|
+
if (fee > amountAfterBridgeFee)
|
|
64
|
+
return 0n;
|
|
65
|
+
return amountAfterBridgeFee - fee;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Calculates the estimated fee from the amount after bridge fee, fee, percent fee, fee type, limit, and whether to deliver the costs
|
|
69
|
+
* @param amountAfterBridgeFee - the amount after bridge fee
|
|
70
|
+
* @param fee - the fee
|
|
71
|
+
* @param percentFee - the percent fee
|
|
72
|
+
* @param feeType - the fee type
|
|
73
|
+
* @param limit - the limit
|
|
74
|
+
* @param costsToDeliver - whether to deliver the costs
|
|
75
|
+
* @returns the estimated fee
|
|
76
|
+
*/
|
|
77
|
+
export const estimatedFee = ({ amountAfterBridgeFee, fee, percentFee, feeType, limit, costsToDeliver, }) => {
|
|
78
|
+
const fixedFee = amountAfterBridgeFee ? (amountAfterBridgeFee * percentFee) / oneEther : null;
|
|
79
|
+
if (!costsToDeliver) {
|
|
80
|
+
return 0n;
|
|
81
|
+
}
|
|
82
|
+
if (feeType === FeeType.FIXED) {
|
|
83
|
+
return fee;
|
|
84
|
+
}
|
|
85
|
+
else if (feeType === FeeType.PERCENT) {
|
|
86
|
+
if (amountAfterBridgeFee === null)
|
|
87
|
+
return null;
|
|
88
|
+
return fixedFee;
|
|
89
|
+
}
|
|
90
|
+
else if (feeType === FeeType.GAS_TIP) {
|
|
91
|
+
return limit;
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Calculates the estimated native network cost from the estimated gas and latest base fee per gas
|
|
97
|
+
* @param estimatedGas - the estimated gas
|
|
98
|
+
* @param latestBaseFeePerGas - the latest base fee per gas
|
|
99
|
+
* @param requiresDelivery - whether to deliver the costs
|
|
100
|
+
* @returns the estimated native network cost
|
|
101
|
+
*/
|
|
102
|
+
export const estimatedNativeNetworkCost = ({ estimatedGas, latestBaseFeePerGas, requiresDelivery, }) => {
|
|
103
|
+
if (!estimatedGas || !latestBaseFeePerGas || !requiresDelivery) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
return BigInt(estimatedGas * latestBaseFeePerGas);
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Calculates the estimated token network cost from the estimated native
|
|
110
|
+
* network cost, price corrective, decimals, and one token int
|
|
111
|
+
* @param estimatedNativeNetworkCost - the estimated native network cost
|
|
112
|
+
* @param priceCorrective - the price corrective
|
|
113
|
+
* @param decimals - the decimals
|
|
114
|
+
* @param oneTokenInt - the one token int
|
|
115
|
+
* @returns the estimated token network cost
|
|
116
|
+
*/
|
|
117
|
+
export const estimatedTokenNetworkCost = ({ estimatedNativeNetworkCost, priceCorrective, decimals, oneTokenInt, }) => {
|
|
118
|
+
if (!priceCorrective || !oneTokenInt || !estimatedNativeNetworkCost || !decimals) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const tokenCost = (estimatedNativeNetworkCost * oneTokenInt) / priceCorrective;
|
|
122
|
+
return tokenCost;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Calculates one token of the asset in as an int
|
|
126
|
+
* @param assetIn - the asset in to bridge
|
|
127
|
+
* @returns the one token int
|
|
128
|
+
*/
|
|
129
|
+
export const oneTokenInt = ({ assetIn, }) => {
|
|
130
|
+
if (!assetIn)
|
|
131
|
+
return 1n;
|
|
132
|
+
return 10n ** BigInt(assetIn.decimals);
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Returns the limit as a bigint. Nil uses 0n
|
|
136
|
+
* @param lim - the limit
|
|
137
|
+
* @returns the limit
|
|
138
|
+
*/
|
|
139
|
+
export const limit = (lim) => {
|
|
140
|
+
if (!lim) {
|
|
141
|
+
return 0n;
|
|
142
|
+
}
|
|
143
|
+
return lim;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Returns the network switch asset out address from the asset out, unwrap, and to chain
|
|
147
|
+
* @param assetOut - the asset out
|
|
148
|
+
* @param unwrap - whether to unwrap
|
|
149
|
+
* @param toChain - the chain to switch to
|
|
150
|
+
* @returns the network switch asset out address
|
|
151
|
+
*/
|
|
152
|
+
export const networkSwitchAssetOutAddress = ({ assetOut, unwrap, toChain, }) => {
|
|
153
|
+
if (!assetOut)
|
|
154
|
+
return null;
|
|
155
|
+
if (!unwrap)
|
|
156
|
+
return assetOut.address;
|
|
157
|
+
return nativeAssetOut[toChain] === assetOut.address ? zeroAddress : assetOut.address;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Calculates the desired excess compensation basis points from the path, asset in, asset out, bridge key, fee type, list, and asset out address
|
|
161
|
+
* @param path - the path
|
|
162
|
+
* @param assetIn - the asset in to bridge
|
|
163
|
+
* @param assetOut - the asset out
|
|
164
|
+
* @param bridgeKey - the bridge key
|
|
165
|
+
* @param feeType - the fee type
|
|
166
|
+
* @param list - the list
|
|
167
|
+
* @param assetOutAddress - the asset out address
|
|
168
|
+
* @returns the desired excess compensation basis points
|
|
169
|
+
*/
|
|
170
|
+
export const desiredExcessCompensationBasisPoints = ({ path, assetIn, assetOut, bridgeKey, feeType, list, assetOutAddress, }) => {
|
|
171
|
+
if (!path?.requiresDelivery) {
|
|
172
|
+
return 0n;
|
|
173
|
+
}
|
|
174
|
+
return (!assetIn
|
|
175
|
+
? 0n
|
|
176
|
+
: feeType === FeeType.PERCENT
|
|
177
|
+
? 1000n
|
|
178
|
+
: isNative(assetIn, bridgeKey) || isNative(assetOut, bridgeKey)
|
|
179
|
+
? 1000n
|
|
180
|
+
: list.has(getAddress(assetIn?.address ?? '')) ||
|
|
181
|
+
list.has(assetOutAddress ? getAddress(assetOutAddress) : '0x')
|
|
182
|
+
? 5000n
|
|
183
|
+
: 10000n);
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Calculates the estimated cost from the should deliver, amount after bridge fee, percent fee,
|
|
187
|
+
* estimated token network cost, reasonable percent on top of gas fee, and fee type
|
|
188
|
+
* @param shouldDeliver - whether to deliver the costs
|
|
189
|
+
* @param amountAfterBridgeFee - the amount after bridge fee
|
|
190
|
+
* @param percentFee - the percent fee
|
|
191
|
+
* @param estimatedTokenNetworkCost - the estimated token network cost
|
|
192
|
+
* @param reasonablePercentOnTopOfGasFee - the reasonable percent on top of gas fee
|
|
193
|
+
* @param feeType - the fee type
|
|
194
|
+
* @returns the estimated cost
|
|
195
|
+
*/
|
|
196
|
+
export const estimatedCost = ({ shouldDeliver, amountAfterBridgeFee, percentFee, estimatedTokenNetworkCost, reasonablePercentOnTopOfGasFee, feeType, }) => {
|
|
197
|
+
if (!shouldDeliver) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
if (feeType === FeeType.PERCENT) {
|
|
201
|
+
if (amountAfterBridgeFee === null)
|
|
202
|
+
return null;
|
|
203
|
+
return (amountAfterBridgeFee * (percentFee ?? 0n)) / oneEther;
|
|
204
|
+
}
|
|
205
|
+
// gas tip
|
|
206
|
+
if (!estimatedTokenNetworkCost) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
if (!reasonablePercentOnTopOfGasFee) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
return estimatedTokenNetworkCost * (reasonablePercentOnTopOfGasFee + oneEther);
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* Calculates the reasonable fixed fee from the estimated token network cost and desired excess compensation basis points
|
|
216
|
+
* @param estimatedTokenNetworkCost - the estimated token network cost
|
|
217
|
+
* @param desiredExcessCompensationBasisPoints - the desired excess compensation basis points
|
|
218
|
+
* @returns the reasonable fixed fee
|
|
219
|
+
*/
|
|
220
|
+
export const reasonableFixedFee = ({ estimatedTokenNetworkCost, desiredExcessCompensationBasisPoints, }) => {
|
|
221
|
+
if (!estimatedTokenNetworkCost) {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
return ((estimatedTokenNetworkCost * (25000n + desiredExcessCompensationBasisPoints)) /
|
|
225
|
+
basisPoints);
|
|
226
|
+
};
|
|
227
|
+
/**
|
|
228
|
+
* Calculates the reasonable percent on gas limit from the gas tip fee and estimated token network cost
|
|
229
|
+
* @param gasTipFee - the gas tip fee
|
|
230
|
+
* @param estimatedTokenNetworkCost - the estimated token network cost
|
|
231
|
+
* @returns the reasonable percent on gas limit
|
|
232
|
+
*/
|
|
233
|
+
export const reasonablePercentOnGasLimit = ({ gasTipFee, estimatedTokenNetworkCost, }) => {
|
|
234
|
+
return ((25000n *
|
|
235
|
+
((oneEther + (gasTipFee ?? 0n)) * (estimatedTokenNetworkCost ?? 0n))) /
|
|
236
|
+
(oneEther * basisPoints));
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* Calculates the reasonable percent fee from the reasonable fixed fee and amount after bridge fee
|
|
240
|
+
* @param reasonableFixedFee - the reasonable fixed fee
|
|
241
|
+
* @param amountAfterBridgeFee - the amount after bridge fee
|
|
242
|
+
* @returns the reasonable percent fee
|
|
243
|
+
*/
|
|
244
|
+
export const reasonablePercentFee = ({ reasonableFixedFee, amountAfterBridgeFee, }) => {
|
|
245
|
+
if (!reasonableFixedFee) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
if (!amountAfterBridgeFee) {
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
const highFee = amountAfterBridgeFee / 10n;
|
|
252
|
+
const basisFeeTruncator = 10n ** 14n;
|
|
253
|
+
const max = 1000n * basisFeeTruncator;
|
|
254
|
+
const min = 5n * basisFeeTruncator;
|
|
255
|
+
if (highFee < reasonableFixedFee) {
|
|
256
|
+
return max; // 10%
|
|
257
|
+
}
|
|
258
|
+
const highResPercent = (reasonableFixedFee * oneEther) / amountAfterBridgeFee;
|
|
259
|
+
if (highResPercent < min) {
|
|
260
|
+
return min;
|
|
261
|
+
}
|
|
262
|
+
else if (highResPercent > max) {
|
|
263
|
+
return max;
|
|
264
|
+
}
|
|
265
|
+
const basisPoint = highResPercent / basisFeeTruncator;
|
|
266
|
+
return basisPoint * basisFeeTruncator;
|
|
267
|
+
};
|
|
268
|
+
/**
|
|
269
|
+
* Returns whether the asset in address is interacting with a bridge token
|
|
270
|
+
* @param assetLink - the asset link
|
|
271
|
+
* @param assetInAddress - the asset in address
|
|
272
|
+
* @returns whether the asset in address is interacting with a bridge token
|
|
273
|
+
*/
|
|
274
|
+
export const interactingWithBridgeToken = ({ assetLink, assetInAddress, }) => {
|
|
275
|
+
const { toForeign, toHome } = assetLink || {};
|
|
276
|
+
const { foreign } = toForeign || {};
|
|
277
|
+
const { home } = toHome || {};
|
|
278
|
+
if (!assetInAddress)
|
|
279
|
+
return false;
|
|
280
|
+
return !!((foreign && getAddress(foreign) === getAddress(assetInAddress)) ||
|
|
281
|
+
(home && getAddress(home) === getAddress(assetInAddress)));
|
|
282
|
+
};
|
|
283
|
+
/**
|
|
284
|
+
* 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
|
|
285
|
+
* @param recipient - the recipient
|
|
286
|
+
* @param bridgePathway - the bridge pathway
|
|
287
|
+
* @param feeType - the fee type
|
|
288
|
+
* @param priceCorrective - the price corrective
|
|
289
|
+
* @param gasTipFee - the gas tip fee
|
|
290
|
+
* @param percentFee - the percent fee
|
|
291
|
+
* @param feeTypeSettings - the fee type settings
|
|
292
|
+
* @param limit - the limit
|
|
293
|
+
* @param assetOut - the asset out
|
|
294
|
+
* @returns the fee director struct encoded
|
|
295
|
+
*/
|
|
296
|
+
export const feeDirectorStructEncoded = ({ recipient, bridgePathway, feeType, priceCorrective, gasTipFee, percentFee, feeTypeSettings, limit, assetOut, }) => {
|
|
297
|
+
if (!assetOut || !bridgePathway) {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
if (!bridgePathway.requiresDelivery) {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
if (!priceCorrective) {
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
let multiplier = 0n;
|
|
307
|
+
if (feeType === FeeType.GAS_TIP && priceCorrective > 0n) {
|
|
308
|
+
multiplier =
|
|
309
|
+
((oneEther + (gasTipFee ?? 0n)) * 10n ** BigInt(assetOut.decimals)) /
|
|
310
|
+
priceCorrective;
|
|
311
|
+
}
|
|
312
|
+
else if (feeType === FeeType.PERCENT) {
|
|
313
|
+
multiplier = percentFee ?? 0n;
|
|
314
|
+
}
|
|
315
|
+
if (!recipient || !isAddress(recipient)) {
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
return encodeAbiParameters(abis.feeDeliveryStruct, [
|
|
319
|
+
[recipient, feeTypeSettings, limit, multiplier],
|
|
320
|
+
]);
|
|
321
|
+
};
|
|
322
|
+
/**
|
|
323
|
+
* Calculates the destination data param from the recipient, bridge pathway, asset in, destination router, fee director struct encoded, asset link, should deliver, and unwrap
|
|
324
|
+
* @param recipient - the recipient
|
|
325
|
+
* @param bridgePathway - the bridge pathway
|
|
326
|
+
* @param assetIn - the asset in to bridge
|
|
327
|
+
* @param destinationRouter - the destination router
|
|
328
|
+
* @param feeDirectorStructEncoded - the fee director struct encoded
|
|
329
|
+
* @param assetLink - the asset link
|
|
330
|
+
* @param shouldDeliver - whether to deliver the costs
|
|
331
|
+
* @param unwrap - whether to unwrap
|
|
332
|
+
* @returns the destination data param
|
|
333
|
+
*/
|
|
334
|
+
export const destinationDataParam = ({ recipient, bridgePathway, assetIn, destinationRouter, feeDirectorStructEncoded, assetLink, shouldDeliver, unwrap, }) => {
|
|
335
|
+
// const recipient = input.recipient.value
|
|
336
|
+
if (!recipient) {
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
if (!bridgePathway || !assetIn) {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
if (!destinationRouter) {
|
|
343
|
+
console.log('no destination router');
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
if (bridgePathway.requiresDelivery && !feeDirectorStructEncoded) {
|
|
347
|
+
console.log('no fee director struct encoded');
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
if (!assetLink) {
|
|
351
|
+
console.log('no asset link');
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
if (bridgePathway.requiresDelivery) {
|
|
355
|
+
// going from home to foreign
|
|
356
|
+
if (!shouldDeliver) {
|
|
357
|
+
// act like a regular bridge
|
|
358
|
+
return recipient;
|
|
359
|
+
}
|
|
360
|
+
// going from foreign to home
|
|
361
|
+
if (feeDirectorStructEncoded) {
|
|
362
|
+
return concatHex([destinationRouter, feeDirectorStructEncoded]);
|
|
363
|
+
}
|
|
364
|
+
return recipient;
|
|
365
|
+
}
|
|
366
|
+
if (!unwrap) {
|
|
367
|
+
return recipient;
|
|
368
|
+
}
|
|
369
|
+
// unwrap wpls->pls
|
|
370
|
+
return concatHex([destinationRouter, recipient]);
|
|
371
|
+
};
|
|
372
|
+
/**
|
|
373
|
+
* Converts a desired excess compensation basis point value into a percentage as an integer, with the denominator assumed to be 1e18
|
|
374
|
+
* @param desiredExcessCompensationBasisPoints - the desired excess compensation basis points
|
|
375
|
+
* @returns the reasonable percent on top of gas fee
|
|
376
|
+
*/
|
|
377
|
+
export const reasonablePercentOnTopOfGasFee = ({ desiredExcessCompensationBasisPoints, }) => {
|
|
378
|
+
return (desiredExcessCompensationBasisPoints * (oneEther / basisPoints));
|
|
379
|
+
};
|
|
380
|
+
/**
|
|
381
|
+
* Calculates the desired compensation ratio from the desired excess compensation basis points
|
|
382
|
+
* @param desiredExcessCompensationBasisPoints - the desired excess compensation basis points
|
|
383
|
+
* @returns the desired compensation ratio
|
|
384
|
+
*/
|
|
385
|
+
export const desiredCompensationRatio = ({ desiredExcessCompensationBasisPoints, }) => {
|
|
386
|
+
return oneEther + (desiredExcessCompensationBasisPoints * oneEther) / basisPoints;
|
|
387
|
+
};
|
|
388
|
+
/**
|
|
389
|
+
* Calculates the available compensation maximum from the amount after bridge fee, percent fee, fee type, fixed fee, and limit
|
|
390
|
+
* @param amountAfterBridgeFee - the amount after bridge fee
|
|
391
|
+
* @param percentFee - the percent fee
|
|
392
|
+
* @param feeType - the fee type
|
|
393
|
+
* @param fixedFee - the fixed fee
|
|
394
|
+
* @param limit - the limit
|
|
395
|
+
* @returns the available compensation maximum
|
|
396
|
+
*/
|
|
397
|
+
export const availableCompensationMaximum = ({ amountAfterBridgeFee, percentFee, feeType, fixedFee, limit, }) => {
|
|
398
|
+
if (feeType === FeeType.PERCENT) {
|
|
399
|
+
if (amountAfterBridgeFee === null)
|
|
400
|
+
return null;
|
|
401
|
+
return (amountAfterBridgeFee * (percentFee ?? 0n)) / oneEther;
|
|
402
|
+
}
|
|
403
|
+
else if (feeType === FeeType.GAS_TIP) {
|
|
404
|
+
return limit;
|
|
405
|
+
}
|
|
406
|
+
else if (feeType === FeeType.FIXED) {
|
|
407
|
+
return fixedFee ?? 0n;
|
|
408
|
+
}
|
|
409
|
+
return 0n;
|
|
410
|
+
};
|
|
411
|
+
/**
|
|
412
|
+
* 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
|
|
413
|
+
* @param bridgePathway - the bridge pathway to use
|
|
414
|
+
* @param assetIn - the asset in to bridge
|
|
415
|
+
* @param recipient - the recipient of the bridge
|
|
416
|
+
* @param account - the account to bridge from
|
|
417
|
+
* @param assetLink - the asset link to use
|
|
418
|
+
* @param destinationDataParam - the destination data param to use
|
|
419
|
+
* @param amountToBridge - the amount to bridge
|
|
420
|
+
* @param feeDirectorStructEncoded - the fee director struct encoded to use
|
|
421
|
+
* @param shouldDeliver - whether to deliver the tokens to the recipient
|
|
422
|
+
* @returns the transaction inputs
|
|
423
|
+
*/
|
|
424
|
+
export const transactionInputs = ({ bridgePathway, assetIn, recipient, account, assetLink, destinationDataParam, amountToBridge, feeDirectorStructEncoded, shouldDeliver, }) => {
|
|
425
|
+
if (!bridgePathway) {
|
|
426
|
+
console.log('no bridge pathway');
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
429
|
+
// check that recipient is valid
|
|
430
|
+
if (!recipient ||
|
|
431
|
+
!isAddress(recipient) ||
|
|
432
|
+
account === zeroAddress) {
|
|
433
|
+
console.log('no recipient');
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
// check that wallet account is valid
|
|
437
|
+
if (!account ||
|
|
438
|
+
!isAddress(account) ||
|
|
439
|
+
account === zeroAddress) {
|
|
440
|
+
console.log('no account');
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
// check that asset in is valid
|
|
444
|
+
if (!assetIn) {
|
|
445
|
+
console.log('no asset in');
|
|
446
|
+
return null;
|
|
447
|
+
}
|
|
448
|
+
// check that asset link is valid
|
|
449
|
+
if (!assetLink) {
|
|
450
|
+
console.log('no asset link');
|
|
451
|
+
return null;
|
|
452
|
+
}
|
|
453
|
+
let value = 0n;
|
|
454
|
+
// we are moving "from" this side, so we need to call a function on the "from" address
|
|
455
|
+
// only relevant for the relayTokens(AndCall) pathway outside of native tokens
|
|
456
|
+
let toAddress = bridgePathway.from;
|
|
457
|
+
let data = '0x';
|
|
458
|
+
const inputIsBridgeToken = interactingWithBridgeToken({
|
|
459
|
+
assetLink,
|
|
460
|
+
assetInAddress: assetIn.address,
|
|
461
|
+
});
|
|
462
|
+
if (inputIsBridgeToken) {
|
|
463
|
+
// when interacting with a bridged token, we need to call the token address directly
|
|
464
|
+
toAddress = assetIn.address;
|
|
465
|
+
value = 0n;
|
|
466
|
+
// if we want delivery of the tokens (going from home to foreign) then we need to have the foreign data param
|
|
467
|
+
// and it needs to start with the destination router
|
|
468
|
+
if (!destinationDataParam) {
|
|
469
|
+
return null;
|
|
470
|
+
}
|
|
471
|
+
data = bridgePathway.usesExtraParam
|
|
472
|
+
? encodeFunctionData({
|
|
473
|
+
abi: abis.erc677ExtraInput,
|
|
474
|
+
functionName: 'transferAndCall',
|
|
475
|
+
args: [
|
|
476
|
+
bridgePathway.from,
|
|
477
|
+
amountToBridge,
|
|
478
|
+
destinationDataParam,
|
|
479
|
+
account,
|
|
480
|
+
],
|
|
481
|
+
})
|
|
482
|
+
: encodeFunctionData({
|
|
483
|
+
abi: abis.erc677,
|
|
484
|
+
functionName: 'transferAndCall',
|
|
485
|
+
args: [bridgePathway.from, amountToBridge, destinationDataParam],
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
else if (assetIn.address === zeroAddress) {
|
|
489
|
+
value = amountToBridge;
|
|
490
|
+
toAddress = bridgePathway.nativeRouter;
|
|
491
|
+
if (bridgePathway.feeManager === 'from' && shouldDeliver) {
|
|
492
|
+
// transferring native to foreign
|
|
493
|
+
if (!feeDirectorStructEncoded)
|
|
494
|
+
return null;
|
|
495
|
+
if (!bridgePathway.destinationRouter)
|
|
496
|
+
return null;
|
|
497
|
+
data = bridgePathway.usesExtraParam
|
|
498
|
+
? encodeFunctionData({
|
|
499
|
+
abi: abis.nativeRouterExtraInput,
|
|
500
|
+
functionName: 'relayTokensAndCall',
|
|
501
|
+
args: [
|
|
502
|
+
bridgePathway.destinationRouter,
|
|
503
|
+
feeDirectorStructEncoded,
|
|
504
|
+
account,
|
|
505
|
+
],
|
|
506
|
+
})
|
|
507
|
+
: encodeFunctionData({
|
|
508
|
+
abi: abis.nativeRouter,
|
|
509
|
+
functionName: 'relayTokensAndCall',
|
|
510
|
+
args: [bridgePathway.destinationRouter, feeDirectorStructEncoded],
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
// delivery always occurs when moving from foreign to home
|
|
515
|
+
data = bridgePathway.usesExtraParam
|
|
516
|
+
? encodeFunctionData({
|
|
517
|
+
abi: abis.nativeRouterExtraInput,
|
|
518
|
+
functionName: 'wrapAndRelayTokens',
|
|
519
|
+
args: [recipient, account],
|
|
520
|
+
})
|
|
521
|
+
: encodeFunctionData({
|
|
522
|
+
abi: abis.nativeRouter,
|
|
523
|
+
functionName: 'wrapAndRelayTokens',
|
|
524
|
+
args: [recipient],
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
// tokens native to this side, entering the bridge
|
|
530
|
+
if (shouldDeliver && bridgePathway.requiresDelivery) {
|
|
531
|
+
if (!feeDirectorStructEncoded)
|
|
532
|
+
return null;
|
|
533
|
+
if (!bridgePathway.destinationRouter)
|
|
534
|
+
return null;
|
|
535
|
+
data = bridgePathway.usesExtraParam
|
|
536
|
+
? encodeFunctionData({
|
|
537
|
+
abi: abis.inputBridgeExtraInput,
|
|
538
|
+
functionName: 'relayTokensAndCall',
|
|
539
|
+
args: [
|
|
540
|
+
assetIn.address,
|
|
541
|
+
bridgePathway.destinationRouter,
|
|
542
|
+
amountToBridge,
|
|
543
|
+
feeDirectorStructEncoded,
|
|
544
|
+
account,
|
|
545
|
+
],
|
|
546
|
+
})
|
|
547
|
+
: encodeFunctionData({
|
|
548
|
+
abi: abis.inputBridge,
|
|
549
|
+
functionName: 'relayTokensAndCall',
|
|
550
|
+
args: [
|
|
551
|
+
assetIn.address,
|
|
552
|
+
bridgePathway.destinationRouter,
|
|
553
|
+
amountToBridge,
|
|
554
|
+
feeDirectorStructEncoded,
|
|
555
|
+
],
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
data = bridgePathway.usesExtraParam
|
|
560
|
+
? encodeFunctionData({
|
|
561
|
+
abi: abis.inputBridgeExtraInput,
|
|
562
|
+
functionName: 'relayTokens',
|
|
563
|
+
args: [
|
|
564
|
+
assetIn.address,
|
|
565
|
+
recipient,
|
|
566
|
+
amountToBridge,
|
|
567
|
+
account,
|
|
568
|
+
],
|
|
569
|
+
})
|
|
570
|
+
: encodeFunctionData({
|
|
571
|
+
abi: abis.inputBridge,
|
|
572
|
+
functionName: 'relayTokens',
|
|
573
|
+
args: [assetIn.address, recipient, amountToBridge],
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
return {
|
|
578
|
+
to: toAddress,
|
|
579
|
+
value,
|
|
580
|
+
data,
|
|
581
|
+
};
|
|
582
|
+
};
|
|
583
|
+
/**
|
|
584
|
+
* Calculates the asset out key from the bridge key path, asset in address, and unwrap
|
|
585
|
+
* @param bridgeKeyPath - the bridge key path
|
|
586
|
+
* @param assetInAddress - the asset in address
|
|
587
|
+
* @param unwrap - whether to unwrap
|
|
588
|
+
* @returns the asset out key
|
|
589
|
+
*/
|
|
590
|
+
export const assetOutKey = ({ bridgeKeyPath, assetInAddress, unwrap, }) => {
|
|
591
|
+
if (!bridgeKeyPath || !assetInAddress)
|
|
592
|
+
return null;
|
|
593
|
+
return `${bridgeKeyPath}/${unwrap ? 'native' : 'erc20'}/${assetInAddress.toLowerCase()}`;
|
|
594
|
+
};
|
|
595
|
+
/**
|
|
596
|
+
* Returns the asset out from the asset in address, assets out, bridge key path, and unwrap
|
|
597
|
+
* @param assetInAddress - the asset in address
|
|
598
|
+
* @param assetsOut - the assets out
|
|
599
|
+
* @param bridgeKeyPath - the bridge key path
|
|
600
|
+
* @param unwrap - whether to unwrap
|
|
601
|
+
* @returns the asset out
|
|
602
|
+
*/
|
|
603
|
+
export const assetOut = ({ assetInAddress, assetsOut, bridgeKeyPath, unwrap, }) => {
|
|
604
|
+
if (!assetInAddress)
|
|
605
|
+
return null;
|
|
606
|
+
const key = assetOutKey({
|
|
607
|
+
bridgeKeyPath,
|
|
608
|
+
assetInAddress,
|
|
609
|
+
unwrap,
|
|
610
|
+
});
|
|
611
|
+
if (!key)
|
|
612
|
+
return null;
|
|
613
|
+
return assetsOut.get(key) ?? null;
|
|
614
|
+
};
|
package/dist/src/types.d.ts
CHANGED
|
@@ -1,35 +1,44 @@
|
|
|
1
1
|
import type { Hex, Chain } from 'viem';
|
|
2
2
|
import type { Chains, Provider } from './config.js';
|
|
3
|
+
/** The per network bridge link */
|
|
3
4
|
export type PerNetworkBridgeLink = {
|
|
4
5
|
tokenAddress: Hex;
|
|
5
6
|
};
|
|
7
|
+
/** The extensions for a token */
|
|
6
8
|
export type Extensions = {
|
|
7
9
|
wrapped?: {
|
|
8
10
|
address: Hex;
|
|
9
11
|
};
|
|
10
12
|
bridgeInfo?: Record<number, PerNetworkBridgeLink>;
|
|
11
13
|
};
|
|
14
|
+
/** The metadata for a token */
|
|
12
15
|
export type TokenMetadata = {
|
|
13
16
|
name: string;
|
|
14
17
|
symbol: string;
|
|
15
18
|
decimals: number;
|
|
16
19
|
};
|
|
20
|
+
/** The token for a given asset */
|
|
17
21
|
export type Token = TokenMetadata & {
|
|
18
22
|
address: string;
|
|
19
23
|
chainId: number;
|
|
20
24
|
logoURI: string | null;
|
|
21
25
|
extensions?: Extensions;
|
|
22
26
|
};
|
|
27
|
+
/** The token out for a given asset */
|
|
23
28
|
export type TokenOut = Omit<Token, 'address'> & {
|
|
24
29
|
address: string | null;
|
|
25
30
|
};
|
|
31
|
+
/** The token list for a given asset */
|
|
26
32
|
export type TokenList = {
|
|
27
33
|
tokens: Token[];
|
|
28
34
|
};
|
|
35
|
+
/** The bridge key for a given provider, from chain, and to chain */
|
|
29
36
|
export type BridgeKey = [Provider, Chains, Chains];
|
|
37
|
+
/** The visual chain for a given chain */
|
|
30
38
|
export type VisualChain = Chain & {
|
|
31
39
|
chainId: Chains;
|
|
32
40
|
logoURI: string;
|
|
33
41
|
alt: string;
|
|
34
42
|
};
|
|
43
|
+
/** The metadata for a chain */
|
|
35
44
|
export type ChainsMetadata = Record<Chains, VisualChain>;
|