@shapeshiftoss/swap-widget 0.0.2 → 0.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.
Files changed (159) hide show
  1. package/dist/index.d.ts +233 -0
  2. package/dist/index.js +63612 -0
  3. package/dist/style.css +1 -0
  4. package/package.json +69 -18
  5. package/Dockerfile +0 -87
  6. package/dist/assets/PhArrowCircleDown-B305t-Sh.js +0 -14
  7. package/dist/assets/PhArrowClockwise-CJPxQhr_.js +0 -14
  8. package/dist/assets/PhArrowDown-C4hT9BVu.js +0 -14
  9. package/dist/assets/PhArrowLeft-Way4Cu-r.js +0 -14
  10. package/dist/assets/PhArrowRight-Cp5ZME0F.js +0 -14
  11. package/dist/assets/PhArrowSquareOut-NnrK69c5.js +0 -14
  12. package/dist/assets/PhArrowUp-Dph6j8rm.js +0 -14
  13. package/dist/assets/PhArrowUpRight-BpJjRRRh.js +0 -14
  14. package/dist/assets/PhArrowsClockwise-CFUT8X7R.js +0 -14
  15. package/dist/assets/PhArrowsDownUp-BjBI4ckC.js +0 -14
  16. package/dist/assets/PhArrowsLeftRight-CuLpbKRk.js +0 -14
  17. package/dist/assets/PhBank-Dchr4XQJ.js +0 -14
  18. package/dist/assets/PhBrowser-dUu2TrC1.js +0 -14
  19. package/dist/assets/PhCaretDown-78IuKU3V.js +0 -14
  20. package/dist/assets/PhCaretLeft-_aiyH7n1.js +0 -14
  21. package/dist/assets/PhCaretRight-8zJQEuDX.js +0 -14
  22. package/dist/assets/PhCaretUp-CiCxKWwN.js +0 -14
  23. package/dist/assets/PhCheck-CcADx8br.js +0 -14
  24. package/dist/assets/PhCircleHalf-BYzSzd2h.js +0 -14
  25. package/dist/assets/PhClock-UItiXeJq.js +0 -14
  26. package/dist/assets/PhCompass-CUy3uA7t.js +0 -14
  27. package/dist/assets/PhCopy-C-PDgSlZ.js +0 -14
  28. package/dist/assets/PhCreditCard-CWRaUT6F.js +0 -14
  29. package/dist/assets/PhCurrencyDollar-Cqla3AXT.js +0 -14
  30. package/dist/assets/PhDesktop-BBIPrYLl.js +0 -14
  31. package/dist/assets/PhDeviceMobile-BdsPaATg.js +0 -14
  32. package/dist/assets/PhDotsThree-BMXCQl-0.js +0 -14
  33. package/dist/assets/PhEnvelope-yUsis6yU.js +0 -14
  34. package/dist/assets/PhFunnelSimple-Ba7BbWTp.js +0 -14
  35. package/dist/assets/PhGlobe-DgLxBk5U.js +0 -14
  36. package/dist/assets/PhIdentificationCard-Czjmq9Z3.js +0 -14
  37. package/dist/assets/PhImage-BAJ_erz6.js +0 -14
  38. package/dist/assets/PhInfo-Cr4DhVUE.js +0 -14
  39. package/dist/assets/PhLightbulb-BX_7duTr.js +0 -14
  40. package/dist/assets/PhMagnifyingGlass-Mygfryvz.js +0 -14
  41. package/dist/assets/PhPaperPlaneRight-BeuCA660.js +0 -14
  42. package/dist/assets/PhPlus-BMjcHjsT.js +0 -14
  43. package/dist/assets/PhPower-CGffGmdb.js +0 -14
  44. package/dist/assets/PhPuzzlePiece-wm_GpVSi.js +0 -14
  45. package/dist/assets/PhQrCode-DRwRzXCH.js +0 -14
  46. package/dist/assets/PhQuestion-M09j2U0T.js +0 -14
  47. package/dist/assets/PhQuestionMark-BP9EMB6h.js +0 -14
  48. package/dist/assets/PhSealCheck-BfG80yKn.js +0 -14
  49. package/dist/assets/PhSignOut-C5YOWlPT.js +0 -14
  50. package/dist/assets/PhSpinner-BXooDYzU.js +0 -14
  51. package/dist/assets/PhTrash-Biq6rmmL.js +0 -14
  52. package/dist/assets/PhUser-CAgZSpGe.js +0 -14
  53. package/dist/assets/PhVault-l2PHF38a.js +0 -14
  54. package/dist/assets/PhWallet-w25D16It.js +0 -14
  55. package/dist/assets/PhWarning-DPEydIPw.js +0 -14
  56. package/dist/assets/PhWarningCircle-BqjT745H.js +0 -14
  57. package/dist/assets/PhX-s-SmVExa.js +0 -14
  58. package/dist/assets/SwapController-If0bFrNc.js +0 -1
  59. package/dist/assets/ccip-BBB7uCdL.js +0 -1
  60. package/dist/assets/ccip-CkkdfKKI.js +0 -1
  61. package/dist/assets/data-capture-D4gAy-Yc.js +0 -242
  62. package/dist/assets/email-B1AJehis.js +0 -90
  63. package/dist/assets/embedded-wallet-Q6DQopDk.js +0 -410
  64. package/dist/assets/features-B6JAPAFb.js +0 -5
  65. package/dist/assets/index-5jd8RPN9.js +0 -7428
  66. package/dist/assets/index-B4kNtSTk.js +0 -1080
  67. package/dist/assets/index-B753eAob.js +0 -1
  68. package/dist/assets/index-BZoLTv77.js +0 -3
  69. package/dist/assets/index-Bcw9UURX.js +0 -3
  70. package/dist/assets/index-BkrV-ahK.js +0 -2
  71. package/dist/assets/index-CRQzQ_up.js +0 -9
  72. package/dist/assets/index-CSW0Gt5y.js +0 -132
  73. package/dist/assets/index-CZ4jTIsk.js +0 -138
  74. package/dist/assets/index-Cwa8SB3h.js +0 -61
  75. package/dist/assets/index-DEwQgT4r.js +0 -78
  76. package/dist/assets/index-DVfQiQ1d.js +0 -1
  77. package/dist/assets/index-cV3UdaMs.css +0 -1
  78. package/dist/assets/index-hAmu622O.js +0 -43
  79. package/dist/assets/onramp-XcPNCLRU.js +0 -422
  80. package/dist/assets/pay-with-exchange-BeHt4OF4.js +0 -280
  81. package/dist/assets/property-C9JG5tag.js +0 -27
  82. package/dist/assets/receive-7ff4he2S.js +0 -131
  83. package/dist/assets/send-CkMBIRXT.js +0 -554
  84. package/dist/assets/socials-DmmxuLrP.js +0 -250
  85. package/dist/assets/swaps-IHAYRQ0x.js +0 -1050
  86. package/dist/assets/transactions-9Cxdk7o9.js +0 -16
  87. package/dist/assets/v4-BOvFkHkt.js +0 -1
  88. package/dist/assets/w3m-modal-kJzFnBfB.js +0 -891
  89. package/dist/assets/wallet-standard-Dv8LMoUB.js +0 -1
  90. package/dist/favicon.png +0 -0
  91. package/dist/favicon.svg +0 -11
  92. package/dist/icon-192x192.png +0 -0
  93. package/dist/icon-512x512.png +0 -0
  94. package/dist/index.html +0 -33
  95. package/index.html +0 -32
  96. package/public/favicon.png +0 -0
  97. package/public/favicon.svg +0 -11
  98. package/public/icon-192x192.png +0 -0
  99. package/public/icon-512x512.png +0 -0
  100. package/railway.toml +0 -10
  101. package/src/api/client.ts +0 -95
  102. package/src/components/AddressInputModal.css +0 -173
  103. package/src/components/AddressInputModal.tsx +0 -250
  104. package/src/components/ApprovalStep.tsx +0 -92
  105. package/src/components/ExecutionStep.tsx +0 -27
  106. package/src/components/InputStep.tsx +0 -431
  107. package/src/components/QuoteSelector.css +0 -146
  108. package/src/components/QuoteSelector.tsx +0 -137
  109. package/src/components/QuotesModal.css +0 -250
  110. package/src/components/QuotesModal.tsx +0 -182
  111. package/src/components/SettingsModal.css +0 -145
  112. package/src/components/SettingsModal.tsx +0 -180
  113. package/src/components/StatusStep.tsx +0 -139
  114. package/src/components/SwapWidget.css +0 -713
  115. package/src/components/SwapWidget.tsx +0 -607
  116. package/src/components/TokenSelectModal.css +0 -438
  117. package/src/components/TokenSelectModal.tsx +0 -487
  118. package/src/components/WalletProvider.tsx +0 -92
  119. package/src/config/appkit.ts +0 -104
  120. package/src/config/wagmi.ts +0 -27
  121. package/src/constants/chains.ts +0 -72
  122. package/src/constants/defaults.ts +0 -28
  123. package/src/constants/swappers.ts +0 -48
  124. package/src/constants/viemChains.ts +0 -69
  125. package/src/contexts/SwapWalletContext.tsx +0 -25
  126. package/src/demo/App.css +0 -458
  127. package/src/demo/App.tsx +0 -481
  128. package/src/demo/main.tsx +0 -25
  129. package/src/hooks/useAssets.ts +0 -180
  130. package/src/hooks/useBalances.ts +0 -822
  131. package/src/hooks/useBitcoinSigning.ts +0 -276
  132. package/src/hooks/useMarketData.ts +0 -169
  133. package/src/hooks/useSolanaSigning.ts +0 -275
  134. package/src/hooks/useStatusPolling.ts +0 -137
  135. package/src/hooks/useSwapApproval.ts +0 -106
  136. package/src/hooks/useSwapDisplayValues.ts +0 -157
  137. package/src/hooks/useSwapExecution.ts +0 -199
  138. package/src/hooks/useSwapHandlers.ts +0 -119
  139. package/src/hooks/useSwapQuote.ts +0 -71
  140. package/src/hooks/useSwapQuoting.ts +0 -102
  141. package/src/hooks/useSwapRates.ts +0 -61
  142. package/src/index.ts +0 -43
  143. package/src/machines/SwapMachineContext.ts +0 -5
  144. package/src/machines/__tests__/guards.test.ts +0 -228
  145. package/src/machines/__tests__/setup.test.ts +0 -7
  146. package/src/machines/__tests__/swapMachine.test.ts +0 -544
  147. package/src/machines/__tests__/types.test.ts +0 -124
  148. package/src/machines/guards.ts +0 -33
  149. package/src/machines/swapMachine.ts +0 -288
  150. package/src/machines/types.ts +0 -54
  151. package/src/services/transactionStatus.ts +0 -322
  152. package/src/types/index.ts +0 -361
  153. package/src/utils/addressValidation.ts +0 -201
  154. package/src/utils/redirect.ts +0 -45
  155. package/src/vite-env.d.ts +0 -10
  156. package/tsconfig.json +0 -23
  157. package/tsconfig.node.json +0 -10
  158. package/vite.config.ts +0 -101
  159. package/vitest.config.ts +0 -18
