@openocean.finance/widget 1.0.28 → 1.0.29

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.
Files changed (110) hide show
  1. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js +46 -39
  2. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js.map +1 -1
  3. package/dist/esm/components/Messages/WarningMessages.js +2 -2
  4. package/dist/esm/components/Messages/WarningMessages.js.map +1 -1
  5. package/dist/esm/components/Step/Step.js +37 -29
  6. package/dist/esm/components/Step/Step.js.map +1 -1
  7. package/dist/esm/components/TransactionDetails.js +2 -5
  8. package/dist/esm/components/TransactionDetails.js.map +1 -1
  9. package/dist/esm/config/version.d.ts +1 -1
  10. package/dist/esm/config/version.js +1 -1
  11. package/dist/esm/cross/adapters/AcrossAdapter.d.ts +15 -0
  12. package/dist/esm/cross/adapters/AcrossAdapter.js +166 -0
  13. package/dist/esm/cross/adapters/AcrossAdapter.js.map +1 -0
  14. package/dist/esm/cross/adapters/BaseSwapAdapter.d.ts +107 -0
  15. package/dist/esm/cross/adapters/BaseSwapAdapter.js +44 -0
  16. package/dist/esm/cross/adapters/BaseSwapAdapter.js.map +1 -0
  17. package/dist/esm/cross/adapters/DebridgeAdapter.d.ts +20 -0
  18. package/dist/esm/cross/adapters/DebridgeAdapter.js +264 -0
  19. package/dist/esm/cross/adapters/DebridgeAdapter.js.map +1 -0
  20. package/dist/esm/cross/adapters/LifiAdapter.d.ts +19 -0
  21. package/dist/esm/cross/adapters/LifiAdapter.js +169 -0
  22. package/dist/esm/cross/adapters/LifiAdapter.js.map +1 -0
  23. package/dist/esm/cross/adapters/MayanAdapter.d.ts +14 -0
  24. package/dist/esm/cross/adapters/MayanAdapter.js +119 -0
  25. package/dist/esm/cross/adapters/MayanAdapter.js.map +1 -0
  26. package/dist/esm/cross/adapters/NearIntentsAdapter.d.ts +21 -0
  27. package/dist/esm/cross/adapters/NearIntentsAdapter.js +425 -0
  28. package/dist/esm/cross/adapters/NearIntentsAdapter.js.map +1 -0
  29. package/dist/esm/cross/adapters/OptimexAdapter.d.ts +19 -0
  30. package/dist/esm/cross/adapters/OptimexAdapter.js +216 -0
  31. package/dist/esm/cross/adapters/OptimexAdapter.js.map +1 -0
  32. package/dist/esm/cross/adapters/OrbiterAdapter.d.ts +20 -0
  33. package/dist/esm/cross/adapters/OrbiterAdapter.js +213 -0
  34. package/dist/esm/cross/adapters/OrbiterAdapter.js.map +1 -0
  35. package/dist/esm/cross/adapters/RelayAdapter.d.ts +14 -0
  36. package/dist/esm/cross/adapters/RelayAdapter.js +171 -0
  37. package/dist/esm/cross/adapters/RelayAdapter.js.map +1 -0
  38. package/dist/esm/cross/adapters/SymbiosisAdapter.d.ts +14 -0
  39. package/dist/esm/cross/adapters/SymbiosisAdapter.js +120 -0
  40. package/dist/esm/cross/adapters/SymbiosisAdapter.js.map +1 -0
  41. package/dist/esm/cross/adapters/XYFinanceAdapter.d.ts +14 -0
  42. package/dist/esm/cross/adapters/XYFinanceAdapter.js +177 -0
  43. package/dist/esm/cross/adapters/XYFinanceAdapter.js.map +1 -0
  44. package/dist/esm/cross/adapters/index.d.ts +2 -0
  45. package/dist/esm/cross/adapters/index.js +10 -0
  46. package/dist/esm/cross/adapters/index.js.map +1 -0
  47. package/dist/esm/cross/constants/index.d.ts +202 -0
  48. package/dist/esm/cross/constants/index.js +183 -0
  49. package/dist/esm/cross/constants/index.js.map +1 -0
  50. package/dist/esm/cross/crossChainQuote.d.ts +25 -0
  51. package/dist/esm/cross/crossChainQuote.js +127 -0
  52. package/dist/esm/cross/crossChainQuote.js.map +1 -0
  53. package/dist/esm/cross/factory.d.ts +9 -0
  54. package/dist/esm/cross/factory.js +125 -0
  55. package/dist/esm/cross/factory.js.map +1 -0
  56. package/dist/esm/cross/registry.d.ts +12 -0
  57. package/dist/esm/cross/registry.js +52 -0
  58. package/dist/esm/cross/registry.js.map +1 -0
  59. package/dist/esm/hooks/useChain.d.ts +1 -1
  60. package/dist/esm/hooks/useGasRefuel.d.ts +1 -1
  61. package/dist/esm/hooks/useGasSufficiencyBridge.js +1 -2
  62. package/dist/esm/hooks/useGasSufficiencyBridge.js.map +1 -1
  63. package/dist/esm/hooks/useRouteExecution.js +2 -1
  64. package/dist/esm/hooks/useRouteExecution.js.map +1 -1
  65. package/dist/esm/hooks/useRoutes.js +50 -32
  66. package/dist/esm/hooks/useRoutes.js.map +1 -1
  67. package/dist/esm/hooks/useSettingMonitor.js +1 -0
  68. package/dist/esm/hooks/useSettingMonitor.js.map +1 -1
  69. package/dist/esm/hooks/useTokenAddressBalance.d.ts +1 -1
  70. package/dist/esm/hooks/useTokenPrice.js +4 -2
  71. package/dist/esm/hooks/useTokenPrice.js.map +1 -1
  72. package/dist/esm/hooks/useTokens.d.ts +1 -1
  73. package/dist/esm/services/ExecuteRoute.js +142 -124
  74. package/dist/esm/services/ExecuteRoute.js.map +1 -1
  75. package/dist/esm/stores/form/useFieldController.d.ts +1 -1
  76. package/dist/esm/stores/routes/createRouteExecutionStore.js +6 -3
  77. package/dist/esm/stores/routes/createRouteExecutionStore.js.map +1 -1
  78. package/dist/esm/stores/routes/useSetExecutableRoute.d.ts +1 -1
  79. package/dist/esm/types/widget.d.ts +3 -0
  80. package/dist/tsconfig.tsbuildinfo +1 -0
  81. package/package.json +14 -4
  82. package/src/components/AmountInput/AmountInputEndAdornment.tsx +46 -46
  83. package/src/components/Messages/WarningMessages.tsx +7 -2
  84. package/src/components/Step/Step.tsx +37 -31
  85. package/src/components/TransactionDetails.tsx +10 -11
  86. package/src/config/version.ts +1 -1
  87. package/src/cross/adapters/AcrossAdapter.ts +193 -0
  88. package/src/cross/adapters/BaseSwapAdapter.ts +173 -0
  89. package/src/cross/adapters/DebridgeAdapter.ts +375 -0
  90. package/src/cross/adapters/LifiAdapter.ts +213 -0
  91. package/src/cross/adapters/MayanAdapter.ts +179 -0
  92. package/src/cross/adapters/NearIntentsAdapter.ts +539 -0
  93. package/src/cross/adapters/OptimexAdapter.ts +273 -0
  94. package/src/cross/adapters/OrbiterAdapter.ts +270 -0
  95. package/src/cross/adapters/RelayAdapter.ts +248 -0
  96. package/src/cross/adapters/SymbiosisAdapter.ts +144 -0
  97. package/src/cross/adapters/XYFinanceAdapter.ts +213 -0
  98. package/src/cross/adapters/index.ts +9 -0
  99. package/src/cross/constants/index.ts +223 -0
  100. package/src/cross/crossChainQuote.ts +181 -0
  101. package/src/cross/factory.ts +145 -0
  102. package/src/cross/registry.ts +65 -0
  103. package/src/hooks/useGasSufficiencyBridge.ts +1 -3
  104. package/src/hooks/useRouteExecution.ts +2 -1
  105. package/src/hooks/useRoutes.ts +64 -43
  106. package/src/hooks/useSettingMonitor.ts +1 -1
  107. package/src/hooks/useTokenPrice.ts +5 -3
  108. package/src/services/ExecuteRoute.ts +184 -171
  109. package/src/stores/routes/createRouteExecutionStore.ts +13 -4
  110. package/src/types/widget.ts +3 -0
