@metamask/transaction-pay-controller 18.0.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 +16 -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 +2 -72
- 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 +1 -71
- package/dist/strategy/across/across-quotes.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/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/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 +6 -5
|
@@ -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":"AAAA,OAAO,EAAE,SAAS,EAAE,2BAA2B;AAQ/C,MAAM,CAAC,MAAM,wBAAwB,GACnC,8CAA8C,CAAC;AACjD,MAAM,CAAC,MAAM,sBAAsB,GACjC,yIAAyI,CAAC;AAC5I,MAAM,CAAC,MAAM,+BAA+B,GAC1C,oMAAoM,CAAC;AAEvM,MAAM,CAAC,MAAM,6BAA6B,GACxC,8GAA8G,CAAC;AAsBjH,MAAM,wBAAwB,GAAG;IAC/B,sBAAsB;IACtB,+BAA+B;CAChC,CAAC;AAEF,MAAM,UAAU,yBAAyB,CACvC,IAA2B,EAC3B,OAAqB;IAErB,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,yBAAyB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,UAAU,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEpD,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC1D,mBAAmB,EAAE,KAAK;YAC1B,KAAK,EAAE,0BAA0B,CAAC,GAAG,CAAC;SACvC,CAAC,CAAC;QACH,iBAAiB,EAAE,UAAU,CAAC,iBAAiB;QAC/C,gBAAgB,EAAE,KAAK;QACvB,MAAM,EAAE,iBAAiB,CAAC,IAAI,CAAC;QAC/B,KAAK,EAAE,GAAG;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAS;IAC5C,MAAM,UAAU,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAE9C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAQ,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,WAA4B,EAC5B,OAAqB;IAErB,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACzB,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC1D,MAAM,8BAA8B,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CACzE,oCAAoC,CAAC,IAAI,EAAE,OAAO,CAAC,CACpD,CAAC;IACF,MAAM,eAAe,GAAG,CAAC,GAAG,gBAAgB,CAAC,CAAC;IAC9C,IAAI,SAAS,GAAG,IAAI,CAAC;IAErB,IAAI,8BAA8B,KAAK,CAAC,CAAC,EAAE,CAAC;QAC1C,MAAM,CAAC,yBAAyB,CAAC,GAAG,eAAe,CAAC,MAAM,CACxD,8BAA8B,EAC9B,CAAC,CACF,CAAC;QAEF,SAAS,GAAG,oBAAoB,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC;IAED,OAAO;QACL,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACpC,yBAAyB,CAAC,IAAI,EAAE,OAAO,CAAC,CACzC;QACD,SAAS;KACV,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oCAAoC,CAClD,IAA2B,EAC3B,OAAqB;IAErB,OAAO,CACL,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QACzB,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS;YACxB,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC7B,kBAAkB,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CACpD,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,IAA2B;IACpD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa;IACvC,kGAAkG;IAClG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAS;IACtC,MAAM,UAAU,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAElD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,0BAA0B,CAAC,KAAc;IAChD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACzB,2BAA2B,CAAC,KAAK,CAAC,CACP,CAAC;IAChC,CAAC;IAED,OAAO,2BAA2B,CAAC,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,yBAAyB,CAChC,IAA2B,EAC3B,OAAqB;IAErB,OAAO;QACL,IAAI,EAAE;YACJ;gBACE,mBAAmB,EAAE,KAAK;gBAC1B,KAAK,EAAE,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC;aACvC;YACD;gBACE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;gBAC9C,mBAAmB,EAAE,IAAI;gBACzB,KAAK,EAAE,GAAG;aACX;SACF;QACD,iBAAiB,EAAE,wBAAwB;QAC3C,gBAAgB,EAAE,KAAK;QACvB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,kBAAkB;QACjD,KAAK,EAAE,GAAG;KACX,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAC1B,WAA4B;IAE5B,MAAM,WAAW,GAAG,CAClB,WAAW,CAAC,kBAAkB,IAAI,EAAE,CACrC,CAAC,OAAO,CAAwB,CAAC,QAAkC,EAAE,EAAE,CACtE,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI;QACnD,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC;QAChD,CAAC,CAAC,EAAE,CACP,CAAC;IAEF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,EAAE,IAAuB,CAAC;IAE3D,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO;QACL;YACE,IAAI;YACJ,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAqB;SACpD;KACF,CAAC;AACJ,CAAC;AAED,SAAS,qCAAqC,CAAC,IAAU;IACvD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAE9C,OAAO,QAAQ;QACb,CAAC,CAAC,GAAG,6BAA6B,2BAA2B,QAAQ,EAAE;QACvE,CAAC,CAAC,6BAA6B,CAAC;AACpC,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAU;IACxC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,EAAS,CAAC;AAChD,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAc;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,SAAS,EAC1B,CAAC;QACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;IAED,mGAAmG;IACnG,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,cAAc,IAAI,KAAK;QACvB,KAAK,CAAC,YAAY,KAAK,IAAI;QAC3B,UAAU,IAAI,KAAK;QACnB,OAAO,KAAK,CAAC,QAAQ,KAAK,UAAU,CACrC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,IAAS;IAC/B,OAAO,oBAAoB,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC;AAClD,CAAC;AAED,SAAS,wBAAwB,CAC/B,IAAS;IAET,KAAK,MAAM,iBAAiB,IAAI,wBAAwB,EAAE,CAAC;QACzD,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,IAAI,SAAS,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAE3D,OAAO;gBACL,iBAAiB;gBACjB,WAAW,EAAE,eAAe,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,CAAC;aACxD,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,uBAAuB;QACzB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAS;IACrC,IAAI,CAAC;QACH,OAAO,IAAI,SAAS,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC","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,11 +1,10 @@
|
|
|
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");
|
|
9
8
|
const transactions_1 = require("./transactions.cjs");
|
|
10
9
|
const constants_1 = require("../../constants.cjs");
|
|
11
10
|
const logger_1 = require("../../logger.cjs");
|
|
@@ -14,13 +13,8 @@ const feature_flags_1 = require("../../utils/feature-flags.cjs");
|
|
|
14
13
|
const gas_1 = require("../../utils/gas.cjs");
|
|
15
14
|
const quote_gas_1 = require("../../utils/quote-gas.cjs");
|
|
16
15
|
const token_1 = require("../../utils/token.cjs");
|
|
17
|
-
const constants_2 = require("../relay/constants.cjs");
|
|
18
16
|
const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'across-strategy');
|
|
19
|
-
const TOKEN_TRANSFER_INTERFACE = new abi_1.Interface([
|
|
20
|
-
'function transfer(address to, uint256 value)',
|
|
21
|
-
]);
|
|
22
17
|
const UNSUPPORTED_AUTHORIZATION_LIST_ERROR = 'Across does not support type-4/EIP-7702 authorization lists yet';
|
|
23
|
-
const UNSUPPORTED_DESTINATION_ERROR = 'Across only supports transfer-style destination flows at the moment';
|
|
24
18
|
/**
|
|
25
19
|
* Fetch Across quotes.
|
|
26
20
|
*
|
|
@@ -55,7 +49,7 @@ async function getSingleQuote(request, fullRequest) {
|
|
|
55
49
|
const slippageDecimal = (0, feature_flags_1.getSlippage)(messenger, sourceChainId, sourceTokenAddress);
|
|
56
50
|
const amount = isMaxAmount ? sourceTokenAmount : targetAmountMinimum;
|
|
57
51
|
const tradeType = isMaxAmount ? 'exactInput' : 'exactOutput';
|
|
58
|
-
const destination = getAcrossDestination(transaction, request);
|
|
52
|
+
const destination = (0, across_actions_1.getAcrossDestination)(transaction, request);
|
|
59
53
|
const quote = await requestAcrossApproval({
|
|
60
54
|
actions: destination.actions,
|
|
61
55
|
amount,
|
|
@@ -105,70 +99,6 @@ async function requestAcrossApproval(request) {
|
|
|
105
99
|
const response = await (0, controller_utils_1.successfulFetch)(url, options);
|
|
106
100
|
return (await response.json());
|
|
107
101
|
}
|
|
108
|
-
function getAcrossDestination(transaction, request) {
|
|
109
|
-
const { txParams } = transaction;
|
|
110
|
-
const { from } = request;
|
|
111
|
-
const transferData = getTransferData(transaction);
|
|
112
|
-
if (transferData) {
|
|
113
|
-
const transferRecipient = getTransferRecipient(transferData);
|
|
114
|
-
if (transaction.type === transaction_controller_1.TransactionType.predictDeposit) {
|
|
115
|
-
return {
|
|
116
|
-
actions: [buildAcrossTransferAction(transferRecipient, request)],
|
|
117
|
-
recipient: from,
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
return {
|
|
121
|
-
actions: [],
|
|
122
|
-
recipient: transferRecipient,
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
const data = txParams?.data;
|
|
126
|
-
const hasNoData = data === undefined || data === '0x';
|
|
127
|
-
const nestedCalldata = getNestedCalldata(transaction);
|
|
128
|
-
if (hasNoData && nestedCalldata.length === 0) {
|
|
129
|
-
return {
|
|
130
|
-
actions: [],
|
|
131
|
-
recipient: from,
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
throw new Error(UNSUPPORTED_DESTINATION_ERROR);
|
|
135
|
-
}
|
|
136
|
-
function buildAcrossTransferAction(transferRecipient, request) {
|
|
137
|
-
return {
|
|
138
|
-
args: [
|
|
139
|
-
{
|
|
140
|
-
populateDynamically: false,
|
|
141
|
-
value: transferRecipient,
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
balanceSourceToken: request.targetTokenAddress,
|
|
145
|
-
populateDynamically: true,
|
|
146
|
-
value: '0',
|
|
147
|
-
},
|
|
148
|
-
],
|
|
149
|
-
functionSignature: 'function transfer(address to, uint256 value)',
|
|
150
|
-
isNativeTransfer: false,
|
|
151
|
-
target: request.targetTokenAddress,
|
|
152
|
-
value: '0',
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
function getTransferData(transaction) {
|
|
156
|
-
const { nestedTransactions, txParams } = transaction;
|
|
157
|
-
const nestedTransferData = nestedTransactions?.find((nestedTx) => nestedTx.data?.startsWith(constants_2.TOKEN_TRANSFER_FOUR_BYTE))?.data;
|
|
158
|
-
const data = txParams?.data;
|
|
159
|
-
const tokenTransferData = data?.startsWith(constants_2.TOKEN_TRANSFER_FOUR_BYTE)
|
|
160
|
-
? data
|
|
161
|
-
: undefined;
|
|
162
|
-
return nestedTransferData ?? tokenTransferData;
|
|
163
|
-
}
|
|
164
|
-
function getNestedCalldata(transaction) {
|
|
165
|
-
return (transaction.nestedTransactions ?? [])
|
|
166
|
-
.map((nestedTx) => nestedTx.data)
|
|
167
|
-
.filter((data) => data !== undefined && data !== '0x');
|
|
168
|
-
}
|
|
169
|
-
function getTransferRecipient(data) {
|
|
170
|
-
return TOKEN_TRANSFER_INTERFACE.decodeFunctionData('transfer', data).to.toLowerCase();
|
|
171
|
-
}
|
|
172
102
|
async function normalizeQuote(original, request, fullRequest) {
|
|
173
103
|
const { messenger } = fullRequest;
|
|
174
104
|
const { quote } = original;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"across-quotes.cjs","sourceRoot":"","sources":["../../../src/strategy/across/across-quotes.ts"],"names":[],"mappings":";;;AAAA,4CAA+C;AAC/C,iEAAoE;AACpE,6EAAmE;AAGnE,2CAAqD;AACrD,+CAAyC;AAEzC,qDAA8D;AAQ9D,mDAAyD;AACzD,6CAA6C;AAS7C,qDAAsE;AACtE,iEAAgF;AAChF,6CAAmD;AACnD,yDAA+D;AAC/D,iDAAqD;AACrD,sDAA8D;AAE9D,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAa,EAAE,iBAAiB,CAAC,CAAC;AAEjE,MAAM,wBAAwB,GAAG,IAAI,eAAS,CAAC;IAC7C,8CAA8C;CAC/C,CAAC,CAAC;AAEH,MAAM,oCAAoC,GACxC,iEAAiE,CAAC;AACpE,MAAM,6BAA6B,GACjC,qEAAqE,CAAC;AASxE;;;;;GAKG;AACI,KAAK,UAAU,eAAe,CACnC,OAAoC;IAEpC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE7B,GAAG,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;IAEjC,IAAI,CAAC;QACH,MAAM,kBAAkB,GAAG,QAAQ,CAAC,MAAM,CACxC,CAAC,aAAa,EAAE,EAAE,CAChB,aAAa,CAAC,WAAW,KAAK,IAAI;YAClC,CAAC,aAAa,CAAC,mBAAmB,KAAK,SAAS;gBAC9C,aAAa,CAAC,mBAAmB,KAAK,GAAG,CAAC,CAC/C,CAAC;QAEF,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC;YAC5D,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,MAAM,OAAO,CAAC,GAAG,CACtB,kBAAkB,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CACvC,cAAc,CAAC,aAAa,EAAE,OAAO,CAAC,CACvC,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC;AACH,CAAC;AAhCD,0CAgCC;AAED,KAAK,UAAU,cAAc,CAC3B,OAAqB,EACrB,WAAwC;IAExC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC;IAC/C,MAAM,EACJ,IAAI,EACJ,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,kBAAkB,GACnB,GAAG,OAAO,CAAC;IAEZ,MAAM,MAAM,GAAG,IAAA,sCAAsB,EAAC,SAAS,CAAC,CAAC;IACjD,MAAM,eAAe,GAAG,IAAA,2BAAW,EACjC,SAAS,EACT,aAAa,EACb,kBAAkB,CACnB,CAAC;IAEF,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,mBAAmB,CAAC;IACrE,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC;IAC7D,MAAM,WAAW,GAAG,oBAAoB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,MAAM,qBAAqB,CAAC;QACxC,OAAO,EAAE,WAAW,CAAC,OAAO;QAC5B,MAAM;QACN,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO;QAC9B,SAAS,EAAE,IAAI;QACf,kBAAkB,EAAE,aAAa;QACjC,UAAU,EAAE,kBAAkB;QAC9B,aAAa,EAAE,aAAa;QAC5B,WAAW,EAAE,kBAAkB;QAC/B,SAAS,EAAE,WAAW,CAAC,SAAS;QAChC,QAAQ,EAAE,eAAe;QACzB,SAAS;KACV,CAAC,CAAC;IAEH,MAAM,aAAa,GAA+B;QAChD,KAAK;QACL,OAAO,EAAE;YACP,MAAM;YACN,SAAS;SACV;KACF,CAAC;IAEF,OAAO,MAAM,cAAc,CAAC,aAAa,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;AACnE,CAAC;AAgBD,KAAK,UAAU,qBAAqB,CAClC,OAA8B;IAE9B,MAAM,EACJ,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,GACV,GAAG,OAAO,CAAC;IAEZ,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;IACrC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7B,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IACrC,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACjE,MAAM,CAAC,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,QAAQ,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3E,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAEnC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,IAAI,GAA4B,EAAE,OAAO,EAAE,CAAC;IAClD,MAAM,GAAG,GAAG,GAAG,OAAO,kBAAkB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC5D,MAAM,OAAO,GAAgB;QAC3B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAC1B,OAAO,EAAE;YACP,MAAM,EAAE,kBAAkB;YAC1B,cAAc,EAAE,kBAAkB;SACnC;QACD,MAAM,EAAE,MAAM;KACf,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,IAAA,kCAAe,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAErD,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA+B,CAAC;AAC/D,CAAC;AAED,SAAS,oBAAoB,CAC3B,WAA4B,EAC5B,OAAqB;IAErB,MAAM,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC;IACjC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACzB,MAAM,YAAY,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAElD,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;QAE7D,IAAI,WAAW,CAAC,IAAI,KAAK,wCAAe,CAAC,cAAc,EAAE,CAAC;YACxD,OAAO;gBACL,OAAO,EAAE,CAAC,yBAAyB,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;gBAChE,SAAS,EAAE,IAAI;aAChB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,iBAAiB;SAC7B,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,EAAE,IAAuB,CAAC;IAC/C,MAAM,SAAS,GAAG,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC;IACtD,MAAM,cAAc,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAEtD,IAAI,SAAS,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7C,OAAO;YACL,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,IAAI;SAChB,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,yBAAyB,CAChC,iBAAsB,EACtB,OAAqB;IAErB,OAAO;QACL,IAAI,EAAE;YACJ;gBACE,mBAAmB,EAAE,KAAK;gBAC1B,KAAK,EAAE,iBAAiB;aACzB;YACD;gBACE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;gBAC9C,mBAAmB,EAAE,IAAI;gBACzB,KAAK,EAAE,GAAG;aACX;SACF;QACD,iBAAiB,EAAE,8CAA8C;QACjE,gBAAgB,EAAE,KAAK;QACvB,MAAM,EAAE,OAAO,CAAC,kBAAkB;QAClC,KAAK,EAAE,GAAG;KACX,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,WAA4B;IACnD,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC;IAErD,MAAM,kBAAkB,GAAG,kBAAkB,EAAE,IAAI,CACjD,CAAC,QAAwB,EAAE,EAAE,CAC3B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,oCAAwB,CAAC,CACtD,EAAE,IAAI,CAAC;IAER,MAAM,IAAI,GAAG,QAAQ,EAAE,IAAuB,CAAC;IAC/C,MAAM,iBAAiB,GAAG,IAAI,EAAE,UAAU,CAAC,oCAAwB,CAAC;QAClE,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO,kBAAkB,IAAI,iBAAiB,CAAC;AACjD,CAAC;AAED,SAAS,iBAAiB,CAAC,WAA4B;IACrD,OAAO,CAAC,WAAW,CAAC,kBAAkB,IAAI,EAAE,CAAC;SAC1C,GAAG,CAAC,CAAC,QAAwB,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;SAChD,MAAM,CACL,CAAC,IAAqB,EAAe,EAAE,CACrC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CACtC,CAAC;AACN,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAS;IACrC,OAAO,wBAAwB,CAAC,kBAAkB,CAChD,UAAU,EACV,IAAI,CACL,CAAC,EAAE,CAAC,WAAW,EAAS,CAAC;AAC5B,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,QAAoC,EACpC,OAAqB,EACrB,WAAwC;IAExC,MAAM,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC;IAClC,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC;IAE3B,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,GAAG,YAAY,CACpE,SAAS,EACT,KAAK,CACN,CAAC;IAEF,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,IAAA,6BAAmB,EAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAEzD,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,0BAA0B,CAC3E,KAAK,EACL,SAAS,EACT,OAAO,CACR,CAAC;IAEF,MAAM,aAAa,GAAG,IAAA,6BAAmB,EAAC,IAAI,wBAAS,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IAE3E,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,IAAI,GAAG,CAAC;IAChD,MAAM,eAAe,GAAG,IAAI,wBAAS,CACnC,KAAK,CAAC,oBAAoB;QACxB,KAAK,CAAC,eAAe;QACrB,OAAO,CAAC,mBAAmB;QAC3B,GAAG,CACN,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEf,MAAM,YAAY,GAAG,wBAAwB,CAAC;QAC5C,SAAS,EAAE,cAAc;QACzB,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,QAAQ;QACnC,QAAQ,EAAE,cAAc;KACzB,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,oBAAoB,CACtC,KAAK,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,KAAK,CAAC,oBAAoB,CAC3B,CAAC;IACF,MAAM,QAAQ,GAAG,IAAA,6BAAmB,EAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IACjE,MAAM,WAAW,GAAG,IAAA,6BAAmB,EACrC,IAAI,wBAAS,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,EACtD,aAAa,CACd,CAAC;IAEF,MAAM,YAAY,GAAG,wBAAwB,CAAC;QAC5C,SAAS,EAAE,eAAe;QAC1B,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,QAAQ;QACpC,QAAQ,EAAE,cAAc;KACzB,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG;QACf,SAAS;QACT,MAAM;KACP,CAAC;IAEF,OAAO;QACL,IAAI;QACJ,iBAAiB,EAAE,KAAK,CAAC,gBAAgB,IAAI,CAAC;QAC9C,IAAI,EAAE;YACJ,QAAQ,EAAE,WAAW;YACrB,QAAQ;YACR,aAAa;YACb,aAAa;SACd;QACD,QAAQ,EAAE;YACR,GAAG,QAAQ;YACX,QAAQ;SACT;QACD,OAAO;QACP,YAAY;QACZ,YAAY;QACZ,QAAQ,EAAE,kCAAsB,CAAC,MAAM;KACJ,CAAC;AACxC,CAAC;AAED,SAAS,YAAY,CACnB,SAA4C,EAC5C,KAAiC;IAMjC,MAAM,cAAc,GAAG,IAAA,wBAAgB,EACrC,SAAS,EACT,KAAK,CAAC,UAAU,CAAC,OAAO,EACxB,IAAA,wBAAK,EAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAChC,CAAC;IAEF,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,cAAc,GAClB,IAAA,wBAAgB,EACd,SAAS,EACT,KAAK,CAAC,WAAW,CAAC,OAAO,EACzB,IAAA,wBAAK,EAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CACjC,IAAI,cAAc,CAAC;IAEtB,MAAM,aAAa,GAAG,IAAI,wBAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,SAAS,CACpE,cAAc,CAAC,OAAO,CACvB,CAAC;IAEF,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC;AAC3D,CAAC;AAED,SAAS,gBAAgB,CACvB,KAAiC,EACjC,OAAqB,EACrB,cAAyB;IAEzB,MAAM,iBAAiB,GAAG,KAAK,CAAC,oBAAoB,CAAC;IAErD,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,IAAI,wBAAS,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,wBAAS,CAAC,iBAAiB,CAAC,CAAC;IACxD,MAAM,aAAa,GAAG,IAAI,wBAAS,CACjC,KAAK,CAAC,eAAe,IAAI,OAAO,CAAC,mBAAmB,IAAI,GAAG,CAC5D,CAAC;IAEF,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,UAAU,EAAE;QAC9D,CAAC,CAAC,IAAI,wBAAS,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAEjE,OAAO,SAAS,CAAC,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,oBAAoB,CAC3B,KAAiC,EACjC,cAAsB,EACtB,cAAyB,EACzB,cAAyB,EACzB,iBAA0B;IAE1B,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC;IAEjD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,IAAI,wBAAS,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,CAAC;IAC1C,CAAC;IAED,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,IAAI,wBAAS,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,wBAAS,CAAC,iBAAiB,CAAC,CAAC;IAExD,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,wBAAS,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,wBAAS,CAAC,cAAc,CAAC;SACjD,SAAS,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC;SACrC,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,iBAAiB,GAAG,cAAc;SACrC,SAAS,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC;SACtC,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAE/D,OAAO,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,wBAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;AACzE,CAAC;AAED,SAAS,wBAAwB,CAAC,EAChC,SAAS,EACT,QAAQ,EACR,QAAQ,GAKT;IACC,MAAM,QAAQ,GAAG,IAAI,wBAAS,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAElC,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEtC,MAAM,GAAG,GAAG,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAErE,OAAO;QACL,IAAI;QACJ,KAAK;QACL,GAAG;QACH,GAAG;KACJ,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,0BAA0B,CACvC,KAAiC,EACjC,SAA4C,EAC5C,OAAqB;IAMrB,MAAM,iBAAiB,GACrB,IAAA,sCAAsB,EAAC,SAAS,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;IACvD,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACzB,MAAM,mBAAmB,GAAG,IAAA,2CAA4B,EAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACpE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,MAAM,WAAW,GAAG,IAAA,wBAAK,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,YAAY,GAAG,MAAM,IAAA,kCAAsB,EAAC;QAChD,WAAW,EAAE,iBAAiB;QAC9B,SAAS;QACT,YAAY,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YACtD,OAAO,EAAE,IAAA,wBAAK,EAAC,WAAW,CAAC,OAAO,CAAC;YACnC,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,IAAI;YACJ,GAAG,EAAE,WAAW,CAAC,GAAG;YACpB,EAAE,EAAE,WAAW,CAAC,EAAE;YAClB,KAAK,EAAE,WAAW,CAAC,KAAK,IAAI,KAAK;SAClC,CAAC,CAAC;KACJ,CAAC,CAAC;IACH,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC;IAE/C,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,QAAQ,GAAG,IAAA,sBAAgB,EAAC;YAChC,OAAO,EAAE,WAAW;YACpB,GAAG,EAAE,aAAa,CAAC,QAAQ;YAC3B,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;YACjD,SAAS;SACV,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,IAAA,sBAAgB,EAAC;YAC3B,OAAO,EAAE,WAAW;YACpB,GAAG,EAAE,aAAa,CAAC,GAAG;YACtB,KAAK,EAAE,IAAI;YACX,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;YACjD,SAAS;SACV,CAAC,CAAC;QAEH,OAAO;YACL,aAAa,EAAE;gBACb,QAAQ;gBACR,GAAG;aACJ;YACD,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE;gBACT;oBACE,QAAQ,EAAE,aAAa,CAAC,QAAQ;oBAChC,GAAG,EAAE,aAAa,CAAC,GAAG;iBACvB;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,GAAG,CAClD,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACvB,WAAW,EAAE,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC;QAC1C,WAAW;KACZ,CAAC,CACH,CAAC;IAEF,MAAM,QAAQ,GAAG,IAAA,oBAAU,EACzB,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE,CACxD,IAAA,sBAAgB,EAAC;QACf,OAAO,EAAE,IAAA,wBAAK,EAAC,WAAW,CAAC,OAAO,CAAC;QACnC,GAAG,EAAE,WAAW,CAAC,QAAQ;QACzB,YAAY,EAAE,WAAW,CAAC,YAAY;QACtC,oBAAoB,EAAE,WAAW,CAAC,oBAAoB;QACtD,SAAS;KACV,CAAC,CACH,CACF,CAAC;IAEF,MAAM,GAAG,GAAG,IAAA,oBAAU,EACpB,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE,CACxD,IAAA,sBAAgB,EAAC;QACf,OAAO,EAAE,IAAA,wBAAK,EAAC,WAAW,CAAC,OAAO,CAAC;QACnC,GAAG,EAAE,WAAW,CAAC,GAAG;QACpB,KAAK,EAAE,IAAI;QACX,YAAY,EAAE,WAAW,CAAC,YAAY;QACtC,oBAAoB,EAAE,WAAW,CAAC,oBAAoB;QACtD,SAAS;KACV,CAAC,CACH,CACF,CAAC;IAEF,OAAO;QACL,aAAa,EAAE;YACb,QAAQ;YACR,GAAG;SACJ;QACD,MAAM,EAAE,KAAK;QACb,SAAS,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;YACxD,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,GAAG,EAAE,WAAW,CAAC,GAAG;SACrB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC","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 { 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';\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 { 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
|
+
{"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"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { Interface } from "@ethersproject/abi";
|
|
2
1
|
import { successfulFetch, toHex } from "@metamask/controller-utils";
|
|
3
|
-
import { TransactionType } from "@metamask/transaction-controller";
|
|
4
2
|
import { createModuleLogger } from "@metamask/utils";
|
|
5
3
|
import { BigNumber } from "bignumber.js";
|
|
4
|
+
import { getAcrossDestination } from "./across-actions.mjs";
|
|
6
5
|
import { getAcrossOrderedTransactions } from "./transactions.mjs";
|
|
7
6
|
import { TransactionPayStrategy } from "../../constants.mjs";
|
|
8
7
|
import { projectLogger } from "../../logger.mjs";
|
|
@@ -11,13 +10,8 @@ import { getPayStrategiesConfig, getSlippage } from "../../utils/feature-flags.m
|
|
|
11
10
|
import { calculateGasCost } from "../../utils/gas.mjs";
|
|
12
11
|
import { estimateQuoteGasLimits } from "../../utils/quote-gas.mjs";
|
|
13
12
|
import { getTokenFiatRate } from "../../utils/token.mjs";
|
|
14
|
-
import { TOKEN_TRANSFER_FOUR_BYTE } from "../relay/constants.mjs";
|
|
15
13
|
const log = createModuleLogger(projectLogger, 'across-strategy');
|
|
16
|
-
const TOKEN_TRANSFER_INTERFACE = new Interface([
|
|
17
|
-
'function transfer(address to, uint256 value)',
|
|
18
|
-
]);
|
|
19
14
|
const UNSUPPORTED_AUTHORIZATION_LIST_ERROR = 'Across does not support type-4/EIP-7702 authorization lists yet';
|
|
20
|
-
const UNSUPPORTED_DESTINATION_ERROR = 'Across only supports transfer-style destination flows at the moment';
|
|
21
15
|
/**
|
|
22
16
|
* Fetch Across quotes.
|
|
23
17
|
*
|
|
@@ -101,70 +95,6 @@ async function requestAcrossApproval(request) {
|
|
|
101
95
|
const response = await successfulFetch(url, options);
|
|
102
96
|
return (await response.json());
|
|
103
97
|
}
|
|
104
|
-
function getAcrossDestination(transaction, request) {
|
|
105
|
-
const { txParams } = transaction;
|
|
106
|
-
const { from } = request;
|
|
107
|
-
const transferData = getTransferData(transaction);
|
|
108
|
-
if (transferData) {
|
|
109
|
-
const transferRecipient = getTransferRecipient(transferData);
|
|
110
|
-
if (transaction.type === TransactionType.predictDeposit) {
|
|
111
|
-
return {
|
|
112
|
-
actions: [buildAcrossTransferAction(transferRecipient, request)],
|
|
113
|
-
recipient: from,
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
actions: [],
|
|
118
|
-
recipient: transferRecipient,
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
const data = txParams?.data;
|
|
122
|
-
const hasNoData = data === undefined || data === '0x';
|
|
123
|
-
const nestedCalldata = getNestedCalldata(transaction);
|
|
124
|
-
if (hasNoData && nestedCalldata.length === 0) {
|
|
125
|
-
return {
|
|
126
|
-
actions: [],
|
|
127
|
-
recipient: from,
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
throw new Error(UNSUPPORTED_DESTINATION_ERROR);
|
|
131
|
-
}
|
|
132
|
-
function buildAcrossTransferAction(transferRecipient, request) {
|
|
133
|
-
return {
|
|
134
|
-
args: [
|
|
135
|
-
{
|
|
136
|
-
populateDynamically: false,
|
|
137
|
-
value: transferRecipient,
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
balanceSourceToken: request.targetTokenAddress,
|
|
141
|
-
populateDynamically: true,
|
|
142
|
-
value: '0',
|
|
143
|
-
},
|
|
144
|
-
],
|
|
145
|
-
functionSignature: 'function transfer(address to, uint256 value)',
|
|
146
|
-
isNativeTransfer: false,
|
|
147
|
-
target: request.targetTokenAddress,
|
|
148
|
-
value: '0',
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
function getTransferData(transaction) {
|
|
152
|
-
const { nestedTransactions, txParams } = transaction;
|
|
153
|
-
const nestedTransferData = nestedTransactions?.find((nestedTx) => nestedTx.data?.startsWith(TOKEN_TRANSFER_FOUR_BYTE))?.data;
|
|
154
|
-
const data = txParams?.data;
|
|
155
|
-
const tokenTransferData = data?.startsWith(TOKEN_TRANSFER_FOUR_BYTE)
|
|
156
|
-
? data
|
|
157
|
-
: undefined;
|
|
158
|
-
return nestedTransferData ?? tokenTransferData;
|
|
159
|
-
}
|
|
160
|
-
function getNestedCalldata(transaction) {
|
|
161
|
-
return (transaction.nestedTransactions ?? [])
|
|
162
|
-
.map((nestedTx) => nestedTx.data)
|
|
163
|
-
.filter((data) => data !== undefined && data !== '0x');
|
|
164
|
-
}
|
|
165
|
-
function getTransferRecipient(data) {
|
|
166
|
-
return TOKEN_TRANSFER_INTERFACE.decodeFunctionData('transfer', data).to.toLowerCase();
|
|
167
|
-
}
|
|
168
98
|
async function normalizeQuote(original, request, fullRequest) {
|
|
169
99
|
const { messenger } = fullRequest;
|
|
170
100
|
const { quote } = original;
|