@metamask/transaction-pay-controller 17.1.0 → 18.1.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/CHANGELOG.md +26 -1
- package/dist/TransactionPayController-method-action-types.cjs +1 -1
- package/dist/TransactionPayController-method-action-types.cjs.map +1 -1
- package/dist/TransactionPayController-method-action-types.d.cts +1 -1
- package/dist/TransactionPayController-method-action-types.d.mts +1 -1
- package/dist/TransactionPayController-method-action-types.mjs +1 -1
- package/dist/TransactionPayController-method-action-types.mjs.map +1 -1
- package/dist/constants.cjs +1 -0
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +1 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +1 -0
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +1 -0
- package/dist/constants.mjs.map +1 -1
- package/dist/strategy/across/across-actions.cjs +185 -0
- package/dist/strategy/across/across-actions.cjs.map +1 -0
- package/dist/strategy/across/across-actions.d.cts +21 -0
- package/dist/strategy/across/across-actions.d.cts.map +1 -0
- package/dist/strategy/across/across-actions.d.mts +21 -0
- package/dist/strategy/across/across-actions.d.mts.map +1 -0
- package/dist/strategy/across/across-actions.mjs +178 -0
- package/dist/strategy/across/across-actions.mjs.map +1 -0
- package/dist/strategy/across/across-quotes.cjs +66 -165
- package/dist/strategy/across/across-quotes.cjs.map +1 -1
- package/dist/strategy/across/across-quotes.d.cts.map +1 -1
- package/dist/strategy/across/across-quotes.d.mts.map +1 -1
- package/dist/strategy/across/across-quotes.mjs +66 -165
- package/dist/strategy/across/across-quotes.mjs.map +1 -1
- package/dist/strategy/across/across-submit.cjs +38 -37
- package/dist/strategy/across/across-submit.cjs.map +1 -1
- package/dist/strategy/across/across-submit.d.cts.map +1 -1
- package/dist/strategy/across/across-submit.d.mts.map +1 -1
- package/dist/strategy/across/across-submit.mjs +38 -37
- package/dist/strategy/across/across-submit.mjs.map +1 -1
- package/dist/strategy/across/transactions.cjs +23 -0
- package/dist/strategy/across/transactions.cjs.map +1 -0
- package/dist/strategy/across/transactions.d.cts +18 -0
- package/dist/strategy/across/transactions.d.cts.map +1 -0
- package/dist/strategy/across/transactions.d.mts +18 -0
- package/dist/strategy/across/transactions.d.mts.map +1 -0
- package/dist/strategy/across/transactions.mjs +19 -0
- package/dist/strategy/across/transactions.mjs.map +1 -0
- package/dist/strategy/across/types.cjs.map +1 -1
- package/dist/strategy/across/types.d.cts +6 -10
- package/dist/strategy/across/types.d.cts.map +1 -1
- package/dist/strategy/across/types.d.mts +6 -10
- package/dist/strategy/across/types.d.mts.map +1 -1
- package/dist/strategy/across/types.mjs.map +1 -1
- package/dist/strategy/fiat/FiatStrategy.cjs +15 -0
- package/dist/strategy/fiat/FiatStrategy.cjs.map +1 -0
- package/dist/strategy/fiat/FiatStrategy.d.cts +7 -0
- package/dist/strategy/fiat/FiatStrategy.d.cts.map +1 -0
- package/dist/strategy/fiat/FiatStrategy.d.mts +7 -0
- package/dist/strategy/fiat/FiatStrategy.d.mts.map +1 -0
- package/dist/strategy/fiat/FiatStrategy.mjs +11 -0
- package/dist/strategy/fiat/FiatStrategy.mjs.map +1 -0
- package/dist/strategy/fiat/constants.cjs +24 -0
- package/dist/strategy/fiat/constants.cjs.map +1 -0
- package/dist/strategy/fiat/constants.d.cts +10 -0
- package/dist/strategy/fiat/constants.d.cts.map +1 -0
- package/dist/strategy/fiat/constants.d.mts +10 -0
- package/dist/strategy/fiat/constants.d.mts.map +1 -0
- package/dist/strategy/fiat/constants.mjs +21 -0
- package/dist/strategy/fiat/constants.mjs.map +1 -0
- package/dist/strategy/fiat/fiat-quotes.cjs +214 -0
- package/dist/strategy/fiat/fiat-quotes.cjs.map +1 -0
- package/dist/strategy/fiat/fiat-quotes.d.cts +17 -0
- package/dist/strategy/fiat/fiat-quotes.d.cts.map +1 -0
- package/dist/strategy/fiat/fiat-quotes.d.mts +17 -0
- package/dist/strategy/fiat/fiat-quotes.d.mts.map +1 -0
- package/dist/strategy/fiat/fiat-quotes.mjs +210 -0
- package/dist/strategy/fiat/fiat-quotes.mjs.map +1 -0
- package/dist/strategy/fiat/fiat-submit.cjs +14 -0
- package/dist/strategy/fiat/fiat-submit.cjs.map +1 -0
- package/dist/strategy/fiat/fiat-submit.d.cts +10 -0
- package/dist/strategy/fiat/fiat-submit.d.cts.map +1 -0
- package/dist/strategy/fiat/fiat-submit.d.mts +10 -0
- package/dist/strategy/fiat/fiat-submit.d.mts.map +1 -0
- package/dist/strategy/fiat/fiat-submit.mjs +10 -0
- package/dist/strategy/fiat/fiat-submit.mjs.map +1 -0
- package/dist/strategy/fiat/types.cjs +3 -0
- package/dist/strategy/fiat/types.cjs.map +1 -0
- package/dist/strategy/fiat/types.d.cts +8 -0
- package/dist/strategy/fiat/types.d.cts.map +1 -0
- package/dist/strategy/fiat/types.d.mts +8 -0
- package/dist/strategy/fiat/types.d.mts.map +1 -0
- package/dist/strategy/fiat/types.mjs +2 -0
- package/dist/strategy/fiat/types.mjs.map +1 -0
- package/dist/strategy/fiat/utils.cjs +23 -0
- package/dist/strategy/fiat/utils.cjs.map +1 -0
- package/dist/strategy/fiat/utils.d.cts +6 -0
- package/dist/strategy/fiat/utils.d.cts.map +1 -0
- package/dist/strategy/fiat/utils.d.mts +6 -0
- package/dist/strategy/fiat/utils.d.mts.map +1 -0
- package/dist/strategy/fiat/utils.mjs +18 -0
- package/dist/strategy/fiat/utils.mjs.map +1 -0
- package/dist/strategy/relay/relay-quotes.cjs +49 -135
- package/dist/strategy/relay/relay-quotes.cjs.map +1 -1
- package/dist/strategy/relay/relay-quotes.d.cts.map +1 -1
- package/dist/strategy/relay/relay-quotes.d.mts.map +1 -1
- package/dist/strategy/relay/relay-quotes.mjs +51 -137
- package/dist/strategy/relay/relay-quotes.mjs.map +1 -1
- package/dist/strategy/relay/relay-submit.cjs +4 -3
- package/dist/strategy/relay/relay-submit.cjs.map +1 -1
- package/dist/strategy/relay/relay-submit.mjs +4 -3
- package/dist/strategy/relay/relay-submit.mjs.map +1 -1
- package/dist/strategy/relay/types.cjs.map +1 -1
- package/dist/strategy/relay/types.d.cts +10 -5
- package/dist/strategy/relay/types.d.cts.map +1 -1
- package/dist/strategy/relay/types.d.mts +10 -5
- package/dist/strategy/relay/types.d.mts.map +1 -1
- package/dist/strategy/relay/types.mjs.map +1 -1
- package/dist/tests/messenger-mock.d.cts +1 -1
- package/dist/tests/messenger-mock.d.mts +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +6 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +6 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/quote-gas.cjs +143 -0
- package/dist/utils/quote-gas.cjs.map +1 -0
- package/dist/utils/quote-gas.d.cts +31 -0
- package/dist/utils/quote-gas.d.cts.map +1 -0
- package/dist/utils/quote-gas.d.mts +31 -0
- package/dist/utils/quote-gas.d.mts.map +1 -0
- package/dist/utils/quote-gas.mjs +139 -0
- package/dist/utils/quote-gas.mjs.map +1 -0
- package/dist/utils/quotes.cjs +4 -2
- package/dist/utils/quotes.cjs.map +1 -1
- package/dist/utils/quotes.d.cts.map +1 -1
- package/dist/utils/quotes.d.mts.map +1 -1
- package/dist/utils/quotes.mjs +4 -2
- package/dist/utils/quotes.mjs.map +1 -1
- package/dist/utils/strategy.cjs +3 -0
- package/dist/utils/strategy.cjs.map +1 -1
- package/dist/utils/strategy.d.cts.map +1 -1
- package/dist/utils/strategy.d.mts.map +1 -1
- package/dist/utils/strategy.mjs +3 -0
- package/dist/utils/strategy.mjs.map +1 -1
- package/dist/utils/token.cjs +26 -1
- package/dist/utils/token.cjs.map +1 -1
- package/dist/utils/token.d.cts +10 -0
- package/dist/utils/token.d.cts.map +1 -1
- package/dist/utils/token.d.mts +10 -0
- package/dist/utils/token.d.mts.map +1 -1
- package/dist/utils/token.mjs +24 -0
- package/dist/utils/token.mjs.map +1 -1
- package/dist/utils/totals.cjs +2 -0
- package/dist/utils/totals.cjs.map +1 -1
- package/dist/utils/totals.d.cts.map +1 -1
- package/dist/utils/totals.d.mts.map +1 -1
- package/dist/utils/totals.mjs +2 -0
- package/dist/utils/totals.mjs.map +1 -1
- package/package.json +7 -6
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { Interface } from "@ethersproject/abi";
|
|
2
|
+
export const TOKEN_TRANSFER_SIGNATURE = 'function transfer(address to, uint256 value)';
|
|
3
|
+
export const CREATE_PROXY_SIGNATURE = 'function createProxy(address paymentToken, uint256 payment, address payable paymentReceiver, (uint8 v, bytes32 r, bytes32 s) createSig)';
|
|
4
|
+
export const SAFE_EXEC_TRANSACTION_SIGNATURE = 'function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures)';
|
|
5
|
+
export const UNSUPPORTED_DESTINATION_ERROR = 'Across only supports direct token transfers and a limited set of post-swap destination actions at the moment';
|
|
6
|
+
const ACROSS_ACTION_SIGNATURES = [
|
|
7
|
+
CREATE_PROXY_SIGNATURE,
|
|
8
|
+
SAFE_EXEC_TRANSACTION_SIGNATURE,
|
|
9
|
+
];
|
|
10
|
+
export function buildAcrossActionFromCall(call, request) {
|
|
11
|
+
if (isTransferCall(call.data)) {
|
|
12
|
+
return buildAcrossTransferAction(call, request);
|
|
13
|
+
}
|
|
14
|
+
const parsedCall = parseAcrossActionCall(call.data);
|
|
15
|
+
return {
|
|
16
|
+
args: Array.from(parsedCall.transaction.args).map((arg) => ({
|
|
17
|
+
populateDynamically: false,
|
|
18
|
+
value: serializeAcrossActionValue(arg),
|
|
19
|
+
})),
|
|
20
|
+
functionSignature: parsedCall.functionSignature,
|
|
21
|
+
isNativeTransfer: false,
|
|
22
|
+
target: getRequiredTarget(call),
|
|
23
|
+
value: '0',
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function getTransferRecipient(data) {
|
|
27
|
+
const parsedCall = tryParseTransferCall(data);
|
|
28
|
+
if (!parsedCall) {
|
|
29
|
+
throw new Error(getUnsupportedDestinationErrorMessage(data));
|
|
30
|
+
}
|
|
31
|
+
return normalizeHexString(String(parsedCall.args[0]));
|
|
32
|
+
}
|
|
33
|
+
export function getAcrossDestination(transaction, request) {
|
|
34
|
+
const { from } = request;
|
|
35
|
+
const destinationCalls = getDestinationCalls(transaction);
|
|
36
|
+
const swapRecipientTransferCallIndex = destinationCalls.findIndex((call) => isExtractableOutputTokenTransferCall(call, request));
|
|
37
|
+
const callsForActions = [...destinationCalls];
|
|
38
|
+
let recipient = from;
|
|
39
|
+
if (swapRecipientTransferCallIndex !== -1) {
|
|
40
|
+
const [swapRecipientTransferCall] = callsForActions.splice(swapRecipientTransferCallIndex, 1);
|
|
41
|
+
recipient = getTransferRecipient(swapRecipientTransferCall.data);
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
actions: callsForActions.map((call) => buildAcrossActionFromCall(call, request)),
|
|
45
|
+
recipient,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function isExtractableOutputTokenTransferCall(call, request) {
|
|
49
|
+
return (isTransferCall(call.data) &&
|
|
50
|
+
(call.target === undefined ||
|
|
51
|
+
normalizeHexString(call.target) ===
|
|
52
|
+
normalizeHexString(request.targetTokenAddress)));
|
|
53
|
+
}
|
|
54
|
+
function getRequiredTarget(call) {
|
|
55
|
+
if (!call.target) {
|
|
56
|
+
throw new Error(UNSUPPORTED_DESTINATION_ERROR);
|
|
57
|
+
}
|
|
58
|
+
return call.target;
|
|
59
|
+
}
|
|
60
|
+
function normalizeHexString(value) {
|
|
61
|
+
/* istanbul ignore next: current supported Across action signatures only emit hex strings here. */
|
|
62
|
+
if (!value.startsWith('0x')) {
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
return value.toLowerCase();
|
|
66
|
+
}
|
|
67
|
+
function parseAcrossActionCall(data) {
|
|
68
|
+
const parsedCall = tryParseAcrossActionCall(data);
|
|
69
|
+
if (!parsedCall) {
|
|
70
|
+
throw new Error(getUnsupportedDestinationErrorMessage(data));
|
|
71
|
+
}
|
|
72
|
+
return parsedCall;
|
|
73
|
+
}
|
|
74
|
+
function serializeAcrossActionValue(value) {
|
|
75
|
+
if (Array.isArray(value)) {
|
|
76
|
+
return value.map((entry) => serializeAcrossActionScalar(entry));
|
|
77
|
+
}
|
|
78
|
+
return serializeAcrossActionScalar(value);
|
|
79
|
+
}
|
|
80
|
+
function buildAcrossTransferAction(call, request) {
|
|
81
|
+
return {
|
|
82
|
+
args: [
|
|
83
|
+
{
|
|
84
|
+
populateDynamically: false,
|
|
85
|
+
value: getTransferRecipient(call.data),
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
balanceSourceToken: request.targetTokenAddress,
|
|
89
|
+
populateDynamically: true,
|
|
90
|
+
value: '0',
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
functionSignature: TOKEN_TRANSFER_SIGNATURE,
|
|
94
|
+
isNativeTransfer: false,
|
|
95
|
+
target: call.target ?? request.targetTokenAddress,
|
|
96
|
+
value: '0',
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function getDestinationCalls(transaction) {
|
|
100
|
+
const nestedCalls = (transaction.nestedTransactions ?? []).flatMap((nestedTx) => nestedTx.data !== undefined && nestedTx.data !== '0x'
|
|
101
|
+
? [{ data: nestedTx.data, target: nestedTx.to }]
|
|
102
|
+
: []);
|
|
103
|
+
if (nestedCalls.length > 0) {
|
|
104
|
+
return nestedCalls;
|
|
105
|
+
}
|
|
106
|
+
const data = transaction.txParams?.data;
|
|
107
|
+
if (data === undefined || data === '0x') {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
return [
|
|
111
|
+
{
|
|
112
|
+
data,
|
|
113
|
+
target: transaction.txParams?.to,
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
}
|
|
117
|
+
function getUnsupportedDestinationErrorMessage(data) {
|
|
118
|
+
const selector = getDestinationSelector(data);
|
|
119
|
+
return selector
|
|
120
|
+
? `${UNSUPPORTED_DESTINATION_ERROR}. Destination selector: ${selector}`
|
|
121
|
+
: UNSUPPORTED_DESTINATION_ERROR;
|
|
122
|
+
}
|
|
123
|
+
function getDestinationSelector(data) {
|
|
124
|
+
if (!data || data.length < 10) {
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
return data.slice(0, 10).toLowerCase();
|
|
128
|
+
}
|
|
129
|
+
function serializeAcrossActionScalar(value) {
|
|
130
|
+
if (typeof value === 'string') {
|
|
131
|
+
return normalizeHexString(value);
|
|
132
|
+
}
|
|
133
|
+
if (typeof value === 'number' ||
|
|
134
|
+
typeof value === 'bigint' ||
|
|
135
|
+
typeof value === 'boolean') {
|
|
136
|
+
return String(value);
|
|
137
|
+
}
|
|
138
|
+
if (isBigNumberLike(value)) {
|
|
139
|
+
return value.toString();
|
|
140
|
+
}
|
|
141
|
+
/* istanbul ignore next: supported Across action ABIs only decode scalars and tuples of scalars. */
|
|
142
|
+
throw new Error(UNSUPPORTED_DESTINATION_ERROR);
|
|
143
|
+
}
|
|
144
|
+
function isBigNumberLike(value) {
|
|
145
|
+
return (typeof value === 'object' &&
|
|
146
|
+
value !== null &&
|
|
147
|
+
'_isBigNumber' in value &&
|
|
148
|
+
value._isBigNumber === true &&
|
|
149
|
+
'toString' in value &&
|
|
150
|
+
typeof value.toString === 'function');
|
|
151
|
+
}
|
|
152
|
+
function isTransferCall(data) {
|
|
153
|
+
return tryParseTransferCall(data) !== undefined;
|
|
154
|
+
}
|
|
155
|
+
function tryParseAcrossActionCall(data) {
|
|
156
|
+
for (const functionSignature of ACROSS_ACTION_SIGNATURES) {
|
|
157
|
+
try {
|
|
158
|
+
const actionInterface = new Interface([functionSignature]);
|
|
159
|
+
return {
|
|
160
|
+
functionSignature,
|
|
161
|
+
transaction: actionInterface.parseTransaction({ data }),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Intentionally empty.
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
function tryParseTransferCall(data) {
|
|
171
|
+
try {
|
|
172
|
+
return new Interface([TOKEN_TRANSFER_SIGNATURE]).parseTransaction({ data });
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
return undefined;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=across-actions.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"across-actions.mjs","sourceRoot":"","sources":["../../../src/strategy/across/across-actions.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport type { TransactionDescription } from '@ethersproject/abi';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport type { AcrossAction, AcrossActionArg } from './types';\nimport type { QuoteRequest } from '../../types';\n\nexport const TOKEN_TRANSFER_SIGNATURE =\n 'function transfer(address to, uint256 value)';\nexport const CREATE_PROXY_SIGNATURE =\n 'function createProxy(address paymentToken, uint256 payment, address payable paymentReceiver, (uint8 v, bytes32 r, bytes32 s) createSig)';\nexport const SAFE_EXEC_TRANSACTION_SIGNATURE =\n 'function execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures)';\n\nexport const UNSUPPORTED_DESTINATION_ERROR =\n 'Across only supports direct token transfers and a limited set of post-swap destination actions at the moment';\n\nexport type AcrossDestinationCall = {\n data: Hex;\n target?: Hex;\n};\n\nexport type AcrossDestination = {\n actions: AcrossAction[];\n recipient: Hex;\n};\n\ntype ParsedAcrossActionCall = {\n functionSignature: string;\n transaction: TransactionDescription;\n};\n\ntype BigNumberLike = {\n _isBigNumber: true;\n toString: () => string;\n};\n\nconst ACROSS_ACTION_SIGNATURES = [\n CREATE_PROXY_SIGNATURE,\n SAFE_EXEC_TRANSACTION_SIGNATURE,\n];\n\nexport function buildAcrossActionFromCall(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): AcrossAction {\n if (isTransferCall(call.data)) {\n return buildAcrossTransferAction(call, request);\n }\n\n const parsedCall = parseAcrossActionCall(call.data);\n\n return {\n args: Array.from(parsedCall.transaction.args).map((arg) => ({\n populateDynamically: false,\n value: serializeAcrossActionValue(arg),\n })),\n functionSignature: parsedCall.functionSignature,\n isNativeTransfer: false,\n target: getRequiredTarget(call),\n value: '0',\n };\n}\n\nexport function getTransferRecipient(data: Hex): Hex {\n const parsedCall = tryParseTransferCall(data);\n\n if (!parsedCall) {\n throw new Error(getUnsupportedDestinationErrorMessage(data));\n }\n\n return normalizeHexString(String(parsedCall.args[0])) as Hex;\n}\n\nexport function getAcrossDestination(\n transaction: TransactionMeta,\n request: QuoteRequest,\n): AcrossDestination {\n const { from } = request;\n const destinationCalls = getDestinationCalls(transaction);\n const swapRecipientTransferCallIndex = destinationCalls.findIndex((call) =>\n isExtractableOutputTokenTransferCall(call, request),\n );\n const callsForActions = [...destinationCalls];\n let recipient = from;\n\n if (swapRecipientTransferCallIndex !== -1) {\n const [swapRecipientTransferCall] = callsForActions.splice(\n swapRecipientTransferCallIndex,\n 1,\n );\n\n recipient = getTransferRecipient(swapRecipientTransferCall.data);\n }\n\n return {\n actions: callsForActions.map((call) =>\n buildAcrossActionFromCall(call, request),\n ),\n recipient,\n };\n}\n\nexport function isExtractableOutputTokenTransferCall(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): boolean {\n return (\n isTransferCall(call.data) &&\n (call.target === undefined ||\n normalizeHexString(call.target) ===\n normalizeHexString(request.targetTokenAddress))\n );\n}\n\nfunction getRequiredTarget(call: AcrossDestinationCall): Hex {\n if (!call.target) {\n throw new Error(UNSUPPORTED_DESTINATION_ERROR);\n }\n\n return call.target;\n}\n\nfunction normalizeHexString(value: string): string {\n /* istanbul ignore next: current supported Across action signatures only emit hex strings here. */\n if (!value.startsWith('0x')) {\n return value;\n }\n\n return value.toLowerCase();\n}\n\nfunction parseAcrossActionCall(data: Hex): ParsedAcrossActionCall {\n const parsedCall = tryParseAcrossActionCall(data);\n\n if (!parsedCall) {\n throw new Error(getUnsupportedDestinationErrorMessage(data));\n }\n\n return parsedCall;\n}\n\nfunction serializeAcrossActionValue(value: unknown): AcrossActionArg['value'] {\n if (Array.isArray(value)) {\n return value.map((entry) =>\n serializeAcrossActionScalar(entry),\n ) as AcrossActionArg['value'];\n }\n\n return serializeAcrossActionScalar(value);\n}\n\nfunction buildAcrossTransferAction(\n call: AcrossDestinationCall,\n request: QuoteRequest,\n): AcrossAction {\n return {\n args: [\n {\n populateDynamically: false,\n value: getTransferRecipient(call.data),\n },\n {\n balanceSourceToken: request.targetTokenAddress,\n populateDynamically: true,\n value: '0',\n },\n ],\n functionSignature: TOKEN_TRANSFER_SIGNATURE,\n isNativeTransfer: false,\n target: call.target ?? request.targetTokenAddress,\n value: '0',\n };\n}\n\nfunction getDestinationCalls(\n transaction: TransactionMeta,\n): AcrossDestinationCall[] {\n const nestedCalls = (\n transaction.nestedTransactions ?? []\n ).flatMap<AcrossDestinationCall>((nestedTx: { data?: Hex; to?: Hex }) =>\n nestedTx.data !== undefined && nestedTx.data !== '0x'\n ? [{ data: nestedTx.data, target: nestedTx.to }]\n : [],\n );\n\n if (nestedCalls.length > 0) {\n return nestedCalls;\n }\n\n const data = transaction.txParams?.data as Hex | undefined;\n\n if (data === undefined || data === '0x') {\n return [];\n }\n\n return [\n {\n data,\n target: transaction.txParams?.to as Hex | undefined,\n },\n ];\n}\n\nfunction getUnsupportedDestinationErrorMessage(data?: Hex): string {\n const selector = getDestinationSelector(data);\n\n return selector\n ? `${UNSUPPORTED_DESTINATION_ERROR}. Destination selector: ${selector}`\n : UNSUPPORTED_DESTINATION_ERROR;\n}\n\nfunction getDestinationSelector(data?: Hex): Hex | undefined {\n if (!data || data.length < 10) {\n return undefined;\n }\n\n return data.slice(0, 10).toLowerCase() as Hex;\n}\n\nfunction serializeAcrossActionScalar(value: unknown): string {\n if (typeof value === 'string') {\n return normalizeHexString(value);\n }\n\n if (\n typeof value === 'number' ||\n typeof value === 'bigint' ||\n typeof value === 'boolean'\n ) {\n return String(value);\n }\n\n if (isBigNumberLike(value)) {\n return value.toString();\n }\n\n /* istanbul ignore next: supported Across action ABIs only decode scalars and tuples of scalars. */\n throw new Error(UNSUPPORTED_DESTINATION_ERROR);\n}\n\nfunction isBigNumberLike(value: unknown): value is BigNumberLike {\n return (\n typeof value === 'object' &&\n value !== null &&\n '_isBigNumber' in value &&\n value._isBigNumber === true &&\n 'toString' in value &&\n typeof value.toString === 'function'\n );\n}\n\nfunction isTransferCall(data: Hex): boolean {\n return tryParseTransferCall(data) !== undefined;\n}\n\nfunction tryParseAcrossActionCall(\n data: Hex,\n): ParsedAcrossActionCall | undefined {\n for (const functionSignature of ACROSS_ACTION_SIGNATURES) {\n try {\n const actionInterface = new Interface([functionSignature]);\n\n return {\n functionSignature,\n transaction: actionInterface.parseTransaction({ data }),\n };\n } catch {\n // Intentionally empty.\n }\n }\n\n return undefined;\n}\n\nfunction tryParseTransferCall(data: Hex): TransactionDescription | undefined {\n try {\n return new Interface([TOKEN_TRANSFER_SIGNATURE]).parseTransaction({ data });\n } catch {\n return undefined;\n }\n}\n"]}
|
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getAcrossQuotes = void 0;
|
|
4
|
-
const abi_1 = require("@ethersproject/abi");
|
|
5
4
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
6
|
-
const transaction_controller_1 = require("@metamask/transaction-controller");
|
|
7
5
|
const utils_1 = require("@metamask/utils");
|
|
8
6
|
const bignumber_js_1 = require("bignumber.js");
|
|
7
|
+
const across_actions_1 = require("./across-actions.cjs");
|
|
8
|
+
const transactions_1 = require("./transactions.cjs");
|
|
9
9
|
const constants_1 = require("../../constants.cjs");
|
|
10
10
|
const logger_1 = require("../../logger.cjs");
|
|
11
11
|
const amounts_1 = require("../../utils/amounts.cjs");
|
|
12
12
|
const feature_flags_1 = require("../../utils/feature-flags.cjs");
|
|
13
13
|
const gas_1 = require("../../utils/gas.cjs");
|
|
14
|
+
const quote_gas_1 = require("../../utils/quote-gas.cjs");
|
|
14
15
|
const token_1 = require("../../utils/token.cjs");
|
|
15
|
-
const constants_2 = require("../relay/constants.cjs");
|
|
16
16
|
const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'across-strategy');
|
|
17
|
-
const TOKEN_TRANSFER_INTERFACE = new abi_1.Interface([
|
|
18
|
-
'function transfer(address to, uint256 value)',
|
|
19
|
-
]);
|
|
20
17
|
const UNSUPPORTED_AUTHORIZATION_LIST_ERROR = 'Across does not support type-4/EIP-7702 authorization lists yet';
|
|
21
|
-
const UNSUPPORTED_DESTINATION_ERROR = 'Across only supports transfer-style destination flows at the moment';
|
|
22
18
|
/**
|
|
23
19
|
* Fetch Across quotes.
|
|
24
20
|
*
|
|
@@ -53,7 +49,7 @@ async function getSingleQuote(request, fullRequest) {
|
|
|
53
49
|
const slippageDecimal = (0, feature_flags_1.getSlippage)(messenger, sourceChainId, sourceTokenAddress);
|
|
54
50
|
const amount = isMaxAmount ? sourceTokenAmount : targetAmountMinimum;
|
|
55
51
|
const tradeType = isMaxAmount ? 'exactInput' : 'exactOutput';
|
|
56
|
-
const destination = getAcrossDestination(transaction, request);
|
|
52
|
+
const destination = (0, across_actions_1.getAcrossDestination)(transaction, request);
|
|
57
53
|
const quote = await requestAcrossApproval({
|
|
58
54
|
actions: destination.actions,
|
|
59
55
|
amount,
|
|
@@ -103,77 +99,13 @@ async function requestAcrossApproval(request) {
|
|
|
103
99
|
const response = await (0, controller_utils_1.successfulFetch)(url, options);
|
|
104
100
|
return (await response.json());
|
|
105
101
|
}
|
|
106
|
-
function getAcrossDestination(transaction, request) {
|
|
107
|
-
const { txParams } = transaction;
|
|
108
|
-
const { from } = request;
|
|
109
|
-
const transferData = getTransferData(transaction);
|
|
110
|
-
if (transferData) {
|
|
111
|
-
const transferRecipient = getTransferRecipient(transferData);
|
|
112
|
-
if (transaction.type === transaction_controller_1.TransactionType.predictDeposit) {
|
|
113
|
-
return {
|
|
114
|
-
actions: [buildAcrossTransferAction(transferRecipient, request)],
|
|
115
|
-
recipient: from,
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
return {
|
|
119
|
-
actions: [],
|
|
120
|
-
recipient: transferRecipient,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
const data = txParams?.data;
|
|
124
|
-
const hasNoData = data === undefined || data === '0x';
|
|
125
|
-
const nestedCalldata = getNestedCalldata(transaction);
|
|
126
|
-
if (hasNoData && nestedCalldata.length === 0) {
|
|
127
|
-
return {
|
|
128
|
-
actions: [],
|
|
129
|
-
recipient: from,
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
throw new Error(UNSUPPORTED_DESTINATION_ERROR);
|
|
133
|
-
}
|
|
134
|
-
function buildAcrossTransferAction(transferRecipient, request) {
|
|
135
|
-
return {
|
|
136
|
-
args: [
|
|
137
|
-
{
|
|
138
|
-
populateDynamically: false,
|
|
139
|
-
value: transferRecipient,
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
balanceSourceToken: request.targetTokenAddress,
|
|
143
|
-
populateDynamically: true,
|
|
144
|
-
value: '0',
|
|
145
|
-
},
|
|
146
|
-
],
|
|
147
|
-
functionSignature: 'function transfer(address to, uint256 value)',
|
|
148
|
-
isNativeTransfer: false,
|
|
149
|
-
target: request.targetTokenAddress,
|
|
150
|
-
value: '0',
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
function getTransferData(transaction) {
|
|
154
|
-
const { nestedTransactions, txParams } = transaction;
|
|
155
|
-
const nestedTransferData = nestedTransactions?.find((nestedTx) => nestedTx.data?.startsWith(constants_2.TOKEN_TRANSFER_FOUR_BYTE))?.data;
|
|
156
|
-
const data = txParams?.data;
|
|
157
|
-
const tokenTransferData = data?.startsWith(constants_2.TOKEN_TRANSFER_FOUR_BYTE)
|
|
158
|
-
? data
|
|
159
|
-
: undefined;
|
|
160
|
-
return nestedTransferData ?? tokenTransferData;
|
|
161
|
-
}
|
|
162
|
-
function getNestedCalldata(transaction) {
|
|
163
|
-
return (transaction.nestedTransactions ?? [])
|
|
164
|
-
.map((nestedTx) => nestedTx.data)
|
|
165
|
-
.filter((data) => data !== undefined && data !== '0x');
|
|
166
|
-
}
|
|
167
|
-
function getTransferRecipient(data) {
|
|
168
|
-
return TOKEN_TRANSFER_INTERFACE.decodeFunctionData('transfer', data).to.toLowerCase();
|
|
169
|
-
}
|
|
170
102
|
async function normalizeQuote(original, request, fullRequest) {
|
|
171
103
|
const { messenger } = fullRequest;
|
|
172
104
|
const { quote } = original;
|
|
173
105
|
const { usdToFiatRate, sourceFiatRate, targetFiatRate } = getFiatRates(messenger, quote);
|
|
174
106
|
const dustUsd = calculateDustUsd(quote, request, targetFiatRate);
|
|
175
107
|
const dust = (0, amounts_1.getFiatValueFromUsd)(dustUsd, usdToFiatRate);
|
|
176
|
-
const {
|
|
108
|
+
const { gasLimits, is7702, sourceNetwork } = await calculateSourceNetworkCost(quote, messenger, request);
|
|
177
109
|
const targetNetwork = (0, amounts_1.getFiatValueFromUsd)(new bignumber_js_1.BigNumber(0), usdToFiatRate);
|
|
178
110
|
const inputAmountRaw = quote.inputAmount ?? '0';
|
|
179
111
|
const outputAmountRaw = new bignumber_js_1.BigNumber(quote.expectedOutputAmount ??
|
|
@@ -195,6 +127,7 @@ async function normalizeQuote(original, request, fullRequest) {
|
|
|
195
127
|
});
|
|
196
128
|
const metamask = {
|
|
197
129
|
gasLimits,
|
|
130
|
+
is7702,
|
|
198
131
|
};
|
|
199
132
|
return {
|
|
200
133
|
dust,
|
|
@@ -275,116 +208,84 @@ function getAmountFromTokenAmount({ amountRaw, decimals, fiatRate, }) {
|
|
|
275
208
|
async function calculateSourceNetworkCost(quote, messenger, request) {
|
|
276
209
|
const acrossFallbackGas = (0, feature_flags_1.getPayStrategiesConfig)(messenger).across.fallbackGas;
|
|
277
210
|
const { from } = request;
|
|
278
|
-
const
|
|
211
|
+
const orderedTransactions = (0, transactions_1.getAcrossOrderedTransactions)({ quote });
|
|
279
212
|
const { swapTx } = quote;
|
|
280
213
|
const swapChainId = (0, controller_utils_1.toHex)(swapTx.chainId);
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
from,
|
|
288
|
-
messenger,
|
|
289
|
-
to: approval.to,
|
|
290
|
-
value: approval.value ?? '0x0',
|
|
291
|
-
});
|
|
292
|
-
if (gas.usedFallback) {
|
|
293
|
-
log('Gas estimate failed, using fallback', {
|
|
294
|
-
error: gas.error,
|
|
295
|
-
transactionType: 'approval',
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
return { chainId, gas };
|
|
299
|
-
}));
|
|
300
|
-
const swapGasFromQuote = parseAcrossSwapGasLimit(swapTx.gas);
|
|
301
|
-
const swapGas = swapGasFromQuote === undefined
|
|
302
|
-
? await (0, gas_1.estimateGasLimit)({
|
|
303
|
-
chainId: swapChainId,
|
|
304
|
-
data: swapTx.data,
|
|
305
|
-
fallbackGas: acrossFallbackGas,
|
|
214
|
+
const gasEstimates = await (0, quote_gas_1.estimateQuoteGasLimits)({
|
|
215
|
+
fallbackGas: acrossFallbackGas,
|
|
216
|
+
messenger,
|
|
217
|
+
transactions: orderedTransactions.map((transaction) => ({
|
|
218
|
+
chainId: (0, controller_utils_1.toHex)(transaction.chainId),
|
|
219
|
+
data: transaction.data,
|
|
306
220
|
from,
|
|
307
|
-
|
|
308
|
-
to:
|
|
309
|
-
value:
|
|
310
|
-
})
|
|
311
|
-
: {
|
|
312
|
-
estimate: swapGasFromQuote,
|
|
313
|
-
max: swapGasFromQuote,
|
|
314
|
-
usedFallback: false,
|
|
315
|
-
};
|
|
316
|
-
if (swapGasFromQuote !== undefined) {
|
|
317
|
-
log('Using Across-provided swap gas limit', {
|
|
318
|
-
gas: swapGasFromQuote,
|
|
319
|
-
transactionType: 'swap',
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
else if (swapGas.usedFallback) {
|
|
323
|
-
log('Gas estimate failed, using fallback', {
|
|
324
|
-
error: swapGas.error,
|
|
325
|
-
transactionType: 'swap',
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
const estimate = (0, amounts_1.sumAmounts)([
|
|
329
|
-
...approvalGasResults.map(({ chainId, gas }) => (0, gas_1.calculateGasCost)({
|
|
330
|
-
chainId,
|
|
331
|
-
gas: gas.estimate,
|
|
332
|
-
messenger,
|
|
221
|
+
gas: transaction.gas,
|
|
222
|
+
to: transaction.to,
|
|
223
|
+
value: transaction.value ?? '0x0',
|
|
333
224
|
})),
|
|
334
|
-
|
|
225
|
+
});
|
|
226
|
+
const { batchGasLimit, is7702 } = gasEstimates;
|
|
227
|
+
if (is7702) {
|
|
228
|
+
if (!batchGasLimit) {
|
|
229
|
+
throw new Error('Across combined batch gas estimate missing');
|
|
230
|
+
}
|
|
231
|
+
const estimate = (0, gas_1.calculateGasCost)({
|
|
335
232
|
chainId: swapChainId,
|
|
336
|
-
gas:
|
|
233
|
+
gas: batchGasLimit.estimate,
|
|
337
234
|
maxFeePerGas: swapTx.maxFeePerGas,
|
|
338
235
|
maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,
|
|
339
236
|
messenger,
|
|
340
|
-
})
|
|
341
|
-
|
|
342
|
-
const max = (0, amounts_1.sumAmounts)([
|
|
343
|
-
...approvalGasResults.map(({ chainId, gas }) => (0, gas_1.calculateGasCost)({
|
|
344
|
-
chainId,
|
|
345
|
-
gas: gas.max,
|
|
346
|
-
isMax: true,
|
|
347
|
-
messenger,
|
|
348
|
-
})),
|
|
349
|
-
(0, gas_1.calculateGasCost)({
|
|
237
|
+
});
|
|
238
|
+
const max = (0, gas_1.calculateGasCost)({
|
|
350
239
|
chainId: swapChainId,
|
|
351
|
-
gas:
|
|
240
|
+
gas: batchGasLimit.max,
|
|
352
241
|
isMax: true,
|
|
353
242
|
maxFeePerGas: swapTx.maxFeePerGas,
|
|
354
243
|
maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,
|
|
355
244
|
messenger,
|
|
356
|
-
})
|
|
357
|
-
|
|
245
|
+
});
|
|
246
|
+
return {
|
|
247
|
+
sourceNetwork: {
|
|
248
|
+
estimate,
|
|
249
|
+
max,
|
|
250
|
+
},
|
|
251
|
+
is7702: true,
|
|
252
|
+
gasLimits: [
|
|
253
|
+
{
|
|
254
|
+
estimate: batchGasLimit.estimate,
|
|
255
|
+
max: batchGasLimit.max,
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
const transactionGasLimits = orderedTransactions.map((transaction, index) => ({
|
|
261
|
+
gasEstimate: gasEstimates.gasLimits[index],
|
|
262
|
+
transaction,
|
|
263
|
+
}));
|
|
264
|
+
const estimate = (0, amounts_1.sumAmounts)(transactionGasLimits.map(({ gasEstimate, transaction }) => (0, gas_1.calculateGasCost)({
|
|
265
|
+
chainId: (0, controller_utils_1.toHex)(transaction.chainId),
|
|
266
|
+
gas: gasEstimate.estimate,
|
|
267
|
+
maxFeePerGas: transaction.maxFeePerGas,
|
|
268
|
+
maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,
|
|
269
|
+
messenger,
|
|
270
|
+
})));
|
|
271
|
+
const max = (0, amounts_1.sumAmounts)(transactionGasLimits.map(({ gasEstimate, transaction }) => (0, gas_1.calculateGasCost)({
|
|
272
|
+
chainId: (0, controller_utils_1.toHex)(transaction.chainId),
|
|
273
|
+
gas: gasEstimate.max,
|
|
274
|
+
isMax: true,
|
|
275
|
+
maxFeePerGas: transaction.maxFeePerGas,
|
|
276
|
+
maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,
|
|
277
|
+
messenger,
|
|
278
|
+
})));
|
|
358
279
|
return {
|
|
359
280
|
sourceNetwork: {
|
|
360
281
|
estimate,
|
|
361
282
|
max,
|
|
362
283
|
},
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
swap: {
|
|
369
|
-
estimate: swapGas.estimate,
|
|
370
|
-
max: swapGas.max,
|
|
371
|
-
},
|
|
372
|
-
},
|
|
284
|
+
is7702: false,
|
|
285
|
+
gasLimits: transactionGasLimits.map(({ gasEstimate }) => ({
|
|
286
|
+
estimate: gasEstimate.estimate,
|
|
287
|
+
max: gasEstimate.max,
|
|
288
|
+
})),
|
|
373
289
|
};
|
|
374
290
|
}
|
|
375
|
-
function parseAcrossSwapGasLimit(gas) {
|
|
376
|
-
if (!gas) {
|
|
377
|
-
return undefined;
|
|
378
|
-
}
|
|
379
|
-
const parsedGas = gas.startsWith('0x')
|
|
380
|
-
? new bignumber_js_1.BigNumber(gas.slice(2), 16)
|
|
381
|
-
: new bignumber_js_1.BigNumber(gas);
|
|
382
|
-
if (!parsedGas.isFinite() ||
|
|
383
|
-
parsedGas.isNaN() ||
|
|
384
|
-
!parsedGas.isInteger() ||
|
|
385
|
-
parsedGas.lte(0)) {
|
|
386
|
-
return undefined;
|
|
387
|
-
}
|
|
388
|
-
return parsedGas.toNumber();
|
|
389
|
-
}
|
|
390
291
|
//# sourceMappingURL=across-quotes.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"across-quotes.cjs","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { successfulFetch, toHex } from '@metamask/controller-utils';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport type {\n AcrossAction,\n AcrossActionRequestBody,\n AcrossGasLimits,\n AcrossQuote,\n AcrossSwapApprovalResponse,\n} from './types';\nimport { TransactionPayStrategy } from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatRates,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { getFiatValueFromUsd, sumAmounts } from '../../utils/amounts';\nimport { getPayStrategiesConfig, getSlippage } from '../../utils/feature-flags';\nimport { calculateGasCost, estimateGasLimit } from '../../utils/gas';\nimport { getTokenFiatRate } from '../../utils/token';\nimport { TOKEN_TRANSFER_FOUR_BYTE } from '../relay/constants';\n\nconst log = createModuleLogger(projectLogger, 'across-strategy');\n\nconst TOKEN_TRANSFER_INTERFACE = new Interface([\n 'function transfer(address to, uint256 value)',\n]);\n\nconst UNSUPPORTED_AUTHORIZATION_LIST_ERROR =\n 'Across does not support type-4/EIP-7702 authorization lists yet';\nconst UNSUPPORTED_DESTINATION_ERROR =\n 'Across only supports transfer-style destination flows at the moment';\n\ntype AcrossQuoteWithoutMetaMask = Omit<AcrossQuote, 'metamask'>;\n\ntype AcrossDestination = {\n actions: AcrossAction[];\n recipient: Hex;\n};\n\n/**\n * Fetch Across quotes.\n *\n * @param request - Request object.\n * @returns Array of quotes.\n */\nexport async function getAcrossQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>[]> {\n const { requests } = request;\n\n log('Fetching quotes', requests);\n\n try {\n const normalizedRequests = requests.filter(\n (singleRequest) =>\n singleRequest.isMaxAmount === true ||\n (singleRequest.targetAmountMinimum !== undefined &&\n singleRequest.targetAmountMinimum !== '0'),\n );\n\n if (normalizedRequests.length === 0) {\n return [];\n }\n\n if (request.transaction.txParams?.authorizationList?.length) {\n throw new Error(UNSUPPORTED_AUTHORIZATION_LIST_ERROR);\n }\n\n return await Promise.all(\n normalizedRequests.map((singleRequest) =>\n getSingleQuote(singleRequest, request),\n ),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Across quotes: ${String(error)}`);\n }\n}\n\nasync function getSingleQuote(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>> {\n const { messenger, transaction } = fullRequest;\n const {\n from,\n isMaxAmount,\n sourceChainId,\n sourceTokenAddress,\n sourceTokenAmount,\n targetAmountMinimum,\n targetChainId,\n targetTokenAddress,\n } = request;\n\n const config = getPayStrategiesConfig(messenger);\n const slippageDecimal = getSlippage(\n messenger,\n sourceChainId,\n sourceTokenAddress,\n );\n\n const amount = isMaxAmount ? sourceTokenAmount : targetAmountMinimum;\n const tradeType = isMaxAmount ? 'exactInput' : 'exactOutput';\n const destination = getAcrossDestination(transaction, request);\n const quote = await requestAcrossApproval({\n actions: destination.actions,\n amount,\n apiBase: config.across.apiBase,\n depositor: from,\n destinationChainId: targetChainId,\n inputToken: sourceTokenAddress,\n originChainId: sourceChainId,\n outputToken: targetTokenAddress,\n recipient: destination.recipient,\n slippage: slippageDecimal,\n tradeType,\n });\n\n const originalQuote: AcrossQuoteWithoutMetaMask = {\n quote,\n request: {\n amount,\n tradeType,\n },\n };\n\n return await normalizeQuote(originalQuote, request, fullRequest);\n}\n\ntype AcrossApprovalRequest = {\n actions: AcrossAction[];\n amount: string;\n apiBase: string;\n depositor: Hex;\n destinationChainId: Hex;\n inputToken: Hex;\n originChainId: Hex;\n outputToken: Hex;\n recipient: Hex;\n slippage?: number;\n tradeType: 'exactInput' | 'exactOutput';\n};\n\nasync function requestAcrossApproval(\n request: AcrossApprovalRequest,\n): Promise<AcrossSwapApprovalResponse> {\n const {\n actions,\n amount,\n apiBase,\n depositor,\n destinationChainId,\n inputToken,\n originChainId,\n outputToken,\n recipient,\n slippage,\n tradeType,\n } = request;\n\n const params = new URLSearchParams();\n params.set('tradeType', tradeType);\n params.set('amount', amount);\n params.set('inputToken', inputToken);\n params.set('outputToken', outputToken);\n params.set('originChainId', String(parseInt(originChainId, 16)));\n params.set('destinationChainId', String(parseInt(destinationChainId, 16)));\n params.set('depositor', depositor);\n params.set('recipient', recipient);\n\n if (slippage !== undefined) {\n params.set('slippage', String(slippage));\n }\n\n const body: AcrossActionRequestBody = { actions };\n const url = `${apiBase}/swap/approval?${params.toString()}`;\n const options: RequestInit = {\n body: JSON.stringify(body),\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n };\n const response = await successfulFetch(url, options);\n\n return (await response.json()) as AcrossSwapApprovalResponse;\n}\n\nfunction getAcrossDestination(\n transaction: TransactionMeta,\n request: QuoteRequest,\n): AcrossDestination {\n const { txParams } = transaction;\n const { from } = request;\n const transferData = getTransferData(transaction);\n\n if (transferData) {\n const transferRecipient = getTransferRecipient(transferData);\n\n if (transaction.type === TransactionType.predictDeposit) {\n return {\n actions: [buildAcrossTransferAction(transferRecipient, request)],\n recipient: from,\n };\n }\n\n return {\n actions: [],\n recipient: transferRecipient,\n };\n }\n\n const data = txParams?.data as Hex | undefined;\n const hasNoData = data === undefined || data === '0x';\n const nestedCalldata = getNestedCalldata(transaction);\n\n if (hasNoData && nestedCalldata.length === 0) {\n return {\n actions: [],\n recipient: from,\n };\n }\n\n throw new Error(UNSUPPORTED_DESTINATION_ERROR);\n}\n\nfunction buildAcrossTransferAction(\n transferRecipient: Hex,\n request: QuoteRequest,\n): AcrossAction {\n return {\n args: [\n {\n populateDynamically: false,\n value: transferRecipient,\n },\n {\n balanceSourceToken: request.targetTokenAddress,\n populateDynamically: true,\n value: '0',\n },\n ],\n functionSignature: 'function transfer(address to, uint256 value)',\n isNativeTransfer: false,\n target: request.targetTokenAddress,\n value: '0',\n };\n}\n\nfunction getTransferData(transaction: TransactionMeta): Hex | undefined {\n const { nestedTransactions, txParams } = transaction;\n\n const nestedTransferData = nestedTransactions?.find(\n (nestedTx: { data?: Hex }) =>\n nestedTx.data?.startsWith(TOKEN_TRANSFER_FOUR_BYTE),\n )?.data;\n\n const data = txParams?.data as Hex | undefined;\n const tokenTransferData = data?.startsWith(TOKEN_TRANSFER_FOUR_BYTE)\n ? data\n : undefined;\n\n return nestedTransferData ?? tokenTransferData;\n}\n\nfunction getNestedCalldata(transaction: TransactionMeta): Hex[] {\n return (transaction.nestedTransactions ?? [])\n .map((nestedTx: { data?: Hex }) => nestedTx.data)\n .filter(\n (data: Hex | undefined): data is Hex =>\n data !== undefined && data !== '0x',\n );\n}\n\nfunction getTransferRecipient(data: Hex): Hex {\n return TOKEN_TRANSFER_INTERFACE.decodeFunctionData(\n 'transfer',\n data,\n ).to.toLowerCase() as Hex;\n}\n\nasync function normalizeQuote(\n original: AcrossQuoteWithoutMetaMask,\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>> {\n const { messenger } = fullRequest;\n const { quote } = original;\n\n const { usdToFiatRate, sourceFiatRate, targetFiatRate } = getFiatRates(\n messenger,\n quote,\n );\n\n const dustUsd = calculateDustUsd(quote, request, targetFiatRate);\n const dust = getFiatValueFromUsd(dustUsd, usdToFiatRate);\n\n const { sourceNetwork, gasLimits } = await calculateSourceNetworkCost(\n quote,\n messenger,\n request,\n );\n\n const targetNetwork = getFiatValueFromUsd(new BigNumber(0), usdToFiatRate);\n\n const inputAmountRaw = quote.inputAmount ?? '0';\n const outputAmountRaw = new BigNumber(\n quote.expectedOutputAmount ??\n quote.minOutputAmount ??\n request.targetAmountMinimum ??\n '0',\n ).toString(10);\n\n const sourceAmount = getAmountFromTokenAmount({\n amountRaw: inputAmountRaw,\n decimals: quote.inputToken.decimals,\n fiatRate: sourceFiatRate,\n });\n\n const providerUsd = calculateProviderUsd(\n quote,\n inputAmountRaw,\n sourceFiatRate,\n targetFiatRate,\n quote.expectedOutputAmount,\n );\n const provider = getFiatValueFromUsd(providerUsd, usdToFiatRate);\n const metaMaskFee = getFiatValueFromUsd(\n new BigNumber(quote.fees?.app?.amountUsd ?? '0').abs(),\n usdToFiatRate,\n );\n\n const targetAmount = getAmountFromTokenAmount({\n amountRaw: outputAmountRaw,\n decimals: quote.outputToken.decimals,\n fiatRate: targetFiatRate,\n });\n\n const metamask = {\n gasLimits,\n };\n\n return {\n dust,\n estimatedDuration: quote.expectedFillTime ?? 0,\n fees: {\n metaMask: metaMaskFee,\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: {\n ...original,\n metamask,\n },\n request,\n sourceAmount,\n targetAmount,\n strategy: TransactionPayStrategy.Across,\n } as TransactionPayQuote<AcrossQuote>;\n}\n\nfunction getFiatRates(\n messenger: TransactionPayControllerMessenger,\n quote: AcrossSwapApprovalResponse,\n): {\n sourceFiatRate: FiatRates;\n targetFiatRate: FiatRates;\n usdToFiatRate: BigNumber;\n} {\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n quote.inputToken.address,\n toHex(quote.inputToken.chainId),\n );\n\n if (!sourceFiatRate) {\n throw new Error('Source token fiat rate not found');\n }\n\n const targetFiatRate =\n getTokenFiatRate(\n messenger,\n quote.outputToken.address,\n toHex(quote.outputToken.chainId),\n ) ?? sourceFiatRate;\n\n const usdToFiatRate = new BigNumber(sourceFiatRate.fiatRate).dividedBy(\n sourceFiatRate.usdRate,\n );\n\n return { sourceFiatRate, targetFiatRate, usdToFiatRate };\n}\n\nfunction calculateDustUsd(\n quote: AcrossSwapApprovalResponse,\n request: QuoteRequest,\n targetFiatRate: FiatRates,\n): BigNumber {\n const expectedOutputRaw = quote.expectedOutputAmount;\n\n if (expectedOutputRaw === undefined) {\n return new BigNumber(0);\n }\n\n const expectedOutput = new BigNumber(expectedOutputRaw);\n const minimumOutput = new BigNumber(\n quote.minOutputAmount ?? request.targetAmountMinimum ?? '0',\n );\n\n const dustRaw = expectedOutput.minus(minimumOutput).isNegative()\n ? new BigNumber(0)\n : expectedOutput.minus(minimumOutput);\n const dustHuman = dustRaw.shiftedBy(-quote.outputToken.decimals);\n\n return dustHuman.multipliedBy(targetFiatRate.usdRate);\n}\n\nfunction calculateProviderUsd(\n quote: AcrossSwapApprovalResponse,\n inputAmountRaw: string,\n sourceFiatRate: FiatRates,\n targetFiatRate: FiatRates,\n expectedOutputRaw?: string,\n): BigNumber {\n const totalFeeUsd = quote.fees?.total?.amountUsd;\n\n if (totalFeeUsd !== undefined) {\n return new BigNumber(totalFeeUsd).abs();\n }\n\n if (expectedOutputRaw === undefined) {\n return new BigNumber(0);\n }\n\n const expectedOutput = new BigNumber(expectedOutputRaw);\n\n if (expectedOutput.lte(0)) {\n return new BigNumber(0);\n }\n\n const inputAmountUsd = new BigNumber(inputAmountRaw)\n .shiftedBy(-quote.inputToken.decimals)\n .multipliedBy(sourceFiatRate.usdRate);\n const expectedOutputUsd = expectedOutput\n .shiftedBy(-quote.outputToken.decimals)\n .multipliedBy(targetFiatRate.usdRate);\n const providerFeeUsd = inputAmountUsd.minus(expectedOutputUsd);\n\n return providerFeeUsd.isNegative() ? new BigNumber(0) : providerFeeUsd;\n}\n\nfunction getAmountFromTokenAmount({\n amountRaw,\n decimals,\n fiatRate,\n}: {\n amountRaw: string;\n decimals: number;\n fiatRate: FiatRates;\n}): Amount {\n const rawValue = new BigNumber(amountRaw);\n const raw = rawValue.toString(10);\n\n const humanValue = rawValue.shiftedBy(-decimals);\n const human = humanValue.toString(10);\n\n const usd = humanValue.multipliedBy(fiatRate.usdRate).toString(10);\n const fiat = humanValue.multipliedBy(fiatRate.fiatRate).toString(10);\n\n return {\n fiat,\n human,\n raw,\n usd,\n };\n}\n\nasync function calculateSourceNetworkCost(\n quote: AcrossSwapApprovalResponse,\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n): Promise<{\n sourceNetwork: TransactionPayQuote<AcrossQuote>['fees']['sourceNetwork'];\n gasLimits: AcrossGasLimits;\n}> {\n const acrossFallbackGas =\n getPayStrategiesConfig(messenger).across.fallbackGas;\n const { from } = request;\n const approvalTxns = quote.approvalTxns ?? [];\n const { swapTx } = quote;\n const swapChainId = toHex(swapTx.chainId);\n\n const approvalGasResults = await Promise.all(\n approvalTxns.map(async (approval) => {\n const chainId = toHex(approval.chainId);\n const gas = await estimateGasLimit({\n chainId,\n data: approval.data,\n fallbackGas: acrossFallbackGas,\n from,\n messenger,\n to: approval.to,\n value: approval.value ?? '0x0',\n });\n\n if (gas.usedFallback) {\n log('Gas estimate failed, using fallback', {\n error: gas.error,\n transactionType: 'approval',\n });\n }\n\n return { chainId, gas };\n }),\n );\n\n const swapGasFromQuote = parseAcrossSwapGasLimit(swapTx.gas);\n const swapGas =\n swapGasFromQuote === undefined\n ? await estimateGasLimit({\n chainId: swapChainId,\n data: swapTx.data,\n fallbackGas: acrossFallbackGas,\n from,\n messenger,\n to: swapTx.to,\n value: swapTx.value ?? '0x0',\n })\n : {\n estimate: swapGasFromQuote,\n max: swapGasFromQuote,\n usedFallback: false,\n };\n\n if (swapGasFromQuote !== undefined) {\n log('Using Across-provided swap gas limit', {\n gas: swapGasFromQuote,\n transactionType: 'swap',\n });\n } else if (swapGas.usedFallback) {\n log('Gas estimate failed, using fallback', {\n error: swapGas.error,\n transactionType: 'swap',\n });\n }\n\n const estimate = sumAmounts([\n ...approvalGasResults.map(({ chainId, gas }) =>\n calculateGasCost({\n chainId,\n gas: gas.estimate,\n messenger,\n }),\n ),\n calculateGasCost({\n chainId: swapChainId,\n gas: swapGas.estimate,\n maxFeePerGas: swapTx.maxFeePerGas,\n maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,\n messenger,\n }),\n ]);\n\n const max = sumAmounts([\n ...approvalGasResults.map(({ chainId, gas }) =>\n calculateGasCost({\n chainId,\n gas: gas.max,\n isMax: true,\n messenger,\n }),\n ),\n calculateGasCost({\n chainId: swapChainId,\n gas: swapGas.max,\n isMax: true,\n maxFeePerGas: swapTx.maxFeePerGas,\n maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,\n messenger,\n }),\n ]);\n\n return {\n sourceNetwork: {\n estimate,\n max,\n },\n gasLimits: {\n approval: approvalGasResults.map(({ gas }) => ({\n estimate: gas.estimate,\n max: gas.max,\n })),\n swap: {\n estimate: swapGas.estimate,\n max: swapGas.max,\n },\n },\n };\n}\n\nfunction parseAcrossSwapGasLimit(gas?: string): number | undefined {\n if (!gas) {\n return undefined;\n }\n\n const parsedGas = gas.startsWith('0x')\n ? new BigNumber(gas.slice(2), 16)\n : new BigNumber(gas);\n\n if (\n !parsedGas.isFinite() ||\n parsedGas.isNaN() ||\n !parsedGas.isInteger() ||\n parsedGas.lte(0)\n ) {\n return undefined;\n }\n\n return parsedGas.toNumber();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"across-quotes.cjs","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { successfulFetch, toHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { getAcrossDestination } from './across-actions';\nimport { getAcrossOrderedTransactions } from './transactions';\nimport type {\n AcrossAction,\n AcrossActionRequestBody,\n AcrossGasLimits,\n AcrossQuote,\n AcrossSwapApprovalResponse,\n} from './types';\nimport { TransactionPayStrategy } from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatRates,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { getFiatValueFromUsd, sumAmounts } from '../../utils/amounts';\nimport { getPayStrategiesConfig, getSlippage } from '../../utils/feature-flags';\nimport { calculateGasCost } from '../../utils/gas';\nimport { estimateQuoteGasLimits } from '../../utils/quote-gas';\nimport { getTokenFiatRate } from '../../utils/token';\n\nconst log = createModuleLogger(projectLogger, 'across-strategy');\n\nconst UNSUPPORTED_AUTHORIZATION_LIST_ERROR =\n 'Across does not support type-4/EIP-7702 authorization lists yet';\n\ntype AcrossQuoteWithoutMetaMask = Omit<AcrossQuote, 'metamask'>;\n\n/**\n * Fetch Across quotes.\n *\n * @param request - Request object.\n * @returns Array of quotes.\n */\nexport async function getAcrossQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>[]> {\n const { requests } = request;\n\n log('Fetching quotes', requests);\n\n try {\n const normalizedRequests = requests.filter(\n (singleRequest) =>\n singleRequest.isMaxAmount === true ||\n (singleRequest.targetAmountMinimum !== undefined &&\n singleRequest.targetAmountMinimum !== '0'),\n );\n\n if (normalizedRequests.length === 0) {\n return [];\n }\n\n if (request.transaction.txParams?.authorizationList?.length) {\n throw new Error(UNSUPPORTED_AUTHORIZATION_LIST_ERROR);\n }\n\n return await Promise.all(\n normalizedRequests.map((singleRequest) =>\n getSingleQuote(singleRequest, request),\n ),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Across quotes: ${String(error)}`);\n }\n}\n\nasync function getSingleQuote(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>> {\n const { messenger, transaction } = fullRequest;\n const {\n from,\n isMaxAmount,\n sourceChainId,\n sourceTokenAddress,\n sourceTokenAmount,\n targetAmountMinimum,\n targetChainId,\n targetTokenAddress,\n } = request;\n\n const config = getPayStrategiesConfig(messenger);\n const slippageDecimal = getSlippage(\n messenger,\n sourceChainId,\n sourceTokenAddress,\n );\n\n const amount = isMaxAmount ? sourceTokenAmount : targetAmountMinimum;\n const tradeType = isMaxAmount ? 'exactInput' : 'exactOutput';\n const destination = getAcrossDestination(transaction, request);\n const quote = await requestAcrossApproval({\n actions: destination.actions,\n amount,\n apiBase: config.across.apiBase,\n depositor: from,\n destinationChainId: targetChainId,\n inputToken: sourceTokenAddress,\n originChainId: sourceChainId,\n outputToken: targetTokenAddress,\n recipient: destination.recipient,\n slippage: slippageDecimal,\n tradeType,\n });\n\n const originalQuote: AcrossQuoteWithoutMetaMask = {\n quote,\n request: {\n amount,\n tradeType,\n },\n };\n\n return await normalizeQuote(originalQuote, request, fullRequest);\n}\n\ntype AcrossApprovalRequest = {\n actions: AcrossAction[];\n amount: string;\n apiBase: string;\n depositor: Hex;\n destinationChainId: Hex;\n inputToken: Hex;\n originChainId: Hex;\n outputToken: Hex;\n recipient: Hex;\n slippage?: number;\n tradeType: 'exactInput' | 'exactOutput';\n};\n\nasync function requestAcrossApproval(\n request: AcrossApprovalRequest,\n): Promise<AcrossSwapApprovalResponse> {\n const {\n actions,\n amount,\n apiBase,\n depositor,\n destinationChainId,\n inputToken,\n originChainId,\n outputToken,\n recipient,\n slippage,\n tradeType,\n } = request;\n\n const params = new URLSearchParams();\n params.set('tradeType', tradeType);\n params.set('amount', amount);\n params.set('inputToken', inputToken);\n params.set('outputToken', outputToken);\n params.set('originChainId', String(parseInt(originChainId, 16)));\n params.set('destinationChainId', String(parseInt(destinationChainId, 16)));\n params.set('depositor', depositor);\n params.set('recipient', recipient);\n\n if (slippage !== undefined) {\n params.set('slippage', String(slippage));\n }\n\n const body: AcrossActionRequestBody = { actions };\n const url = `${apiBase}/swap/approval?${params.toString()}`;\n const options: RequestInit = {\n body: JSON.stringify(body),\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n };\n const response = await successfulFetch(url, options);\n\n return (await response.json()) as AcrossSwapApprovalResponse;\n}\n\nasync function normalizeQuote(\n original: AcrossQuoteWithoutMetaMask,\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<AcrossQuote>> {\n const { messenger } = fullRequest;\n const { quote } = original;\n\n const { usdToFiatRate, sourceFiatRate, targetFiatRate } = getFiatRates(\n messenger,\n quote,\n );\n\n const dustUsd = calculateDustUsd(quote, request, targetFiatRate);\n const dust = getFiatValueFromUsd(dustUsd, usdToFiatRate);\n\n const { gasLimits, is7702, sourceNetwork } = await calculateSourceNetworkCost(\n quote,\n messenger,\n request,\n );\n\n const targetNetwork = getFiatValueFromUsd(new BigNumber(0), usdToFiatRate);\n\n const inputAmountRaw = quote.inputAmount ?? '0';\n const outputAmountRaw = new BigNumber(\n quote.expectedOutputAmount ??\n quote.minOutputAmount ??\n request.targetAmountMinimum ??\n '0',\n ).toString(10);\n\n const sourceAmount = getAmountFromTokenAmount({\n amountRaw: inputAmountRaw,\n decimals: quote.inputToken.decimals,\n fiatRate: sourceFiatRate,\n });\n\n const providerUsd = calculateProviderUsd(\n quote,\n inputAmountRaw,\n sourceFiatRate,\n targetFiatRate,\n quote.expectedOutputAmount,\n );\n const provider = getFiatValueFromUsd(providerUsd, usdToFiatRate);\n const metaMaskFee = getFiatValueFromUsd(\n new BigNumber(quote.fees?.app?.amountUsd ?? '0').abs(),\n usdToFiatRate,\n );\n\n const targetAmount = getAmountFromTokenAmount({\n amountRaw: outputAmountRaw,\n decimals: quote.outputToken.decimals,\n fiatRate: targetFiatRate,\n });\n\n const metamask = {\n gasLimits,\n is7702,\n };\n\n return {\n dust,\n estimatedDuration: quote.expectedFillTime ?? 0,\n fees: {\n metaMask: metaMaskFee,\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: {\n ...original,\n metamask,\n },\n request,\n sourceAmount,\n targetAmount,\n strategy: TransactionPayStrategy.Across,\n } as TransactionPayQuote<AcrossQuote>;\n}\n\nfunction getFiatRates(\n messenger: TransactionPayControllerMessenger,\n quote: AcrossSwapApprovalResponse,\n): {\n sourceFiatRate: FiatRates;\n targetFiatRate: FiatRates;\n usdToFiatRate: BigNumber;\n} {\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n quote.inputToken.address,\n toHex(quote.inputToken.chainId),\n );\n\n if (!sourceFiatRate) {\n throw new Error('Source token fiat rate not found');\n }\n\n const targetFiatRate =\n getTokenFiatRate(\n messenger,\n quote.outputToken.address,\n toHex(quote.outputToken.chainId),\n ) ?? sourceFiatRate;\n\n const usdToFiatRate = new BigNumber(sourceFiatRate.fiatRate).dividedBy(\n sourceFiatRate.usdRate,\n );\n\n return { sourceFiatRate, targetFiatRate, usdToFiatRate };\n}\n\nfunction calculateDustUsd(\n quote: AcrossSwapApprovalResponse,\n request: QuoteRequest,\n targetFiatRate: FiatRates,\n): BigNumber {\n const expectedOutputRaw = quote.expectedOutputAmount;\n\n if (expectedOutputRaw === undefined) {\n return new BigNumber(0);\n }\n\n const expectedOutput = new BigNumber(expectedOutputRaw);\n const minimumOutput = new BigNumber(\n quote.minOutputAmount ?? request.targetAmountMinimum ?? '0',\n );\n\n const dustRaw = expectedOutput.minus(minimumOutput).isNegative()\n ? new BigNumber(0)\n : expectedOutput.minus(minimumOutput);\n const dustHuman = dustRaw.shiftedBy(-quote.outputToken.decimals);\n\n return dustHuman.multipliedBy(targetFiatRate.usdRate);\n}\n\nfunction calculateProviderUsd(\n quote: AcrossSwapApprovalResponse,\n inputAmountRaw: string,\n sourceFiatRate: FiatRates,\n targetFiatRate: FiatRates,\n expectedOutputRaw?: string,\n): BigNumber {\n const totalFeeUsd = quote.fees?.total?.amountUsd;\n\n if (totalFeeUsd !== undefined) {\n return new BigNumber(totalFeeUsd).abs();\n }\n\n if (expectedOutputRaw === undefined) {\n return new BigNumber(0);\n }\n\n const expectedOutput = new BigNumber(expectedOutputRaw);\n\n if (expectedOutput.lte(0)) {\n return new BigNumber(0);\n }\n\n const inputAmountUsd = new BigNumber(inputAmountRaw)\n .shiftedBy(-quote.inputToken.decimals)\n .multipliedBy(sourceFiatRate.usdRate);\n const expectedOutputUsd = expectedOutput\n .shiftedBy(-quote.outputToken.decimals)\n .multipliedBy(targetFiatRate.usdRate);\n const providerFeeUsd = inputAmountUsd.minus(expectedOutputUsd);\n\n return providerFeeUsd.isNegative() ? new BigNumber(0) : providerFeeUsd;\n}\n\nfunction getAmountFromTokenAmount({\n amountRaw,\n decimals,\n fiatRate,\n}: {\n amountRaw: string;\n decimals: number;\n fiatRate: FiatRates;\n}): Amount {\n const rawValue = new BigNumber(amountRaw);\n const raw = rawValue.toString(10);\n\n const humanValue = rawValue.shiftedBy(-decimals);\n const human = humanValue.toString(10);\n\n const usd = humanValue.multipliedBy(fiatRate.usdRate).toString(10);\n const fiat = humanValue.multipliedBy(fiatRate.fiatRate).toString(10);\n\n return {\n fiat,\n human,\n raw,\n usd,\n };\n}\n\nasync function calculateSourceNetworkCost(\n quote: AcrossSwapApprovalResponse,\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n): Promise<{\n sourceNetwork: TransactionPayQuote<AcrossQuote>['fees']['sourceNetwork'];\n gasLimits: AcrossGasLimits;\n is7702: boolean;\n}> {\n const acrossFallbackGas =\n getPayStrategiesConfig(messenger).across.fallbackGas;\n const { from } = request;\n const orderedTransactions = getAcrossOrderedTransactions({ quote });\n const { swapTx } = quote;\n const swapChainId = toHex(swapTx.chainId);\n const gasEstimates = await estimateQuoteGasLimits({\n fallbackGas: acrossFallbackGas,\n messenger,\n transactions: orderedTransactions.map((transaction) => ({\n chainId: toHex(transaction.chainId),\n data: transaction.data,\n from,\n gas: transaction.gas,\n to: transaction.to,\n value: transaction.value ?? '0x0',\n })),\n });\n const { batchGasLimit, is7702 } = gasEstimates;\n\n if (is7702) {\n if (!batchGasLimit) {\n throw new Error('Across combined batch gas estimate missing');\n }\n\n const estimate = calculateGasCost({\n chainId: swapChainId,\n gas: batchGasLimit.estimate,\n maxFeePerGas: swapTx.maxFeePerGas,\n maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,\n messenger,\n });\n const max = calculateGasCost({\n chainId: swapChainId,\n gas: batchGasLimit.max,\n isMax: true,\n maxFeePerGas: swapTx.maxFeePerGas,\n maxPriorityFeePerGas: swapTx.maxPriorityFeePerGas,\n messenger,\n });\n\n return {\n sourceNetwork: {\n estimate,\n max,\n },\n is7702: true,\n gasLimits: [\n {\n estimate: batchGasLimit.estimate,\n max: batchGasLimit.max,\n },\n ],\n };\n }\n\n const transactionGasLimits = orderedTransactions.map(\n (transaction, index) => ({\n gasEstimate: gasEstimates.gasLimits[index],\n transaction,\n }),\n );\n\n const estimate = sumAmounts(\n transactionGasLimits.map(({ gasEstimate, transaction }) =>\n calculateGasCost({\n chainId: toHex(transaction.chainId),\n gas: gasEstimate.estimate,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n messenger,\n }),\n ),\n );\n\n const max = sumAmounts(\n transactionGasLimits.map(({ gasEstimate, transaction }) =>\n calculateGasCost({\n chainId: toHex(transaction.chainId),\n gas: gasEstimate.max,\n isMax: true,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n messenger,\n }),\n ),\n );\n\n return {\n sourceNetwork: {\n estimate,\n max,\n },\n is7702: false,\n gasLimits: transactionGasLimits.map(({ gasEstimate }) => ({\n estimate: gasEstimate.estimate,\n max: gasEstimate.max,\n })),\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"across-quotes.d.cts","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"across-quotes.d.cts","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAIV,WAAW,EAEZ,oBAAgB;AAGjB,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AAcrB;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC,CA8B7C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"across-quotes.d.mts","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"across-quotes.d.mts","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAIV,WAAW,EAEZ,oBAAgB;AAGjB,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AAcrB;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC,CA8B7C"}
|