@rabby-wallet/rabby-bridge 0.0.13-alpha.1 → 0.0.13
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 +1 -159
- package/dist/chains.d.ts +2 -1
- package/dist/chains.js +2 -0
- package/dist/data.d.ts +3 -0
- package/dist/data.js +3 -0
- package/dist/index.d.ts +1 -6
- package/dist/index.js +0 -3
- package/dist/quote.d.ts +4 -26
- package/dist/quote.js +67 -200
- package/package.json +3 -13
- package/dist/calldata/abi.d.ts +0 -29
- package/dist/calldata/abi.js +0 -160
- package/dist/calldata/across/deposit.d.ts +0 -2
- package/dist/calldata/across/deposit.js +0 -36
- package/dist/calldata/across/depositNative.d.ts +0 -2
- package/dist/calldata/across/depositNative.js +0 -45
- package/dist/calldata/across/depositNow.d.ts +0 -2
- package/dist/calldata/across/depositNow.js +0 -35
- package/dist/calldata/across/depositV3.d.ts +0 -2
- package/dist/calldata/across/depositV3.js +0 -35
- package/dist/calldata/across/depositV3Now.d.ts +0 -2
- package/dist/calldata/across/depositV3Now.js +0 -34
- package/dist/calldata/across/index.d.ts +0 -4
- package/dist/calldata/across/index.js +0 -31
- package/dist/calldata/across/swapAndBridge.d.ts +0 -2
- package/dist/calldata/across/swapAndBridge.js +0 -70
- package/dist/calldata/across/validate.d.ts +0 -3
- package/dist/calldata/across/validate.js +0 -34
- package/dist/calldata/chains.d.ts +0 -2
- package/dist/calldata/chains.js +0 -35
- package/dist/calldata/destination.d.ts +0 -6
- package/dist/calldata/destination.js +0 -211
- package/dist/calldata/destinationSwap.d.ts +0 -14
- package/dist/calldata/destinationSwap.js +0 -80
- package/dist/calldata/diagnostics.d.ts +0 -4
- package/dist/calldata/diagnostics.js +0 -18
- package/dist/calldata/expect.d.ts +0 -27
- package/dist/calldata/expect.js +0 -158
- package/dist/calldata/hex.d.ts +0 -6
- package/dist/calldata/hex.js +0 -46
- package/dist/calldata/index.d.ts +0 -20
- package/dist/calldata/index.js +0 -88
- package/dist/calldata/lifi/across/acrossV4Erc20Min.d.ts +0 -2
- package/dist/calldata/lifi/across/acrossV4Erc20Min.js +0 -26
- package/dist/calldata/lifi/across/acrossV4NativeMin.d.ts +0 -2
- package/dist/calldata/lifi/across/acrossV4NativeMin.js +0 -22
- package/dist/calldata/lifi/across/index.d.ts +0 -6
- package/dist/calldata/lifi/across/index.js +0 -19
- package/dist/calldata/lifi/allbridge/index.d.ts +0 -3
- package/dist/calldata/lifi/allbridge/index.js +0 -26
- package/dist/calldata/lifi/celer/index.d.ts +0 -4
- package/dist/calldata/lifi/celer/index.js +0 -10
- package/dist/calldata/lifi/centrifuge/index.d.ts +0 -3
- package/dist/calldata/lifi/centrifuge/index.js +0 -22
- package/dist/calldata/lifi/destination.d.ts +0 -5
- package/dist/calldata/lifi/destination.js +0 -40
- package/dist/calldata/lifi/frax/index.d.ts +0 -4
- package/dist/calldata/lifi/frax/index.js +0 -29
- package/dist/calldata/lifi/garden/index.d.ts +0 -3
- package/dist/calldata/lifi/garden/index.js +0 -22
- package/dist/calldata/lifi/gaszip/index.d.ts +0 -6
- package/dist/calldata/lifi/gaszip/index.js +0 -15
- package/dist/calldata/lifi/index.d.ts +0 -4
- package/dist/calldata/lifi/index.js +0 -62
- package/dist/calldata/lifi/intents/index.d.ts +0 -4
- package/dist/calldata/lifi/intents/index.js +0 -10
- package/dist/calldata/lifi/layerswap/index.d.ts +0 -4
- package/dist/calldata/lifi/layerswap/index.js +0 -10
- package/dist/calldata/lifi/m0/index.d.ts +0 -3
- package/dist/calldata/lifi/m0/index.js +0 -33
- package/dist/calldata/lifi/mayan/index.d.ts +0 -4
- package/dist/calldata/lifi/mayan/index.js +0 -10
- package/dist/calldata/lifi/method.d.ts +0 -6
- package/dist/calldata/lifi/method.js +0 -16
- package/dist/calldata/lifi/native/index.d.ts +0 -4
- package/dist/calldata/lifi/native/index.js +0 -80
- package/dist/calldata/lifi/params.d.ts +0 -28
- package/dist/calldata/lifi/params.js +0 -347
- package/dist/calldata/lifi/paxos/index.d.ts +0 -4
- package/dist/calldata/lifi/paxos/index.js +0 -10
- package/dist/calldata/lifi/polymer/index.d.ts +0 -4
- package/dist/calldata/lifi/polymer/index.js +0 -10
- package/dist/calldata/lifi/relay/index.d.ts +0 -6
- package/dist/calldata/lifi/relay/index.js +0 -15
- package/dist/calldata/lifi/shape.d.ts +0 -4
- package/dist/calldata/lifi/shape.js +0 -31
- package/dist/calldata/lifi/squid/index.d.ts +0 -6
- package/dist/calldata/lifi/squid/index.js +0 -15
- package/dist/calldata/lifi/stargate/index.d.ts +0 -5
- package/dist/calldata/lifi/stargate/index.js +0 -15
- package/dist/calldata/lifi/swap/index.d.ts +0 -5
- package/dist/calldata/lifi/swap/index.js +0 -18
- package/dist/calldata/lifi/swap/swapMethod.d.ts +0 -2
- package/dist/calldata/lifi/swap/swapMethod.js +0 -40
- package/dist/calldata/lifi/swapData.d.ts +0 -5
- package/dist/calldata/lifi/swapData.js +0 -33
- package/dist/calldata/match.d.ts +0 -3
- package/dist/calldata/match.js +0 -21
- package/dist/calldata/mayan/destination.d.ts +0 -2
- package/dist/calldata/mayan/destination.js +0 -13
- package/dist/calldata/mayan/fastMctpBridge.d.ts +0 -3
- package/dist/calldata/mayan/fastMctpBridge.js +0 -48
- package/dist/calldata/mayan/fastMctpCreateOrder.d.ts +0 -3
- package/dist/calldata/mayan/fastMctpCreateOrder.js +0 -39
- package/dist/calldata/mayan/forward.d.ts +0 -8
- package/dist/calldata/mayan/forward.js +0 -35
- package/dist/calldata/mayan/forwardERC20.d.ts +0 -2
- package/dist/calldata/mayan/forwardERC20.js +0 -19
- package/dist/calldata/mayan/forwardEth.d.ts +0 -2
- package/dist/calldata/mayan/forwardEth.js +0 -16
- package/dist/calldata/mayan/index.d.ts +0 -4
- package/dist/calldata/mayan/index.js +0 -21
- package/dist/calldata/mayan/mctp.d.ts +0 -5
- package/dist/calldata/mayan/mctp.js +0 -41
- package/dist/calldata/mayan/readProtocol.d.ts +0 -2
- package/dist/calldata/mayan/readProtocol.js +0 -29
- package/dist/calldata/mayan/swapAndForwardERC20.d.ts +0 -2
- package/dist/calldata/mayan/swapAndForwardERC20.js +0 -24
- package/dist/calldata/mayan/swapAndForwardEth.d.ts +0 -2
- package/dist/calldata/mayan/swapAndForwardEth.js +0 -23
- package/dist/calldata/mayan/swiftCreateOrder.d.ts +0 -3
- package/dist/calldata/mayan/swiftCreateOrder.js +0 -49
- package/dist/calldata/mayan/validate.d.ts +0 -3
- package/dist/calldata/mayan/validate.js +0 -20
- package/dist/calldata/protocols.d.ts +0 -9
- package/dist/calldata/protocols.js +0 -57
- package/dist/calldata/relay/calls.d.ts +0 -13
- package/dist/calldata/relay/calls.js +0 -54
- package/dist/calldata/relay/depositErc20.d.ts +0 -2
- package/dist/calldata/relay/depositErc20.js +0 -22
- package/dist/calldata/relay/depositErc20Allowance.d.ts +0 -2
- package/dist/calldata/relay/depositErc20Allowance.js +0 -20
- package/dist/calldata/relay/depositNative.d.ts +0 -2
- package/dist/calldata/relay/depositNative.js +0 -20
- package/dist/calldata/relay/index.d.ts +0 -4
- package/dist/calldata/relay/index.js +0 -42
- package/dist/calldata/relay/multicall.d.ts +0 -2
- package/dist/calldata/relay/multicall.js +0 -15
- package/dist/calldata/relay/permit2TransferAndMulticall.d.ts +0 -2
- package/dist/calldata/relay/permit2TransferAndMulticall.js +0 -42
- package/dist/calldata/relay/permit3009TransferAndMulticall.d.ts +0 -2
- package/dist/calldata/relay/permit3009TransferAndMulticall.js +0 -41
- package/dist/calldata/relay/permit3009TransferAndMulticallSigned.d.ts +0 -2
- package/dist/calldata/relay/permit3009TransferAndMulticallSigned.js +0 -40
- package/dist/calldata/relay/permitTransferAndMulticall.d.ts +0 -2
- package/dist/calldata/relay/permitTransferAndMulticall.js +0 -34
- package/dist/calldata/relay/permitTransferAndMulticallLegacy.d.ts +0 -2
- package/dist/calldata/relay/permitTransferAndMulticallLegacy.js +0 -35
- package/dist/calldata/relay/transferAndMulticall.d.ts +0 -2
- package/dist/calldata/relay/transferAndMulticall.js +0 -26
- package/dist/calldata/relay/validate.d.ts +0 -3
- package/dist/calldata/relay/validate.js +0 -18
- package/dist/calldata/resolve.d.ts +0 -2
- package/dist/calldata/resolve.js +0 -28
- package/dist/calldata/socket/bridge.d.ts +0 -2
- package/dist/calldata/socket/bridge.js +0 -28
- package/dist/calldata/socket/exec.d.ts +0 -2
- package/dist/calldata/socket/exec.js +0 -71
- package/dist/calldata/socket/index.d.ts +0 -4
- package/dist/calldata/socket/index.js +0 -13
- package/dist/calldata/socket/params.d.ts +0 -5
- package/dist/calldata/socket/params.js +0 -14
- package/dist/calldata/socket/protocols/ccip.d.ts +0 -2
- package/dist/calldata/socket/protocols/ccip.js +0 -32
- package/dist/calldata/socket/protocols/cctp.d.ts +0 -2
- package/dist/calldata/socket/protocols/cctp.js +0 -24
- package/dist/calldata/socket/protocols/eco.d.ts +0 -2
- package/dist/calldata/socket/protocols/eco.js +0 -20
- package/dist/calldata/socket/protocols/index.d.ts +0 -3
- package/dist/calldata/socket/protocols/index.js +0 -86
- package/dist/calldata/socket/protocols/native.d.ts +0 -2
- package/dist/calldata/socket/protocols/native.js +0 -70
- package/dist/calldata/socket/protocols/oft.d.ts +0 -2
- package/dist/calldata/socket/protocols/oft.js +0 -33
- package/dist/calldata/socket/protocols/swapsXYZ.d.ts +0 -2
- package/dist/calldata/socket/protocols/swapsXYZ.js +0 -62
- package/dist/calldata/socket/swapAndBridge.d.ts +0 -2
- package/dist/calldata/socket/swapAndBridge.js +0 -41
- package/dist/calldata/socket/validate.d.ts +0 -3
- package/dist/calldata/socket/validate.js +0 -24
- package/dist/calldata/types.d.ts +0 -82
- package/dist/calldata/types.js +0 -20
- package/dist/errors/constants.d.ts +0 -891
- package/dist/errors/constants.js +0 -898
- package/dist/errors/index.d.ts +0 -66
- package/dist/errors/index.js +0 -53
- package/dist/errors/sanitize.d.ts +0 -3
- package/dist/errors/sanitize.js +0 -74
- package/dist/providers/data.d.ts +0 -23
- package/dist/providers/data.js +0 -116
- package/dist/providers/errors.d.ts +0 -7
- package/dist/providers/errors.js +0 -10
- package/dist/providers/layerswap.d.ts +0 -9
- package/dist/providers/layerswap.js +0 -95
- package/dist/providers/relay.d.ts +0 -59
- package/dist/providers/relay.js +0 -185
- package/dist/providers/socket.d.ts +0 -5
- package/dist/providers/socket.js +0 -57
package/dist/quote.js
CHANGED
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
import { BRIDGE_ERRORS, BridgeError, asBridgeError, reportBridgeError } from './errors/index.js';
|
|
2
|
-
import { InvalidBridgeCalldataError, validateBridgeCalldata, } from './calldata/index.js';
|
|
3
|
-
import { calldataDiagnostics } from './calldata/diagnostics.js';
|
|
4
|
-
import { sanitizeBridgeError } from './errors/sanitize.js';
|
|
5
1
|
import { BRIDGE_ENUM } from './consts.js';
|
|
6
2
|
import { getBridgeAltContracts, getBridgeRouter, getBridgeSpender, isSupportedBridgeAggregator, isSupportedBridgeChain, } from './list.js';
|
|
7
|
-
export class InvalidBridgeContractError extends
|
|
3
|
+
export class InvalidBridgeContractError extends Error {
|
|
8
4
|
constructor(kind, aggregatorId, chainId, expected, received, bridgeId) {
|
|
9
|
-
super(kind
|
|
5
|
+
super(`Invalid bridge ${kind} for ${aggregatorId} on ${chainId}: expected ${expected}, got ${received}`);
|
|
10
6
|
this.kind = kind;
|
|
11
7
|
this.aggregatorId = aggregatorId;
|
|
12
8
|
this.chainId = chainId;
|
|
13
9
|
this.expected = expected;
|
|
14
10
|
this.received = received;
|
|
15
11
|
this.bridgeId = bridgeId;
|
|
16
|
-
this.message =
|
|
17
|
-
`Invalid bridge ${kind} for ${aggregatorId} on ${chainId}: expected ${expected}, got ${received}`;
|
|
18
12
|
this.name = 'InvalidBridgeContractError';
|
|
19
13
|
}
|
|
20
14
|
}
|
|
@@ -26,19 +20,15 @@ const isSameAddress = (left, right) => {
|
|
|
26
20
|
};
|
|
27
21
|
function assertSupported(aggregatorId, fromChainId) {
|
|
28
22
|
if (!isSupportedBridgeAggregator(aggregatorId)) {
|
|
29
|
-
|
|
30
|
-
error.message = `${aggregatorId} is not supported`;
|
|
31
|
-
throw error;
|
|
23
|
+
throw new Error(`${aggregatorId} is not supported`);
|
|
32
24
|
}
|
|
33
25
|
if (!isSupportedBridgeChain(aggregatorId, fromChainId)) {
|
|
34
|
-
|
|
35
|
-
error.message = `${aggregatorId} does not support ${fromChainId}`;
|
|
36
|
-
throw error;
|
|
26
|
+
throw new Error(`${aggregatorId} does not support ${fromChainId}`);
|
|
37
27
|
}
|
|
38
28
|
}
|
|
39
29
|
const requireSlippage = (slippage) => {
|
|
40
30
|
if (!slippage) {
|
|
41
|
-
throw new
|
|
31
|
+
throw new Error('slippage is required for this API call');
|
|
42
32
|
}
|
|
43
33
|
return slippage;
|
|
44
34
|
};
|
|
@@ -49,22 +39,13 @@ const stringifyQuoteKey = (quoteKey) => {
|
|
|
49
39
|
return JSON.stringify(quoteKey || {});
|
|
50
40
|
};
|
|
51
41
|
const shouldValidateBridgeContracts = (aggregatorId) => aggregatorId !== BRIDGE_ENUM.NEAR_INTENTS;
|
|
52
|
-
const
|
|
53
|
-
if (!options.lite)
|
|
54
|
-
throw error;
|
|
55
|
-
reportBridgeError(options.onError, asBridgeError(error), { ...context, lite: true, blocking: false });
|
|
56
|
-
};
|
|
57
|
-
export const validateBridgeQuote = (aggregatorId, fromChainId, quote, options = {}) => {
|
|
42
|
+
export const validateBridgeQuote = (aggregatorId, fromChainId, quote) => {
|
|
58
43
|
if (!shouldValidateBridgeContracts(aggregatorId)) {
|
|
59
44
|
return true;
|
|
60
45
|
}
|
|
61
46
|
const expectedSpender = getBridgeSpender(aggregatorId, fromChainId);
|
|
62
47
|
const receivedSpender = quote.approve_contract_id;
|
|
63
|
-
if (!receivedSpender) {
|
|
64
|
-
return true;
|
|
65
|
-
}
|
|
66
|
-
if (!expectedSpender) {
|
|
67
|
-
handleNewValidationError(new InvalidBridgeContractError('spender', aggregatorId, fromChainId, 'configured spender', receivedSpender, quote.bridge_id), options, { aggregatorId, chainId: fromChainId, bridgeId: quote.bridge_id, operation: 'getQuote' });
|
|
48
|
+
if (!expectedSpender || !receivedSpender) {
|
|
68
49
|
return true;
|
|
69
50
|
}
|
|
70
51
|
const allowedSpenders = [
|
|
@@ -76,191 +57,81 @@ export const validateBridgeQuote = (aggregatorId, fromChainId, quote, options =
|
|
|
76
57
|
}
|
|
77
58
|
return true;
|
|
78
59
|
};
|
|
79
|
-
const
|
|
80
|
-
let key = quoteKey;
|
|
81
|
-
if (typeof key === 'string') {
|
|
82
|
-
try {
|
|
83
|
-
key = JSON.parse(key);
|
|
84
|
-
}
|
|
85
|
-
catch {
|
|
86
|
-
return undefined;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (!key || typeof key !== 'object' || Array.isArray(key))
|
|
90
|
-
return undefined;
|
|
91
|
-
const amount = key.to_token_raw_amount;
|
|
92
|
-
if (typeof amount === 'string' || (typeof amount === 'number' && Number.isSafeInteger(amount))) {
|
|
93
|
-
return String(amount);
|
|
94
|
-
}
|
|
95
|
-
return undefined;
|
|
96
|
-
};
|
|
97
|
-
const validateBridgeRouter = (aggregatorId, fromChainId, bridgeId, tx) => {
|
|
60
|
+
export const validateBridgeTx = (aggregatorId, fromChainId, bridgeId, tx) => {
|
|
98
61
|
if (!shouldValidateBridgeContracts(aggregatorId)) {
|
|
99
62
|
return true;
|
|
100
63
|
}
|
|
101
64
|
const expectedRouter = getBridgeRouter(aggregatorId, fromChainId);
|
|
65
|
+
if (!expectedRouter) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
102
68
|
const allowedRouters = [
|
|
103
|
-
|
|
69
|
+
expectedRouter,
|
|
104
70
|
...getBridgeAltContracts(aggregatorId),
|
|
105
71
|
];
|
|
106
72
|
if (!allowedRouters.some((addr) => isSameAddress(addr, tx.to))) {
|
|
107
|
-
throw
|
|
108
|
-
pass: false, routerPass: false, fromPass: false, toPass: false, receiverPass: false, blocking: true });
|
|
73
|
+
throw new InvalidBridgeContractError('router', aggregatorId, fromChainId, expectedRouter, tx.to, bridgeId);
|
|
109
74
|
}
|
|
110
75
|
return true;
|
|
111
76
|
};
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
BRIDGE_ERRORS.QUOTE_ID_MISMATCH, BRIDGE_ERRORS.REQUEST_ID_MISMATCH, BRIDGE_ERRORS.SOCKET_RFQ_QUOTE_ID_MISMATCH,
|
|
125
|
-
];
|
|
126
|
-
const checkBridgeTx = (aggregatorId, fromChainId, bridgeId, tx, expectation, options = {}, operation = 'verifyTx') => {
|
|
127
|
-
const routerPass = validateBridgeRouter(aggregatorId, fromChainId, bridgeId, tx);
|
|
128
|
-
let check;
|
|
129
|
-
try {
|
|
130
|
-
check = validateBridgeCalldata(aggregatorId, fromChainId, tx, expectation);
|
|
131
|
-
}
|
|
132
|
-
catch (error) {
|
|
133
|
-
check = { ok: false, aggregatorId, errors: asBridgeError(error, BRIDGE_ERRORS.INVALID_CALLDATA).errors };
|
|
134
|
-
}
|
|
135
|
-
const unverifiedFields = check.unverifiedFields ?? [
|
|
136
|
-
'sourceToken', 'sourceAmount', 'outputToken', 'minOutputAmount', 'receiver',
|
|
137
|
-
...(expectation?.toChainId ? ['destinationChainId'] : []),
|
|
138
|
-
];
|
|
139
|
-
const externalDestination = check.parsed && (aggregatorId === BRIDGE_ENUM.RELAY ||
|
|
140
|
-
(aggregatorId === BRIDGE_ENUM.SOCKET &&
|
|
141
|
-
['receiveERC20', 'receiveNative', 'depositForBurn'].includes(check.parsed.protocolMethod ?? '')));
|
|
142
|
-
// Known local limits remain unverified, without repeating an expected gap as an error.
|
|
143
|
-
const reportableFields = unverifiedFields.filter((field) => {
|
|
144
|
-
if (!check.parsed)
|
|
145
|
-
return true;
|
|
146
|
-
if (field === 'outputToken')
|
|
147
|
-
return false;
|
|
148
|
-
if (field === 'minOutputAmount')
|
|
149
|
-
return check.parsed.minOutputAmount !== undefined;
|
|
150
|
-
return !(externalDestination && ['receiver', 'destinationChainId'].includes(field));
|
|
151
|
-
});
|
|
152
|
-
// Unclassified structure failures invalidate every field; known field failures stay separate.
|
|
153
|
-
const comparable = Boolean(expectation && check.parsed) && check.errors.every((error) => bindingErrors.some((item) => item.error_code === error.error_code) ||
|
|
154
|
-
Object.values(fieldErrors).some((group) => group.some((item) => item.error_code === error.error_code)));
|
|
155
|
-
const fieldPass = (field, required) => comparable &&
|
|
156
|
-
required.every((item) => !unverifiedFields.includes(item)) &&
|
|
157
|
-
!check.errors.some((error) => fieldErrors[field].some((item) => item.error_code === error.error_code));
|
|
158
|
-
const flags = {
|
|
159
|
-
// shortcut: field checks are observation-only until collected routes justify enforcement.
|
|
160
|
-
pass: routerPass, routerPass,
|
|
161
|
-
fromPass: fieldPass('fromPass', ['sourceToken', 'sourceAmount']),
|
|
162
|
-
toPass: fieldPass('toPass', ['outputToken', 'minOutputAmount', ...(expectation?.toChainId ? ['destinationChainId'] : [])]),
|
|
163
|
-
receiverPass: fieldPass('receiverPass', ['receiver']),
|
|
164
|
-
};
|
|
165
|
-
const context = {
|
|
166
|
-
...check.parsed?.diagnostics, ...calldataDiagnostics(tx.data), aggregatorId,
|
|
167
|
-
chainId: fromChainId, toChainId: expectation?.toChainId, bridgeId, operation, method: check.method,
|
|
168
|
-
...(check.parsed ? { hasDestinationCall: Boolean(check.parsed.hasDestinationCall || check.parsed.destinationCallData !== undefined) } : {}),
|
|
169
|
-
...flags, lite: Boolean(options.lite), blocking: false,
|
|
77
|
+
export const getQuote = async (aggregatorId, params, api) => {
|
|
78
|
+
assertSupported(aggregatorId, params.fromChainId);
|
|
79
|
+
const baseParams = {
|
|
80
|
+
aggregator_id: aggregatorId,
|
|
81
|
+
user_addr: params.userAddress,
|
|
82
|
+
from_chain_id: params.fromChainId,
|
|
83
|
+
from_token_id: params.fromTokenId,
|
|
84
|
+
from_token_raw_amount: params.fromTokenRawAmount,
|
|
85
|
+
to_chain_id: params.toChainId,
|
|
86
|
+
to_token_id: params.toTokenId,
|
|
87
|
+
fee_rate: params.feeRate,
|
|
88
|
+
slippage: requireSlippage(params.slippage),
|
|
170
89
|
};
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
reportBridgeError(options.onError, new InvalidBridgeCalldataError(aggregatorId, fromChainId, check.method, check.reason || errors[0].message, errors), context);
|
|
90
|
+
const quotes = api.getBridgeQuoteListV2
|
|
91
|
+
? await api.getBridgeQuoteListV2(baseParams)
|
|
92
|
+
: await api.getBridgeQuoteV2?.(baseParams);
|
|
93
|
+
if (!quotes) {
|
|
94
|
+
throw new Error('Bridge API does not provide a quote list method');
|
|
177
95
|
}
|
|
178
|
-
return
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
aggregator_id: aggregatorId,
|
|
187
|
-
user_addr: params.userAddress,
|
|
188
|
-
from_chain_id: params.fromChainId,
|
|
189
|
-
from_token_id: params.fromTokenId,
|
|
190
|
-
from_token_raw_amount: params.fromTokenRawAmount,
|
|
191
|
-
to_chain_id: params.toChainId,
|
|
192
|
-
to_token_id: params.toTokenId,
|
|
193
|
-
fee_rate: params.feeRate,
|
|
194
|
-
slippage: requireSlippage(params.slippage),
|
|
195
|
-
};
|
|
196
|
-
const quotes = api.getBridgeQuoteListV2
|
|
197
|
-
? await api.getBridgeQuoteListV2(baseParams).catch((error) => { throw asBridgeError(error, BRIDGE_ERRORS.BACKEND_QUOTE_REQUEST_FAILED, { requestKind: 'backend_quote' }); })
|
|
198
|
-
: await api.getBridgeQuoteV2?.(baseParams).catch((error) => { throw asBridgeError(error, BRIDGE_ERRORS.BACKEND_QUOTE_REQUEST_FAILED, { requestKind: 'backend_quote' }); });
|
|
199
|
-
if (!quotes)
|
|
200
|
-
throw new BridgeError(BRIDGE_ERRORS.MISSING_QUOTE_API);
|
|
201
|
-
return quotes.filter((quote) => {
|
|
202
|
-
try {
|
|
203
|
-
validateBridgeQuote(aggregatorId, params.fromChainId, quote, params);
|
|
204
|
-
return true;
|
|
205
|
-
}
|
|
206
|
-
catch (error) {
|
|
207
|
-
if (error instanceof InvalidBridgeContractError) {
|
|
208
|
-
reportBridgeError(params.onError, error, { aggregatorId, chainId: params.fromChainId, toChainId: params.toChainId, bridgeId: quote.bridge_id, operation: 'getQuote', ...(params.lite ? { lite: true, blocking: true } : {}) });
|
|
209
|
-
return false;
|
|
210
|
-
}
|
|
211
|
-
throw error;
|
|
96
|
+
return quotes.filter((quote) => {
|
|
97
|
+
try {
|
|
98
|
+
validateBridgeQuote(aggregatorId, params.fromChainId, quote);
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (error instanceof InvalidBridgeContractError) {
|
|
103
|
+
return false;
|
|
212
104
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
throw asBridgeError(error, BRIDGE_ERRORS.UNKNOWN, { aggregatorId, chainId: params.fromChainId, toChainId: params.toChainId, operation: 'getQuote', ...(params.lite ? { lite: true, blocking: true } : {}) });
|
|
217
|
-
}
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
218
108
|
};
|
|
219
109
|
export const buildTx = async (aggregatorId, params, api) => {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
slippage: requireSlippage(params.slippage),
|
|
246
|
-
};
|
|
247
|
-
const tx = api.buildBridgeTx
|
|
248
|
-
? await api.buildBridgeTx({
|
|
249
|
-
...buildParams,
|
|
250
|
-
quote_key: quoteKey,
|
|
251
|
-
}).catch((error) => { throw asBridgeError(error, BRIDGE_ERRORS.BACKEND_BUILD_REQUEST_FAILED, { requestKind: 'backend_build' }); })
|
|
252
|
-
: (await api.getBridgeQuoteTxV2?.({
|
|
253
|
-
...buildParams,
|
|
254
|
-
}).catch((error) => { throw asBridgeError(error, BRIDGE_ERRORS.BACKEND_BUILD_REQUEST_FAILED, { requestKind: 'backend_build' }); }))?.tx;
|
|
255
|
-
if (!tx) {
|
|
256
|
-
throw new BridgeError(BRIDGE_ERRORS.MISSING_BUILD_API);
|
|
257
|
-
}
|
|
258
|
-
checkBridgeTx(aggregatorId, params.fromChainId, params.bridgeId, tx, expectation, params, 'buildTx');
|
|
259
|
-
return tx;
|
|
260
|
-
}
|
|
261
|
-
catch (error) {
|
|
262
|
-
throw asBridgeError(error, BRIDGE_ERRORS.UNKNOWN, { aggregatorId, chainId: params.fromChainId, toChainId: params.toChainId, operation: 'buildTx', bridgeId: params.bridgeId, ...(params.lite ? { lite: true, blocking: true } : {}) });
|
|
263
|
-
}
|
|
110
|
+
assertSupported(aggregatorId, params.fromChainId);
|
|
111
|
+
const buildParams = {
|
|
112
|
+
aggregator_id: aggregatorId,
|
|
113
|
+
bridge_id: params.bridgeId,
|
|
114
|
+
user_addr: params.userAddress,
|
|
115
|
+
from_chain_id: params.fromChainId,
|
|
116
|
+
from_token_id: params.fromTokenId,
|
|
117
|
+
from_token_raw_amount: params.fromTokenRawAmount,
|
|
118
|
+
to_chain_id: params.toChainId,
|
|
119
|
+
to_token_id: params.toTokenId,
|
|
120
|
+
slippage: requireSlippage(params.slippage),
|
|
121
|
+
};
|
|
122
|
+
const tx = api.buildBridgeTx
|
|
123
|
+
? await api.buildBridgeTx({
|
|
124
|
+
...buildParams,
|
|
125
|
+
quote_key: stringifyQuoteKey(params.quoteKey),
|
|
126
|
+
})
|
|
127
|
+
: (await api.getBridgeQuoteTxV2?.({
|
|
128
|
+
...buildParams,
|
|
129
|
+
}))?.tx;
|
|
130
|
+
if (!tx) {
|
|
131
|
+
throw new Error('Bridge API does not provide a build tx method');
|
|
132
|
+
}
|
|
133
|
+
validateBridgeTx(aggregatorId, params.fromChainId, params.bridgeId, tx);
|
|
134
|
+
return tx;
|
|
264
135
|
};
|
|
265
136
|
export const getQuoteListWithTx = async (aggregatorId, params, api) => {
|
|
266
137
|
const quotes = await getQuote(aggregatorId, params, api);
|
|
@@ -270,8 +141,6 @@ export const getQuoteListWithTx = async (aggregatorId, params, api) => {
|
|
|
270
141
|
...params,
|
|
271
142
|
bridgeId: quote.bridge_id,
|
|
272
143
|
quoteKey: quote.quote_key,
|
|
273
|
-
toTokenRawAmount: quote.to_token_raw_amount_hex_str ??
|
|
274
|
-
(Number.isSafeInteger(quote.to_token_raw_amount) ? String(quote.to_token_raw_amount) : undefined),
|
|
275
144
|
}, api);
|
|
276
145
|
return {
|
|
277
146
|
...quote,
|
|
@@ -279,9 +148,7 @@ export const getQuoteListWithTx = async (aggregatorId, params, api) => {
|
|
|
279
148
|
};
|
|
280
149
|
}
|
|
281
150
|
catch (error) {
|
|
282
|
-
if (error instanceof InvalidBridgeContractError
|
|
283
|
-
error instanceof InvalidBridgeCalldataError) {
|
|
284
|
-
reportBridgeError(params.onError, error, { aggregatorId, chainId: params.fromChainId, toChainId: params.toChainId, bridgeId: quote.bridge_id, operation: 'buildTx', ...(params.lite ? { lite: true, blocking: true } : {}) });
|
|
151
|
+
if (error instanceof InvalidBridgeContractError) {
|
|
285
152
|
return null;
|
|
286
153
|
}
|
|
287
154
|
throw error;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rabby-wallet/rabby-bridge",
|
|
3
|
-
"version": "0.0.13
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "Bridge quote helpers and contract allowlists for Rabby",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,13 +22,7 @@
|
|
|
22
22
|
"scripts": {
|
|
23
23
|
"prepublishOnly": "yarn build",
|
|
24
24
|
"build": "rimraf dist && tsc",
|
|
25
|
-
"test": "yarn build && NODE_OPTIONS=--experimental-vm-modules jest --runInBand --watchman=false"
|
|
26
|
-
"test:bridge-calldata": "yarn build && NODE_OPTIONS=--experimental-vm-modules jest --runInBand --watchman=false tests/calldata",
|
|
27
|
-
"test:bridge-calldata:lifi": "yarn test:bridge-calldata --testNamePattern='\\[LiFi\\]'",
|
|
28
|
-
"test:bridge-calldata:socket": "yarn test:bridge-calldata --testNamePattern='\\[Socket\\]'",
|
|
29
|
-
"test:bridge-calldata:relay": "yarn test:bridge-calldata --testNamePattern='\\[Relay\\]'",
|
|
30
|
-
"test:bridge-calldata:across": "yarn test:bridge-calldata --testNamePattern='\\[Across\\]'",
|
|
31
|
-
"test:bridge-calldata:mayan": "yarn test:bridge-calldata --testNamePattern='\\[Mayan\\]'"
|
|
25
|
+
"test": "yarn build && NODE_OPTIONS=--experimental-vm-modules jest --runInBand --watchman=false"
|
|
32
26
|
},
|
|
33
27
|
"devDependencies": {
|
|
34
28
|
"@debank/common": "^0.3.60",
|
|
@@ -38,9 +32,5 @@
|
|
|
38
32
|
"rimraf": "^3.0.2",
|
|
39
33
|
"typescript": "^5.8.3"
|
|
40
34
|
},
|
|
41
|
-
"packageManager": "yarn@4.12.0"
|
|
42
|
-
"dependencies": {
|
|
43
|
-
"@ethersproject/hash": "5.8.0",
|
|
44
|
-
"@ethersproject/strings": "5.8.0"
|
|
45
|
-
}
|
|
35
|
+
"packageManager": "yarn@4.12.0"
|
|
46
36
|
}
|
package/dist/calldata/abi.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { ParsedBridgeCall } from './types.js';
|
|
2
|
-
export type AbiParam = {
|
|
3
|
-
name: string;
|
|
4
|
-
kind: 'address' | 'uint' | 'bool' | 'bytes' | 'string' | 'array' | 'tuple';
|
|
5
|
-
size?: number;
|
|
6
|
-
length?: number;
|
|
7
|
-
item?: AbiParam;
|
|
8
|
-
components?: AbiParam[];
|
|
9
|
-
};
|
|
10
|
-
export type AbiValue = string | bigint | boolean | AbiValue[] | {
|
|
11
|
-
[key: string]: AbiValue;
|
|
12
|
-
};
|
|
13
|
-
export declare const decodeCall: (params: AbiParam[], calldata: string) => {
|
|
14
|
-
[key: string]: AbiValue;
|
|
15
|
-
};
|
|
16
|
-
export declare const decodeParameters: (params: AbiParam[], data: string) => {
|
|
17
|
-
[key: string]: AbiValue;
|
|
18
|
-
};
|
|
19
|
-
export declare const asRecord: (value: AbiValue) => {
|
|
20
|
-
[key: string]: AbiValue;
|
|
21
|
-
};
|
|
22
|
-
export declare const asArray: (value: AbiValue) => AbiValue[];
|
|
23
|
-
export declare const asBigint: (value: AbiValue) => bigint;
|
|
24
|
-
export declare const asString: (value: AbiValue) => string;
|
|
25
|
-
export type CalldataMethod = {
|
|
26
|
-
name: string;
|
|
27
|
-
selector: string;
|
|
28
|
-
decode: (data: string, value: bigint) => ParsedBridgeCall;
|
|
29
|
-
};
|
package/dist/calldata/abi.js
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import { BRIDGE_ERRORS, BridgeError } from '../errors/index.js';
|
|
2
|
-
import { toUtf8String, Utf8ErrorFuncs } from '@ethersproject/strings';
|
|
3
|
-
import { bytesToHex, hexToBytes } from './hex.js';
|
|
4
|
-
const isDynamic = (param) => {
|
|
5
|
-
if (param.kind === 'string') {
|
|
6
|
-
return true;
|
|
7
|
-
}
|
|
8
|
-
if (param.kind === 'bytes') {
|
|
9
|
-
return param.size === undefined;
|
|
10
|
-
}
|
|
11
|
-
if (param.kind === 'array') {
|
|
12
|
-
return param.length === undefined || isDynamic(param.item);
|
|
13
|
-
}
|
|
14
|
-
if (param.kind === 'tuple') {
|
|
15
|
-
return (param.components ?? []).some(isDynamic);
|
|
16
|
-
}
|
|
17
|
-
return false;
|
|
18
|
-
};
|
|
19
|
-
const staticWordCount = (param) => {
|
|
20
|
-
if (isDynamic(param)) {
|
|
21
|
-
return 1;
|
|
22
|
-
}
|
|
23
|
-
if (param.kind === 'tuple') {
|
|
24
|
-
return (param.components ?? []).reduce((sum, item) => sum + staticWordCount(item), 0);
|
|
25
|
-
}
|
|
26
|
-
if (param.kind === 'array') {
|
|
27
|
-
return (param.length ?? 0) * staticWordCount(param.item);
|
|
28
|
-
}
|
|
29
|
-
return 1;
|
|
30
|
-
};
|
|
31
|
-
const readWord = (buf, offset) => {
|
|
32
|
-
if (offset < 0 || offset + 32 > buf.length) {
|
|
33
|
-
throw new BridgeError(BRIDGE_ERRORS.ABI_WORD_OUT_OF_BOUNDS, { abiOffset: offset, abiBufferBytes: buf.length });
|
|
34
|
-
}
|
|
35
|
-
let value = 0n;
|
|
36
|
-
for (let index = 0; index < 32; index += 1) {
|
|
37
|
-
value = (value << 8n) + BigInt(buf[offset + index]);
|
|
38
|
-
}
|
|
39
|
-
return value;
|
|
40
|
-
};
|
|
41
|
-
const toAddress = (word) => {
|
|
42
|
-
if (word >= (1n << 160n))
|
|
43
|
-
throw new BridgeError(BRIDGE_ERRORS.INVALID_ABI_ADDRESS);
|
|
44
|
-
return `0x${word.toString(16).padStart(40, '0')}`;
|
|
45
|
-
};
|
|
46
|
-
const readByteLength = (buf, offset) => {
|
|
47
|
-
const length = readWord(buf, offset);
|
|
48
|
-
if (length > BigInt(buf.length)) {
|
|
49
|
-
throw new BridgeError(BRIDGE_ERRORS.ABI_BYTES_OUT_OF_BOUNDS, { abiOffset: offset, abiBufferBytes: buf.length });
|
|
50
|
-
}
|
|
51
|
-
return Number(length);
|
|
52
|
-
};
|
|
53
|
-
const readDynamicBytes = (buf, offset) => {
|
|
54
|
-
const length = readByteLength(buf, offset);
|
|
55
|
-
const start = offset + 32;
|
|
56
|
-
if (start + length > buf.length) {
|
|
57
|
-
throw new BridgeError(BRIDGE_ERRORS.ABI_BYTES_OUT_OF_BOUNDS, { abiOffset: offset, abiBufferBytes: buf.length });
|
|
58
|
-
}
|
|
59
|
-
return bytesToHex(buf.subarray(start, start + length));
|
|
60
|
-
};
|
|
61
|
-
const decodeSequence = (params, buf, base) => {
|
|
62
|
-
let cursor = base;
|
|
63
|
-
const locations = [];
|
|
64
|
-
for (const param of params) {
|
|
65
|
-
if (isDynamic(param)) {
|
|
66
|
-
const relative = readWord(buf, cursor);
|
|
67
|
-
if (relative > BigInt(buf.length)) {
|
|
68
|
-
throw new BridgeError(BRIDGE_ERRORS.ABI_OFFSET_OUT_OF_BOUNDS, { abiOffset: cursor, abiBufferBytes: buf.length });
|
|
69
|
-
}
|
|
70
|
-
locations.push(base + Number(relative));
|
|
71
|
-
cursor += 32;
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
locations.push(cursor);
|
|
75
|
-
cursor += staticWordCount(param) * 32;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return params.map((param, index) => decodeAt(param, buf, locations[index]));
|
|
79
|
-
};
|
|
80
|
-
const decodeAt = (param, buf, offset) => {
|
|
81
|
-
switch (param.kind) {
|
|
82
|
-
case 'address':
|
|
83
|
-
return toAddress(readWord(buf, offset));
|
|
84
|
-
case 'uint':
|
|
85
|
-
return readWord(buf, offset);
|
|
86
|
-
case 'bool': {
|
|
87
|
-
const word = readWord(buf, offset);
|
|
88
|
-
if (word !== 0n && word !== 1n) {
|
|
89
|
-
throw new BridgeError(BRIDGE_ERRORS.INVALID_BOOL);
|
|
90
|
-
}
|
|
91
|
-
return word === 1n;
|
|
92
|
-
}
|
|
93
|
-
case 'bytes': {
|
|
94
|
-
if (param.size === undefined) {
|
|
95
|
-
return readDynamicBytes(buf, offset);
|
|
96
|
-
}
|
|
97
|
-
if (offset + 32 > buf.length) {
|
|
98
|
-
throw new BridgeError(BRIDGE_ERRORS.ABI_WORD_OUT_OF_BOUNDS, { abiOffset: offset, abiBufferBytes: buf.length });
|
|
99
|
-
}
|
|
100
|
-
return bytesToHex(buf.subarray(offset, offset + param.size));
|
|
101
|
-
}
|
|
102
|
-
case 'string':
|
|
103
|
-
return toUtf8String(readDynamicBytes(buf, offset), Utf8ErrorFuncs.replace).replace(/^\uFEFF/, '');
|
|
104
|
-
case 'tuple':
|
|
105
|
-
return decodeTuple(param.components ?? [], buf, offset);
|
|
106
|
-
case 'array': {
|
|
107
|
-
const item = param.item;
|
|
108
|
-
if (param.length === undefined) {
|
|
109
|
-
const length = readByteLength(buf, offset);
|
|
110
|
-
if (length > 2048) {
|
|
111
|
-
throw new BridgeError(BRIDGE_ERRORS.ABI_ARRAY_TOO_LONG);
|
|
112
|
-
}
|
|
113
|
-
return decodeSequence(Array.from({ length }, () => item), buf, offset + 32);
|
|
114
|
-
}
|
|
115
|
-
return decodeSequence(Array.from({ length: param.length }, () => item), buf, offset);
|
|
116
|
-
}
|
|
117
|
-
default:
|
|
118
|
-
throw new BridgeError(BRIDGE_ERRORS.UNSUPPORTED_ABI_TYPE);
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
const decodeTuple = (components, buf, offset) => {
|
|
122
|
-
const values = decodeSequence(components, buf, offset);
|
|
123
|
-
return Object.fromEntries(components.map((component, index) => [component.name, values[index]]));
|
|
124
|
-
};
|
|
125
|
-
export const decodeCall = (params, calldata) => {
|
|
126
|
-
const bytes = hexToBytes(calldata);
|
|
127
|
-
if (bytes.length < 4) {
|
|
128
|
-
throw new BridgeError(BRIDGE_ERRORS.MISSING_SELECTOR);
|
|
129
|
-
}
|
|
130
|
-
const values = decodeSequence(params, bytes.subarray(4), 0);
|
|
131
|
-
return Object.fromEntries(params.map((param, index) => [param.name, values[index]]));
|
|
132
|
-
};
|
|
133
|
-
export const decodeParameters = (params, data) => {
|
|
134
|
-
const values = decodeSequence(params, hexToBytes(data), 0);
|
|
135
|
-
return Object.fromEntries(params.map((param, index) => [param.name, values[index]]));
|
|
136
|
-
};
|
|
137
|
-
export const asRecord = (value) => {
|
|
138
|
-
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
139
|
-
throw new BridgeError(BRIDGE_ERRORS.EXPECTED_TUPLE);
|
|
140
|
-
}
|
|
141
|
-
return value;
|
|
142
|
-
};
|
|
143
|
-
export const asArray = (value) => {
|
|
144
|
-
if (!Array.isArray(value)) {
|
|
145
|
-
throw new BridgeError(BRIDGE_ERRORS.EXPECTED_ARRAY);
|
|
146
|
-
}
|
|
147
|
-
return value;
|
|
148
|
-
};
|
|
149
|
-
export const asBigint = (value) => {
|
|
150
|
-
if (typeof value !== 'bigint') {
|
|
151
|
-
throw new BridgeError(BRIDGE_ERRORS.EXPECTED_UINT);
|
|
152
|
-
}
|
|
153
|
-
return value;
|
|
154
|
-
};
|
|
155
|
-
export const asString = (value) => {
|
|
156
|
-
if (typeof value !== 'string') {
|
|
157
|
-
throw new BridgeError(BRIDGE_ERRORS.EXPECTED_STRING);
|
|
158
|
-
}
|
|
159
|
-
return value;
|
|
160
|
-
};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { applyAcrossMessage } from '../destination.js';
|
|
2
|
-
import { asBigint, asString, decodeCall } from '../abi.js';
|
|
3
|
-
import { accountFromBytes32 } from '../hex.js';
|
|
4
|
-
const fields = [
|
|
5
|
-
{ name: 'depositor', kind: 'bytes', size: 32 },
|
|
6
|
-
{ name: 'recipient', kind: 'bytes', size: 32 },
|
|
7
|
-
{ name: 'inputToken', kind: 'bytes', size: 32 },
|
|
8
|
-
{ name: 'outputToken', kind: 'bytes', size: 32 },
|
|
9
|
-
{ name: 'inputAmount', kind: 'uint' },
|
|
10
|
-
{ name: 'outputAmount', kind: 'uint' },
|
|
11
|
-
{ name: 'destinationChainId', kind: 'uint' },
|
|
12
|
-
{ name: 'exclusiveRelayer', kind: 'bytes', size: 32 },
|
|
13
|
-
{ name: 'quoteTimestamp', kind: 'uint' },
|
|
14
|
-
{ name: 'fillDeadline', kind: 'uint' },
|
|
15
|
-
{ name: 'exclusivityParameter', kind: 'uint' },
|
|
16
|
-
{ name: 'message', kind: 'bytes' },
|
|
17
|
-
];
|
|
18
|
-
export const deposit = {
|
|
19
|
-
name: 'deposit',
|
|
20
|
-
selector: '0xad5425c6',
|
|
21
|
-
decode(data) {
|
|
22
|
-
const args = decodeCall(fields, data);
|
|
23
|
-
return applyAcrossMessage({
|
|
24
|
-
aggregatorId: 'across',
|
|
25
|
-
method: 'deposit',
|
|
26
|
-
kind: 'bridge',
|
|
27
|
-
depositor: accountFromBytes32(asString(args.depositor)),
|
|
28
|
-
sourceToken: accountFromBytes32(asString(args.inputToken)),
|
|
29
|
-
sourceAmount: asBigint(args.inputAmount),
|
|
30
|
-
destinationChainId: asBigint(args.destinationChainId),
|
|
31
|
-
receiver: accountFromBytes32(asString(args.recipient)),
|
|
32
|
-
outputToken: accountFromBytes32(asString(args.outputToken)),
|
|
33
|
-
minOutputAmount: asBigint(args.outputAmount),
|
|
34
|
-
}, asString(args.message));
|
|
35
|
-
},
|
|
36
|
-
};
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { BRIDGE_ERRORS, BridgeError } from '../../errors/index.js';
|
|
2
|
-
import { applyAcrossMessage } from '../destination.js';
|
|
3
|
-
import { asBigint, asString, decodeCall } from '../abi.js';
|
|
4
|
-
import { accountFromBytes32 } from '../hex.js';
|
|
5
|
-
import { NATIVE_TOKEN } from '../protocols.js';
|
|
6
|
-
const fields = [
|
|
7
|
-
{ name: 'spokePool', kind: 'address' },
|
|
8
|
-
{ name: 'depositor', kind: 'address' },
|
|
9
|
-
{ name: 'recipient', kind: 'bytes', size: 32 },
|
|
10
|
-
{ name: 'inputToken', kind: 'address' },
|
|
11
|
-
{ name: 'inputAmount', kind: 'uint' },
|
|
12
|
-
{ name: 'outputToken', kind: 'bytes', size: 32 },
|
|
13
|
-
{ name: 'outputAmount', kind: 'uint' },
|
|
14
|
-
{ name: 'destinationChainId', kind: 'uint' },
|
|
15
|
-
{ name: 'exclusiveRelayer', kind: 'bytes', size: 32 },
|
|
16
|
-
{ name: 'quoteTimestamp', kind: 'uint' },
|
|
17
|
-
{ name: 'fillDeadline', kind: 'uint' },
|
|
18
|
-
{ name: 'exclusivityParameter', kind: 'uint' },
|
|
19
|
-
{ name: 'message', kind: 'bytes' },
|
|
20
|
-
];
|
|
21
|
-
export const depositNative = {
|
|
22
|
-
name: 'depositNative',
|
|
23
|
-
selector: '0x609ea081',
|
|
24
|
-
decode(data, value) {
|
|
25
|
-
const args = decodeCall(fields, data);
|
|
26
|
-
const inputAmount = asBigint(args.inputAmount);
|
|
27
|
-
if (inputAmount > 0n && value !== inputAmount)
|
|
28
|
-
throw new BridgeError(BRIDGE_ERRORS.ACROSS_NATIVE_VALUE_MISMATCH);
|
|
29
|
-
return applyAcrossMessage({
|
|
30
|
-
aggregatorId: 'across',
|
|
31
|
-
method: 'depositNative',
|
|
32
|
-
kind: 'bridge',
|
|
33
|
-
depositor: asString(args.depositor),
|
|
34
|
-
sourceToken: NATIVE_TOKEN,
|
|
35
|
-
sourceAmount: inputAmount > 0n ? inputAmount : value,
|
|
36
|
-
bridgeToken: asString(args.inputToken),
|
|
37
|
-
bridgeAmount: inputAmount > 0n ? inputAmount : value,
|
|
38
|
-
destinationChainId: asBigint(args.destinationChainId),
|
|
39
|
-
receiver: accountFromBytes32(asString(args.recipient)),
|
|
40
|
-
outputToken: accountFromBytes32(asString(args.outputToken)),
|
|
41
|
-
minOutputAmount: asBigint(args.outputAmount),
|
|
42
|
-
spokePool: asString(args.spokePool),
|
|
43
|
-
}, asString(args.message));
|
|
44
|
-
},
|
|
45
|
-
};
|