@shapeshiftoss/swapper 18.1.0 → 19.0.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/swappers/AcrossSwapper/constant.js +2 -1
- package/dist/cjs/swappers/AcrossSwapper/endpoints.js +1 -1
- package/dist/cjs/swappers/AcrossSwapper/getTradeQuote/getTradeQuote.js +2 -1
- package/dist/cjs/swappers/AcrossSwapper/utils/acrossService.d.ts +6 -3
- package/dist/cjs/swappers/AcrossSwapper/utils/acrossService.js +5 -1
- package/dist/cjs/swappers/AcrossSwapper/utils/fetchAcrossTrade.js +1 -1
- package/dist/cjs/swappers/AcrossSwapper/utils/getAcrossTradeContext.d.ts +1 -0
- package/dist/cjs/swappers/AcrossSwapper/utils/getAcrossTradeContext.js +1 -0
- package/dist/cjs/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.js +2 -0
- package/dist/cjs/swappers/AvnuSwapper/swapperApi/getTradeQuote.js +3 -1
- package/dist/cjs/swappers/AvnuSwapper/utils/getAvnuTradeContext.d.ts +1 -0
- package/dist/cjs/swappers/AvnuSwapper/utils/getAvnuTradeContext.js +1 -0
- package/dist/cjs/swappers/BebopSwapper/getBebopSolanaTradeQuote/getBebopSolanaTradeQuote.js +5 -2
- package/dist/cjs/swappers/BebopSwapper/getBebopTradeQuote/getBebopTradeQuote.js +2 -1
- package/dist/cjs/swappers/BebopSwapper/types.d.ts +2 -2
- package/dist/cjs/swappers/BebopSwapper/types.js +2 -0
- package/dist/cjs/swappers/BebopSwapper/utils/getBebopTradeContext.d.ts +1 -0
- package/dist/cjs/swappers/BebopSwapper/utils/getBebopTradeContext.js +1 -0
- package/dist/cjs/swappers/BebopSwapper/utils/helpers.d.ts +1 -1
- package/dist/cjs/swappers/BobGatewaySwapper/swapperApi/getTradeQuote.js +2 -0
- package/dist/cjs/swappers/ButterSwap/swapperApi/getTradeQuote.js +2 -0
- package/dist/cjs/swappers/ButterSwap/utils/helpers.js +10 -8
- package/dist/cjs/swappers/CetusSwapper/swapperApi/getTradeQuote.js +2 -0
- package/dist/cjs/swappers/ChainflipSwapper/constants.d.ts +1 -0
- package/dist/cjs/swappers/ChainflipSwapper/constants.js +3 -1
- package/dist/cjs/swappers/ChainflipSwapper/swapperApi/getTradeQuote.js +2 -0
- package/dist/cjs/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.js +1 -0
- package/dist/cjs/swappers/DebridgeSwapper/constant.js +10 -8
- package/dist/cjs/swappers/DebridgeSwapper/getTradeQuote/getTradeQuote.js +2 -0
- package/dist/cjs/swappers/NearIntentsSwapper/endpoints.js +3 -1
- package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.js +7 -0
- package/dist/cjs/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.js +11 -0
- package/dist/cjs/swappers/RelaySwapper/constant.js +4 -3
- package/dist/cjs/swappers/RelaySwapper/endpoints.js +6 -2
- package/dist/cjs/swappers/RelaySwapper/getTradeQuote/getTradeQuote.js +2 -0
- package/dist/cjs/swappers/RelaySwapper/utils/fetchRelayTrade.js +1 -1
- package/dist/cjs/swappers/RelaySwapper/utils/getLatestRelayStatusMessage.js +3 -1
- package/dist/cjs/swappers/RelaySwapper/utils/notifyTransactionIndexing.js +1 -1
- package/dist/cjs/swappers/RelaySwapper/utils/relayService.d.ts +6 -3
- package/dist/cjs/swappers/RelaySwapper/utils/relayService.js +3 -1
- package/dist/cjs/swappers/RelaySwapper/utils/relayTokenToAssetId.js +5 -0
- package/dist/cjs/swappers/RelaySwapper/utils/types.d.ts +2 -2
- package/dist/cjs/swappers/StonfiSwapper/endpoints.js +40 -14
- package/dist/cjs/swappers/StonfiSwapper/swapperApi/getTradeQuote.js +2 -0
- package/dist/cjs/swappers/SunioSwapper/getSunioTradeQuote/getSunioTradeQuote.js +2 -0
- package/dist/cjs/swappers/ThorchainSwapper/getTradeQuote/getTradeQuote.test.js +2 -0
- package/dist/cjs/swappers/ThorchainSwapper/utils/getLongtailQuote.js +2 -0
- package/dist/cjs/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.js +1 -0
- package/dist/cjs/swappers/ZrxSwapper/types.d.ts +1 -1
- package/dist/cjs/swappers/ZrxSwapper/types.js +1 -0
- package/dist/cjs/swappers/ZrxSwapper/utils/constants.js +1 -0
- package/dist/cjs/swappers/ZrxSwapper/utils/helpers.d.ts +1 -1
- package/dist/cjs/swappers/ZrxSwapper/utils/helpers.js +5 -0
- package/dist/cjs/types.d.ts +3 -0
- package/dist/cjs/utils/helpers.d.ts +2 -0
- package/dist/cjs/utils/helpers.js +14 -1
- package/dist/cjs/utils/helpers.test.js +17 -0
- package/dist/cjs/utils/test-data/setupSwapQuote.js +1 -0
- package/dist/cjs/utils/thorchain/getThorL1TradeQuote.js +3 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/swappers/AcrossSwapper/constant.js +4 -3
- package/dist/esm/swappers/AcrossSwapper/endpoints.js +2 -2
- package/dist/esm/swappers/AcrossSwapper/getTradeQuote/getTradeQuote.js +2 -1
- package/dist/esm/swappers/AcrossSwapper/utils/acrossService.d.ts +6 -3
- package/dist/esm/swappers/AcrossSwapper/utils/acrossService.js +3 -0
- package/dist/esm/swappers/AcrossSwapper/utils/fetchAcrossTrade.js +2 -2
- package/dist/esm/swappers/AcrossSwapper/utils/getAcrossTradeContext.d.ts +1 -0
- package/dist/esm/swappers/AcrossSwapper/utils/getAcrossTradeContext.js +2 -1
- package/dist/esm/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.js +2 -0
- package/dist/esm/swappers/AvnuSwapper/swapperApi/getTradeQuote.js +3 -1
- package/dist/esm/swappers/AvnuSwapper/utils/getAvnuTradeContext.d.ts +1 -0
- package/dist/esm/swappers/AvnuSwapper/utils/getAvnuTradeContext.js +2 -1
- package/dist/esm/swappers/BebopSwapper/getBebopSolanaTradeQuote/getBebopSolanaTradeQuote.js +3 -0
- package/dist/esm/swappers/BebopSwapper/getBebopTradeQuote/getBebopTradeQuote.js +2 -1
- package/dist/esm/swappers/BebopSwapper/types.d.ts +2 -2
- package/dist/esm/swappers/BebopSwapper/types.js +2 -0
- package/dist/esm/swappers/BebopSwapper/utils/getBebopTradeContext.d.ts +1 -0
- package/dist/esm/swappers/BebopSwapper/utils/getBebopTradeContext.js +2 -1
- package/dist/esm/swappers/BebopSwapper/utils/helpers.d.ts +1 -1
- package/dist/esm/swappers/BobGatewaySwapper/swapperApi/getTradeQuote.js +2 -0
- package/dist/esm/swappers/ButterSwap/swapperApi/getTradeQuote.js +2 -0
- package/dist/esm/swappers/ButterSwap/utils/helpers.js +10 -8
- package/dist/esm/swappers/CetusSwapper/swapperApi/getTradeQuote.js +2 -0
- package/dist/esm/swappers/ChainflipSwapper/constants.d.ts +1 -0
- package/dist/esm/swappers/ChainflipSwapper/constants.js +2 -0
- package/dist/esm/swappers/ChainflipSwapper/swapperApi/getTradeQuote.js +2 -0
- package/dist/esm/swappers/CowSwapper/getCowSwapTradeQuote/getCowSwapTradeQuote.js +1 -0
- package/dist/esm/swappers/DebridgeSwapper/constant.js +11 -9
- package/dist/esm/swappers/DebridgeSwapper/getTradeQuote/getTradeQuote.js +2 -0
- package/dist/esm/swappers/NearIntentsSwapper/endpoints.js +3 -1
- package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.js +7 -0
- package/dist/esm/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.js +12 -1
- package/dist/esm/swappers/RelaySwapper/constant.js +6 -5
- package/dist/esm/swappers/RelaySwapper/endpoints.js +7 -3
- package/dist/esm/swappers/RelaySwapper/getTradeQuote/getTradeQuote.js +2 -0
- package/dist/esm/swappers/RelaySwapper/utils/fetchRelayTrade.js +2 -2
- package/dist/esm/swappers/RelaySwapper/utils/getLatestRelayStatusMessage.js +3 -1
- package/dist/esm/swappers/RelaySwapper/utils/notifyTransactionIndexing.js +2 -2
- package/dist/esm/swappers/RelaySwapper/utils/relayService.d.ts +6 -3
- package/dist/esm/swappers/RelaySwapper/utils/relayService.js +1 -0
- package/dist/esm/swappers/RelaySwapper/utils/relayTokenToAssetId.js +5 -0
- package/dist/esm/swappers/RelaySwapper/utils/types.d.ts +2 -2
- package/dist/esm/swappers/StonfiSwapper/endpoints.js +41 -15
- package/dist/esm/swappers/StonfiSwapper/swapperApi/getTradeQuote.js +2 -0
- package/dist/esm/swappers/SunioSwapper/getSunioTradeQuote/getSunioTradeQuote.js +2 -0
- package/dist/esm/swappers/ThorchainSwapper/getTradeQuote/getTradeQuote.test.js +2 -0
- package/dist/esm/swappers/ThorchainSwapper/utils/getLongtailQuote.js +2 -0
- package/dist/esm/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.js +2 -1
- package/dist/esm/swappers/ZrxSwapper/types.d.ts +1 -1
- package/dist/esm/swappers/ZrxSwapper/types.js +1 -0
- package/dist/esm/swappers/ZrxSwapper/utils/constants.js +1 -0
- package/dist/esm/swappers/ZrxSwapper/utils/helpers.d.ts +1 -1
- package/dist/esm/swappers/ZrxSwapper/utils/helpers.js +5 -0
- package/dist/esm/types.d.ts +3 -0
- package/dist/esm/utils/helpers.d.ts +2 -0
- package/dist/esm/utils/helpers.js +12 -0
- package/dist/esm/utils/helpers.test.js +18 -1
- package/dist/esm/utils/test-data/setupSwapQuote.js +1 -0
- package/dist/esm/utils/thorchain/getThorL1TradeQuote.js +3 -0
- package/package.json +5 -5
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Err, Ok } from '@sniptt/monads';
|
|
2
2
|
import { assertQuoteAddresses } from '../../../utils/index.js';
|
|
3
|
+
import { FALLBACK_QUOTE_DEADLINE_MS } from '../../../utils/helpers.js';
|
|
3
4
|
import { getRelayStepData } from '../utils/getRelayStepData.js';
|
|
4
5
|
import { getRelayTradeContext } from '../utils/getRelayTradeContext.js';
|
|
5
6
|
export const getTradeQuote = async (input, deps, relayChainMap) => {
|
|
@@ -42,6 +43,7 @@ export const getTradeQuote = async (input, deps, relayChainMap) => {
|
|
|
42
43
|
const tradeQuote = {
|
|
43
44
|
...tradeCommon,
|
|
44
45
|
quoteOrRate: 'quote',
|
|
46
|
+
deadline: Date.now() + FALLBACK_QUOTE_DEADLINE_MS,
|
|
45
47
|
receiveAddress,
|
|
46
48
|
steps,
|
|
47
49
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { relayService } from './relayService.js';
|
|
1
|
+
import { getRelayRequestConfig, relayService } from './relayService.js';
|
|
2
2
|
export const fetchRelayTrade = async (params, config) => {
|
|
3
|
-
return await relayService.post(`${config.VITE_RELAY_API_URL}/quote/v2`, params);
|
|
3
|
+
return await relayService.post(`${config.VITE_RELAY_API_URL}/quote/v2`, params, getRelayRequestConfig(config));
|
|
4
4
|
};
|
|
@@ -7,10 +7,12 @@ export const getLatestRelayStatusMessage = (status) => {
|
|
|
7
7
|
case statusValue === 'delayed':
|
|
8
8
|
return RelayStatusMessage.Retrying;
|
|
9
9
|
case statusValue === 'pending':
|
|
10
|
+
case statusValue === 'depositing':
|
|
11
|
+
case statusValue === 'submitted':
|
|
10
12
|
return RelayStatusMessage.DepositDetected;
|
|
11
13
|
case statusValue === 'success':
|
|
12
14
|
return RelayStatusMessage.SwapComplete;
|
|
13
|
-
case statusValue === '
|
|
15
|
+
case statusValue === 'failure':
|
|
14
16
|
return RelayStatusMessage.SwapFailed;
|
|
15
17
|
default:
|
|
16
18
|
return 'Unknown status';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { relayService } from './relayService.js';
|
|
1
|
+
import { getRelayRequestConfig, relayService } from './relayService.js';
|
|
2
2
|
export const notifyTransactionIndexing = async (params, config) => {
|
|
3
|
-
return await relayService.post(`${config.VITE_RELAY_API_URL}/transactions/single`, params);
|
|
3
|
+
return await relayService.post(`${config.VITE_RELAY_API_URL}/transactions/single`, params, getRelayRequestConfig(config));
|
|
4
4
|
};
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import type { AxiosRequestConfig } from 'axios';
|
|
2
|
+
import type { SwapperConfig } from '../../../types.js';
|
|
1
3
|
export declare const relayService: {
|
|
2
|
-
get: <T = any>(url: string, config?:
|
|
3
|
-
post: <T_1 = any>(url: string, data: any, config?:
|
|
4
|
-
delete: <T_2 = any>(url: string, data: any, config?:
|
|
4
|
+
get: <T = any>(url: string, config?: AxiosRequestConfig<any> | undefined) => Promise<import("@sniptt/monads").Result<import("axios").AxiosResponse<T, any, {}>, import("../../../types.js").SwapErrorRight>>;
|
|
5
|
+
post: <T_1 = any>(url: string, data: any, config?: AxiosRequestConfig<any> | undefined) => Promise<import("@sniptt/monads").Result<import("axios").AxiosResponse<T_1, any, {}>, import("../../../types.js").SwapErrorRight>>;
|
|
6
|
+
delete: <T_2 = any>(url: string, data: any, config?: AxiosRequestConfig<any> | undefined) => Promise<import("@sniptt/monads").Result<import("axios").AxiosResponse<T_2, any, {}>, import("../../../types.js").SwapErrorRight>>;
|
|
5
7
|
};
|
|
8
|
+
export declare const getRelayRequestConfig: (config: SwapperConfig) => AxiosRequestConfig | undefined;
|
|
@@ -10,3 +10,4 @@ const axiosConfig = {
|
|
|
10
10
|
};
|
|
11
11
|
const relayServiceBase = createCache(maxAgeMillis, cachedUrls, axiosConfig);
|
|
12
12
|
export const relayService = makeSwapperAxiosServiceMonadic(relayServiceBase);
|
|
13
|
+
export const getRelayRequestConfig = (config) => config.VITE_RELAY_API_KEY ? { headers: { 'x-api-key': config.VITE_RELAY_API_KEY } } : undefined;
|
|
@@ -229,6 +229,11 @@ export const relayTokenToAssetId = (relayToken) => {
|
|
|
229
229
|
assetReference: ASSET_REFERENCE.Abstract,
|
|
230
230
|
assetNamespace: ASSET_NAMESPACE.slip44,
|
|
231
231
|
};
|
|
232
|
+
case CHAIN_REFERENCE.RobinhoodMainnet:
|
|
233
|
+
return {
|
|
234
|
+
assetReference: ASSET_REFERENCE.Robinhood,
|
|
235
|
+
assetNamespace: ASSET_NAMESPACE.slip44,
|
|
236
|
+
};
|
|
232
237
|
default:
|
|
233
238
|
throw Error(`chainId '${relayToken.chainId}' not supported`);
|
|
234
239
|
}
|
|
@@ -11,11 +11,11 @@ export type RelayMetadata = {
|
|
|
11
11
|
data?: string;
|
|
12
12
|
};
|
|
13
13
|
export type RelayStatus = {
|
|
14
|
-
status: 'success' | '
|
|
14
|
+
status: 'success' | 'failure' | 'pending' | 'submitted' | 'depositing' | 'refund' | 'delayed' | 'waiting';
|
|
15
15
|
details?: string;
|
|
16
16
|
inTxHashes: string[];
|
|
17
17
|
txHashes: string[];
|
|
18
|
-
|
|
18
|
+
updatedAt: number;
|
|
19
19
|
originChainId: number;
|
|
20
20
|
destinationChainId: number;
|
|
21
21
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toAddressNList } from '@shapeshiftoss/chain-adapters';
|
|
2
|
-
import { TxStatus } from '@shapeshiftoss/unchained-client';
|
|
2
|
+
import { TransferType, TxStatus } from '@shapeshiftoss/unchained-client';
|
|
3
3
|
import { Blockchain } from '@ston-fi/omniston-sdk';
|
|
4
4
|
import { createDefaultStatusResponse, getExecutableTradeStep, getSwapMetadata, isExecutableTradeQuote, } from '../../utils/index.js';
|
|
5
5
|
import { getTradeQuote } from './swapperApi/getTradeQuote.js';
|
|
@@ -97,6 +97,20 @@ export const stonfiApi = {
|
|
|
97
97
|
}
|
|
98
98
|
};
|
|
99
99
|
const { quoteId } = getSwapMetadata(swap.metadata.swapperMetadata, 'stonfi');
|
|
100
|
+
// Settlement precedes toncenter's jetton indexer, and confirmed rows are never re-parsed -
|
|
101
|
+
// hold confirmation until the receive leg is visible so the confirmed-time parse and upsert
|
|
102
|
+
// carries both legs of the swap
|
|
103
|
+
const hasVisibleReceiveLeg = async () => {
|
|
104
|
+
const adapter = assertGetTonChainAdapter(swap.sellAsset.chainId);
|
|
105
|
+
const sellAddress = swap.sellAccountId.split(':')[2] ?? '';
|
|
106
|
+
const addresses = new Set([sellAddress, swap.receiveAddress].filter((address) => Boolean(address)));
|
|
107
|
+
for (const address of addresses) {
|
|
108
|
+
const tx = await adapter.parseTx(sellTxHash, address);
|
|
109
|
+
if (tx.transfers.some(transfer => transfer.type === TransferType.Receive))
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
};
|
|
100
114
|
try {
|
|
101
115
|
const tradeStatus = await waitForFirstTradeStatus({
|
|
102
116
|
quoteId,
|
|
@@ -110,14 +124,13 @@ export const stonfiApi = {
|
|
|
110
124
|
return checkTxStatusViaChainAdapter();
|
|
111
125
|
}
|
|
112
126
|
const statusOneOf = tradeStatus.status;
|
|
127
|
+
// While the trade is in flight the wallet tx may already be confirmed, but the payout leg
|
|
128
|
+
// hasn't landed - confirming here would parse and upsert a trace without the receive, so
|
|
129
|
+
// completion waits for settlement
|
|
113
130
|
if (statusOneOf.awaitingTransfer ||
|
|
114
131
|
statusOneOf.transferring ||
|
|
115
132
|
statusOneOf.swapping ||
|
|
116
133
|
statusOneOf.receivingFunds) {
|
|
117
|
-
const chainStatus = await checkTxStatusViaChainAdapter();
|
|
118
|
-
if (chainStatus.status === TxStatus.Confirmed) {
|
|
119
|
-
return chainStatus;
|
|
120
|
-
}
|
|
121
134
|
if (statusOneOf.awaitingTransfer) {
|
|
122
135
|
return {
|
|
123
136
|
status: TxStatus.Pending,
|
|
@@ -149,19 +162,32 @@ export const stonfiApi = {
|
|
|
149
162
|
}
|
|
150
163
|
if (statusOneOf.tradeSettled) {
|
|
151
164
|
const result = statusOneOf.tradeSettled.result;
|
|
152
|
-
if (result === 'TRADE_RESULT_FULLY_FILLED') {
|
|
153
|
-
|
|
154
|
-
status: TxStatus.Confirmed,
|
|
155
|
-
buyTxHash: sellTxHash,
|
|
156
|
-
message: undefined,
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
if (result === 'TRADE_RESULT_PARTIALLY_FILLED') {
|
|
160
|
-
return {
|
|
165
|
+
if (result === 'TRADE_RESULT_FULLY_FILLED' || result === 'TRADE_RESULT_PARTIALLY_FILLED') {
|
|
166
|
+
const settled = {
|
|
161
167
|
status: TxStatus.Confirmed,
|
|
162
168
|
buyTxHash: sellTxHash,
|
|
163
|
-
message: '
|
|
169
|
+
message: result === 'TRADE_RESULT_PARTIALLY_FILLED'
|
|
170
|
+
? 'trade.statuses.partiallyFilled'
|
|
171
|
+
: undefined,
|
|
164
172
|
};
|
|
173
|
+
try {
|
|
174
|
+
if (await hasVisibleReceiveLeg())
|
|
175
|
+
return settled;
|
|
176
|
+
return {
|
|
177
|
+
status: TxStatus.Pending,
|
|
178
|
+
buyTxHash: undefined,
|
|
179
|
+
message: 'trade.statuses.receivingFunds',
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
// Indexer/API failure must not block completion
|
|
184
|
+
console.error('[Stonfi] Error verifying settlement receive leg:', {
|
|
185
|
+
sellTxHash,
|
|
186
|
+
result,
|
|
187
|
+
error,
|
|
188
|
+
});
|
|
189
|
+
return settled;
|
|
190
|
+
}
|
|
165
191
|
}
|
|
166
192
|
if (result === 'TRADE_RESULT_ABORTED') {
|
|
167
193
|
return {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Err, Ok } from '@sniptt/monads';
|
|
2
2
|
import { assertQuoteAddresses } from '../../../utils/index.js';
|
|
3
|
+
import { normalizeEpochToMs } from '../../../utils/helpers.js';
|
|
3
4
|
import { getStonfiStepData } from '../utils/getStonfiStepData.js';
|
|
4
5
|
import { getStonfiTradeContext } from '../utils/getStonfiTradeContext.js';
|
|
5
6
|
export const getTradeQuote = async (input, deps) => {
|
|
@@ -24,6 +25,7 @@ export const getTradeQuote = async (input, deps) => {
|
|
|
24
25
|
const tradeQuote = {
|
|
25
26
|
...tradeCommon,
|
|
26
27
|
quoteOrRate: 'quote',
|
|
28
|
+
deadline: normalizeEpochToMs(stonfiTransactionData.tradeStartDeadline),
|
|
27
29
|
receiveAddress,
|
|
28
30
|
steps: [
|
|
29
31
|
{
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Err, Ok } from '@sniptt/monads';
|
|
2
2
|
import { assertQuoteAddresses } from '../../../utils/index.js';
|
|
3
|
+
import { FALLBACK_QUOTE_DEADLINE_MS } from '../../../utils/helpers.js';
|
|
3
4
|
import { getSunioStepData } from '../utils/getSunioStepData.js';
|
|
4
5
|
import { getSunioTradeContext } from '../utils/getSunioTradeContext.js';
|
|
5
6
|
export const getSunioTradeQuote = async (input, deps) => {
|
|
@@ -24,6 +25,7 @@ export const getSunioTradeQuote = async (input, deps) => {
|
|
|
24
25
|
const tradeQuote = {
|
|
25
26
|
...tradeCommon,
|
|
26
27
|
quoteOrRate: 'quote',
|
|
28
|
+
deadline: Date.now() + FALLBACK_QUOTE_DEADLINE_MS,
|
|
27
29
|
receiveAddress,
|
|
28
30
|
steps: [
|
|
29
31
|
{
|
|
@@ -62,6 +62,7 @@ const expectedQuoteResponse = [
|
|
|
62
62
|
tradeType: TradeType.L1ToL1,
|
|
63
63
|
slippageTolerancePercentageDecimal: '0.04357',
|
|
64
64
|
expiry: 1713710808,
|
|
65
|
+
deadline: 1713710808000,
|
|
65
66
|
swapperName: SwapperName.Thorchain,
|
|
66
67
|
steps: [
|
|
67
68
|
{
|
|
@@ -112,6 +113,7 @@ const expectedQuoteResponse = [
|
|
|
112
113
|
tradeType: TradeType.L1ToL1,
|
|
113
114
|
slippageTolerancePercentageDecimal: undefined,
|
|
114
115
|
expiry: 1713710808,
|
|
116
|
+
deadline: 1713710808000,
|
|
115
117
|
swapperName: SwapperName.Thorchain,
|
|
116
118
|
steps: [
|
|
117
119
|
{
|
|
@@ -73,6 +73,8 @@ export const getLongtailToL1Quote = async (input, deps, streamingInterval, swapp
|
|
|
73
73
|
const { data, transactionData, networkFeeCryptoBaseUnit } = maybeStepData.unwrap();
|
|
74
74
|
return Ok({
|
|
75
75
|
...quote,
|
|
76
|
+
// The aggregator swapIn deadline is tighter than the daemon quote expiry
|
|
77
|
+
deadline: Math.min(quote.deadline, Number(deadline) * 1000),
|
|
76
78
|
data: data ?? quote.data,
|
|
77
79
|
// This logic will need to be updated to support multi-hop, if that's ever implemented for THORChain
|
|
78
80
|
steps: quote.steps.map(s => ({
|
|
@@ -2,7 +2,7 @@ import { Err, Ok } from '@sniptt/monads';
|
|
|
2
2
|
import { getDefaultSlippageDecimalPercentageForSwapper } from '../../../constants.js';
|
|
3
3
|
import { SwapperName, TradeQuoteError } from '../../../types.js';
|
|
4
4
|
import { assertQuoteAddresses, makeSwapErrorRight } from '../../../utils/index.js';
|
|
5
|
-
import { isNativeEvmAsset } from '../../../utils/helpers.js';
|
|
5
|
+
import { FALLBACK_QUOTE_DEADLINE_MS, isNativeEvmAsset } from '../../../utils/helpers.js';
|
|
6
6
|
import { fetchZrxQuote } from '../utils/fetchFromZrx.js';
|
|
7
7
|
import { getZrxStepData } from '../utils/getZrxStepData.js';
|
|
8
8
|
import { getZrxTradeContext } from '../utils/getZrxTradeContext.js';
|
|
@@ -76,6 +76,7 @@ export const getZrxTradeQuote = async (input, deps) => {
|
|
|
76
76
|
const tradeQuote = {
|
|
77
77
|
...tradeCommon,
|
|
78
78
|
quoteOrRate: 'quote',
|
|
79
|
+
deadline: Date.now() + FALLBACK_QUOTE_DEADLINE_MS,
|
|
79
80
|
receiveAddress,
|
|
80
81
|
steps: [
|
|
81
82
|
{
|
|
@@ -3,7 +3,7 @@ import type { Address, TypedData } from 'viem';
|
|
|
3
3
|
import type { GetEvmTradeQuoteInput, GetEvmTradeRateInput } from '../../types.js';
|
|
4
4
|
export type ZrxTradeQuoteInput = GetEvmTradeQuoteInput;
|
|
5
5
|
export type ZrxTradeRateInput = GetEvmTradeRateInput;
|
|
6
|
-
export declare const zrxSupportedChainIds: readonly [KnownChainIds.EthereumMainnet, KnownChainIds.AvalancheMainnet, KnownChainIds.OptimismMainnet, KnownChainIds.BnbSmartChainMainnet, KnownChainIds.PolygonMainnet, KnownChainIds.ArbitrumMainnet, KnownChainIds.BaseMainnet];
|
|
6
|
+
export declare const zrxSupportedChainIds: readonly [KnownChainIds.EthereumMainnet, KnownChainIds.AvalancheMainnet, KnownChainIds.OptimismMainnet, KnownChainIds.BnbSmartChainMainnet, KnownChainIds.PolygonMainnet, KnownChainIds.ArbitrumMainnet, KnownChainIds.BaseMainnet, KnownChainIds.RobinhoodMainnet];
|
|
7
7
|
export type ZrxSupportedChainId = (typeof zrxSupportedChainIds)[number];
|
|
8
8
|
type ZrxFee = {
|
|
9
9
|
amount: string;
|
|
@@ -18,6 +18,7 @@ export const ZRX_SUPPORTED_CHAINIDS = Object.freeze([
|
|
|
18
18
|
KnownChainIds.PolygonMainnet,
|
|
19
19
|
KnownChainIds.ArbitrumMainnet,
|
|
20
20
|
KnownChainIds.BaseMainnet,
|
|
21
|
+
KnownChainIds.RobinhoodMainnet,
|
|
21
22
|
]);
|
|
22
23
|
// https://0x.org/docs/developer-resources/faqs-and-troubleshooting
|
|
23
24
|
export const ZRX_NATIVE_ASSET_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
|
|
@@ -6,7 +6,7 @@ import type { SwapErrorRight } from '../../../types.js';
|
|
|
6
6
|
import type { ZrxFees, ZrxPriceResponse } from '../types.js';
|
|
7
7
|
export declare const assetIdToZrxToken: (assetId: AssetId) => string;
|
|
8
8
|
export declare const zrxTokenToAssetId: (token: string, chainId: ChainId) => AssetId;
|
|
9
|
-
export declare const isSupportedChainId: (chainId: ChainId) => chainId is KnownChainIds.EthereumMainnet | KnownChainIds.AvalancheMainnet | KnownChainIds.OptimismMainnet | KnownChainIds.BnbSmartChainMainnet | KnownChainIds.PolygonMainnet | KnownChainIds.ArbitrumMainnet | KnownChainIds.BaseMainnet;
|
|
9
|
+
export declare const isSupportedChainId: (chainId: ChainId) => chainId is KnownChainIds.EthereumMainnet | KnownChainIds.AvalancheMainnet | KnownChainIds.OptimismMainnet | KnownChainIds.BnbSmartChainMainnet | KnownChainIds.PolygonMainnet | KnownChainIds.ArbitrumMainnet | KnownChainIds.BaseMainnet | KnownChainIds.RobinhoodMainnet;
|
|
10
10
|
export declare const isWrappedNativeSell: (route: ZrxPriceResponse['route']) => boolean;
|
|
11
11
|
export declare const assertValidTrade: ({ buyAsset, sellAsset, }: {
|
|
12
12
|
buyAsset: Asset;
|
|
@@ -56,6 +56,11 @@ export const zrxTokenToAssetId = (token, chainId) => {
|
|
|
56
56
|
assetReference: ASSET_REFERENCE.Base,
|
|
57
57
|
assetNamespace: ASSET_NAMESPACE.slip44,
|
|
58
58
|
};
|
|
59
|
+
case KnownChainIds.RobinhoodMainnet:
|
|
60
|
+
return {
|
|
61
|
+
assetReference: ASSET_REFERENCE.Robinhood,
|
|
62
|
+
assetNamespace: ASSET_NAMESPACE.slip44,
|
|
63
|
+
};
|
|
59
64
|
default:
|
|
60
65
|
throw Error(`chainId '${chainId}' not supported`);
|
|
61
66
|
}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -49,11 +49,13 @@ export type SwapperConfig = {
|
|
|
49
49
|
VITE_CHAINFLIP_API_URL: string;
|
|
50
50
|
VITE_FEATURE_CHAINFLIP_SWAP_DCA: boolean;
|
|
51
51
|
VITE_RELAY_API_URL: string;
|
|
52
|
+
VITE_RELAY_API_KEY: string;
|
|
52
53
|
VITE_BEBOP_API_KEY: string;
|
|
53
54
|
VITE_NEAR_INTENTS_API_KEY: string;
|
|
54
55
|
VITE_SUI_NODE_URL: string;
|
|
55
56
|
VITE_ACROSS_API_URL: string;
|
|
56
57
|
VITE_ACROSS_INTEGRATOR_ID: string;
|
|
58
|
+
VITE_ACROSS_API_KEY: string;
|
|
57
59
|
VITE_DEBRIDGE_API_URL: string;
|
|
58
60
|
VITE_BOB_GATEWAY_API_KEY: string;
|
|
59
61
|
};
|
|
@@ -439,6 +441,7 @@ export type TradeQuote = TradeQuoteBase & {
|
|
|
439
441
|
} & {
|
|
440
442
|
quoteOrRate: 'quote';
|
|
441
443
|
receiveAddress: string;
|
|
444
|
+
deadline: number;
|
|
442
445
|
};
|
|
443
446
|
export type MultiHopTradeQuote = TradeQuote & {
|
|
444
447
|
steps: MultiHopTradeQuoteSteps;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { AssetId, ChainId } from '@shapeshiftoss/caip';
|
|
2
|
+
export declare const FALLBACK_QUOTE_DEADLINE_MS = 60000;
|
|
3
|
+
export declare const normalizeEpochToMs: (value: number) => number;
|
|
2
4
|
export declare const isNativeEvmAsset: (assetId: AssetId) => boolean;
|
|
3
5
|
export declare const getTreasuryAddressFromChainId: (chainId: ChainId) => string;
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { arbitrumAssetId, avalancheAssetId, baseAssetId, bscAssetId, ethAssetId, fromAssetId, gnosisAssetId, katanaAssetId, monadAssetId, optimismAssetId, plasmaAssetId, polygonAssetId, } from '@shapeshiftoss/caip';
|
|
2
2
|
import { KnownChainIds } from '@shapeshiftoss/types';
|
|
3
3
|
import { DAO_TREASURY_ARBITRUM, DAO_TREASURY_AVALANCHE, DAO_TREASURY_BASE, DAO_TREASURY_BITCOIN, DAO_TREASURY_BOB, DAO_TREASURY_BSC, DAO_TREASURY_ETHEREUM_MAINNET, DAO_TREASURY_GNOSIS, DAO_TREASURY_HYPEREVM, DAO_TREASURY_MONAD, DAO_TREASURY_OPTIMISM, DAO_TREASURY_POLYGON, DAO_TREASURY_SOLANA, DAO_TREASURY_STARKNET, DAO_TREASURY_TON, isTreasuryChainId, } from '@shapeshiftoss/utils';
|
|
4
|
+
// Deadline for providers without their own expiry - short enough to keep priced amounts honest
|
|
5
|
+
export const FALLBACK_QUOTE_DEADLINE_MS = 60_000;
|
|
6
|
+
// Bands are unambiguous for any realistic date: unix s land ~2e9, ms ~2e12, µs ~2e15, ns ~2e18
|
|
7
|
+
export const normalizeEpochToMs = (value) => {
|
|
8
|
+
if (value < 1e12)
|
|
9
|
+
return value * 1000;
|
|
10
|
+
if (value < 1e15)
|
|
11
|
+
return value;
|
|
12
|
+
if (value < 1e18)
|
|
13
|
+
return Math.floor(value / 1000);
|
|
14
|
+
return Math.floor(value / 1e6);
|
|
15
|
+
};
|
|
4
16
|
export const isNativeEvmAsset = (assetId) => {
|
|
5
17
|
const { chainId } = fromAssetId(assetId);
|
|
6
18
|
switch (chainId) {
|
|
@@ -2,7 +2,7 @@ import { thorchainChainId } from '@shapeshiftoss/caip';
|
|
|
2
2
|
import { KnownChainIds } from '@shapeshiftoss/types';
|
|
3
3
|
import { treasuryChainIds } from '@shapeshiftoss/utils';
|
|
4
4
|
import { describe, expect, it } from 'vitest';
|
|
5
|
-
import { getTreasuryAddressFromChainId } from './helpers.js';
|
|
5
|
+
import { getTreasuryAddressFromChainId, normalizeEpochToMs } from './helpers.js';
|
|
6
6
|
describe('getTreasuryAddressFromChainId', () => {
|
|
7
7
|
// Affiliate and fee recipient addresses for every swapper flow through here, so pin the values
|
|
8
8
|
// rather than the wiring - a chain pointing at another chain's treasury misroutes revenue silently
|
|
@@ -30,3 +30,20 @@ describe('getTreasuryAddressFromChainId', () => {
|
|
|
30
30
|
expect(() => getTreasuryAddressFromChainId(thorchainChainId)).toThrow('[getTreasuryAddressFromChainId] - Unsupported chainId');
|
|
31
31
|
});
|
|
32
32
|
});
|
|
33
|
+
describe('normalizeEpochToMs', () => {
|
|
34
|
+
// 2026-08-05T00:00:00Z expressed in each unit
|
|
35
|
+
const epochS = 1785888000;
|
|
36
|
+
const epochMs = epochS * 1000;
|
|
37
|
+
it('converts unix seconds to ms', () => {
|
|
38
|
+
expect(normalizeEpochToMs(epochS)).toBe(epochMs);
|
|
39
|
+
});
|
|
40
|
+
it('passes milliseconds through', () => {
|
|
41
|
+
expect(normalizeEpochToMs(epochMs)).toBe(epochMs);
|
|
42
|
+
});
|
|
43
|
+
it('converts microseconds to ms', () => {
|
|
44
|
+
expect(normalizeEpochToMs(epochMs * 1000)).toBe(epochMs);
|
|
45
|
+
});
|
|
46
|
+
it('converts nanoseconds to ms', () => {
|
|
47
|
+
expect(normalizeEpochToMs(epochMs * 1e6)).toBe(epochMs);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Err, Ok } from '@sniptt/monads';
|
|
2
2
|
import { assertQuoteAddresses, makeTradeStepBuildFailedErr } from '../../utils/index.js';
|
|
3
|
+
import { normalizeEpochToMs } from '../helpers.js';
|
|
3
4
|
import { getLimitWithManualSlippage } from './getLimitWithManualSlippage/getLimitWithManualSlippage.js';
|
|
4
5
|
import { getSuccessfulTrades, getThorL1TradeContexts } from './getThorL1TradeContexts.js';
|
|
5
6
|
import { getThorStepData } from './getThorStepData.js';
|
|
@@ -50,6 +51,8 @@ export const getThorL1TradeQuote = async (input, deps, streamingInterval, tradeT
|
|
|
50
51
|
const quote = {
|
|
51
52
|
...tradeCommon,
|
|
52
53
|
quoteOrRate: 'quote',
|
|
54
|
+
// The daemon quote expiry scopes the inbound address - sending later risks a rotated vault
|
|
55
|
+
deadline: normalizeEpochToMs(tradeCommon.expiry),
|
|
53
56
|
memo,
|
|
54
57
|
receiveAddress,
|
|
55
58
|
data,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshiftoss/swapper",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "19.0.0",
|
|
4
4
|
"repository": "https://github.com/shapeshift/web",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -49,14 +49,14 @@
|
|
|
49
49
|
"qs": "^6.14.2",
|
|
50
50
|
"retry-axios": "^2.6.0",
|
|
51
51
|
"uuid": "^9.0.0",
|
|
52
|
-
"viem": "2.
|
|
52
|
+
"viem": "2.55.11",
|
|
53
53
|
"@shapeshiftoss/caip": "^8.16.10",
|
|
54
|
-
"@shapeshiftoss/chain-adapters": "^11.5.0",
|
|
55
|
-
"@shapeshiftoss/contracts": "^1.0.7",
|
|
56
54
|
"@shapeshiftoss/hdwallet-core": "^1.62.41",
|
|
57
55
|
"@shapeshiftoss/types": "^9.0.0",
|
|
58
56
|
"@shapeshiftoss/unchained-client": "^10.14.11",
|
|
59
|
-
"@shapeshiftoss/
|
|
57
|
+
"@shapeshiftoss/contracts": "^1.0.7",
|
|
58
|
+
"@shapeshiftoss/utils": "^1.1.0",
|
|
59
|
+
"@shapeshiftoss/chain-adapters": "^11.5.1"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/lodash": "^4.14.178",
|