@@ -1,119 +0,0 @@
1
- import { useCallback } from 'react'
2
-
3
- import { useSwapWallet } from '../contexts/SwapWalletContext'
4
- import { SwapMachineCtx } from '../machines/SwapMachineContext'
5
- import type { Asset, TradeRate } from '../types'
6
- import { parseAmount } from '../types'
7
-
8
- type UseSwapHandlersParams = {
9
- onConnectWallet?: () => void
10
- onAssetSelect?: (type: 'sell' | 'buy', asset: Asset) => void
11
- }
12
-
13
- export const useSwapHandlers = ({ onConnectWallet, onAssetSelect }: UseSwapHandlersParams) => {
14
- const actorRef = SwapMachineCtx.useActorRef()
15
- const { walletClient, bitcoin, solana } = useSwapWallet()
16
-
17
- const handleSwapTokens = useCallback(() => {
18
- const snap = actorRef.getSnapshot()
19
- actorRef.send({ type: 'SET_SELL_ASSET', asset: snap.context.buyAsset })
20
- actorRef.send({ type: 'SET_BUY_ASSET', asset: snap.context.sellAsset })
21
- actorRef.send({ type: 'SET_SELL_AMOUNT', amount: '', amountBaseUnit: undefined })
22
- }, [actorRef])
23
-
24
- const handleSellAssetSelect = useCallback(
25
- (asset: Asset) => {
26
- actorRef.send({ type: 'SET_SELL_ASSET', asset })
27
- onAssetSelect?.('sell', asset)
28
- },
29
- [actorRef, onAssetSelect],
30
- )
31
-
32
- const handleBuyAssetSelect = useCallback(
33
- (asset: Asset) => {
34
- actorRef.send({ type: 'SET_BUY_ASSET', asset })
35
- onAssetSelect?.('buy', asset)
36
- },
37
- [actorRef, onAssetSelect],
38
- )
39
-
40
- const handleSellAmountChange = useCallback(
41
- (value: string) => {
42
- const snap = actorRef.getSnapshot()
43
- const baseUnit = value ? parseAmount(value, snap.context.sellAsset.precision) : undefined
44
- actorRef.send({ type: 'SET_SELL_AMOUNT', amount: value, amountBaseUnit: baseUnit })
45
- },
46
- [actorRef],
47
- )
48
-
49
- const handleSelectRate = useCallback(
50
- (rate: TradeRate) => {
51
- actorRef.send({ type: 'SELECT_RATE', rate })
52
- },
53
- [actorRef],
54
- )
55
-
56
- const handleSlippageChange = useCallback(
57
- (value: string) => {
58
- actorRef.send({ type: 'SET_SLIPPAGE', slippage: value })
59
- },
60
- [actorRef],
61
- )
62
-
63
- const redirectToShapeShift = useCallback(() => {
64
- const snap = actorRef.getSnapshot()
65
- const params = new URLSearchParams({
66
- sellAssetId: snap.context.sellAsset.assetId,
67
- buyAssetId: snap.context.buyAsset.assetId,
68
- sellAmount: snap.context.sellAmount,
69
- })
70
- window.open(
71
- `https://app.shapeshift.com/trade?${params.toString()}`,
72
- '_blank',
73
- 'noopener,noreferrer',
74
- )
75
- }, [actorRef])
76
-
77
- const handleButtonClick = useCallback(() => {
78
- const snap = actorRef.getSnapshot()
79
- if (snap.context.isSellAssetUtxo && !bitcoin.isConnected) {
80
- return
81
- }
82
- if (snap.context.isSellAssetSolana && !solana.isConnected) {
83
- return
84
- }
85
- if (!walletClient && snap.context.isSellAssetEvm && onConnectWallet) {
86
- onConnectWallet()
87
- return
88
- }
89
- if (
90
- !snap.context.isSellAssetEvm &&
91
- !snap.context.isSellAssetUtxo &&
92
- !snap.context.isSellAssetSolana
93
- ) {
94
- const params = new URLSearchParams({
95
- sellAssetId: snap.context.sellAsset.assetId,
96
- buyAssetId: snap.context.buyAsset.assetId,
97
- sellAmount: snap.context.sellAmount,
98
- })
99
- window.open(
100
- `https://app.shapeshift.com/trade?${params.toString()}`,
101
- '_blank',
102
- 'noopener,noreferrer',
103
- )
104
- return
105
- }
106
- actorRef.send({ type: 'FETCH_QUOTE' })
107
- }, [actorRef, bitcoin.isConnected, solana.isConnected, walletClient, onConnectWallet])
108
-
109
- return {
110
- handleSwapTokens,
111
- handleSellAssetSelect,
112
- handleBuyAssetSelect,
113
- handleSellAmountChange,
114
- handleSelectRate,
115
- handleSlippageChange,
116
- redirectToShapeShift,
117
- handleButtonClick,
118
- }
119
- }
@@ -1,71 +0,0 @@
1
- import { useQuery } from '@tanstack/react-query'
2
-
3
- import type { ApiClient } from '../api/client'
4
- import type { AssetId, QuoteResponse, SwapperName } from '../types'
5
-
6
- export type UseSwapQuoteParams = {
7
- sellAssetId: AssetId | undefined
8
- buyAssetId: AssetId | undefined
9
- sellAmountCryptoBaseUnit: string | undefined
10
- sendAddress: string | undefined
11
- receiveAddress: string | undefined
12
- swapperName: SwapperName | undefined
13
- slippageTolerancePercentageDecimal?: string
14
- enabled?: boolean
15
- }
16
-
17
- export const useSwapQuote = (apiClient: ApiClient, params: UseSwapQuoteParams) => {
18
- const {
19
- sellAssetId,
20
- buyAssetId,
21
- sellAmountCryptoBaseUnit,
22
- sendAddress,
23
- receiveAddress,
24
- swapperName,
25
- slippageTolerancePercentageDecimal,
26
- enabled = true,
27
- } = params
28
-
29
- return useQuery({
30
- queryKey: [
31
- 'swapQuote',
32
- sellAssetId,
33
- buyAssetId,
34
- sellAmountCryptoBaseUnit,
35
- sendAddress,
36
- receiveAddress,
37
- swapperName,
38
- slippageTolerancePercentageDecimal,
39
- ],
40
- queryFn: (): Promise<QuoteResponse | null> => {
41
- if (
42
- !sellAssetId ||
43
- !buyAssetId ||
44
- !sellAmountCryptoBaseUnit ||
45
- !sendAddress ||
46
- !receiveAddress ||
47
- !swapperName
48
- ) {
49
- return Promise.resolve(null)
50
- }
51
- return apiClient.getQuote({
52
- sellAssetId,
53
- buyAssetId,
54
- sellAmountCryptoBaseUnit,
55
- sendAddress,
56
- receiveAddress,
57
- swapperName,
58
- slippageTolerancePercentageDecimal,
59
- })
60
- },
61
- enabled:
62
- enabled &&
63
- !!sellAssetId &&
64
- !!buyAssetId &&
65
- !!sellAmountCryptoBaseUnit &&
66
- !!sendAddress &&
67
- !!receiveAddress &&
68
- !!swapperName,
69
- staleTime: 30_000,
70
- })
71
- }
@@ -1,102 +0,0 @@
1
- import { useEffect, useRef } from 'react'
2
-
3
- import type { ApiClient } from '../api/client'
4
- import { useSwapWallet } from '../contexts/SwapWalletContext'
5
- import { SwapMachineCtx } from '../machines/SwapMachineContext'
6
- import type { TradeRate } from '../types'
7
-
8
- type BalanceData =
9
- | {
10
- balance: string
11
- balanceFormatted: string
12
- }
13
- | undefined
14
-
15
- type UseSwapQuotingParams = {
16
- apiClient: ApiClient
17
- rates: TradeRate[] | undefined
18
- sellAssetBalance: BalanceData
19
- }
20
-
21
- export const useSwapQuoting = ({ apiClient, rates, sellAssetBalance }: UseSwapQuotingParams) => {
22
- const stateValue = SwapMachineCtx.useSelector(s => s.value)
23
- const context = SwapMachineCtx.useSelector(s => s.context)
24
- const actorRef = SwapMachineCtx.useActorRef()
25
-
26
- const { walletAddress, effectiveReceiveAddress, bitcoin, solana } = useSwapWallet()
27
- const bitcoinAddress = bitcoin.address
28
- const solanaAddress = solana.address
29
-
30
- const quotingRef = useRef(false)
31
-
32
- useEffect(() => {
33
- const snap = actorRef.getSnapshot()
34
- if (!snap.matches('quoting') || quotingRef.current) return
35
- quotingRef.current = true
36
-
37
- const fetchQuote = async () => {
38
- try {
39
- if (sellAssetBalance?.balance && context.sellAmountBaseUnit) {
40
- const balanceBigInt = BigInt(sellAssetBalance.balance)
41
- const amountBigInt = BigInt(context.sellAmountBaseUnit)
42
- if (amountBigInt > balanceBigInt) {
43
- actorRef.send({ type: 'QUOTE_ERROR', error: 'Insufficient balance' })
44
- return
45
- }
46
- }
47
-
48
- const parsedSlippage = parseFloat(context.slippage)
49
- if (isNaN(parsedSlippage) || parsedSlippage < 0) {
50
- actorRef.send({ type: 'QUOTE_ERROR', error: 'Invalid slippage value' })
51
- return
52
- }
53
- const slippageDecimal = (parsedSlippage / 100).toString()
54
- const rateToUse = context.selectedRate ?? rates?.[0]
55
- if (!rateToUse || !context.sellAmountBaseUnit) {
56
- actorRef.send({ type: 'QUOTE_ERROR', error: 'No rate or amount available' })
57
- return
58
- }
59
-
60
- const sendAddress = context.isSellAssetEvm
61
- ? walletAddress
62
- : context.isSellAssetUtxo
63
- ? bitcoinAddress
64
- : context.isSellAssetSolana
65
- ? solanaAddress
66
- : undefined
67
-
68
- if (!sendAddress) {
69
- actorRef.send({ type: 'QUOTE_ERROR', error: 'No wallet address available' })
70
- return
71
- }
72
-
73
- const receiveAddr = effectiveReceiveAddress || sendAddress
74
-
75
- if (!receiveAddr) {
76
- actorRef.send({ type: 'QUOTE_ERROR', error: 'No receive address available' })
77
- return
78
- }
79
-
80
- const response = await apiClient.getQuote({
81
- sellAssetId: context.sellAsset.assetId,
82
- buyAssetId: context.buyAsset.assetId,
83
- sellAmountCryptoBaseUnit: context.sellAmountBaseUnit,
84
- sendAddress,
85
- receiveAddress: receiveAddr,
86
- swapperName: rateToUse.swapperName,
87
- slippageTolerancePercentageDecimal: slippageDecimal,
88
- })
89
-
90
- actorRef.send({ type: 'QUOTE_SUCCESS', quote: response })
91
- } catch (error) {
92
- const errorMessage = error instanceof Error ? error.message : 'Failed to get quote'
93
- actorRef.send({ type: 'QUOTE_ERROR', error: errorMessage })
94
- } finally {
95
- quotingRef.current = false
96
- }
97
- }
98
-
99
- fetchQuote()
100
- // eslint-disable-next-line react-hooks/exhaustive-deps -- stateValue is the sole trigger; other deps are stable refs read from snapshot
101
- }, [stateValue])
102
- }
@@ -1,61 +0,0 @@
1
- import { bnOrZero } from '@shapeshiftoss/utils'
2
- import { useQuery } from '@tanstack/react-query'
3
-
4
- import type { ApiClient } from '../api/client'
5
- import type { AssetId, SwapperName, TradeRate } from '../types'
6
-
7
- export type UseSwapRatesParams = {
8
- sellAssetId: AssetId | undefined
9
- buyAssetId: AssetId | undefined
10
- sellAmountCryptoBaseUnit: string | undefined
11
- enabled?: boolean
12
- allowedSwapperNames?: SwapperName[]
13
- refetchInterval?: number
14
- }
15
-
16
- export const useSwapRates = (apiClient: ApiClient, params: UseSwapRatesParams) => {
17
- const {
18
- sellAssetId,
19
- buyAssetId,
20
- sellAmountCryptoBaseUnit,
21
- enabled = true,
22
- allowedSwapperNames,
23
- refetchInterval = 15_000,
24
- } = params
25
-
26
- return useQuery({
27
- queryKey: ['swapRates', sellAssetId, buyAssetId, sellAmountCryptoBaseUnit, allowedSwapperNames],
28
- queryFn: async (): Promise<TradeRate[]> => {
29
- if (!sellAssetId || !buyAssetId || !sellAmountCryptoBaseUnit) {
30
- return []
31
- }
32
- const response = await apiClient.getRates({
33
- sellAssetId,
34
- buyAssetId,
35
- sellAmountCryptoBaseUnit,
36
- })
37
-
38
- let filteredRates = response.rates.filter(
39
- rate => !rate.error && rate.buyAmountCryptoBaseUnit !== '0',
40
- )
41
-
42
- if (allowedSwapperNames?.length) {
43
- filteredRates = filteredRates.filter(rate => allowedSwapperNames.includes(rate.swapperName))
44
- }
45
-
46
- return filteredRates
47
- .map((rate, index) => ({
48
- ...rate,
49
- id: rate.id ?? `${rate.swapperName}-${index}`,
50
- }))
51
- .sort((a, b) => {
52
- const aAmount = bnOrZero(a.buyAmountCryptoBaseUnit)
53
- const bAmount = bnOrZero(b.buyAmountCryptoBaseUnit)
54
- return bAmount.minus(aAmount).toNumber()
55
- })
56
- },
57
- enabled: enabled && !!sellAssetId && !!buyAssetId && !!sellAmountCryptoBaseUnit,
58
- staleTime: 10_000,
59
- refetchInterval,
60
- })
61
- }
package/src/index.ts DELETED
@@ -1,43 +0,0 @@
1
- export { SwapWidget } from './components/SwapWidget'
2
-
3
- export type {
4
- Asset,
5
- AssetId,
6
- ChainId,
7
- Chain,
8
- TradeRate,
9
- TradeQuote,
10
- SwapWidgetProps,
11
- ThemeMode,
12
- ThemeConfig,
13
- } from './types'
14
-
15
- export {
16
- SwapperName,
17
- isEvmChainId,
18
- getEvmNetworkId,
19
- getChainType,
20
- formatAmount,
21
- parseAmount,
22
- truncateAddress,
23
- EVM_CHAIN_IDS,
24
- UTXO_CHAIN_IDS,
25
- COSMOS_CHAIN_IDS,
26
- OTHER_CHAIN_IDS,
27
- } from './types'
28
-
29
- export {
30
- getBaseAsset,
31
- getChainName,
32
- getChainIcon,
33
- getChainColor,
34
- getExplorerTxLink,
35
- } from './constants/chains'
36
-
37
- export {
38
- useAssets,
39
- useAssetById,
40
- useChains,
41
- useAssetsByChainId,
42
- useAssetSearch,
43
- } from './hooks/useAssets'
@@ -1,5 +0,0 @@
1
- import { createActorContext } from '@xstate/react'
2
-
3
- import { swapMachine } from './swapMachine'
4
-
5
- export const SwapMachineCtx = createActorContext(swapMachine)
@@ -1,228 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
-
3
- import type { QuoteResponse } from '../../types'
4
- import {
5
- canRetry,
6
- hasQuote,
7
- hasReceiveAddress,
8
- hasValidInput,
9
- hasWallet,
10
- isApprovalRequired,
11
- isEvmChain,
12
- isSolanaChain,
13
- isUtxoChain,
14
- } from '../guards'
15
- import type { SwapMachineContext } from '../types'
16
-
17
- const createTestContext = (overrides?: Partial<SwapMachineContext>): SwapMachineContext => ({
18
- sellAsset: {
19
- assetId: 'eip155:1/slip44:60',
20
- chainId: 'eip155:1',
21
- symbol: 'ETH',
22
- name: 'Ethereum',
23
- precision: 18,
24
- },
25
- buyAsset: {
26
- assetId: 'eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
27
- chainId: 'eip155:1',
28
- symbol: 'USDC',
29
- name: 'USD Coin',
30
- precision: 6,
31
- },
32
- sellAmount: '1.0',
33
- sellAmountBaseUnit: '1000000000000000000',
34
- selectedRate: null,
35
- quote: null,
36
- txHash: null,
37
- approvalTxHash: null,
38
- error: null,
39
- errorSource: null,
40
- retryCount: 0,
41
- chainType: 'evm',
42
- slippage: '0.5',
43
- walletAddress: '0x1234567890abcdef1234567890abcdef12345678',
44
- effectiveReceiveAddress: '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd',
45
- isSellAssetEvm: true,
46
- isSellAssetUtxo: false,
47
- isSellAssetSolana: false,
48
- isBuyAssetEvm: true,
49
- ...overrides,
50
- })
51
-
52
- describe('guards', () => {
53
- describe('hasValidInput', () => {
54
- it('returns true when all required fields are present', () => {
55
- expect(hasValidInput(createTestContext())).toBe(true)
56
- })
57
-
58
- it('returns false when sellAmountBaseUnit is undefined', () => {
59
- expect(hasValidInput(createTestContext({ sellAmountBaseUnit: undefined }))).toBe(false)
60
- })
61
-
62
- it('returns false when sellAmountBaseUnit is "0"', () => {
63
- expect(hasValidInput(createTestContext({ sellAmountBaseUnit: '0' }))).toBe(false)
64
- })
65
-
66
- it('returns false when sellAmountBaseUnit is empty string', () => {
67
- expect(hasValidInput(createTestContext({ sellAmountBaseUnit: '' }))).toBe(false)
68
- })
69
- })
70
-
71
- describe('hasQuote', () => {
72
- it('returns false when quote is null', () => {
73
- expect(hasQuote(createTestContext())).toBe(false)
74
- })
75
-
76
- it('returns true when quote is present', () => {
77
- expect(hasQuote(createTestContext({ quote: {} as QuoteResponse }))).toBe(true)
78
- })
79
-
80
- it('returns true when quote has approval data', () => {
81
- expect(
82
- hasQuote(
83
- createTestContext({
84
- quote: { approval: { isRequired: true, spender: '0xSpender' } } as QuoteResponse,
85
- }),
86
- ),
87
- ).toBe(true)
88
- })
89
- })
90
-
91
- describe('isApprovalRequired', () => {
92
- it('returns false when quote is null', () => {
93
- expect(isApprovalRequired(createTestContext())).toBe(false)
94
- })
95
-
96
- it('returns false when approval is not required', () => {
97
- expect(
98
- isApprovalRequired(
99
- createTestContext({
100
- quote: { approval: { isRequired: false, spender: '0xSpender' } } as QuoteResponse,
101
- }),
102
- ),
103
- ).toBe(false)
104
- })
105
-
106
- it('returns true when approval is required for ERC20 on EVM chain', () => {
107
- expect(
108
- isApprovalRequired(
109
- createTestContext({
110
- sellAsset: {
111
- assetId: 'eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
112
- chainId: 'eip155:1',
113
- symbol: 'USDC',
114
- name: 'USD Coin',
115
- precision: 6,
116
- },
117
- chainType: 'evm',
118
- quote: { approval: { isRequired: true, spender: '0xSpender' } } as QuoteResponse,
119
- }),
120
- ),
121
- ).toBe(true)
122
- })
123
-
124
- it('returns false when approval is required but sell asset is native (slip44)', () => {
125
- expect(
126
- isApprovalRequired(
127
- createTestContext({
128
- chainType: 'evm',
129
- quote: { approval: { isRequired: true, spender: '0xSpender' } } as QuoteResponse,
130
- }),
131
- ),
132
- ).toBe(false)
133
- })
134
-
135
- it('returns false when approval is required but chain is not EVM', () => {
136
- expect(
137
- isApprovalRequired(
138
- createTestContext({
139
- chainType: 'utxo',
140
- quote: { approval: { isRequired: true, spender: '0xSpender' } } as QuoteResponse,
141
- }),
142
- ),
143
- ).toBe(false)
144
- })
145
-
146
- it('returns false when quote has no approval field', () => {
147
- expect(
148
- isApprovalRequired(
149
- createTestContext({
150
- quote: {} as QuoteResponse,
151
- }),
152
- ),
153
- ).toBe(false)
154
- })
155
- })
156
-
157
- describe('canRetry', () => {
158
- it('returns true when retryCount is 0', () => {
159
- expect(canRetry(createTestContext({ retryCount: 0 }))).toBe(true)
160
- })
161
-
162
- it('returns true when retryCount is 2', () => {
163
- expect(canRetry(createTestContext({ retryCount: 2 }))).toBe(true)
164
- })
165
-
166
- it('returns false when retryCount is 3', () => {
167
- expect(canRetry(createTestContext({ retryCount: 3 }))).toBe(false)
168
- })
169
-
170
- it('returns false when retryCount is greater than 3', () => {
171
- expect(canRetry(createTestContext({ retryCount: 5 }))).toBe(false)
172
- })
173
- })
174
-
175
- describe('isEvmChain', () => {
176
- it('returns true for evm chain', () => {
177
- expect(isEvmChain(createTestContext({ chainType: 'evm' }))).toBe(true)
178
- })
179
-
180
- it('returns false for utxo chain', () => {
181
- expect(isEvmChain(createTestContext({ chainType: 'utxo' }))).toBe(false)
182
- })
183
- })
184
-
185
- describe('isUtxoChain', () => {
186
- it('returns true for utxo chain', () => {
187
- expect(isUtxoChain(createTestContext({ chainType: 'utxo' }))).toBe(true)
188
- })
189
-
190
- it('returns false for evm chain', () => {
191
- expect(isUtxoChain(createTestContext({ chainType: 'evm' }))).toBe(false)
192
- })
193
- })
194
-
195
- describe('isSolanaChain', () => {
196
- it('returns true for solana chain', () => {
197
- expect(isSolanaChain(createTestContext({ chainType: 'solana' }))).toBe(true)
198
- })
199
-
200
- it('returns false for evm chain', () => {
201
- expect(isSolanaChain(createTestContext({ chainType: 'evm' }))).toBe(false)
202
- })
203
- })
204
-
205
- describe('hasWallet', () => {
206
- it('returns true when walletAddress is set', () => {
207
- expect(hasWallet(createTestContext())).toBe(true)
208
- })
209
-
210
- it('returns false when walletAddress is undefined', () => {
211
- expect(hasWallet(createTestContext({ walletAddress: undefined }))).toBe(false)
212
- })
213
-
214
- it('returns false when walletAddress is empty string', () => {
215
- expect(hasWallet(createTestContext({ walletAddress: '' }))).toBe(false)
216
- })
217
- })
218
-
219
- describe('hasReceiveAddress', () => {
220
- it('returns true when effectiveReceiveAddress is set', () => {
221
- expect(hasReceiveAddress(createTestContext())).toBe(true)
222
- })
223
-
224
- it('returns false when effectiveReceiveAddress is empty', () => {
225
- expect(hasReceiveAddress(createTestContext({ effectiveReceiveAddress: '' }))).toBe(false)
226
- })
227
- })
228
- })
@@ -1,7 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
-
3
- describe('test infrastructure', () => {
4
- it('should work', () => {
5
- expect(true).toBe(true)
6
- })
7
- })