@@ -0,0 +1,248 @@
1
+ import {
2
+ MAINNET_RELAY_API,
3
+ type RelayChain,
4
+ convertViemChainToRelayChain,
5
+ createClient,
6
+ getClient,
7
+ } from '@reservoir0x/relay-sdk'
8
+ import { type WalletClient, formatUnits } from 'viem'
9
+ import {
10
+ arbitrum,
11
+ avalanche,
12
+ base,
13
+ berachain,
14
+ blast,
15
+ bsc,
16
+ fantom,
17
+ linea,
18
+ mainnet,
19
+ mantle,
20
+ optimism,
21
+ polygon,
22
+ ronin,
23
+ scroll,
24
+ sonic,
25
+ unichain,
26
+ zksync,
27
+ } from 'viem/chains'
28
+ import type { Currency } from '../constants/index.js'
29
+
30
+ import {
31
+ CROSS_CHAIN_FEE_RECEIVER,
32
+ CROSS_CHAIN_FEE_RECEIVER_SOLANA,
33
+ MAINNET_NETWORKS,
34
+ type SolanaToken,
35
+ ZERO_ADDRESS,
36
+ } from '../constants/index.js'
37
+
38
+ import type { Quote } from '../registry.js'
39
+ import {
40
+ BaseSwapAdapter,
41
+ type Chain,
42
+ NOT_SUPPORTED_CHAINS_PRICE_SERVICE,
43
+ NonEvmChain,
44
+ type NormalizedQuote,
45
+ type NormalizedTxResponse,
46
+ type QuoteParams,
47
+ type SwapStatus,
48
+ } from './BaseSwapAdapter.js'
49
+
50
+ const SolanaChainId = 792703809
51
+
52
+ const solanaChain = {
53
+ id: SolanaChainId,
54
+ name: 'Solana',
55
+ displayName: 'Solana',
56
+ vmType: 'svm' as const,
57
+ } as RelayChain
58
+
59
+ export class RelayAdapter extends BaseSwapAdapter {
60
+ constructor() {
61
+ super()
62
+ createClient({
63
+ baseApiUrl: MAINNET_RELAY_API,
64
+ source: 'openocean',
65
+ chains: [
66
+ arbitrum,
67
+ avalanche,
68
+ base,
69
+ berachain,
70
+ blast,
71
+ bsc,
72
+ fantom,
73
+ linea,
74
+ mainnet,
75
+ mantle,
76
+ optimism,
77
+ polygon,
78
+ scroll,
79
+ sonic,
80
+ zksync,
81
+ ronin,
82
+ unichain,
83
+ ]
84
+ .map(convertViemChainToRelayChain)
85
+ .concat(solanaChain as any),
86
+ })
87
+ }
88
+
89
+ getName(): string {
90
+ return 'Relay'
91
+ }
92
+ getIcon(): string {
93
+ return 'https://storage.googleapis.com/ks-setting-1d682dca/84e906bb-eaeb-45d3-a64c-2aa9c84eb3ea1747759080942.png'
94
+ }
95
+ getSupportedChains(): Chain[] {
96
+ return [NonEvmChain.Solana, ...MAINNET_NETWORKS]
97
+ }
98
+
99
+ getSupportedTokens(_sourceChain: Chain, _destChain: Chain): Currency[] {
100
+ return []
101
+ }
102
+
103
+ async getQuote(params: QuoteParams): Promise<NormalizedQuote> {
104
+ const evmFromToken = params.fromToken as Currency
105
+ const evmToToken = params.toToken as Currency
106
+ const currency =
107
+ params.fromChain === 'solana'
108
+ ? (params.fromToken as SolanaToken).id
109
+ : evmFromToken.isNative
110
+ ? ZERO_ADDRESS
111
+ : evmFromToken.address
112
+
113
+ const toCurrency =
114
+ params.toChain === 'solana'
115
+ ? (params.toToken as SolanaToken).id
116
+ : evmToToken.isNative
117
+ ? ZERO_ADDRESS
118
+ : evmToToken.address
119
+
120
+ const resp = await getClient().actions.getQuote({
121
+ chainId:
122
+ params.fromChain === 'solana' ? SolanaChainId : +params.fromChain,
123
+ toChainId: params.toChain === 'solana' ? SolanaChainId : +params.toChain,
124
+ currency,
125
+ toCurrency,
126
+ amount: params.amount,
127
+ tradeType: 'EXACT_INPUT',
128
+ wallet: params.walletClient,
129
+ recipient: params.recipient,
130
+ user: params.sender,
131
+ options: {
132
+ appFees: [
133
+ {
134
+ recipient: params.fromChain === 'solana' ? CROSS_CHAIN_FEE_RECEIVER_SOLANA : CROSS_CHAIN_FEE_RECEIVER,
135
+ fee: params.feeBps.toString(),
136
+ },
137
+ ],
138
+ // includedSwapSources: ['open-ocean'],
139
+ },
140
+ })
141
+
142
+ const formattedOutputAmount = formatUnits(
143
+ BigInt(resp.details?.currencyOut?.amount || '0'),
144
+ params.toToken.decimals
145
+ )
146
+ const formattedInputAmount = formatUnits(
147
+ BigInt(params.amount),
148
+ params.fromToken.decimals
149
+ )
150
+ const inputUsd = NOT_SUPPORTED_CHAINS_PRICE_SERVICE.includes(
151
+ params.fromChain
152
+ )
153
+ ? Number(resp.details?.currencyIn?.amountUsd || 0)
154
+ : params.tokenInUsd * +formattedInputAmount
155
+ const outputUsd = NOT_SUPPORTED_CHAINS_PRICE_SERVICE.includes(
156
+ params.toChain
157
+ )
158
+ ? Number(resp.details?.currencyOut?.amountUsd || 0)
159
+ : params.tokenOutUsd * +formattedOutputAmount
160
+ if (params.walletClient) {
161
+ params.walletClient = {
162
+ account: {
163
+ address: params.sender,
164
+ },
165
+ } as any
166
+ }
167
+ const protocolFee: any = resp.fees?.relayer?.amountUsd || 0
168
+
169
+ return {
170
+ quoteParams: params,
171
+ outputAmount: BigInt(resp.details?.currencyOut?.amount || '0'),
172
+ formattedOutputAmount,
173
+ inputUsd,
174
+ outputUsd,
175
+ priceImpact:
176
+ !inputUsd || !outputUsd
177
+ ? Number.NaN
178
+ : ((inputUsd - outputUsd) * 100) / inputUsd,
179
+ //rate: Number(resp.details?.rate || 0),
180
+ rate: +formattedOutputAmount / +formattedInputAmount,
181
+ gasFeeUsd: Number(resp.fees?.gas?.amountUsd || 0),
182
+ timeEstimate: resp.details?.timeEstimate || 0,
183
+ // Relay dont need to approve, we send token to contract directly
184
+ contractAddress: ZERO_ADDRESS,
185
+ rawQuote: resp,
186
+ protocolFee: protocolFee,
187
+ platformFeePercent: (params.feeBps * 100) / 10000,
188
+ }
189
+ }
190
+
191
+ async executeSwap(
192
+ { quote }: Quote,
193
+ walletClient: WalletClient
194
+ ): Promise<NormalizedTxResponse> {
195
+ return new Promise<NormalizedTxResponse>((resolve, reject) => {
196
+ getClient()
197
+ .actions.execute({
198
+ quote: quote.rawQuote,
199
+ wallet: walletClient,
200
+ onProgress: ({ currentStep }) => {
201
+ if (
202
+ currentStep?.id === 'deposit' &&
203
+ currentStep.requestId &&
204
+ currentStep.kind === 'transaction'
205
+ ) {
206
+ const txHash = currentStep.items?.[0]?.txHashes?.[0].txHash
207
+ if (txHash) {
208
+ resolve({
209
+ sender: quote.quoteParams.sender,
210
+ sourceTxHash: txHash,
211
+ adapter: this.getName(),
212
+ id: currentStep.requestId,
213
+ sourceChain: quote.quoteParams.fromChain,
214
+ targetChain: quote.quoteParams.toChain,
215
+ inputAmount: quote.quoteParams.amount,
216
+ outputAmount: quote.outputAmount.toString(),
217
+ sourceToken: quote.quoteParams.fromToken,
218
+ targetToken: quote.quoteParams.toToken,
219
+ timestamp: new Date().getTime(),
220
+ })
221
+ }
222
+ }
223
+ },
224
+ })
225
+ .catch((e) => {
226
+ reject(e) // Make sure errors from execute are also caught
227
+ })
228
+ })
229
+ }
230
+
231
+ async getTransactionStatus(p: NormalizedTxResponse): Promise<SwapStatus> {
232
+ const res = await fetch(
233
+ `https://api.relay.link/intents/status/v2?requestId=${p.id}`
234
+ ).then((r) => r.json())
235
+
236
+ return {
237
+ txHash: res.txHashes?.[0] || '',
238
+ status:
239
+ res.status === 'success'
240
+ ? 'Success'
241
+ : res.status === 'refund'
242
+ ? 'Refunded'
243
+ : res.status === 'failure'
244
+ ? 'Failed'
245
+ : 'Processing',
246
+ }
247
+ }
248
+ }
@@ -0,0 +1,144 @@
1
+ import { ChainId } from '@openocean.finance/widget-sdk'
2
+ import { Currency } from '../constants/index.js'
3
+
4
+ import { WalletClient, formatUnits } from 'viem'
5
+
6
+ import { ZERO_ADDRESS } from '../constants/index.js'
7
+
8
+ import { Quote } from '../registry.js'
9
+ import {
10
+ BaseSwapAdapter,
11
+ Chain,
12
+ EvmQuoteParams,
13
+ NormalizedQuote,
14
+ NormalizedTxResponse,
15
+ SwapStatus,
16
+ } from './BaseSwapAdapter.js'
17
+
18
+ const SYMBIOSIS_API = 'https://api.symbiosis.finance/crosschain/v1'
19
+
20
+ export class SymbiosisAdapter extends BaseSwapAdapter {
21
+ constructor() {
22
+ super()
23
+ }
24
+
25
+ getName(): string {
26
+ return 'Symbiosis'
27
+ }
28
+ getIcon(): string {
29
+ return 'https://app.symbiosis.finance/images/favicon-32x32.png'
30
+ }
31
+ getSupportedChains(): Chain[] {
32
+ return [
33
+ ChainId.MAINNET,
34
+ ChainId.BSCMAINNET,
35
+ ChainId.MATIC,
36
+ ChainId.AVAXMAINNET,
37
+ ChainId.ZKSYNC,
38
+ ChainId.ARBITRUM,
39
+ ChainId.OPTIMISM,
40
+ ChainId.LINEA,
41
+ ChainId.MANTLE,
42
+ ChainId.BASE,
43
+ ChainId.SCROLL,
44
+ ChainId.BLAST,
45
+ ChainId.SONIC,
46
+ ChainId.BERA,
47
+ ]
48
+ }
49
+
50
+ getSupportedTokens(_sourceChain: Chain, _destChain: Chain): Currency[] {
51
+ return []
52
+ }
53
+
54
+ async getQuote(params: EvmQuoteParams): Promise<NormalizedQuote> {
55
+ const body = {
56
+ tokenAmountIn: {
57
+ address: params.fromToken.isNative ? '' : params.fromToken.address,
58
+ amount: params.amount,
59
+ chainId: params.fromChain,
60
+ decimals: params.fromToken.decimals,
61
+ },
62
+ tokenOut: {
63
+ chainId: params.toChain,
64
+ address: params.toToken.isNative ? '' : params.toToken.address,
65
+ symbol: params.toToken.symbol,
66
+ decimals: params.toToken.decimals,
67
+ },
68
+ from: params.sender,
69
+ to: params.recipient,
70
+ slippage: params.slippage,
71
+ }
72
+
73
+ const res = await fetch(`${SYMBIOSIS_API}/swap`, {
74
+ method: 'POST',
75
+ headers: {
76
+ 'Content-Type': 'application/json',
77
+ },
78
+ body: JSON.stringify(body),
79
+ }).then(r => r.json())
80
+
81
+ if (!res.tx) throw new Error('No route found')
82
+
83
+ const formattedOutputAmount = formatUnits(BigInt(res.tokenAmountOut.amount), params.toToken.decimals)
84
+ const formattedInputAmount = formatUnits(BigInt(params.amount), params.fromToken.decimals)
85
+
86
+ const tokenInUsd = params.tokenInUsd
87
+ const tokenOutUsd = params.tokenOutUsd
88
+
89
+ const inputUsd = tokenInUsd * +formattedInputAmount
90
+ const outputUsd = tokenOutUsd * +formattedOutputAmount
91
+
92
+ return {
93
+ quoteParams: params,
94
+ outputAmount: BigInt(res.tokenAmountOut.amount),
95
+ formattedOutputAmount,
96
+ inputUsd,
97
+ outputUsd,
98
+ priceImpact: !inputUsd || !outputUsd ? NaN : ((inputUsd - outputUsd) * 100) / inputUsd,
99
+ rate: +formattedOutputAmount / +formattedInputAmount,
100
+ gasFeeUsd: 0,
101
+ timeEstimate: res.estimatedTime,
102
+ contractAddress: res.approveTo || ZERO_ADDRESS,
103
+ rawQuote: res,
104
+
105
+ // TODO: add Fee
106
+ protocolFee: 0,
107
+ platformFeePercent: 0,
108
+ }
109
+ }
110
+
111
+ async executeSwap({ quote }: Quote, walletClient: WalletClient): Promise<NormalizedTxResponse> {
112
+ const account = walletClient.account?.address
113
+ if (!account) throw new Error('WalletClient account is not defined')
114
+
115
+ const tx = await walletClient.sendTransaction({
116
+ chain: undefined,
117
+ account,
118
+ to: quote.rawQuote.tx.to,
119
+ value: BigInt(quote.rawQuote.tx.value),
120
+ data: quote.rawQuote.tx.data,
121
+ })
122
+ return {
123
+ sender: quote.quoteParams.sender,
124
+ id: tx, // specific id for each provider
125
+ sourceTxHash: tx,
126
+ adapter: this.getName(),
127
+ sourceChain: quote.quoteParams.fromChain,
128
+ targetChain: quote.quoteParams.toChain,
129
+ inputAmount: quote.quoteParams.amount,
130
+ outputAmount: quote.outputAmount.toString(),
131
+ sourceToken: quote.quoteParams.fromToken,
132
+ targetToken: quote.quoteParams.toToken,
133
+ timestamp: new Date().getTime(),
134
+ }
135
+ }
136
+
137
+ async getTransactionStatus(p: NormalizedTxResponse): Promise<SwapStatus> {
138
+ const res = await fetch(`${SYMBIOSIS_API}/tx/${p.sourceChain}/${p.sourceTxHash}`).then(r => r.json())
139
+ return {
140
+ txHash: res?.tx?.hash || '',
141
+ status: res.status.code === 0 ? 'Success' : res.status.code === 3 ? 'Failed' : 'Processing',
142
+ }
143
+ }
144
+ }
@@ -0,0 +1,213 @@
1
+ import { ChainId } from '@openocean.finance/widget-sdk'
2
+ import { Currency } from '../constants/index.js'
3
+ import { getPublicClient } from '@wagmi/core'
4
+ import { WalletClient, formatUnits } from 'viem'
5
+ import { useConfig } from 'wagmi'
6
+
7
+ import { CROSS_CHAIN_FEE_RECEIVER, ETHER_ADDRESS } from '../constants/index.js'
8
+
9
+ import { Quote } from '../registry.js'
10
+ import {
11
+ BaseSwapAdapter,
12
+ Chain,
13
+ EvmQuoteParams,
14
+ NOT_SUPPORTED_CHAINS_PRICE_SERVICE,
15
+ NormalizedQuote,
16
+ NormalizedTxResponse,
17
+ SwapStatus,
18
+ } from './BaseSwapAdapter.js'
19
+
20
+ const XY_FINANCE_API = 'https://aggregator-api.xy.finance/v1'
21
+
22
+ export class XYFinanceAdapter extends BaseSwapAdapter {
23
+ constructor() {
24
+ super()
25
+ }
26
+
27
+ getName(): string {
28
+ return 'XYFinance'
29
+ }
30
+ getIcon(): string {
31
+ return 'https://xy.finance/img/favicon.ico'
32
+ }
33
+ getSupportedChains(): Chain[] {
34
+ return [
35
+ ChainId.MAINNET,
36
+ ChainId.BSCMAINNET,
37
+ ChainId.MATIC,
38
+ ChainId.FANTOM,
39
+ ChainId.AVAXMAINNET,
40
+ ChainId.ARBITRUM,
41
+ ChainId.OPTIMISM,
42
+ ChainId.ZKSYNC,
43
+ ChainId.LINEA,
44
+ ChainId.BASE,
45
+ ChainId.MANTLE,
46
+ ChainId.SCROLL,
47
+ ChainId.BLAST,
48
+ ChainId.BERA,
49
+ ChainId.SONIC,
50
+ ChainId.UNICHAIN,
51
+ ]
52
+ }
53
+
54
+ getSupportedTokens(_sourceChain: Chain, _destChain: Chain): Currency[] {
55
+ return []
56
+ }
57
+
58
+ async getQuote(params: EvmQuoteParams): Promise<NormalizedQuote> {
59
+ const p = {
60
+ srcChainId: params.fromChain,
61
+ srcQuoteTokenAddress: params.fromToken.isNative ? ETHER_ADDRESS : params.fromToken.address,
62
+ srcQuoteTokenAmount: params.amount,
63
+ dstChainId: params.toChain,
64
+ dstQuoteTokenAddress: params.toToken.isNative ? ETHER_ADDRESS : params.toToken.address,
65
+ slippage: (params.slippage * 100) / 10_000,
66
+ srcSwapProviders: 'KyberSwap V1 DexAggregator',
67
+
68
+ // bridgeProviders: 'yBridge',
69
+
70
+ affiliate: CROSS_CHAIN_FEE_RECEIVER,
71
+ //represents the fee you wish to collect. It is an integer between 0 and 100,000. In this range, 100,000 corresponds to 10%, 10,000 represents 1%, and so on in a similar fashion.
72
+ commissionRate: (params.feeBps / 10_000) * 1_000_000,
73
+ }
74
+ // Convert the parameters object to URL query string
75
+ const queryParams = new URLSearchParams()
76
+ for (const [key, value] of Object.entries(p)) {
77
+ queryParams.append(key, String(value))
78
+ }
79
+ const resp = await fetch(`${XY_FINANCE_API}/quote?${queryParams.toString()}`).then(res => res.json())
80
+ const r = resp?.routes?.sort((a: any, b: any) => {
81
+ return +(BigInt(b.dstQuoteTokenAmount) - BigInt(a.dstQuoteTokenAmount)).toString()
82
+ })?.[0]
83
+
84
+ if (!r) {
85
+ throw new Error('No route found')
86
+ }
87
+
88
+ const formattedOutputAmount = formatUnits(BigInt(r.dstQuoteTokenAmount), params.toToken.decimals)
89
+ const formattedInputAmount = formatUnits(BigInt(params.amount), params.fromToken.decimals)
90
+
91
+ const tokenInUsd = params.tokenInUsd
92
+ const tokenOutUsd = params.tokenOutUsd
93
+ const inputUsd = NOT_SUPPORTED_CHAINS_PRICE_SERVICE.includes(params.fromChain)
94
+ ? Number(r.srcQuoteTokenUsdValue)
95
+ : tokenInUsd * +formattedInputAmount
96
+ const outputUsd = NOT_SUPPORTED_CHAINS_PRICE_SERVICE.includes(params.toChain)
97
+ ? Number(r.dstQuoteTokenUsdValue)
98
+ : tokenOutUsd * +formattedOutputAmount
99
+
100
+ return {
101
+ quoteParams: params,
102
+ outputAmount: BigInt(r.dstQuoteTokenAmount),
103
+ formattedOutputAmount,
104
+ inputUsd,
105
+ outputUsd,
106
+ priceImpact: !inputUsd || !outputUsd ? NaN : ((inputUsd - outputUsd) * 100) / inputUsd,
107
+ rate: +formattedOutputAmount / +formattedInputAmount,
108
+ gasFeeUsd: 0,
109
+ timeEstimate: r.estimatedTransferTime,
110
+ contractAddress: r.contractAddress,
111
+ rawQuote: r,
112
+
113
+ protocolFee: 0,
114
+ platformFeePercent: (params.feeBps * 100) / 10_000,
115
+ }
116
+ }
117
+
118
+ async executeSwap({ quote }: Quote, walletClient: WalletClient): Promise<NormalizedTxResponse> {
119
+ const account = walletClient.account?.address
120
+ if (!account) throw new Error('WalletClient account is not defined')
121
+
122
+ const fromToken = quote.quoteParams.fromToken as Currency
123
+ const toToken = quote.quoteParams.toToken as Currency
124
+ const buildSlippage =
125
+ Math.floor(quote.quoteParams.slippage * 0.9) > 1
126
+ ? Math.floor(quote.quoteParams.slippage * 0.9)
127
+ : quote.quoteParams.slippage
128
+
129
+ const p = {
130
+ srcChainId: quote.quoteParams.fromChain,
131
+ srcQuoteTokenAddress: fromToken.isNative ? ETHER_ADDRESS : fromToken.address,
132
+ srcQuoteTokenAmount: quote.quoteParams.amount,
133
+ dstChainId: quote.quoteParams.toChain,
134
+ dstQuoteTokenAddress: toToken.isNative ? ETHER_ADDRESS : toToken.address,
135
+ // slippage: quote.quoteParams.slippage,
136
+ slippage: (buildSlippage * 100) / 10_000,
137
+ receiver: quote.quoteParams.recipient,
138
+ bridgeProvider: quote.rawQuote.bridgeDescription.provider,
139
+ srcBridgeTokenAddress: quote.rawQuote.bridgeDescription.srcBridgeTokenAddress,
140
+ dstBridgeTokenAddress: quote.rawQuote.bridgeDescription.dstBridgeTokenAddress,
141
+ affiliate: CROSS_CHAIN_FEE_RECEIVER,
142
+ //represents the fee you wish to collect. It is an integer between 0 and 100,000. In this range, 100,000 corresponds to 10%, 10,000 represents 1%, and so on in a similar fashion.
143
+ commissionRate: (quote.quoteParams.feeBps / 10_000) * 1_000_000,
144
+
145
+ ...(quote.rawQuote.srcSwapDescription ? { srcSwapProvider: quote.rawQuote.srcSwapDescription.provider } : {}),
146
+ ...(quote.rawQuote.dstSwapDescription
147
+ ? {
148
+ dstSwapProvider: quote.rawQuote.dstSwapDescription?.provider,
149
+ }
150
+ : {}),
151
+ }
152
+
153
+ // Convert the parameters object to URL query string
154
+ const queryParams = new URLSearchParams()
155
+ for (const [key, value] of Object.entries(p)) {
156
+ queryParams.append(key, String(value))
157
+ }
158
+ const resp = await fetch(`${XY_FINANCE_API}/buildTx?${queryParams.toString()}`).then(res => res.json())
159
+
160
+ if (BigInt(resp.route.minReceiveAmount) < BigInt(quote.rawQuote.minReceiveAmount)) {
161
+ throw new Error('Rate has changed')
162
+ }
163
+
164
+ if (resp.tx) {
165
+ const tx = await walletClient.sendTransaction({
166
+ chain: undefined,
167
+ account,
168
+ to: resp.tx.to,
169
+ value: resp.tx.value,
170
+ data: resp.tx.data,
171
+ })
172
+ return {
173
+ sender: quote.quoteParams.sender,
174
+ id: tx, // specific id for each provider
175
+ sourceTxHash: tx,
176
+ adapter: this.getName(),
177
+ sourceChain: quote.quoteParams.fromChain,
178
+ targetChain: quote.quoteParams.toChain,
179
+ inputAmount: quote.quoteParams.amount,
180
+ outputAmount: quote.outputAmount.toString(),
181
+ sourceToken: fromToken,
182
+ targetToken: toToken,
183
+ timestamp: new Date().getTime(),
184
+ }
185
+ }
186
+
187
+ throw new Error('No transaction found')
188
+ }
189
+
190
+ async getTransactionStatus(p: NormalizedTxResponse): Promise<SwapStatus> {
191
+ const publicClient = getPublicClient(useConfig(), {
192
+ chainId: p.sourceChain as any,
193
+ })
194
+ const receipt = await publicClient?.getTransactionReceipt({
195
+ hash: p.id as `0x${string}`,
196
+ })
197
+ if (receipt.status === 'reverted') {
198
+ return {
199
+ txHash: '',
200
+ status: 'Failed',
201
+ }
202
+ }
203
+
204
+ const res = await fetch(`${XY_FINANCE_API}/crossChainStatus?srcChainId=${p.sourceChain}&srcTxHash=${p.id}`).then(
205
+ r => r.json(),
206
+ )
207
+
208
+ return {
209
+ txHash: res.tx || '',
210
+ status: res.status === 'Done' ? 'Success' : res.status === 'Refunded' ? 'Refunded' : 'Processing',
211
+ }
212
+ }
213
+ }
@@ -0,0 +1,9 @@
1
+ // export * from './BaseSwapAdapter.js'
2
+ // export * from './AcrossAdapter.js'
3
+ export * from './RelayAdapter.js'
4
+ // export * from './XYFinanceAdapter.js'
5
+ export * from './MayanAdapter.js'
6
+ // export * from './SymbiosisAdapter.js'
7
+ // export * from './DebridgeAdapter.js'
8
+ // export * from './LifiAdapter.js'
9
+ // export * from './KyberSwapAdapter.js'