@shapeshiftoss/swap-widget 0.0.2 → 0.2.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/LICENSE.md +21 -0
- package/README.md +18 -11
- package/package.json +77 -28
- package/Dockerfile +0 -87
- package/dist/assets/PhArrowCircleDown-B305t-Sh.js +0 -14
- package/dist/assets/PhArrowClockwise-CJPxQhr_.js +0 -14
- package/dist/assets/PhArrowDown-C4hT9BVu.js +0 -14
- package/dist/assets/PhArrowLeft-Way4Cu-r.js +0 -14
- package/dist/assets/PhArrowRight-Cp5ZME0F.js +0 -14
- package/dist/assets/PhArrowSquareOut-NnrK69c5.js +0 -14
- package/dist/assets/PhArrowUp-Dph6j8rm.js +0 -14
- package/dist/assets/PhArrowUpRight-BpJjRRRh.js +0 -14
- package/dist/assets/PhArrowsClockwise-CFUT8X7R.js +0 -14
- package/dist/assets/PhArrowsDownUp-BjBI4ckC.js +0 -14
- package/dist/assets/PhArrowsLeftRight-CuLpbKRk.js +0 -14
- package/dist/assets/PhBank-Dchr4XQJ.js +0 -14
- package/dist/assets/PhBrowser-dUu2TrC1.js +0 -14
- package/dist/assets/PhCaretDown-78IuKU3V.js +0 -14
- package/dist/assets/PhCaretLeft-_aiyH7n1.js +0 -14
- package/dist/assets/PhCaretRight-8zJQEuDX.js +0 -14
- package/dist/assets/PhCaretUp-CiCxKWwN.js +0 -14
- package/dist/assets/PhCheck-CcADx8br.js +0 -14
- package/dist/assets/PhCircleHalf-BYzSzd2h.js +0 -14
- package/dist/assets/PhClock-UItiXeJq.js +0 -14
- package/dist/assets/PhCompass-CUy3uA7t.js +0 -14
- package/dist/assets/PhCopy-C-PDgSlZ.js +0 -14
- package/dist/assets/PhCreditCard-CWRaUT6F.js +0 -14
- package/dist/assets/PhCurrencyDollar-Cqla3AXT.js +0 -14
- package/dist/assets/PhDesktop-BBIPrYLl.js +0 -14
- package/dist/assets/PhDeviceMobile-BdsPaATg.js +0 -14
- package/dist/assets/PhDotsThree-BMXCQl-0.js +0 -14
- package/dist/assets/PhEnvelope-yUsis6yU.js +0 -14
- package/dist/assets/PhFunnelSimple-Ba7BbWTp.js +0 -14
- package/dist/assets/PhGlobe-DgLxBk5U.js +0 -14
- package/dist/assets/PhIdentificationCard-Czjmq9Z3.js +0 -14
- package/dist/assets/PhImage-BAJ_erz6.js +0 -14
- package/dist/assets/PhInfo-Cr4DhVUE.js +0 -14
- package/dist/assets/PhLightbulb-BX_7duTr.js +0 -14
- package/dist/assets/PhMagnifyingGlass-Mygfryvz.js +0 -14
- package/dist/assets/PhPaperPlaneRight-BeuCA660.js +0 -14
- package/dist/assets/PhPlus-BMjcHjsT.js +0 -14
- package/dist/assets/PhPower-CGffGmdb.js +0 -14
- package/dist/assets/PhPuzzlePiece-wm_GpVSi.js +0 -14
- package/dist/assets/PhQrCode-DRwRzXCH.js +0 -14
- package/dist/assets/PhQuestion-M09j2U0T.js +0 -14
- package/dist/assets/PhQuestionMark-BP9EMB6h.js +0 -14
- package/dist/assets/PhSealCheck-BfG80yKn.js +0 -14
- package/dist/assets/PhSignOut-C5YOWlPT.js +0 -14
- package/dist/assets/PhSpinner-BXooDYzU.js +0 -14
- package/dist/assets/PhTrash-Biq6rmmL.js +0 -14
- package/dist/assets/PhUser-CAgZSpGe.js +0 -14
- package/dist/assets/PhVault-l2PHF38a.js +0 -14
- package/dist/assets/PhWallet-w25D16It.js +0 -14
- package/dist/assets/PhWarning-DPEydIPw.js +0 -14
- package/dist/assets/PhWarningCircle-BqjT745H.js +0 -14
- package/dist/assets/PhX-s-SmVExa.js +0 -14
- package/dist/assets/SwapController-If0bFrNc.js +0 -1
- package/dist/assets/ccip-BBB7uCdL.js +0 -1
- package/dist/assets/ccip-CkkdfKKI.js +0 -1
- package/dist/assets/data-capture-D4gAy-Yc.js +0 -242
- package/dist/assets/email-B1AJehis.js +0 -90
- package/dist/assets/embedded-wallet-Q6DQopDk.js +0 -410
- package/dist/assets/features-B6JAPAFb.js +0 -5
- package/dist/assets/index-5jd8RPN9.js +0 -7428
- package/dist/assets/index-B4kNtSTk.js +0 -1080
- package/dist/assets/index-B753eAob.js +0 -1
- package/dist/assets/index-BZoLTv77.js +0 -3
- package/dist/assets/index-Bcw9UURX.js +0 -3
- package/dist/assets/index-BkrV-ahK.js +0 -2
- package/dist/assets/index-CRQzQ_up.js +0 -9
- package/dist/assets/index-CSW0Gt5y.js +0 -132
- package/dist/assets/index-CZ4jTIsk.js +0 -138
- package/dist/assets/index-Cwa8SB3h.js +0 -61
- package/dist/assets/index-DEwQgT4r.js +0 -78
- package/dist/assets/index-DVfQiQ1d.js +0 -1
- package/dist/assets/index-cV3UdaMs.css +0 -1
- package/dist/assets/index-hAmu622O.js +0 -43
- package/dist/assets/onramp-XcPNCLRU.js +0 -422
- package/dist/assets/pay-with-exchange-BeHt4OF4.js +0 -280
- package/dist/assets/property-C9JG5tag.js +0 -27
- package/dist/assets/receive-7ff4he2S.js +0 -131
- package/dist/assets/send-CkMBIRXT.js +0 -554
- package/dist/assets/socials-DmmxuLrP.js +0 -250
- package/dist/assets/swaps-IHAYRQ0x.js +0 -1050
- package/dist/assets/transactions-9Cxdk7o9.js +0 -16
- package/dist/assets/v4-BOvFkHkt.js +0 -1
- package/dist/assets/w3m-modal-kJzFnBfB.js +0 -891
- package/dist/assets/wallet-standard-Dv8LMoUB.js +0 -1
- package/dist/favicon.png +0 -0
- package/dist/favicon.svg +0 -11
- package/dist/icon-192x192.png +0 -0
- package/dist/icon-512x512.png +0 -0
- package/dist/index.html +0 -33
- package/index.html +0 -32
- package/public/favicon.png +0 -0
- package/public/favicon.svg +0 -11
- package/public/icon-192x192.png +0 -0
- package/public/icon-512x512.png +0 -0
- package/railway.toml +0 -10
- package/src/api/client.ts +0 -95
- package/src/components/AddressInputModal.css +0 -173
- package/src/components/AddressInputModal.tsx +0 -250
- package/src/components/ApprovalStep.tsx +0 -92
- package/src/components/ExecutionStep.tsx +0 -27
- package/src/components/InputStep.tsx +0 -431
- package/src/components/QuoteSelector.css +0 -146
- package/src/components/QuoteSelector.tsx +0 -137
- package/src/components/QuotesModal.css +0 -250
- package/src/components/QuotesModal.tsx +0 -182
- package/src/components/SettingsModal.css +0 -145
- package/src/components/SettingsModal.tsx +0 -180
- package/src/components/StatusStep.tsx +0 -139
- package/src/components/SwapWidget.css +0 -713
- package/src/components/SwapWidget.tsx +0 -607
- package/src/components/TokenSelectModal.css +0 -438
- package/src/components/TokenSelectModal.tsx +0 -487
- package/src/components/WalletProvider.tsx +0 -92
- package/src/config/appkit.ts +0 -104
- package/src/config/wagmi.ts +0 -27
- package/src/constants/chains.ts +0 -72
- package/src/constants/defaults.ts +0 -28
- package/src/constants/swappers.ts +0 -48
- package/src/constants/viemChains.ts +0 -69
- package/src/contexts/SwapWalletContext.tsx +0 -25
- package/src/demo/App.css +0 -458
- package/src/demo/App.tsx +0 -481
- package/src/demo/main.tsx +0 -25
- package/src/hooks/useAssets.ts +0 -180
- package/src/hooks/useBalances.ts +0 -822
- package/src/hooks/useBitcoinSigning.ts +0 -276
- package/src/hooks/useMarketData.ts +0 -169
- package/src/hooks/useSolanaSigning.ts +0 -275
- package/src/hooks/useStatusPolling.ts +0 -137
- package/src/hooks/useSwapApproval.ts +0 -106
- package/src/hooks/useSwapDisplayValues.ts +0 -157
- package/src/hooks/useSwapExecution.ts +0 -199
- package/src/hooks/useSwapHandlers.ts +0 -119
- package/src/hooks/useSwapQuote.ts +0 -71
- package/src/hooks/useSwapQuoting.ts +0 -102
- package/src/hooks/useSwapRates.ts +0 -61
- package/src/index.ts +0 -43
- package/src/machines/SwapMachineContext.ts +0 -5
- package/src/machines/__tests__/guards.test.ts +0 -228
- package/src/machines/__tests__/setup.test.ts +0 -7
- package/src/machines/__tests__/swapMachine.test.ts +0 -544
- package/src/machines/__tests__/types.test.ts +0 -124
- package/src/machines/guards.ts +0 -33
- package/src/machines/swapMachine.ts +0 -288
- package/src/machines/types.ts +0 -54
- package/src/services/transactionStatus.ts +0 -322
- package/src/types/index.ts +0 -361
- package/src/utils/addressValidation.ts +0 -201
- package/src/utils/redirect.ts +0 -45
- package/src/vite-env.d.ts +0 -10
- package/tsconfig.json +0 -23
- package/tsconfig.node.json +0 -10
- package/vite.config.ts +0 -101
- package/vitest.config.ts +0 -18
package/src/types/index.ts
DELETED
|
@@ -1,361 +0,0 @@
|
|
|
1
|
-
import type { BitcoinConnector } from '@reown/appkit-adapter-bitcoin'
|
|
2
|
-
import type { Provider as SolanaProvider } from '@reown/appkit-adapter-solana/react'
|
|
3
|
-
import type { AssetId, ChainId } from '@shapeshiftoss/caip'
|
|
4
|
-
import {
|
|
5
|
-
arbitrumChainId,
|
|
6
|
-
avalancheChainId,
|
|
7
|
-
baseChainId,
|
|
8
|
-
bchChainId,
|
|
9
|
-
bscChainId,
|
|
10
|
-
btcChainId,
|
|
11
|
-
CHAIN_NAMESPACE,
|
|
12
|
-
cosmosChainId,
|
|
13
|
-
dogeChainId,
|
|
14
|
-
ethChainId,
|
|
15
|
-
fromChainId,
|
|
16
|
-
gnosisChainId,
|
|
17
|
-
hyperEvmChainId,
|
|
18
|
-
katanaChainId,
|
|
19
|
-
ltcChainId,
|
|
20
|
-
mayachainChainId,
|
|
21
|
-
monadChainId,
|
|
22
|
-
optimismChainId,
|
|
23
|
-
plasmaChainId,
|
|
24
|
-
polygonChainId,
|
|
25
|
-
solanaChainId,
|
|
26
|
-
thorchainChainId,
|
|
27
|
-
worldChainChainId,
|
|
28
|
-
} from '@shapeshiftoss/caip'
|
|
29
|
-
import type { TransactionData } from '@shapeshiftoss/types'
|
|
30
|
-
import { BigAmount } from '@shapeshiftoss/utils'
|
|
31
|
-
import type { WalletClient } from 'viem'
|
|
32
|
-
import { erc20Abi } from 'viem'
|
|
33
|
-
|
|
34
|
-
export type { AssetId, ChainId }
|
|
35
|
-
export type { BitcoinConnector }
|
|
36
|
-
export type { SolanaProvider }
|
|
37
|
-
|
|
38
|
-
export enum SwapperName {
|
|
39
|
-
Thorchain = 'THORChain',
|
|
40
|
-
Mayachain = 'MAYAChain',
|
|
41
|
-
CowSwap = 'CoW Swap',
|
|
42
|
-
Zrx = '0x',
|
|
43
|
-
ArbitrumBridge = 'Arbitrum Bridge',
|
|
44
|
-
Portals = 'Portals',
|
|
45
|
-
Chainflip = 'Chainflip',
|
|
46
|
-
Jupiter = 'Jupiter',
|
|
47
|
-
Relay = 'Relay',
|
|
48
|
-
ButterSwap = 'ButterSwap',
|
|
49
|
-
Bebop = 'Bebop',
|
|
50
|
-
NearIntents = 'NEAR Intents',
|
|
51
|
-
Cetus = 'Cetus',
|
|
52
|
-
Sunio = 'Sun.io',
|
|
53
|
-
Avnu = 'AVNU',
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export type Chain = {
|
|
57
|
-
chainId: ChainId
|
|
58
|
-
name: string
|
|
59
|
-
icon: string
|
|
60
|
-
color: string
|
|
61
|
-
nativeAssetId: AssetId
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export type Asset = {
|
|
65
|
-
assetId: AssetId
|
|
66
|
-
chainId: ChainId
|
|
67
|
-
symbol: string
|
|
68
|
-
name: string
|
|
69
|
-
precision: number
|
|
70
|
-
icon?: string
|
|
71
|
-
color?: string
|
|
72
|
-
networkName?: string
|
|
73
|
-
networkIcon?: string
|
|
74
|
-
explorer?: string
|
|
75
|
-
explorerTxLink?: string
|
|
76
|
-
explorerAddressLink?: string
|
|
77
|
-
relatedAssetKey?: AssetId | null
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export type TradeQuoteStep = {
|
|
81
|
-
sellAsset: Asset
|
|
82
|
-
buyAsset: Asset
|
|
83
|
-
sellAmountCryptoBaseUnit: string
|
|
84
|
-
buyAmountCryptoBaseUnit: string
|
|
85
|
-
rate: string
|
|
86
|
-
source: SwapperName
|
|
87
|
-
feeData: {
|
|
88
|
-
networkFeeCryptoBaseUnit: string
|
|
89
|
-
protocolFees?: Record<AssetId, { amountCryptoBaseUnit: string }>
|
|
90
|
-
}
|
|
91
|
-
allowanceContract?: string
|
|
92
|
-
estimatedExecutionTimeMs?: number
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export type TradeQuote = {
|
|
96
|
-
id: string
|
|
97
|
-
rate: string
|
|
98
|
-
swapperName: SwapperName
|
|
99
|
-
steps: TradeQuoteStep[]
|
|
100
|
-
receiveAddress: string
|
|
101
|
-
affiliateBps: string
|
|
102
|
-
slippageTolerancePercentageDecimal?: string
|
|
103
|
-
isStreaming?: boolean
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export type TradeRate = {
|
|
107
|
-
swapperName: SwapperName
|
|
108
|
-
rate: string
|
|
109
|
-
buyAmountCryptoBaseUnit: string
|
|
110
|
-
sellAmountCryptoBaseUnit: string
|
|
111
|
-
steps: number
|
|
112
|
-
estimatedExecutionTimeMs?: number
|
|
113
|
-
affiliateBps: string
|
|
114
|
-
networkFeeCryptoBaseUnit?: string
|
|
115
|
-
error?: {
|
|
116
|
-
code: string
|
|
117
|
-
message: string
|
|
118
|
-
}
|
|
119
|
-
id?: string
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export type ThemeMode = 'light' | 'dark'
|
|
123
|
-
|
|
124
|
-
export type ThemeConfig = {
|
|
125
|
-
mode: ThemeMode
|
|
126
|
-
accentColor?: string
|
|
127
|
-
backgroundColor?: string
|
|
128
|
-
cardColor?: string
|
|
129
|
-
textColor?: string
|
|
130
|
-
borderRadius?: string
|
|
131
|
-
fontFamily?: string
|
|
132
|
-
borderColor?: string
|
|
133
|
-
secondaryTextColor?: string
|
|
134
|
-
mutedTextColor?: string
|
|
135
|
-
inputColor?: string
|
|
136
|
-
hoverColor?: string
|
|
137
|
-
buttonVariant?: 'filled' | 'outline'
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export type SwapWidgetProps = {
|
|
141
|
-
affiliateAddress?: string
|
|
142
|
-
apiBaseUrl?: string
|
|
143
|
-
defaultSellAsset?: Asset
|
|
144
|
-
defaultBuyAsset?: Asset
|
|
145
|
-
disabledChainIds?: ChainId[]
|
|
146
|
-
disabledAssetIds?: AssetId[]
|
|
147
|
-
allowedChainIds?: ChainId[]
|
|
148
|
-
sellDisabledChainIds?: ChainId[]
|
|
149
|
-
buyDisabledChainIds?: ChainId[]
|
|
150
|
-
sellDisabledAssetIds?: AssetId[]
|
|
151
|
-
buyDisabledAssetIds?: AssetId[]
|
|
152
|
-
sellAllowedChainIds?: ChainId[]
|
|
153
|
-
buyAllowedChainIds?: ChainId[]
|
|
154
|
-
sellAllowedAssetIds?: AssetId[]
|
|
155
|
-
buyAllowedAssetIds?: AssetId[]
|
|
156
|
-
allowedSwapperNames?: SwapperName[]
|
|
157
|
-
walletClient?: WalletClient
|
|
158
|
-
onConnectWallet?: () => void
|
|
159
|
-
onSwapSuccess?: (txHash: string) => void
|
|
160
|
-
onSwapError?: (error: Error) => void
|
|
161
|
-
onAssetSelect?: (type: 'sell' | 'buy', asset: Asset) => void
|
|
162
|
-
theme?: ThemeMode | ThemeConfig
|
|
163
|
-
defaultSlippage?: string
|
|
164
|
-
showPoweredBy?: boolean
|
|
165
|
-
enableWalletConnection?: boolean
|
|
166
|
-
walletConnectProjectId?: string
|
|
167
|
-
defaultReceiveAddress?: string
|
|
168
|
-
ratesRefetchInterval?: number
|
|
169
|
-
isBuyAssetLocked?: boolean
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export type RatesResponse = {
|
|
173
|
-
rates: TradeRate[]
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export type {
|
|
177
|
-
CosmosTransactionData,
|
|
178
|
-
EvmTransactionData,
|
|
179
|
-
Permit2SignatureRequired,
|
|
180
|
-
SolanaTransactionData,
|
|
181
|
-
TransactionData,
|
|
182
|
-
UtxoDepositTransactionData,
|
|
183
|
-
UtxoPsbtTransactionData,
|
|
184
|
-
UtxoTransactionData,
|
|
185
|
-
} from '@shapeshiftoss/types'
|
|
186
|
-
|
|
187
|
-
export type ApiQuoteStep = {
|
|
188
|
-
sellAsset: Asset
|
|
189
|
-
buyAsset: Asset
|
|
190
|
-
sellAmountCryptoBaseUnit: string
|
|
191
|
-
buyAmountAfterFeesCryptoBaseUnit: string
|
|
192
|
-
allowanceContract: string
|
|
193
|
-
estimatedExecutionTimeMs: number | undefined
|
|
194
|
-
source: string
|
|
195
|
-
transactionData?: TransactionData
|
|
196
|
-
relayTransactionMetadata?: TransactionData
|
|
197
|
-
butterSwapTransactionMetadata?: TransactionData
|
|
198
|
-
solanaTransactionMetadata?: {
|
|
199
|
-
instructions: {
|
|
200
|
-
programId: string
|
|
201
|
-
keys: { pubkey: string; isSigner: boolean; isWritable: boolean }[]
|
|
202
|
-
data: { data: number[] }
|
|
203
|
-
}[]
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
export type ApprovalInfo = {
|
|
208
|
-
isRequired: boolean
|
|
209
|
-
spender: string
|
|
210
|
-
approvalTx?: {
|
|
211
|
-
to: string
|
|
212
|
-
data: string
|
|
213
|
-
value: string
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
export type QuoteResponse = {
|
|
218
|
-
quoteId: string
|
|
219
|
-
swapperName: SwapperName
|
|
220
|
-
rate: string
|
|
221
|
-
sellAsset: Asset
|
|
222
|
-
buyAsset: Asset
|
|
223
|
-
sellAmountCryptoBaseUnit: string
|
|
224
|
-
buyAmountBeforeFeesCryptoBaseUnit: string
|
|
225
|
-
buyAmountAfterFeesCryptoBaseUnit: string
|
|
226
|
-
affiliateBps: string
|
|
227
|
-
slippageTolerancePercentageDecimal: string | undefined
|
|
228
|
-
networkFeeCryptoBaseUnit: string | undefined
|
|
229
|
-
/** @deprecated Use `quote.steps` instead. Top-level `steps` is kept for backward compatibility. */
|
|
230
|
-
steps: ApiQuoteStep[]
|
|
231
|
-
approval: ApprovalInfo
|
|
232
|
-
expiresAt: number
|
|
233
|
-
transactionData?: TransactionData
|
|
234
|
-
quote?: {
|
|
235
|
-
steps?: ApiQuoteStep[]
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
export { erc20Abi as ERC20_ABI }
|
|
240
|
-
|
|
241
|
-
export type AssetsResponse = {
|
|
242
|
-
byId: Record<AssetId, Asset>
|
|
243
|
-
ids: AssetId[]
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export const EVM_CHAIN_IDS = {
|
|
247
|
-
ethereum: ethChainId,
|
|
248
|
-
arbitrum: arbitrumChainId,
|
|
249
|
-
optimism: optimismChainId,
|
|
250
|
-
polygon: polygonChainId,
|
|
251
|
-
base: baseChainId,
|
|
252
|
-
avalanche: avalancheChainId,
|
|
253
|
-
bsc: bscChainId,
|
|
254
|
-
gnosis: gnosisChainId,
|
|
255
|
-
monad: monadChainId,
|
|
256
|
-
hyperEvm: hyperEvmChainId,
|
|
257
|
-
plasma: plasmaChainId,
|
|
258
|
-
worldChain: worldChainChainId,
|
|
259
|
-
katana: katanaChainId,
|
|
260
|
-
} as const
|
|
261
|
-
|
|
262
|
-
export const UTXO_CHAIN_IDS = {
|
|
263
|
-
bitcoin: btcChainId,
|
|
264
|
-
bitcoinCash: bchChainId,
|
|
265
|
-
dogecoin: dogeChainId,
|
|
266
|
-
litecoin: ltcChainId,
|
|
267
|
-
} as const
|
|
268
|
-
|
|
269
|
-
export const COSMOS_CHAIN_IDS = {
|
|
270
|
-
cosmos: cosmosChainId,
|
|
271
|
-
thorchain: thorchainChainId,
|
|
272
|
-
mayachain: mayachainChainId,
|
|
273
|
-
} as const
|
|
274
|
-
|
|
275
|
-
export const OTHER_CHAIN_IDS = {
|
|
276
|
-
solana: solanaChainId,
|
|
277
|
-
} as const
|
|
278
|
-
|
|
279
|
-
export const isEvmChainId = (chainId: string): boolean => {
|
|
280
|
-
const { chainNamespace } = fromChainId(chainId as ChainId)
|
|
281
|
-
return chainNamespace === CHAIN_NAMESPACE.Evm
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
export const getEvmNetworkId = (chainId: string): number => {
|
|
285
|
-
const { chainReference } = fromChainId(chainId as ChainId)
|
|
286
|
-
return parseInt(chainReference, 10)
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
export const getChainType = (chainId: string): 'evm' | 'utxo' | 'cosmos' | 'solana' | 'other' => {
|
|
290
|
-
const { chainNamespace } = fromChainId(chainId as ChainId)
|
|
291
|
-
switch (chainNamespace) {
|
|
292
|
-
case CHAIN_NAMESPACE.Evm:
|
|
293
|
-
return 'evm'
|
|
294
|
-
case CHAIN_NAMESPACE.Utxo:
|
|
295
|
-
return 'utxo'
|
|
296
|
-
case CHAIN_NAMESPACE.CosmosSdk:
|
|
297
|
-
return 'cosmos'
|
|
298
|
-
case CHAIN_NAMESPACE.Solana:
|
|
299
|
-
return 'solana'
|
|
300
|
-
default:
|
|
301
|
-
return 'other'
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
export const formatAmount = (amount: string, decimals: number, maxDecimals?: number): string => {
|
|
306
|
-
const effectiveMaxDecimals = maxDecimals ?? Math.min(decimals, 8)
|
|
307
|
-
const result = BigAmount.fromBaseUnit({ value: amount, precision: decimals }).toFixed(
|
|
308
|
-
effectiveMaxDecimals,
|
|
309
|
-
)
|
|
310
|
-
const num = Number(result)
|
|
311
|
-
if (num === 0) return '0'
|
|
312
|
-
|
|
313
|
-
const threshold = Math.pow(10, -effectiveMaxDecimals)
|
|
314
|
-
if (num > 0 && num < threshold) {
|
|
315
|
-
return `< ${threshold.toFixed(effectiveMaxDecimals)}`
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
return num.toLocaleString(undefined, {
|
|
319
|
-
maximumFractionDigits: effectiveMaxDecimals,
|
|
320
|
-
minimumFractionDigits: 0,
|
|
321
|
-
})
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
export const parseAmount = (amount: string, decimals: number): string => {
|
|
325
|
-
return BigAmount.fromPrecision({ value: amount, precision: decimals }).toBaseUnit()
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
export const truncateAddress = (address: string, chars = 4): string => {
|
|
329
|
-
if (address.length <= chars * 2 + 2) return address
|
|
330
|
-
return `${address.slice(0, chars + 2)}...${address.slice(-chars)}`
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
export type TransactionStatus = 'pending' | 'confirmed' | 'failed'
|
|
334
|
-
|
|
335
|
-
export type TransactionStatusResult = {
|
|
336
|
-
status: TransactionStatus
|
|
337
|
-
confirmations?: number
|
|
338
|
-
blockNumber?: number
|
|
339
|
-
error?: string
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
export type BitcoinTransactionStatus = {
|
|
343
|
-
confirmed: boolean
|
|
344
|
-
block_height?: number
|
|
345
|
-
block_hash?: string
|
|
346
|
-
block_time?: number
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
export type WalletProviderNamespace = 'eip155' | 'bip122' | 'solana'
|
|
350
|
-
|
|
351
|
-
export type MultiChainAddress = {
|
|
352
|
-
namespace: WalletProviderNamespace
|
|
353
|
-
address: string
|
|
354
|
-
chainId?: ChainId
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
export type MultiChainWalletState = {
|
|
358
|
-
isConnected: boolean
|
|
359
|
-
addresses: MultiChainAddress[]
|
|
360
|
-
activeNamespace?: WalletProviderNamespace
|
|
361
|
-
}
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import { bech32 } from 'bech32'
|
|
2
|
-
import { isAddress } from 'viem'
|
|
3
|
-
|
|
4
|
-
import type { ChainId } from '../types'
|
|
5
|
-
import { COSMOS_CHAIN_IDS, getChainType } from '../types'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Validates a Bitcoin address (Legacy, SegWit, Native SegWit, Taproot)
|
|
9
|
-
*/
|
|
10
|
-
export const isValidBitcoinAddress = (address: string): boolean => {
|
|
11
|
-
// Legacy (P2PKH) - starts with 1
|
|
12
|
-
const legacyRegex = /^1[a-km-zA-HJ-NP-Z1-9]{25,34}$/
|
|
13
|
-
// Legacy (P2SH) - starts with 3
|
|
14
|
-
const p2shRegex = /^3[a-km-zA-HJ-NP-Z1-9]{25,34}$/
|
|
15
|
-
// Native SegWit (Bech32) - starts with bc1q
|
|
16
|
-
const nativeSegwitRegex = /^bc1q[a-z0-9]{38,58}$/i
|
|
17
|
-
// Taproot (Bech32m) - starts with bc1p
|
|
18
|
-
const taprootRegex = /^bc1p[a-z0-9]{58}$/i
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
legacyRegex.test(address) ||
|
|
22
|
-
p2shRegex.test(address) ||
|
|
23
|
-
nativeSegwitRegex.test(address) ||
|
|
24
|
-
taprootRegex.test(address)
|
|
25
|
-
)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Validates a Bitcoin Cash address
|
|
30
|
-
*/
|
|
31
|
-
export const isValidBitcoinCashAddress = (address: string): boolean => {
|
|
32
|
-
// CashAddr format - starts with bitcoincash: or just q/p
|
|
33
|
-
const cashAddrRegex = /^(bitcoincash:)?[qp][a-z0-9]{41}$/i
|
|
34
|
-
// Legacy format (same as Bitcoin)
|
|
35
|
-
const legacyRegex = /^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$/
|
|
36
|
-
|
|
37
|
-
return cashAddrRegex.test(address) || legacyRegex.test(address)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Validates a Litecoin address
|
|
42
|
-
*/
|
|
43
|
-
export const isValidLitecoinAddress = (address: string): boolean => {
|
|
44
|
-
// Legacy (P2PKH) - starts with L
|
|
45
|
-
const legacyRegex = /^L[a-km-zA-HJ-NP-Z1-9]{25,34}$/
|
|
46
|
-
// Legacy (P2SH) - starts with M or 3
|
|
47
|
-
const p2shRegex = /^[M3][a-km-zA-HJ-NP-Z1-9]{25,34}$/
|
|
48
|
-
// Native SegWit (Bech32) - starts with ltc1
|
|
49
|
-
const nativeSegwitRegex = /^ltc1[a-z0-9]{38,58}$/i
|
|
50
|
-
|
|
51
|
-
return legacyRegex.test(address) || p2shRegex.test(address) || nativeSegwitRegex.test(address)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Validates a Dogecoin address
|
|
56
|
-
*/
|
|
57
|
-
export const isValidDogecoinAddress = (address: string): boolean => {
|
|
58
|
-
// P2PKH - starts with D
|
|
59
|
-
const p2pkhRegex = /^D[5-9A-HJ-NP-U][a-km-zA-HJ-NP-Z1-9]{32}$/
|
|
60
|
-
// P2SH - starts with 9 or A
|
|
61
|
-
const p2shRegex = /^[9A][a-km-zA-HJ-NP-Z1-9]{33}$/
|
|
62
|
-
|
|
63
|
-
return p2pkhRegex.test(address) || p2shRegex.test(address)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export const isValidCosmosAddress = (address: string, expectedPrefix?: string): boolean => {
|
|
67
|
-
try {
|
|
68
|
-
const decoded = bech32.decode(address)
|
|
69
|
-
if (expectedPrefix && decoded.prefix !== expectedPrefix) {
|
|
70
|
-
return false
|
|
71
|
-
}
|
|
72
|
-
return true
|
|
73
|
-
} catch {
|
|
74
|
-
return false
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Gets the expected bech32 prefix for a Cosmos chain
|
|
80
|
-
*/
|
|
81
|
-
const getCosmosPrefix = (chainId: ChainId): string | undefined => {
|
|
82
|
-
const prefixMap: Record<string, string> = {
|
|
83
|
-
[COSMOS_CHAIN_IDS.cosmos]: 'cosmos',
|
|
84
|
-
[COSMOS_CHAIN_IDS.thorchain]: 'thor',
|
|
85
|
-
[COSMOS_CHAIN_IDS.mayachain]: 'maya',
|
|
86
|
-
}
|
|
87
|
-
return prefixMap[chainId]
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Validates a Solana address (base58, 32-44 chars)
|
|
92
|
-
*/
|
|
93
|
-
export const isValidSolanaAddress = (address: string): boolean => {
|
|
94
|
-
// Solana addresses are base58 encoded, typically 32-44 characters
|
|
95
|
-
// Base58 alphabet excludes 0, O, I, l
|
|
96
|
-
const base58Regex = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/
|
|
97
|
-
return base58Regex.test(address)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Validates an address for a specific chain
|
|
102
|
-
*/
|
|
103
|
-
export const validateAddress = (
|
|
104
|
-
address: string,
|
|
105
|
-
chainId: ChainId,
|
|
106
|
-
): { valid: boolean; error?: string } => {
|
|
107
|
-
if (!address || address.trim() === '') {
|
|
108
|
-
return { valid: false, error: 'Address is required' }
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const trimmedAddress = address.trim()
|
|
112
|
-
const chainType = getChainType(chainId)
|
|
113
|
-
|
|
114
|
-
switch (chainType) {
|
|
115
|
-
case 'evm':
|
|
116
|
-
if (!isAddress(trimmedAddress, { strict: false })) {
|
|
117
|
-
return { valid: false, error: 'Invalid EVM address' }
|
|
118
|
-
}
|
|
119
|
-
break
|
|
120
|
-
|
|
121
|
-
case 'utxo':
|
|
122
|
-
// Determine specific UTXO chain
|
|
123
|
-
if (chainId.includes('000000000019d6689c085ae165831e93')) {
|
|
124
|
-
// Bitcoin
|
|
125
|
-
if (!isValidBitcoinAddress(trimmedAddress)) {
|
|
126
|
-
return { valid: false, error: 'Invalid Bitcoin address' }
|
|
127
|
-
}
|
|
128
|
-
} else if (chainId.includes('000000000000000000651ef99cb9fcbe')) {
|
|
129
|
-
// Bitcoin Cash
|
|
130
|
-
if (!isValidBitcoinCashAddress(trimmedAddress)) {
|
|
131
|
-
return { valid: false, error: 'Invalid Bitcoin Cash address' }
|
|
132
|
-
}
|
|
133
|
-
} else if (chainId.includes('12a765e31ffd4059bada1e25190f6e98')) {
|
|
134
|
-
// Litecoin
|
|
135
|
-
if (!isValidLitecoinAddress(trimmedAddress)) {
|
|
136
|
-
return { valid: false, error: 'Invalid Litecoin address' }
|
|
137
|
-
}
|
|
138
|
-
} else if (chainId.includes('00000000001a91e3dace36e2be3bf030')) {
|
|
139
|
-
// Dogecoin
|
|
140
|
-
if (!isValidDogecoinAddress(trimmedAddress)) {
|
|
141
|
-
return { valid: false, error: 'Invalid Dogecoin address' }
|
|
142
|
-
}
|
|
143
|
-
} else {
|
|
144
|
-
return { valid: false, error: 'Unsupported UTXO chain' }
|
|
145
|
-
}
|
|
146
|
-
break
|
|
147
|
-
|
|
148
|
-
case 'cosmos': {
|
|
149
|
-
const expectedPrefix = getCosmosPrefix(chainId)
|
|
150
|
-
if (!isValidCosmosAddress(trimmedAddress, expectedPrefix)) {
|
|
151
|
-
const chainName = expectedPrefix
|
|
152
|
-
? expectedPrefix.charAt(0).toUpperCase() + expectedPrefix.slice(1)
|
|
153
|
-
: 'Cosmos'
|
|
154
|
-
return { valid: false, error: `Invalid ${chainName} address` }
|
|
155
|
-
}
|
|
156
|
-
break
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
case 'solana':
|
|
160
|
-
if (!isValidSolanaAddress(trimmedAddress)) {
|
|
161
|
-
return { valid: false, error: 'Invalid Solana address' }
|
|
162
|
-
}
|
|
163
|
-
break
|
|
164
|
-
|
|
165
|
-
default:
|
|
166
|
-
return { valid: false, error: 'Unsupported chain type' }
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return { valid: true }
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Gets the expected address format hint for a chain
|
|
174
|
-
*/
|
|
175
|
-
export const getAddressFormatHint = (chainId: ChainId): string => {
|
|
176
|
-
const chainType = getChainType(chainId)
|
|
177
|
-
|
|
178
|
-
switch (chainType) {
|
|
179
|
-
case 'evm':
|
|
180
|
-
return '0x...'
|
|
181
|
-
case 'utxo':
|
|
182
|
-
if (chainId.includes('000000000019d6689c085ae165831e93')) {
|
|
183
|
-
return 'bc1... or 1... or 3...'
|
|
184
|
-
} else if (chainId.includes('000000000000000000651ef99cb9fcbe')) {
|
|
185
|
-
return 'bitcoincash:q... or 1...'
|
|
186
|
-
} else if (chainId.includes('12a765e31ffd4059bada1e25190f6e98')) {
|
|
187
|
-
return 'ltc1... or L... or M...'
|
|
188
|
-
} else if (chainId.includes('00000000001a91e3dace36e2be3bf030')) {
|
|
189
|
-
return 'D...'
|
|
190
|
-
}
|
|
191
|
-
return 'Enter address'
|
|
192
|
-
case 'cosmos': {
|
|
193
|
-
const prefix = getCosmosPrefix(chainId)
|
|
194
|
-
return prefix ? `${prefix}1...` : 'Enter address'
|
|
195
|
-
}
|
|
196
|
-
case 'solana':
|
|
197
|
-
return 'Enter Solana address'
|
|
198
|
-
default:
|
|
199
|
-
return 'Enter address'
|
|
200
|
-
}
|
|
201
|
-
}
|
package/src/utils/redirect.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import type { Asset, AssetId } from '../types'
|
|
2
|
-
import { isEvmChainId } from '../types'
|
|
3
|
-
|
|
4
|
-
const SHAPESHIFT_APP_URL = 'https://app.shapeshift.com'
|
|
5
|
-
|
|
6
|
-
export type RedirectParams = {
|
|
7
|
-
sellAssetId: AssetId
|
|
8
|
-
buyAssetId: AssetId
|
|
9
|
-
sellAmount?: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const buildShapeShiftTradeUrl = (params: RedirectParams): string => {
|
|
13
|
-
const url = new URL(`${SHAPESHIFT_APP_URL}/trade`)
|
|
14
|
-
url.searchParams.set('sellAssetId', params.sellAssetId)
|
|
15
|
-
url.searchParams.set('buyAssetId', params.buyAssetId)
|
|
16
|
-
if (params.sellAmount) {
|
|
17
|
-
url.searchParams.set('sellAmount', params.sellAmount)
|
|
18
|
-
}
|
|
19
|
-
return url.toString()
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const redirectToShapeShift = (params: RedirectParams): void => {
|
|
23
|
-
const url = buildShapeShiftTradeUrl(params)
|
|
24
|
-
window.open(url, '_blank', 'noopener,noreferrer')
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export type ChainType = 'evm' | 'utxo' | 'cosmos' | 'solana' | 'other'
|
|
28
|
-
|
|
29
|
-
export const getChainTypeFromAsset = (asset: Asset): ChainType => {
|
|
30
|
-
const chainId = asset.chainId
|
|
31
|
-
|
|
32
|
-
if (isEvmChainId(chainId)) return 'evm'
|
|
33
|
-
if (chainId.startsWith('bip122:')) return 'utxo'
|
|
34
|
-
if (chainId.startsWith('cosmos:')) return 'cosmos'
|
|
35
|
-
if (chainId.startsWith('solana:')) return 'solana'
|
|
36
|
-
|
|
37
|
-
return 'other'
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export const canExecuteInWidget = (sellAsset: Asset, buyAsset: Asset): boolean => {
|
|
41
|
-
const sellChainType = getChainTypeFromAsset(sellAsset)
|
|
42
|
-
const buyChainType = getChainTypeFromAsset(buyAsset)
|
|
43
|
-
|
|
44
|
-
return sellChainType === 'evm' && buyChainType === 'evm'
|
|
45
|
-
}
|
package/src/vite-env.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/// <reference types="vite/client" />
|
|
2
|
-
|
|
3
|
-
interface EthereumProvider {
|
|
4
|
-
request: (args: { method: string; params?: unknown[] }) => Promise<unknown>
|
|
5
|
-
on: (event: string, callback: (accounts: string[]) => void) => void
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
interface Window {
|
|
9
|
-
ethereum?: EthereumProvider
|
|
10
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"useDefineForClassFields": true,
|
|
5
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"skipLibCheck": true,
|
|
8
|
-
|
|
9
|
-
"moduleResolution": "bundler",
|
|
10
|
-
"allowImportingTsExtensions": true,
|
|
11
|
-
"resolveJsonModule": true,
|
|
12
|
-
"isolatedModules": true,
|
|
13
|
-
"noEmit": true,
|
|
14
|
-
"jsx": "react-jsx",
|
|
15
|
-
|
|
16
|
-
"strict": true,
|
|
17
|
-
"noUnusedLocals": true,
|
|
18
|
-
"noUnusedParameters": true,
|
|
19
|
-
"noFallthroughCasesInSwitch": true
|
|
20
|
-
},
|
|
21
|
-
"include": ["src"],
|
|
22
|
-
"references": [{ "path": "./tsconfig.node.json" }]
|
|
23
|
-
}
|