@shapeshiftoss/swapper 17.6.5 → 17.6.6-alpha.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/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/constants.js +17 -8
- package/dist/cjs/swappers/NearIntentsSwapper/NearIntentsSwapper.d.ts +2 -0
- package/dist/cjs/swappers/NearIntentsSwapper/NearIntentsSwapper.js +11 -0
- package/dist/cjs/swappers/NearIntentsSwapper/constants.d.ts +3 -0
- package/dist/cjs/swappers/NearIntentsSwapper/constants.js +6 -0
- package/dist/cjs/swappers/NearIntentsSwapper/endpoints.d.ts +2 -0
- package/dist/cjs/swappers/NearIntentsSwapper/endpoints.js +165 -0
- package/dist/cjs/swappers/NearIntentsSwapper/index.d.ts +4 -0
- package/dist/cjs/swappers/NearIntentsSwapper/index.js +20 -0
- package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.d.ts +3 -0
- package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.js +209 -0
- package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeRate.d.ts +3 -0
- package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeRate.js +208 -0
- package/dist/cjs/swappers/NearIntentsSwapper/types.d.ts +6 -0
- package/dist/cjs/swappers/NearIntentsSwapper/types.js +32 -0
- package/dist/cjs/swappers/NearIntentsSwapper/utils/helpers/helpers.d.ts +12 -0
- package/dist/cjs/swappers/NearIntentsSwapper/utils/helpers/helpers.js +99 -0
- package/dist/cjs/swappers/NearIntentsSwapper/utils/oneClickService.d.ts +3 -0
- package/dist/cjs/swappers/NearIntentsSwapper/utils/oneClickService.js +16 -0
- package/dist/cjs/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.js +55 -12
- package/dist/cjs/swappers/RelaySwapper/constant.js +1 -0
- package/dist/cjs/swappers/RelaySwapper/utils/fetchRelayTrade.d.ts +1 -1
- package/dist/cjs/swappers/RelaySwapper/utils/getRelayPsbtRelayer.js +2 -2
- package/dist/cjs/swappers/RelaySwapper/utils/getTrade.js +45 -0
- package/dist/cjs/swappers/RelaySwapper/utils/notifyTransactionIndexing.d.ts +1 -1
- package/dist/cjs/swappers/RelaySwapper/utils/relayTokenToAssetId.js +0 -2
- package/dist/cjs/swappers/RelaySwapper/utils/types.d.ts +1 -0
- package/dist/cjs/swappers/RelaySwapper/utils/types.js +1 -0
- package/dist/cjs/swappers/ThorchainSwapper/generated/generatedThorLongtailTokens.json +3153 -3153
- package/dist/cjs/swappers/ThorchainSwapper/generated/generatedTradableAssetMap.json +6 -6
- package/dist/cjs/swappers/ZrxSwapper/utils/helpers/helpers.js +1 -3
- package/dist/cjs/thorchain-utils/getL1RateOrQuote.js +20 -17
- package/dist/cjs/types.d.ts +18 -1
- package/dist/cjs/types.js +1 -0
- package/dist/cjs/utils/tenderly/index.d.ts +3 -0
- package/dist/cjs/utils/tenderly/index.js +19 -0
- package/dist/cjs/utils/tenderly/simulate.d.ts +20 -0
- package/dist/cjs/utils/tenderly/simulate.js +109 -0
- package/dist/cjs/utils/tenderly/storageSlots.d.ts +8 -0
- package/dist/cjs/utils/tenderly/storageSlots.js +94 -0
- package/dist/cjs/utils/tenderly/types.d.ts +56 -0
- package/dist/cjs/utils/tenderly/types.js +2 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/constants.js +9 -0
- package/dist/esm/swappers/NearIntentsSwapper/NearIntentsSwapper.d.ts +2 -0
- package/dist/esm/swappers/NearIntentsSwapper/NearIntentsSwapper.js +8 -0
- package/dist/esm/swappers/NearIntentsSwapper/constants.d.ts +3 -0
- package/dist/esm/swappers/NearIntentsSwapper/constants.js +3 -0
- package/dist/esm/swappers/NearIntentsSwapper/endpoints.d.ts +2 -0
- package/dist/esm/swappers/NearIntentsSwapper/endpoints.js +162 -0
- package/dist/esm/swappers/NearIntentsSwapper/index.d.ts +4 -0
- package/dist/esm/swappers/NearIntentsSwapper/index.js +4 -0
- package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.d.ts +3 -0
- package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.js +205 -0
- package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeRate.d.ts +3 -0
- package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeRate.js +204 -0
- package/dist/esm/swappers/NearIntentsSwapper/types.d.ts +6 -0
- package/dist/esm/swappers/NearIntentsSwapper/types.js +28 -0
- package/dist/esm/swappers/NearIntentsSwapper/utils/helpers/helpers.d.ts +12 -0
- package/dist/esm/swappers/NearIntentsSwapper/utils/helpers/helpers.js +91 -0
- package/dist/esm/swappers/NearIntentsSwapper/utils/oneClickService.d.ts +3 -0
- package/dist/esm/swappers/NearIntentsSwapper/utils/oneClickService.js +12 -0
- package/dist/esm/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.js +59 -16
- package/dist/esm/swappers/RelaySwapper/constant.js +1 -0
- package/dist/esm/swappers/RelaySwapper/utils/fetchRelayTrade.d.ts +1 -1
- package/dist/esm/swappers/RelaySwapper/utils/getRelayPsbtRelayer.js +2 -2
- package/dist/esm/swappers/RelaySwapper/utils/getTrade.js +47 -2
- package/dist/esm/swappers/RelaySwapper/utils/notifyTransactionIndexing.d.ts +1 -1
- package/dist/esm/swappers/RelaySwapper/utils/relayTokenToAssetId.js +0 -2
- package/dist/esm/swappers/RelaySwapper/utils/types.d.ts +1 -0
- package/dist/esm/swappers/RelaySwapper/utils/types.js +1 -0
- package/dist/esm/swappers/ThorchainSwapper/generated/generatedThorLongtailTokens.json +3153 -3153
- package/dist/esm/swappers/ThorchainSwapper/generated/generatedTradableAssetMap.json +6 -6
- package/dist/esm/swappers/ZrxSwapper/utils/helpers/helpers.js +1 -3
- package/dist/esm/thorchain-utils/getL1RateOrQuote.js +20 -17
- package/dist/esm/types.d.ts +18 -1
- package/dist/esm/types.js +1 -0
- package/dist/esm/utils/tenderly/index.d.ts +3 -0
- package/dist/esm/utils/tenderly/index.js +3 -0
- package/dist/esm/utils/tenderly/simulate.d.ts +20 -0
- package/dist/esm/utils/tenderly/simulate.js +102 -0
- package/dist/esm/utils/tenderly/storageSlots.d.ts +8 -0
- package/dist/esm/utils/tenderly/storageSlots.js +86 -0
- package/dist/esm/utils/tenderly/types.d.ts +56 -0
- package/dist/esm/utils/tenderly/types.js +1 -0
- package/package.json +32 -6
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
"BASE.VVV-0XACFE6019ED1A7DC6F7B508C02D1B04EC88CC21BF": "eip155:8453/erc20:0xacfe6019ed1a7dc6f7b508c02d1b04ec88cc21bf",
|
|
10
10
|
"BCH.BCH": "bip122:000000000000000000651ef99cb9fcbe/slip44:145",
|
|
11
11
|
"BSC.BNB": "eip155:56/slip44:60",
|
|
12
|
-
"BSC.BTCB-0X7130D2A12B9BCBFAE4F2634D864A1EE1CE3EAD9C": "eip155:56/
|
|
13
|
-
"BSC.BUSD-0XE9E7CEA3DEDCA5984780BAFC599BD69ADD087D56": "eip155:56/
|
|
14
|
-
"BSC.ETH-0X2170ED0880AC9A755FD29B2688956BD959F933F8": "eip155:56/
|
|
15
|
-
"BSC.TWT-0X4B0F1812E5DF2A09796481FF14017E6005508003": "eip155:56/
|
|
16
|
-
"BSC.USDC-0X8AC76A51CC950D9822D68B83FE1AD97B32CD580D": "eip155:56/
|
|
17
|
-
"BSC.USDT-0X55D398326F99059FF775485246999027B3197955": "eip155:56/
|
|
12
|
+
"BSC.BTCB-0X7130D2A12B9BCBFAE4F2634D864A1EE1CE3EAD9C": "eip155:56/erc20:0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c",
|
|
13
|
+
"BSC.BUSD-0XE9E7CEA3DEDCA5984780BAFC599BD69ADD087D56": "eip155:56/erc20:0xe9e7cea3dedca5984780bafc599bd69add087d56",
|
|
14
|
+
"BSC.ETH-0X2170ED0880AC9A755FD29B2688956BD959F933F8": "eip155:56/erc20:0x2170ed0880ac9a755fd29b2688956bd959f933f8",
|
|
15
|
+
"BSC.TWT-0X4B0F1812E5DF2A09796481FF14017E6005508003": "eip155:56/erc20:0x4b0f1812e5df2a09796481ff14017e6005508003",
|
|
16
|
+
"BSC.USDC-0X8AC76A51CC950D9822D68B83FE1AD97B32CD580D": "eip155:56/erc20:0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
|
|
17
|
+
"BSC.USDT-0X55D398326F99059FF775485246999027B3197955": "eip155:56/erc20:0x55d398326f99059ff775485246999027b3197955",
|
|
18
18
|
"BTC.BTC": "bip122:000000000019d6689c085ae165831e93/slip44:0",
|
|
19
19
|
"DOGE.DOGE": "bip122:00000000001a91e3dace36e2be3bf030/slip44:3",
|
|
20
20
|
"ETH.AAVE-0X7FC66500C84A76AD7E9C93437BFC5AC33E2DDAE9": "eip155:1/erc20:0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9",
|
|
@@ -18,9 +18,7 @@ export const zrxTokenToAssetId = (token, chainId) => {
|
|
|
18
18
|
if (!isDefaultAddress)
|
|
19
19
|
return {
|
|
20
20
|
assetReference: token,
|
|
21
|
-
assetNamespace:
|
|
22
|
-
? ASSET_NAMESPACE.bep20
|
|
23
|
-
: ASSET_NAMESPACE.erc20,
|
|
21
|
+
assetNamespace: ASSET_NAMESPACE.erc20,
|
|
24
22
|
};
|
|
25
23
|
switch (chainId) {
|
|
26
24
|
case KnownChainIds.EthereumMainnet:
|
|
@@ -33,21 +33,14 @@ export const getL1RateOrQuote = async (input, deps, streamingInterval, tradeType
|
|
|
33
33
|
swapperName,
|
|
34
34
|
};
|
|
35
35
|
const maybeSwapQuote = await getQuote({ ...baseQuoteArgs, streaming: false }, deps);
|
|
36
|
-
if (maybeSwapQuote.isErr())
|
|
37
|
-
return Err(maybeSwapQuote.unwrapErr());
|
|
38
|
-
const swapQuote = maybeSwapQuote.unwrap();
|
|
39
36
|
const maybeStreamingSwapQuote = await getQuote({ ...baseQuoteArgs, streaming: true, streamingInterval }, deps);
|
|
40
|
-
if (maybeStreamingSwapQuote
|
|
41
|
-
return Err(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
?
|
|
46
|
-
|
|
47
|
-
inputExponent: sellAssetNativePrecision,
|
|
48
|
-
outputExponent: sellAsset.precision,
|
|
49
|
-
}).toFixed()
|
|
50
|
-
: '0';
|
|
37
|
+
if (maybeSwapQuote.isErr() && maybeStreamingSwapQuote.isErr()) {
|
|
38
|
+
return Err(maybeSwapQuote.unwrapErr());
|
|
39
|
+
}
|
|
40
|
+
const swapQuote = maybeSwapQuote.isOk() ? maybeSwapQuote.unwrap() : undefined;
|
|
41
|
+
const streamingSwapQuote = maybeStreamingSwapQuote.isOk()
|
|
42
|
+
? maybeStreamingSwapQuote.unwrap()
|
|
43
|
+
: undefined;
|
|
51
44
|
const getRouteValues = (quote, isStreaming) => {
|
|
52
45
|
const source = getSwapSource(tradeType, isStreaming, swapperName);
|
|
53
46
|
return {
|
|
@@ -64,10 +57,20 @@ export const getL1RateOrQuote = async (input, deps, streamingInterval, tradeType
|
|
|
64
57
|
: undefined,
|
|
65
58
|
};
|
|
66
59
|
};
|
|
67
|
-
const perRouteValues = [
|
|
68
|
-
if (
|
|
60
|
+
const perRouteValues = [];
|
|
61
|
+
if (swapQuote)
|
|
62
|
+
perRouteValues.push(getRouteValues(swapQuote, false));
|
|
63
|
+
if (streamingSwapQuote)
|
|
69
64
|
perRouteValues.push(getRouteValues(streamingSwapQuote, true));
|
|
70
|
-
|
|
65
|
+
const recommendedMinAmountIn = swapQuote?.recommended_min_amount_in ?? streamingSwapQuote?.recommended_min_amount_in;
|
|
66
|
+
// recommended_min_amount_in should be the same value for both types of swaps
|
|
67
|
+
const recommendedMinimumCryptoBaseUnit = recommendedMinAmountIn
|
|
68
|
+
? convertPrecision({
|
|
69
|
+
value: recommendedMinAmountIn,
|
|
70
|
+
inputExponent: sellAssetNativePrecision,
|
|
71
|
+
outputExponent: sellAsset.precision,
|
|
72
|
+
}).toFixed()
|
|
73
|
+
: '0';
|
|
71
74
|
const getRouteBuyAmountBeforeFeesCryptoBaseUnit = (quote) => {
|
|
72
75
|
const buyAmountBeforeFeesCryptoThorPrecision = bn(quote.expected_amount_out).plus(quote.fees.total);
|
|
73
76
|
return toBaseUnit(fromBaseUnit(buyAmountBeforeFeesCryptoThorPrecision, buyAssetNativePrecision), buyAsset.precision);
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -41,6 +41,10 @@ export type SwapperConfig = {
|
|
|
41
41
|
VITE_JUPITER_API_URL: string;
|
|
42
42
|
VITE_RELAY_API_URL: string;
|
|
43
43
|
VITE_BEBOP_API_KEY: string;
|
|
44
|
+
VITE_NEAR_INTENTS_API_KEY: string;
|
|
45
|
+
VITE_TENDERLY_API_KEY: string;
|
|
46
|
+
VITE_TENDERLY_ACCOUNT_SLUG: string;
|
|
47
|
+
VITE_TENDERLY_PROJECT_SLUG: string;
|
|
44
48
|
};
|
|
45
49
|
export declare enum SwapperName {
|
|
46
50
|
Thorchain = "THORChain",
|
|
@@ -54,7 +58,8 @@ export declare enum SwapperName {
|
|
|
54
58
|
Jupiter = "Jupiter",
|
|
55
59
|
Relay = "Relay",
|
|
56
60
|
ButterSwap = "ButterSwap",
|
|
57
|
-
Bebop = "Bebop"
|
|
61
|
+
Bebop = "Bebop",
|
|
62
|
+
NearIntents = "NEAR Intents"
|
|
58
63
|
}
|
|
59
64
|
export type SwapSource = SwapperName | `${SwapperName} • ${string}`;
|
|
60
65
|
export type SwapErrorRight = {
|
|
@@ -233,6 +238,12 @@ export type TradeQuoteStep = {
|
|
|
233
238
|
chainflipChunkIntervalBlocks?: number;
|
|
234
239
|
chainflipMaxBoostFee?: number;
|
|
235
240
|
};
|
|
241
|
+
nearIntentsSpecific?: {
|
|
242
|
+
depositAddress: string;
|
|
243
|
+
depositMemo?: string;
|
|
244
|
+
timeEstimate: number;
|
|
245
|
+
deadline: string;
|
|
246
|
+
};
|
|
236
247
|
thorchainSpecific?: {
|
|
237
248
|
maxStreamingQuantity?: number;
|
|
238
249
|
};
|
|
@@ -288,6 +299,12 @@ export type SwapExecutionMetadata = {
|
|
|
288
299
|
};
|
|
289
300
|
export type SwapperSpecificMetadata = {
|
|
290
301
|
chainflipSwapId: number | undefined;
|
|
302
|
+
nearIntentsSpecific?: {
|
|
303
|
+
depositAddress: string;
|
|
304
|
+
depositMemo?: string;
|
|
305
|
+
timeEstimate: number;
|
|
306
|
+
deadline: string;
|
|
307
|
+
};
|
|
291
308
|
relayTransactionMetadata: RelayTransactionMetadata | undefined;
|
|
292
309
|
relayerExplorerTxLink: string | undefined;
|
|
293
310
|
relayerTxHash: string | undefined;
|
package/dist/esm/types.js
CHANGED
|
@@ -12,6 +12,7 @@ export var SwapperName;
|
|
|
12
12
|
SwapperName["Relay"] = "Relay";
|
|
13
13
|
SwapperName["ButterSwap"] = "ButterSwap";
|
|
14
14
|
SwapperName["Bebop"] = "Bebop";
|
|
15
|
+
SwapperName["NearIntents"] = "NEAR Intents";
|
|
15
16
|
})(SwapperName || (SwapperName = {}));
|
|
16
17
|
export var TradeQuoteError;
|
|
17
18
|
(function (TradeQuoteError) {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ChainId } from '@shapeshiftoss/caip';
|
|
2
|
+
import type { Asset } from '@shapeshiftoss/types';
|
|
3
|
+
import type { Address, Hex } from 'viem';
|
|
4
|
+
import type { TenderlyConfig } from './types.js';
|
|
5
|
+
export type SimulationResult = {
|
|
6
|
+
success: boolean;
|
|
7
|
+
gasUsed: bigint;
|
|
8
|
+
gasLimit: bigint;
|
|
9
|
+
errorMessage?: string;
|
|
10
|
+
};
|
|
11
|
+
export type SimulateTransactionParams = {
|
|
12
|
+
chainId: ChainId;
|
|
13
|
+
from: Address;
|
|
14
|
+
to: Address;
|
|
15
|
+
data: Hex;
|
|
16
|
+
value?: string | bigint;
|
|
17
|
+
sellAsset: Asset;
|
|
18
|
+
spenderAddress?: Address;
|
|
19
|
+
};
|
|
20
|
+
export declare const simulateWithStateOverrides: (params: SimulateTransactionParams, config: TenderlyConfig) => Promise<SimulationResult>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { fromChainId } from '@shapeshiftoss/caip';
|
|
2
|
+
import { contractAddressOrUndefined } from '@shapeshiftoss/utils';
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
import { isAddress, maxUint256, parseEther, toHex } from 'viem';
|
|
5
|
+
import { isNativeEvmAsset } from '../../swappers/utils/helpers/helpers.js';
|
|
6
|
+
import { getAllowanceStorageSlot, getBalanceStorageSlot, getMaxBalanceValue, getTokenAllowanceSlot, getTokenBalanceSlot, } from './storageSlots.js';
|
|
7
|
+
export const simulateWithStateOverrides = async (params, config) => {
|
|
8
|
+
const { chainId, from, to, data, value, sellAsset, spenderAddress } = params;
|
|
9
|
+
try {
|
|
10
|
+
if (!isAddress(from))
|
|
11
|
+
throw new Error(`Invalid from address: ${from}`);
|
|
12
|
+
if (!isAddress(to))
|
|
13
|
+
throw new Error(`Invalid to address: ${to}`);
|
|
14
|
+
const evmNetworkId = Number(fromChainId(chainId).chainReference);
|
|
15
|
+
const spender = spenderAddress ?? to;
|
|
16
|
+
const stateOverrides = buildStateOverrides({
|
|
17
|
+
from,
|
|
18
|
+
spender,
|
|
19
|
+
sellAsset,
|
|
20
|
+
});
|
|
21
|
+
const request = {
|
|
22
|
+
network_id: evmNetworkId.toString(),
|
|
23
|
+
from: from.toLowerCase(),
|
|
24
|
+
to: to.toLowerCase(),
|
|
25
|
+
input: data,
|
|
26
|
+
value: value ? toHex(BigInt(value)) : '0x0',
|
|
27
|
+
save: false,
|
|
28
|
+
state_objects: stateOverrides,
|
|
29
|
+
};
|
|
30
|
+
const url = `https://api.tenderly.co/api/v1/account/${config.accountSlug}/project/${config.projectSlug}/simulate`;
|
|
31
|
+
const response = await axios.post(url, request, {
|
|
32
|
+
headers: {
|
|
33
|
+
'Content-Type': 'application/json',
|
|
34
|
+
'X-Access-Key': config.apiKey,
|
|
35
|
+
},
|
|
36
|
+
timeout: 10000,
|
|
37
|
+
});
|
|
38
|
+
if ('error' in response.data) {
|
|
39
|
+
const error = response.data.error;
|
|
40
|
+
return {
|
|
41
|
+
success: false,
|
|
42
|
+
gasUsed: 0n,
|
|
43
|
+
gasLimit: 0n,
|
|
44
|
+
errorMessage: `Tenderly API error: ${error.message}`,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const { transaction } = response.data;
|
|
48
|
+
const gasUsed = BigInt(transaction.gas_used);
|
|
49
|
+
return {
|
|
50
|
+
success: transaction.status,
|
|
51
|
+
gasUsed,
|
|
52
|
+
gasLimit: gasUsed,
|
|
53
|
+
errorMessage: transaction.error_message,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
gasUsed: 0n,
|
|
60
|
+
gasLimit: 0n,
|
|
61
|
+
errorMessage: error instanceof Error ? error.message : 'Unknown simulation error',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const buildStateOverrides = (params) => {
|
|
66
|
+
const { from, spender, sellAsset } = params;
|
|
67
|
+
// Large native balance for gas (1B is overkill but guarantees success on all chains)
|
|
68
|
+
const nativeBalanceOverride = toHex(parseEther('1000000000'));
|
|
69
|
+
const isNative = isNativeEvmAsset(sellAsset.assetId);
|
|
70
|
+
return isNative
|
|
71
|
+
? {
|
|
72
|
+
[from.toLowerCase()]: {
|
|
73
|
+
balance: nativeBalanceOverride,
|
|
74
|
+
},
|
|
75
|
+
}
|
|
76
|
+
: (() => {
|
|
77
|
+
const contractAddress = contractAddressOrUndefined(sellAsset.assetId);
|
|
78
|
+
if (!contractAddress) {
|
|
79
|
+
return {
|
|
80
|
+
[from.toLowerCase()]: {
|
|
81
|
+
balance: nativeBalanceOverride,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const balanceSlot = getTokenBalanceSlot(contractAddress);
|
|
86
|
+
const balanceStorageSlot = getBalanceStorageSlot(from, balanceSlot);
|
|
87
|
+
const maxBalance = getMaxBalanceValue(contractAddress);
|
|
88
|
+
const allowanceSlot = getTokenAllowanceSlot(contractAddress);
|
|
89
|
+
const allowanceStorageSlot = getAllowanceStorageSlot(from, spender, allowanceSlot);
|
|
90
|
+
return {
|
|
91
|
+
[from.toLowerCase()]: {
|
|
92
|
+
balance: nativeBalanceOverride,
|
|
93
|
+
},
|
|
94
|
+
[contractAddress.toLowerCase()]: {
|
|
95
|
+
storage: {
|
|
96
|
+
[balanceStorageSlot]: maxBalance,
|
|
97
|
+
[allowanceStorageSlot]: toHex(maxUint256),
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
})();
|
|
102
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Address, Hex } from 'viem';
|
|
2
|
+
export declare const getBalanceStorageSlot: (userAddress: Address, balanceSlotNumber?: number) => Hex;
|
|
3
|
+
export declare const getAllowanceStorageSlot: (ownerAddress: Address, spenderAddress: Address, allowanceSlotNumber?: number) => Hex;
|
|
4
|
+
export declare const KNOWN_BALANCE_SLOTS: Record<string, number>;
|
|
5
|
+
export declare const KNOWN_ALLOWANCE_SLOTS: Record<string, number>;
|
|
6
|
+
export declare const getTokenBalanceSlot: (tokenAddress: Address) => number;
|
|
7
|
+
export declare const getTokenAllowanceSlot: (tokenAddress: Address) => number;
|
|
8
|
+
export declare const getMaxBalanceValue: (tokenAddress: Address) => Hex;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { concat, keccak256, maxUint256, pad, toHex } from 'viem';
|
|
2
|
+
// keccak256(concat(pad(address), pad(slot)))
|
|
3
|
+
export const getBalanceStorageSlot = (userAddress, balanceSlotNumber = 0) => {
|
|
4
|
+
const paddedAddress = pad(userAddress.toLowerCase(), { size: 32 });
|
|
5
|
+
const paddedSlot = pad(toHex(balanceSlotNumber), { size: 32 });
|
|
6
|
+
return keccak256(concat([paddedAddress, paddedSlot]));
|
|
7
|
+
};
|
|
8
|
+
// keccak256(spender, keccak256(owner, slot))
|
|
9
|
+
export const getAllowanceStorageSlot = (ownerAddress, spenderAddress, allowanceSlotNumber = 1) => {
|
|
10
|
+
const paddedOwner = pad(ownerAddress.toLowerCase(), { size: 32 });
|
|
11
|
+
const paddedAllowanceSlot = pad(toHex(allowanceSlotNumber), { size: 32 });
|
|
12
|
+
const innerSlot = keccak256(concat([paddedOwner, paddedAllowanceSlot]));
|
|
13
|
+
const paddedSpender = pad(spenderAddress.toLowerCase(), { size: 32 });
|
|
14
|
+
return keccak256(concat([paddedSpender, innerSlot]));
|
|
15
|
+
};
|
|
16
|
+
// Most ERC20s: balance at slot 0, allowance at slot 1
|
|
17
|
+
// Slot 51/52 pattern (StandardArbERC20, some L2 implementations)
|
|
18
|
+
// Slot 5/6 pattern (Wormhole bridge)
|
|
19
|
+
// USDT (native Tether - Ethereum): balance at slot 2, allowance at slot 5
|
|
20
|
+
// USDT (BEP20 - BSC): balance at slot 1, allowance at slot 2
|
|
21
|
+
// USDT (xDai bridge - Gnosis): balance at slot 3, allowance at slot 4
|
|
22
|
+
// USDC (Circle native): balance at slot 9, allowance at slot 10
|
|
23
|
+
// USDC (BEP20 - BSC): balance at slot 1, allowance at slot 2
|
|
24
|
+
export const KNOWN_BALANCE_SLOTS = {
|
|
25
|
+
// USDT - Native Tether deployment (custom slot 2)
|
|
26
|
+
'0xdac17f958d2ee523a2206206994597c13d831ec7': 2,
|
|
27
|
+
// Slot 51 pattern (L2GatewayToken + ERC20Upgradeable + storage gaps)
|
|
28
|
+
// Various L2 tokens use this pattern with different implementations
|
|
29
|
+
'0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9': 51,
|
|
30
|
+
'0x912ce59144191c1204e64559fe8253a0e49e6548': 51,
|
|
31
|
+
'0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7': 51,
|
|
32
|
+
'0x01bff41798a0bcf287b996046ca68b395dbc1071': 51,
|
|
33
|
+
// Wormhole bridge pattern (slot 5)
|
|
34
|
+
'0xca7dec8550f43a5e46e3dfb95801f64280e75b27': 5,
|
|
35
|
+
// USDT - BEP20 pattern (slot 1 - Binance-Peg token)
|
|
36
|
+
'0x55d398326f99059ff775485246999027b3197955': 1,
|
|
37
|
+
// USDT - xDai bridge pattern (slot 3)
|
|
38
|
+
'0x4ecaba5870353805a9f068101a40e0f32ed605c6': 3,
|
|
39
|
+
// USDT - Standard ERC20 deployments (slot 0)
|
|
40
|
+
// Polygon confirmed, Optimism bridged USDT (0x94b008aa...) also uses slot 0
|
|
41
|
+
// USDC (Circle native deployments - all use slot 9)
|
|
42
|
+
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': 9,
|
|
43
|
+
'0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e': 9,
|
|
44
|
+
'0x0b2c639c533813f4aa9d7837caf62653d097ff85': 9,
|
|
45
|
+
'0x3c499c542cef5e3811e1192ce70d8cc03d5c3359': 9,
|
|
46
|
+
'0xaf88d065e77c8cc2239327c5edb3a432268e5831': 9,
|
|
47
|
+
'0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': 9,
|
|
48
|
+
// USDC (BEP20 pattern on BSC - slot 1)
|
|
49
|
+
'0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d': 1, // USDC BSC (BEP20)
|
|
50
|
+
};
|
|
51
|
+
export const KNOWN_ALLOWANCE_SLOTS = {
|
|
52
|
+
// USDT allowance slots (explicit mapping for all non-standard implementations)
|
|
53
|
+
'0xdac17f958d2ee523a2206206994597c13d831ec7': 5,
|
|
54
|
+
'0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9': 52,
|
|
55
|
+
'0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7': 52,
|
|
56
|
+
'0x01bff41798a0bcf287b996046ca68b395dbc1071': 52,
|
|
57
|
+
'0x55d398326f99059ff775485246999027b3197955': 2,
|
|
58
|
+
'0x4ecaba5870353805a9f068101a40e0f32ed605c6': 4,
|
|
59
|
+
// Note: Polygon and Optimism standard bridged USDT (0x94b008aa...) use slot 1 (fallback)
|
|
60
|
+
// Note: SWEAT (slot 5) allowance auto-inferred to slot 6 via Wormhole pattern
|
|
61
|
+
// USDC allowance slots (BSC uses BEP20 pattern, not Circle FiatToken)
|
|
62
|
+
'0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d': 2, // USDC BSC (BEP20)
|
|
63
|
+
// Note: All other USDC (Circle native) use slot 10 (handled by USDC pattern check)
|
|
64
|
+
};
|
|
65
|
+
export const getTokenBalanceSlot = (tokenAddress) => KNOWN_BALANCE_SLOTS[tokenAddress.toLowerCase()] ?? 0;
|
|
66
|
+
export const getTokenAllowanceSlot = (tokenAddress) => {
|
|
67
|
+
// Check explicit allowance mapping first
|
|
68
|
+
const explicitSlot = KNOWN_ALLOWANCE_SLOTS[tokenAddress.toLowerCase()];
|
|
69
|
+
if (explicitSlot !== undefined)
|
|
70
|
+
return explicitSlot;
|
|
71
|
+
// Infer allowance slot from balance slot for known patterns
|
|
72
|
+
const balanceSlot = getTokenBalanceSlot(tokenAddress);
|
|
73
|
+
if (balanceSlot === 9)
|
|
74
|
+
return 10; // USDC pattern
|
|
75
|
+
if (balanceSlot === 51)
|
|
76
|
+
return 52; // StandardArbERC20 pattern
|
|
77
|
+
if (balanceSlot === 5)
|
|
78
|
+
return 6; // Wormhole pattern
|
|
79
|
+
// Standard ERC20: allowance at slot 1
|
|
80
|
+
return 1;
|
|
81
|
+
};
|
|
82
|
+
// USDC slot 9: bit 255 is blacklist flag, must keep cleared
|
|
83
|
+
export const getMaxBalanceValue = (tokenAddress) => {
|
|
84
|
+
const slot = getTokenBalanceSlot(tokenAddress);
|
|
85
|
+
return slot === 9 ? toHex(maxUint256 >> 1n) : toHex(maxUint256);
|
|
86
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Address, Hex } from 'viem';
|
|
2
|
+
export type TenderlyStateOverrides = {
|
|
3
|
+
[address: Address]: {
|
|
4
|
+
balance?: Hex;
|
|
5
|
+
storage?: {
|
|
6
|
+
[slot: Hex]: Hex;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export type TenderlySimulationRequest = {
|
|
11
|
+
network_id: string;
|
|
12
|
+
from: Address;
|
|
13
|
+
to: Address;
|
|
14
|
+
input: Hex;
|
|
15
|
+
value?: Hex;
|
|
16
|
+
gas?: number;
|
|
17
|
+
gas_price?: string;
|
|
18
|
+
max_fee_per_gas?: string;
|
|
19
|
+
max_priority_fee_per_gas?: string;
|
|
20
|
+
save?: boolean;
|
|
21
|
+
state_objects?: TenderlyStateOverrides;
|
|
22
|
+
};
|
|
23
|
+
export type TenderlySimulationResponse = {
|
|
24
|
+
transaction: {
|
|
25
|
+
hash: string;
|
|
26
|
+
status: boolean;
|
|
27
|
+
error_message?: string;
|
|
28
|
+
gas_used: number;
|
|
29
|
+
gas: number;
|
|
30
|
+
gas_price: string;
|
|
31
|
+
value: string;
|
|
32
|
+
call_trace?: unknown[];
|
|
33
|
+
asset_changes?: unknown[];
|
|
34
|
+
};
|
|
35
|
+
simulation: {
|
|
36
|
+
id: string;
|
|
37
|
+
network_id: string;
|
|
38
|
+
block_number: number;
|
|
39
|
+
block_hash: string;
|
|
40
|
+
timestamp: string;
|
|
41
|
+
gas_used: number;
|
|
42
|
+
status: boolean;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
export type TenderlyErrorResponse = {
|
|
46
|
+
error: {
|
|
47
|
+
id: string;
|
|
48
|
+
slug: string;
|
|
49
|
+
message: string;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
export type TenderlyConfig = {
|
|
53
|
+
apiKey: string;
|
|
54
|
+
accountSlug: string;
|
|
55
|
+
projectSlug: string;
|
|
56
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshiftoss/swapper",
|
|
3
|
-
"version": "17.6.
|
|
3
|
+
"version": "17.6.6-alpha.0",
|
|
4
4
|
"packageManager": "yarn@3.5.0",
|
|
5
5
|
"repository": "https://github.com/shapeshift/web",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,10 +30,36 @@
|
|
|
30
30
|
"postbuild:cjs": "echo '{\"type\": \"commonjs\"}' > dist/cjs/package.json"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
+
"@arbitrum/sdk": "^4.0.1",
|
|
33
34
|
"@coral-xyz/anchor": "0.29.0",
|
|
34
|
-
"@
|
|
35
|
-
"@
|
|
36
|
-
"@
|
|
37
|
-
"@shapeshiftoss/
|
|
35
|
+
"@cowprotocol/app-data": "^2.3.0",
|
|
36
|
+
"@defuse-protocol/one-click-sdk-typescript": "^0.1.1-0.2",
|
|
37
|
+
"@jup-ag/api": "^6.0.30",
|
|
38
|
+
"@shapeshiftoss/bitcoinjs-lib": "5.2.0-shapeshift.2",
|
|
39
|
+
"@shapeshiftoss/caip": "workspace:^",
|
|
40
|
+
"@shapeshiftoss/chain-adapters": "workspace:^",
|
|
41
|
+
"@shapeshiftoss/contracts": "workspace:^",
|
|
42
|
+
"@shapeshiftoss/hdwallet-core": "1.62.9",
|
|
43
|
+
"@shapeshiftoss/types": "workspace:^",
|
|
44
|
+
"@shapeshiftoss/unchained-client": "workspace:^",
|
|
45
|
+
"@shapeshiftoss/utils": "workspace:^",
|
|
46
|
+
"@sniptt/monads": "^0.5.10",
|
|
47
|
+
"@solana/web3.js": "^1.98.0",
|
|
48
|
+
"@uniswap/sdk-core": "^5.3.1",
|
|
49
|
+
"@uniswap/v3-sdk": "^3.13.1",
|
|
50
|
+
"axios": "^1.13.0",
|
|
51
|
+
"axios-cache-interceptor": "^1.5.3",
|
|
52
|
+
"bignumber.js": "^9.3.1",
|
|
53
|
+
"eip-712": "^1.0.0",
|
|
54
|
+
"ethers": "6.11.1",
|
|
55
|
+
"ethers5": "npm:ethers@5.7.2",
|
|
56
|
+
"lodash": "^4.17.21",
|
|
57
|
+
"mixpanel-browser": "^2.67.0",
|
|
58
|
+
"node-polyglot": "^2.4.0",
|
|
59
|
+
"pretty-ms": "7.0.1",
|
|
60
|
+
"qs": "^6.10.5",
|
|
61
|
+
"retry-axios": "^2.6.0",
|
|
62
|
+
"uuid": "^9.0.0",
|
|
63
|
+
"viem": "^2.10.9"
|
|
38
64
|
}
|
|
39
|
-
}
|
|
65
|
+
}
|