diff --git a/.changeset/honest-feet-sleep.md b/.changeset/khaki-emus-change.md similarity index 100% rename from .changeset/honest-feet-sleep.md rename to .changeset/khaki-emus-change.md diff --git a/apps/guard/CHANGELOG.md b/apps/guard/CHANGELOG.md index c4bd7727..1ea046e8 100644 --- a/apps/guard/CHANGELOG.md +++ b/apps/guard/CHANGELOG.md @@ -1,5 +1,14 @@ # @rosen-bridge/guard-app +## 1.9.1 + +### Patch Changes + +- Integrated the Version component in the SideBar to display version information optimized for both desktop and mobile views. +- Updated dependencies + - @rosen-bridge/icons@1.0.0 + - @rosen-bridge/ui-kit@1.7.0 + ## 1.9.0 ### Minor Changes diff --git a/apps/guard/app/SideBar.tsx b/apps/guard/app/SideBar.tsx index f26995c7..8dc91516 100644 --- a/apps/guard/app/SideBar.tsx +++ b/apps/guard/app/SideBar.tsx @@ -1,5 +1,6 @@ import Link from 'next/link'; import { usePathname, useRouter } from 'next/navigation'; +import { useMemo, useState } from 'react'; import { BitcoinCircle, @@ -14,6 +15,7 @@ import { AppLogo, NavigationBar, NavigationButton, + Version, } from '@rosen-bridge/ui-kit'; import packageJson from '../package.json'; @@ -62,28 +64,25 @@ export const SideBar = () => { const { data: info, isLoading } = useInfo(); - const versions = [ - { - title: 'Guard', - value: info?.versions.app, - important: true, - }, - { - title: 'UI', - value: packageJson.version, - }, - { - title: 'Contract', - value: info?.versions.contract, - }, - ]; - - if (!isLoading && info?.versions.contract !== info?.versions.tokensMap) { - versions.push({ - title: 'Tokens', - value: info?.versions.tokensMap, - }); - } + const sub = useMemo(() => { + const result = [ + { + label: 'UI', + value: packageJson.version, + }, + { + label: 'Contract', + value: info?.versions.contract, + }, + ]; + if (!isLoading && info?.versions.contract !== info?.versions.tokensMap) { + result.push({ + label: 'Tokens', + value: info?.versions.tokensMap, + }); + } + return result; + }, [info, isLoading]); return ( { /> } - versions={versions} + versions={} navigationBar={ {routes.map((route) => ( diff --git a/apps/guard/package.json b/apps/guard/package.json index c9e842f6..5640b1c6 100644 --- a/apps/guard/package.json +++ b/apps/guard/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-bridge/guard-app", - "version": "1.9.0", + "version": "1.9.1", "private": true, "scripts": { "prettify": "prettier --write . --ignore-path ../../.gitignore", @@ -14,9 +14,9 @@ "dependencies": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/shared-contexts": "^0.0.2", - "@rosen-bridge/ui-kit": "^1.6.0", + "@rosen-bridge/ui-kit": "^1.7.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/swr-helpers": "^0.2.0", "@rosen-ui/utils": "^0.4.2", diff --git a/apps/rosen-service/CHANGELOG.md b/apps/rosen-service/CHANGELOG.md index fc2f8a4f..1ad14971 100644 --- a/apps/rosen-service/CHANGELOG.md +++ b/apps/rosen-service/CHANGELOG.md @@ -1,5 +1,11 @@ # @rosen-bridge/rosen-service +## 2.2.0 + +### Minor Changes + +- Add binance chain scanner with observation and event trigger extractors + ## 2.1.0 ### Minor Changes diff --git a/apps/rosen-service/config/default.yaml b/apps/rosen-service/config/default.yaml index f8377520..17fe7d36 100644 --- a/apps/rosen-service/config/default.yaml +++ b/apps/rosen-service/config/default.yaml @@ -46,6 +46,16 @@ ethereum: rwt: initialHeight: rpcUrl: https://eth-mainnet.public.blastapi.io +binance: + addresses: + lock: + eventTrigger: + permit: + fraud: + tokens: + rwt: + initialHeight: + rpcUrl: https://bsc-mainnet.public.blastapi.io/ # rpcAuthToken: postgres: url: # postgresql://username:password@host:port/databasename diff --git a/apps/rosen-service/package.json b/apps/rosen-service/package.json index 95de1526..a2482671 100644 --- a/apps/rosen-service/package.json +++ b/apps/rosen-service/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-bridge/rosen-service", - "version": "2.1.0", + "version": "2.2.0", "private": true, "license": "GPL-3.0", "author": "Rosen Team", diff --git a/apps/rosen-service/src/configs.ts b/apps/rosen-service/src/configs.ts index 80d6fca2..f944cb5b 100644 --- a/apps/rosen-service/src/configs.ts +++ b/apps/rosen-service/src/configs.ts @@ -33,7 +33,7 @@ const getConfig = () => { addresses: { lock: nodeConfig.get('cardano.addresses.lock'), eventTrigger: nodeConfig.get( - 'cardano.addresses.eventTrigger', + 'cardano.addresses.eventTrigger' ), permit: nodeConfig.get('cardano.addresses.permit'), fraud: nodeConfig.get('cardano.addresses.fraud'), @@ -49,7 +49,7 @@ const getConfig = () => { addresses: { lock: nodeConfig.get('bitcoin.addresses.lock'), eventTrigger: nodeConfig.get( - 'bitcoin.addresses.eventTrigger', + 'bitcoin.addresses.eventTrigger' ), permit: nodeConfig.get('bitcoin.addresses.permit'), fraud: nodeConfig.get('bitcoin.addresses.fraud'), @@ -67,7 +67,7 @@ const getConfig = () => { addresses: { lock: nodeConfig.get('ethereum.addresses.lock'), eventTrigger: nodeConfig.get( - 'ethereum.addresses.eventTrigger', + 'ethereum.addresses.eventTrigger' ), permit: nodeConfig.get('ethereum.addresses.permit'), fraud: nodeConfig.get('ethereum.addresses.fraud'), @@ -79,6 +79,22 @@ const getConfig = () => { rpcUrl: nodeConfig.get('ethereum.rpcUrl'), rpcAuthToken: getOptionalString('ethereum.rpcAuthToken'), }, + binance: { + addresses: { + lock: nodeConfig.get('binance.addresses.lock'), + eventTrigger: nodeConfig.get( + 'binance.addresses.eventTrigger' + ), + permit: nodeConfig.get('binance.addresses.permit'), + fraud: nodeConfig.get('binance.addresses.fraud'), + }, + initialHeight: nodeConfig.get('binance.initialHeight'), + tokens: { + rwt: nodeConfig.get('binance.tokens.rwt'), + }, + rpcUrl: nodeConfig.get('binance.rpcUrl'), + rpcAuthToken: getOptionalString('binance.rpcAuthToken'), + }, postgres: { url: nodeConfig.get('postgres.url'), logging: nodeConfig.get('postgres.logging'), @@ -98,7 +114,7 @@ const getConfig = () => { `an error occurred reading some service configs: ${error}`, false, 'error', - error instanceof Error ? error.stack : undefined, + error instanceof Error ? error.stack : undefined ); } }; diff --git a/apps/rosen-service/src/constants.ts b/apps/rosen-service/src/constants.ts index 77be0b9b..edffd938 100644 --- a/apps/rosen-service/src/constants.ts +++ b/apps/rosen-service/src/constants.ts @@ -4,9 +4,11 @@ export const ERGO_SCANNER_INTERVAL = 2 * 60 * 1000; export const CARDANO_SCANNER_INTERVAL = 30 * 1000; export const BITCOIN_SCANNER_INTERVAL = 10 * 60 * 1000; export const ETHEREUM_SCANNER_INTERVAL = 60 * 1000; +export const BINANCE_SCANNER_INTERVAL = 10 * 1000; export const ASSET_CALCULATOR_INTERVAL = 30 * 1000; export const ERGO_SCANNER_LOGGER_NAME = 'ergo-scanner'; export const CARDANO_SCANNER_LOGGER_NAME = 'cardano-scanner'; export const BITCOIN_SCANNER_LOGGER_NAME = 'bitcoin-scanner'; export const ETHEREUM_SCANNER_LOGGER_NAME = 'ethereum-scanner'; +export const BINANCE_SCANNER_LOGGER_NAME = 'binance-scanner'; diff --git a/apps/rosen-service/src/event-trigger/event-trigger-service.ts b/apps/rosen-service/src/event-trigger/event-trigger-service.ts index 7d505c46..7e7cac55 100644 --- a/apps/rosen-service/src/event-trigger/event-trigger-service.ts +++ b/apps/rosen-service/src/event-trigger/event-trigger-service.ts @@ -17,6 +17,8 @@ const bitcoinEventTriggerExtractorLogger = WinstonLogger.getInstance().getLogger('bitcoin-event-trigger-extractor'); const ethereumEventTriggerExtractorLogger = WinstonLogger.getInstance().getLogger('ethereum-event-trigger-extractor'); +const binanceEventTriggerExtractorLogger = + WinstonLogger.getInstance().getLogger('binance-event-trigger-extractor'); /** * register event trigger extractors for all chains @@ -68,11 +70,23 @@ export const registerExtractors = (scanner: ErgoScanner) => { configs.ethereum.addresses.fraud, ethereumEventTriggerExtractorLogger, ); + const binanceEventTriggerExtractor = new EventTriggerExtractor( + 'binance-extractor', + dataSource, + ErgoNetworkType.Explorer, + configs.ergo.explorerUrl, + configs.binance.addresses.eventTrigger, + configs.binance.tokens.rwt, + configs.binance.addresses.permit, + configs.binance.addresses.fraud, + binanceEventTriggerExtractorLogger, + ); scanner.registerExtractor(ergoEventTriggerExtractor); scanner.registerExtractor(cardanoEventTriggerExtractor); scanner.registerExtractor(bitcoinEventTriggerExtractor); scanner.registerExtractor(ethereumEventTriggerExtractor); + scanner.registerExtractor(binanceEventTriggerExtractor); logger.debug('event trigger extractors registered', { scannerName: scanner.name(), @@ -81,6 +95,7 @@ export const registerExtractors = (scanner: ErgoScanner) => { cardanoEventTriggerExtractor.getId(), bitcoinEventTriggerExtractor.getId(), ethereumEventTriggerExtractor.getId(), + binanceEventTriggerExtractor.getId(), ], }); } catch (error) { diff --git a/apps/rosen-service/src/observation/chains/binance.ts b/apps/rosen-service/src/observation/chains/binance.ts new file mode 100644 index 00000000..f557ea3c --- /dev/null +++ b/apps/rosen-service/src/observation/chains/binance.ts @@ -0,0 +1,41 @@ +import { BinanceRpcObservationExtractor } from '@rosen-bridge/evm-observation-extractor'; +import { EvmRpcScanner } from '@rosen-bridge/evm-rpc-scanner'; +import WinstonLogger from '@rosen-bridge/winston-logger'; + +import config from '../../configs'; +import dataSource from '../../data-source'; +import AppError from '../../errors/AppError'; +import { getRosenTokens } from '../../utils'; + +const logger = WinstonLogger.getInstance().getLogger(import.meta.url); + +/** + * register an observation extractor for the provided scanner + * @param scanner + */ +export const registerBinanceExtractor = (scanner: EvmRpcScanner) => { + try { + const observationExtractor = new BinanceRpcObservationExtractor( + config.binance.addresses.lock, + dataSource, + getRosenTokens(), + logger + ); + + scanner.registerExtractor(observationExtractor); + + logger.debug('binance observation extractor registered', { + scannerName: scanner.name(), + }); + } catch (error) { + throw new AppError( + `cannot create or register binance observation extractor due to error: ${error}`, + false, + 'error', + error instanceof Error ? error.stack : undefined, + { + scannerName: scanner.name(), + } + ); + } +}; diff --git a/apps/rosen-service/src/observation/observation-service.ts b/apps/rosen-service/src/observation/observation-service.ts index 58d3ec6e..b7107016 100644 --- a/apps/rosen-service/src/observation/observation-service.ts +++ b/apps/rosen-service/src/observation/observation-service.ts @@ -1,3 +1,4 @@ +import { registerBinanceExtractor } from './chains/binance'; import { registerBitcoinExtractor } from './chains/bitcoin'; import { registerCardanoExtractor } from './chains/cardano'; import { registerErgoExtractor } from './chains/ergo'; @@ -8,6 +9,7 @@ const observationService = { registerCardanoExtractor, registerErgoExtractor, registerEthereumExtractor, + registerBinanceExtractor, }; export default observationService; diff --git a/apps/rosen-service/src/scanner/chains/binance.ts b/apps/rosen-service/src/scanner/chains/binance.ts new file mode 100644 index 00000000..d314cbee --- /dev/null +++ b/apps/rosen-service/src/scanner/chains/binance.ts @@ -0,0 +1,53 @@ +import { EvmRpcScanner } from '@rosen-bridge/evm-rpc-scanner'; +import WinstonLogger from '@rosen-bridge/winston-logger'; + +import config from '../../configs'; +import { + BINANCE_SCANNER_INTERVAL, + BINANCE_SCANNER_LOGGER_NAME, + SCANNER_API_TIMEOUT, +} from '../../constants'; +import dataSource from '../../data-source'; +import AppError from '../../errors/AppError'; +import observationService from '../../observation/observation-service'; +import { startScanner } from '../scanner-utils'; + +const logger = WinstonLogger.getInstance().getLogger(import.meta.url); +const scannerLogger = WinstonLogger.getInstance().getLogger( + BINANCE_SCANNER_LOGGER_NAME +); + +/** + * create a binance scanner, initializing it and calling its update method + * periodically + */ +export const startBinanceScanner = async () => { + try { + const scanner = new EvmRpcScanner( + 'binance', + { + RpcUrl: config.binance.rpcUrl, + dataSource, + initialHeight: config.binance.initialHeight, + timeout: SCANNER_API_TIMEOUT, + }, + scannerLogger, + config.binance.rpcAuthToken + ); + + observationService.registerBinanceExtractor(scanner); + + await startScanner(scanner, import.meta.url, BINANCE_SCANNER_INTERVAL); + + logger.debug('binance scanner started'); + + return scanner; + } catch (error) { + throw new AppError( + `cannot create or start binance scanner due to error: ${error}`, + false, + 'error', + error instanceof Error ? error.stack : undefined + ); + } +}; diff --git a/apps/rosen-service/src/scanner/scanner-service.ts b/apps/rosen-service/src/scanner/scanner-service.ts index 15f9bfd6..c3b2d081 100644 --- a/apps/rosen-service/src/scanner/scanner-service.ts +++ b/apps/rosen-service/src/scanner/scanner-service.ts @@ -1,6 +1,7 @@ import WinstonLogger from '@rosen-bridge/winston-logger/dist/WinstonLogger'; import { handleError } from '../utils'; +import { startBinanceScanner } from './chains/binance'; import { startBitcoinScanner } from './chains/bitcoin'; import { startCardanoScanner } from './chains/cardano'; import { startErgoScanner } from './chains/ergo'; @@ -13,13 +14,19 @@ const logger = WinstonLogger.getInstance().getLogger(import.meta.url); */ const start = async () => { try { - const [ergoScanner, cardanoScanner, bitcoinScanner, ethereumScanner] = - await Promise.all([ - startErgoScanner(), - startCardanoScanner(), - startBitcoinScanner(), - startEthereumScanner(), - ]); + const [ + ergoScanner, + cardanoScanner, + bitcoinScanner, + ethereumScanner, + binanceScanner, + ] = await Promise.all([ + startErgoScanner(), + startCardanoScanner(), + startBitcoinScanner(), + startEthereumScanner(), + startBinanceScanner(), + ]); logger.debug('all scanners started and their extractors registered', { scannerNames: [ @@ -27,6 +34,7 @@ const start = async () => { cardanoScanner.name(), bitcoinScanner.name(), ethereumScanner.name(), + binanceScanner.name(), ], }); } catch (error) { diff --git a/apps/rosen/CHANGELOG.md b/apps/rosen/CHANGELOG.md index 560d5032..19a4d5c1 100644 --- a/apps/rosen/CHANGELOG.md +++ b/apps/rosen/CHANGELOG.md @@ -1,5 +1,38 @@ # @rosen-bridge/rosen-app +## 4.0.0 + +### Major Changes + +- Discontinue support for the Flint and Vespr wallets + +### Minor Changes + +- Enhance error handling on the bridge form and automatically close the transaction modal upon successful processing +- Revise the wallet-related logic to align with the latest updates in the wallet packages +- Improve the transaction dialog confirmation to enhance its responsiveness and user experience + +### Patch Changes + +- Review theme colors in Figma and ensure consistency by identifying and fixing any mismatches +- Refactor the token map hook to enhance efficiency +- Add a paste button to the address field in the bridge form +- Address the issue where selecting a token with assets and then switching to a token without any causes the 'use all' button to display an incorrect amount instead of zero +- Integrated the Version component in the SideBar to display version information optimized for both desktop and mobile views. +- Updated dependencies + - @rosen-bridge/icons@1.0.0 + - @rosen-bridge/ui-kit@1.7.0 + - @rosen-network/ethereum@1.0.0 + - @rosen-network/bitcoin@2.0.0 + - @rosen-network/cardano@2.0.0 + - @rosen-network/ergo@2.0.0 + - @rosen-ui/metamask-wallet@1.0.0 + - @rosen-ui/nautilus-wallet@2.0.0 + - @rosen-ui/okx-wallet@1.0.0 + - @rosen-ui/eternl-wallet@2.0.0 + - @rosen-ui/lace-wallet@2.0.0 + - @rosen-ui/nami-wallet@2.0.0 + ## 3.0.0 ### Major Changes diff --git a/apps/rosen/app/(bridge)/BridgeForm.tsx b/apps/rosen/app/(bridge)/BridgeForm.tsx index ceadf27f..9e765189 100644 --- a/apps/rosen/app/(bridge)/BridgeForm.tsx +++ b/apps/rosen/app/(bridge)/BridgeForm.tsx @@ -2,6 +2,7 @@ import { useCallback, ChangeEvent } from 'react'; +import { Paste } from '@rosen-bridge/icons'; import { RosenChainToken } from '@rosen-bridge/tokens'; import { Grid, @@ -14,6 +15,8 @@ import { SvgIcon, Alert, Autocomplete, + InputAdornment, + IconButton, } from '@rosen-bridge/ui-kit'; import { NETWORKS } from '@rosen-ui/constants'; import { getDecimalString } from '@rosen-ui/utils'; @@ -27,6 +30,7 @@ import { useTransactionFormData, useWallet, } from '@/_hooks'; +import { theme } from '@/_theme/theme'; import { getTokenNameAndId } from '@/_utils'; import { UseAllAmount } from './UseAllAmount'; @@ -224,7 +228,32 @@ export const BridgeForm = () => { + { + try { + const clipboardText = + await navigator.clipboard.readText(); + addressField.onChange(clipboardText); + } catch (err) { + console.error('Failed to read clipboard: ', err); + } + }} + > + + + + ), + } as any + } variant="filled" error={!!errors?.walletAddress} helperText={ diff --git a/apps/rosen/app/(bridge)/BridgeTransaction.tsx b/apps/rosen/app/(bridge)/BridgeTransaction.tsx index 5307454f..b761f761 100644 --- a/apps/rosen/app/(bridge)/BridgeTransaction.tsx +++ b/apps/rosen/app/(bridge)/BridgeTransaction.tsx @@ -80,7 +80,7 @@ export const BridgeTransaction = ({ backgroundColor: (theme) => theme.palette.mode === 'light' ? theme.palette.primary.light - : theme.palette.primary.dark, + : theme.palette.background.paper, padding: (theme) => theme.spacing(3), }} > diff --git a/apps/rosen/app/(bridge)/ConnectOrSubmitButton.tsx b/apps/rosen/app/(bridge)/ConnectOrSubmitButton.tsx index 7e0bbc42..da932b3f 100644 --- a/apps/rosen/app/(bridge)/ConnectOrSubmitButton.tsx +++ b/apps/rosen/app/(bridge)/ConnectOrSubmitButton.tsx @@ -5,9 +5,10 @@ import { Amount, Box, Card, - Dialog, DialogActions, + DialogContent, Divider, + EnhancedDialog, EnhancedDialogTitle, Grid, LoadingButton, @@ -41,7 +42,7 @@ export const ConnectOrSubmitButton = ({ targetValue, tokenValue, amountValue, - formState: { isSubmitting: isFormSubmitting, errors }, + formState: { isSubmitting: isFormSubmitting, errors, isValidating }, walletAddressValue, handleSubmit, } = useTransactionFormData(); @@ -61,7 +62,7 @@ export const ConnectOrSubmitButton = ({ useTransaction(); const handleFormSubmit = handleSubmit(() => { - startTransaction(bridgeFee, networkFee); + startTransaction(bridgeFee, networkFee).then(() => setOpen(false)); }); const { availableSources } = useNetwork(); @@ -89,6 +90,19 @@ export const ConnectOrSubmitButton = ({ const targetTokenInfo = targetValue && targetTokenSearchResults?.[0]?.[targetValue]; + const disabled = selectedWallet + ? !sourceValue || + !targetValue || + !tokenValue || + !amountValue || + !walletAddressValue || + !bridgeFee || + !networkFee || + !!errors.amount || + !!errors.walletAddress || + isValidating + : !sourceValue; + return ( <> { - if (!selectedWallet) { - setChooseWalletsModalOpen(true); - } else if ( - sourceValue && - targetValue && - tokenValue && - amountValue && - walletAddressValue && - bridgeFee && - networkFee && - !errors.amount && - !errors.walletAddress - ) { + if (selectedWallet) { setOpen(true); + } else { + setChooseWalletsModalOpen(true); } }} > {!selectedWallet ? 'CONNECT WALLET' : 'SUBMIT'} - setOpen(false)}> + setOpen(false)} + > } onClose={() => setOpen(false)} > Confirm Transaction - - theme.palette.mode === 'light' - ? theme.palette.primary.light - : theme.palette.primary.dark, - px: 2, - py: 3, - mx: 3, - }} - > - - - - + + theme.palette.mode === 'light' + ? theme.palette.primary.light + : theme.palette.primary.dark, + px: 2, + py: 3, }} > - - {SourceLogo && ( - - - - )} - {source?.label} - - - - - - {TargetLogo && ( - - - - )} - {target?.label} + + - - - - - - - - - - Destination address - - - {walletAddressValue} - - + + + {SourceLogo && ( + + + + )} + {source?.label} + + + + + + {TargetLogo && ( + + + + )} + {target?.label} + + + + + + + + + + + Destination address + + + {walletAddressValue} + + + - + ); }; diff --git a/apps/rosen/app/App.tsx b/apps/rosen/app/App.tsx index 482c5ea7..6625e7bf 100644 --- a/apps/rosen/app/App.tsx +++ b/apps/rosen/app/App.tsx @@ -12,6 +12,7 @@ import { App as AppBase } from '@rosen-bridge/ui-kit'; import { theme } from '@/_theme/theme'; import { WalletContextProvider } from './_contexts/walletContext'; +import { TokenMapProvider } from './_hooks'; import { SideBar } from './SideBar'; import { Toolbar } from './Toolbar'; @@ -19,7 +20,9 @@ export const App = ({ children }: { children?: React.ReactNode }) => { return ( } theme={theme} toolbar={}> - {children} + + {children} + ); diff --git a/apps/rosen/app/SideBar.tsx b/apps/rosen/app/SideBar.tsx index 0843bfe9..2689aa04 100644 --- a/apps/rosen/app/SideBar.tsx +++ b/apps/rosen/app/SideBar.tsx @@ -13,6 +13,7 @@ import { AppLogo, NavigationBar, NavigationButton, + Version, } from '@rosen-bridge/ui-kit'; import packageJson from '../package.json'; @@ -71,12 +72,7 @@ export const SideBar = () => { /> } - versions={[ - { - title: 'UI', - value: packageJson.version, - }, - ]} + versions={} navigationBar={ {routes.map((route) => ( diff --git a/apps/rosen/app/_hooks/useMaxTransfer.ts b/apps/rosen/app/_hooks/useMaxTransfer.ts index f8a350bd..96b67f36 100644 --- a/apps/rosen/app/_hooks/useMaxTransfer.ts +++ b/apps/rosen/app/_hooks/useMaxTransfer.ts @@ -33,6 +33,8 @@ export const useMaxTransfer = () => { const loading = isTokenBalanceLoading || isTransitionLoading; const load = useCallback(async () => { + setMax(0n); + const skip = !amount || isTokenBalanceLoading || @@ -46,16 +48,6 @@ export const useMaxTransfer = () => { setError(false); try { - let eventData: any; - - if (selectedSource.name === NETWORKS.BITCOIN) { - eventData = { - fromAddress: await selectedWallet.getAddress(), - toAddress: walletAddressValue, - toChain: targetValue, - }; - } - const max = await getMaxTransfer( selectedSource, { diff --git a/apps/rosen/app/_hooks/useTokenBalance.ts b/apps/rosen/app/_hooks/useTokenBalance.ts index 865f71d9..0677f2ff 100644 --- a/apps/rosen/app/_hooks/useTokenBalance.ts +++ b/apps/rosen/app/_hooks/useTokenBalance.ts @@ -34,9 +34,13 @@ export const useTokenBalance = () => { const getAssetBalance = useCallback( async (wallet: Wallet) => { setBalanceState({ isLoading: true, amount: 0n, token: null }); - // THIS IS A WRAPPED-VALUE - const balance = await wallet.getBalance(token); - setBalanceState({ isLoading: false, amount: balance || 0n, token }); + try { + // THIS IS A WRAPPED-VALUE + const balance = await wallet.getBalance(token); + setBalanceState({ isLoading: false, amount: balance || 0n, token }); + } catch { + setBalanceState({ isLoading: false, amount: 0n, token }); + } }, [token], ); diff --git a/apps/rosen/app/_hooks/useTokenMap.ts b/apps/rosen/app/_hooks/useTokenMap.ts deleted file mode 100644 index 8435523c..00000000 --- a/apps/rosen/app/_hooks/useTokenMap.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { useEffect, useState, useTransition } from 'react'; - -import { TokenMap } from '@rosen-bridge/tokens'; - -import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; - -/** - * return TokenMap instance - */ -export const useTokenMap = (): TokenMap => { - const [tokenMap, setTokenMap] = useState( - new TokenMap({ idKeys: {}, tokens: [] }), - ); - - const [, startTransition] = useTransition(); - useEffect(() => { - startTransition(async () => { - setTokenMap(await getTokenMap()); - }); - }, []); - - return tokenMap!; -}; diff --git a/apps/rosen/app/_hooks/useTokenMap.tsx b/apps/rosen/app/_hooks/useTokenMap.tsx new file mode 100644 index 00000000..86e4cc61 --- /dev/null +++ b/apps/rosen/app/_hooks/useTokenMap.tsx @@ -0,0 +1,55 @@ +import { + ReactNode, + createContext, + useContext, + useEffect, + useState, + useTransition, +} from 'react'; + +import { TokenMap } from '@rosen-bridge/tokens'; + +import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; + +/** + * return TokenMap instance + */ +export const useTokenMap = () => { + const context = useContext(TokenMapContext); + + if (!context) { + throw new Error('useTokenMap must be used within TokenMapProvider'); + } + + return context; +}; + +export type TokenMapContextType = TokenMap; + +export const TokenMapContext = createContext(null); + +export const TokenMapProvider = ({ children }: { children: ReactNode }) => { + const [tokenMap, setTokenMap] = useState( + new TokenMap({ idKeys: {}, tokens: [] }), + ); + + const [, startTransition] = useTransition(); + + useEffect(() => { + startTransition(async () => { + try { + setTokenMap(await getTokenMap()); + } catch (error) { + throw new Error('Failed to fetch TokenMap, reload the page.', { + cause: error, + }); + } + }); + }, []); + + return ( + + {children} + + ); +}; diff --git a/apps/rosen/app/_hooks/useTransaction.ts b/apps/rosen/app/_hooks/useTransaction.ts index f945e7a2..eade7d24 100644 --- a/apps/rosen/app/_hooks/useTransaction.ts +++ b/apps/rosen/app/_hooks/useTransaction.ts @@ -48,29 +48,44 @@ export const useTransaction = () => { tokenMap.getSignificantDecimals(tokenValue.tokenId) || 0, ), ); - const txId = await selectedWallet?.transfer( - tokenValue as RosenChainToken, - amountValueWrapped, - targetValue, - selectedTarget.toSafeAddress(walletAddressValue), + const txId = await selectedWallet?.transfer({ + token: tokenValue as RosenChainToken, + amount: amountValueWrapped, + toChain: targetValue, + address: selectedTarget.toSafeAddress(walletAddressValue), bridgeFee, networkFee, lockAddress, - ); + }); openSnackbar(`Transaction submitted with id [${txId}]`, 'success'); - } catch (error) { + } catch (error: any) { /** * FIXME: Customize error messages based on error data * local:ergo/rosen-bridge/ui#169 */ - if (error instanceof Error) { - openSnackbar( - `An error occurred during submission: ${error.message}`, - 'error', - ); + const data = { + message: '', + details: '', + }; + + if (error.code && error.info) { + data.message = 'An error occurred during submission'; + data.details = error.info; + } else if (error.code && error.message) { + data.message = 'An error occurred during submission'; + data.details = error.message; + } else if (error instanceof Error) { + data.message = 'An error occurred during submission'; + data.details = error.message; } else { - openSnackbar(`An unknown error occurred: ${error}`, 'error'); + data.message = 'An unknown error occurred'; + data.details = error; } + + openSnackbar( + data.message + (data.details ? ` (${data.details})` : ''), + 'error', + ); } finally { setIsSubmitting(false); } diff --git a/apps/rosen/app/_hooks/useWallet.ts b/apps/rosen/app/_hooks/useWallet.ts index bf073965..3f8619b6 100644 --- a/apps/rosen/app/_hooks/useWallet.ts +++ b/apps/rosen/app/_hooks/useWallet.ts @@ -1,7 +1,7 @@ import { useEffect, useContext, useCallback, useRef } from 'react'; import { useLocalStorageManager } from '@rosen-ui/common-hooks'; -import { Wallet, WalletBase } from '@rosen-ui/wallet-api'; +import { Wallet } from '@rosen-ui/wallet-api'; import { WalletContext } from '@/_contexts/walletContext'; @@ -15,7 +15,7 @@ interface WalletDescriptor { /** * generates and return the wallet object to save in the local storage */ -const toWalletDescriptor = (wallet: WalletBase): WalletDescriptor => { +const toWalletDescriptor = (wallet: Wallet): WalletDescriptor => { let expDate = new Date(); return { name: wallet.name, @@ -39,19 +39,10 @@ export const useWallet = () => { * and return the wallet object if it finds a match */ const getWallet = useCallback( - (name: string): Wallet => { - let wallet: Wallet | undefined; - - wallet = ( - selectedSource - ? selectedSource.wallets.filter((wallet) => wallet.isAvailable()) - : [] - ).find((w: Wallet) => w.name === name); - if (!wallet) { - throw new Error(`unsupported wallet with name ${name}`); - } - - return wallet; + (name: string) => { + return selectedSource?.wallets + .filter((wallet) => wallet.isAvailable()) + .find((wallet) => wallet.name === name); }, [selectedSource], ); @@ -80,11 +71,9 @@ export const useWallet = () => { const setSelectedWallet = useCallback( async (wallet: Wallet) => { const prevWallet = getCurrentWallet(); - const status = await wallet.connectWallet(); + const status = await wallet.connect(); if (typeof status === 'boolean' && status) { - prevWallet?.onDisconnect && prevWallet.onDisconnect(); - wallet.onConnect && wallet.onConnect(); set(selectedSource!.name, toWalletDescriptor(wallet)); walletGlobalContext?.dispatch({ type: 'set', wallet }); } @@ -98,7 +87,7 @@ export const useWallet = () => { selectedWallet?.name !== walletGlobalContext?.state.selectedWallet?.name ) { if (selectedWallet) { - const status = await selectedWallet.connectWallet(); + const status = await selectedWallet.connect(); if (typeof status === 'boolean' && status) { walletGlobalContext?.dispatch({ type: 'set', diff --git a/apps/rosen/app/_networks/bitcoin/client.ts b/apps/rosen/app/_networks/bitcoin/client.ts index 5f9269a3..923b8806 100644 --- a/apps/rosen/app/_networks/bitcoin/client.ts +++ b/apps/rosen/app/_networks/bitcoin/client.ts @@ -1,6 +1,6 @@ import { BitcoinIcon } from '@rosen-bridge/icons'; import { NETWORK_LABELS, NETWORKS } from '@rosen-ui/constants'; -import { okxWalletCreator } from '@rosen-ui/okx-wallet'; +import { OKXWallet } from '@rosen-ui/okx-wallet'; import { unwrap } from '@/_safeServerAction'; import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; @@ -31,7 +31,7 @@ export const BitcoinNetwork: BitcoinNetworkType = { name: NETWORKS.BITCOIN, label: NETWORK_LABELS.BITCOIN, logo: BitcoinIcon, - wallets: [okxWalletCreator(config)], + wallets: [new OKXWallet(config)], nextHeightInterval: 1, lockAddress: process.env.NEXT_PUBLIC_BITCOIN_LOCK_ADDRESS!, getMaxTransfer: unwrap(getMaxTransfer), diff --git a/apps/rosen/app/_networks/cardano/client.ts b/apps/rosen/app/_networks/cardano/client.ts index 1dcd1385..905d3e01 100644 --- a/apps/rosen/app/_networks/cardano/client.ts +++ b/apps/rosen/app/_networks/cardano/client.ts @@ -1,9 +1,8 @@ import { CardanoIcon } from '@rosen-bridge/icons'; import { NETWORK_LABELS, NETWORKS } from '@rosen-ui/constants'; -import { eternlWalletCreator } from '@rosen-ui/eternl-wallet'; -import { flintWalletCreator } from '@rosen-ui/flint-wallet'; -import { laceWalletCreator } from '@rosen-ui/lace-wallet'; -import { namiWalletCreator } from '@rosen-ui/nami-wallet'; +import { EtrnlWallet } from '@rosen-ui/eternl-wallet'; +import { LaceWallet } from '@rosen-ui/lace-wallet'; +import { NamiWallet } from '@rosen-ui/nami-wallet'; import { unwrap } from '@/_safeServerAction'; import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; @@ -34,10 +33,9 @@ export const CardanoNetwork: CardanoNetworkType = { name: NETWORKS.CARDANO, label: NETWORK_LABELS.CARDANO, wallets: [ - eternlWalletCreator(config), - flintWalletCreator(config), - laceWalletCreator(config), - namiWalletCreator(config), + new EtrnlWallet(config), + new LaceWallet(config), + new NamiWallet(config), ], nextHeightInterval: 25, logo: CardanoIcon, diff --git a/apps/rosen/app/_networks/ergo/client.ts b/apps/rosen/app/_networks/ergo/client.ts index 3d5238e2..a25cca49 100644 --- a/apps/rosen/app/_networks/ergo/client.ts +++ b/apps/rosen/app/_networks/ergo/client.ts @@ -1,6 +1,6 @@ import { ErgoIcon } from '@rosen-bridge/icons'; import { NETWORK_LABELS, NETWORKS } from '@rosen-ui/constants'; -import { nautilusWalletCreator } from '@rosen-ui/nautilus-wallet'; +import { NautilusWallet } from '@rosen-ui/nautilus-wallet'; import { unwrap } from '@/_safeServerAction'; import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; @@ -22,7 +22,7 @@ const config = { export const ErgoNetwork: ErgoNetworkType = { name: NETWORKS.ERGO, label: NETWORK_LABELS.ERGO, - wallets: [nautilusWalletCreator(config)], + wallets: [new NautilusWallet(config)], logo: ErgoIcon, nextHeightInterval: 5, lockAddress: process.env.NEXT_PUBLIC_ERGO_LOCK_ADDRESS!, diff --git a/apps/rosen/app/_networks/ethereum/client.ts b/apps/rosen/app/_networks/ethereum/client.ts index 3c5ca9e3..06c1a223 100644 --- a/apps/rosen/app/_networks/ethereum/client.ts +++ b/apps/rosen/app/_networks/ethereum/client.ts @@ -1,6 +1,6 @@ import { EthereumIcon } from '@rosen-bridge/icons'; import { NETWORK_LABELS, NETWORKS } from '@rosen-ui/constants'; -import { metaMaskWalletCreator } from '@rosen-ui/metamask-wallet'; +import { MetaMaskWallet } from '@rosen-ui/metamask-wallet'; import { unwrap } from '@/_safeServerAction'; import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; @@ -18,7 +18,7 @@ export const EthereumNetwork: EthereumNetworkType = { name: NETWORKS.ETHEREUM, label: NETWORK_LABELS.ETHEREUM, wallets: [ - metaMaskWalletCreator({ + new MetaMaskWallet({ getTokenMap, generateLockData: unwrap(generateLockData), generateTxParameters: unwrap(generateTxParameters), diff --git a/apps/rosen/app/_safeServerAction/safeServerAction.ts b/apps/rosen/app/_safeServerAction/safeServerAction.ts index 3d010153..f05ff3a7 100644 --- a/apps/rosen/app/_safeServerAction/safeServerAction.ts +++ b/apps/rosen/app/_safeServerAction/safeServerAction.ts @@ -103,7 +103,13 @@ export const createSafeAction = (config: CreateSafeActionConfig) => { return async (...args) => { const key = [ actions.get(action), - ...args.map((arg) => arg.toString()), + ...args.map((arg) => { + try { + return JSON.stringify(arg); + } catch { + return arg.toString(); + } + }), ].join('_'); const handler = fromSafeData(action); diff --git a/apps/rosen/package.json b/apps/rosen/package.json index 21750e19..bf24667e 100644 --- a/apps/rosen/package.json +++ b/apps/rosen/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-bridge/rosen-app", - "version": "3.0.0", + "version": "4.0.0", "private": true, "scripts": { "prettify": "prettier --write . --ignore-path ../../.gitignore", @@ -22,33 +22,31 @@ "@rosen-bridge/cli": "^0.2.0", "@rosen-bridge/ergo-box-selection": "^0.1.0", "@rosen-bridge/extended-typeorm": "^0.0.3", - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/minimum-fee": "^2.0.1", "@rosen-bridge/observation-extractor": "^5.0.8", "@rosen-bridge/scanner": "^5.0.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-bridge/ui-kit": "^1.6.0", + "@rosen-bridge/ui-kit": "^1.7.0", "@rosen-bridge/watcher-data-extractor": "^9.0.0", "@rosen-clients/cardano-koios": "^2.0.1", "@rosen-clients/ergo-explorer": "^1.0.2", - "@rosen-network/bitcoin": "^1.1.0", - "@rosen-network/cardano": "^1.0.1", - "@rosen-network/ergo": "^1.0.0", - "@rosen-network/ethereum": "^0.1.1", + "@rosen-network/bitcoin": "^2.0.0", + "@rosen-network/cardano": "^2.0.0", + "@rosen-network/ergo": "^2.0.0", + "@rosen-network/ethereum": "^1.0.0", "@rosen-ui/asset-calculator": "^2.0.1", "@rosen-ui/common-hooks": "^0.1.1", "@rosen-ui/constants": "^0.0.5", - "@rosen-ui/eternl-wallet": "^1.0.3", - "@rosen-ui/flint-wallet": "^1.0.3", - "@rosen-ui/lace-wallet": "^1.0.3", - "@rosen-ui/metamask-wallet": "^0.1.4", - "@rosen-ui/nami-wallet": "^1.0.3", - "@rosen-ui/nautilus-wallet": "^1.0.3", - "@rosen-ui/okx-wallet": "^0.1.0", + "@rosen-ui/eternl-wallet": "^2.0.0", + "@rosen-ui/lace-wallet": "^2.0.0", + "@rosen-ui/metamask-wallet": "^1.0.0", + "@rosen-ui/nami-wallet": "^2.0.0", + "@rosen-ui/nautilus-wallet": "^2.0.0", + "@rosen-ui/okx-wallet": "^1.0.0", "@rosen-ui/swr-helpers": "^0.2.0", "@rosen-ui/types": "^0.3.1", "@rosen-ui/utils": "^0.4.2", - "@rosen-ui/vespr-wallet": "^0.0.11", "@rosen-ui/wallet-api": "^1.0.3", "@upstash/ratelimit": "^1.2.1", "@vercel/kv": "^2.0.0", diff --git a/apps/watcher/CHANGELOG.md b/apps/watcher/CHANGELOG.md index cb7b7cb2..404eb383 100644 --- a/apps/watcher/CHANGELOG.md +++ b/apps/watcher/CHANGELOG.md @@ -1,5 +1,15 @@ # @rosen-bridge/watcher-app +## 3.1.1 + +### Patch Changes + +- Resolve the dynamic title glitch that occurs when navigating between pages +- Integrated the Version component in the SideBar to display version information optimized for both desktop and mobile views. +- Updated dependencies + - @rosen-bridge/icons@1.0.0 + - @rosen-bridge/ui-kit@1.7.0 + ## 3.1.0 ### Minor Changes diff --git a/apps/watcher/app/App.tsx b/apps/watcher/app/App.tsx index 6df45561..92d74451 100644 --- a/apps/watcher/app/App.tsx +++ b/apps/watcher/app/App.tsx @@ -26,6 +26,8 @@ export const App = ({ children }: { children?: ReactNode }) => { * local:ergo/rosen-bridge/ui#408 */ useEffect(() => { + document.title = `Watcher`; + if (!info) return; document.title = `[${upperFirst(info.network)}] Watcher`; diff --git a/apps/watcher/app/SideBar.tsx b/apps/watcher/app/SideBar.tsx index dafeac1f..6425e479 100644 --- a/apps/watcher/app/SideBar.tsx +++ b/apps/watcher/app/SideBar.tsx @@ -1,5 +1,6 @@ import Link from 'next/link'; import { usePathname, useRouter } from 'next/navigation'; +import { useMemo, useState } from 'react'; import { Estate, @@ -13,6 +14,7 @@ import { AppLogo, NavigationBar, NavigationButton, + Version, } from '@rosen-bridge/ui-kit'; import packageJson from '../package.json'; @@ -55,28 +57,25 @@ export const SideBar = () => { const { data: info, isLoading } = useInfo(); - const versions = [ - { - title: 'Watcher', - value: info?.versions.app, - important: true, - }, - { - title: 'UI', - value: packageJson.version, - }, - { - title: 'Contract', - value: info?.versions.contract, - }, - ]; - - if (!isLoading && info?.versions.contract !== info?.versions.tokensMap) { - versions.push({ - title: 'Tokens', - value: info!.versions.tokensMap, - }); - } + const sub = useMemo(() => { + const result = [ + { + label: 'UI', + value: packageJson.version, + }, + { + label: 'Contract', + value: info?.versions.contract, + }, + ]; + if (!isLoading && info?.versions.contract !== info?.versions.tokensMap) { + result.push({ + label: 'Tokens', + value: info!.versions.tokensMap, + }); + } + return result; + }, [info, isLoading]); return ( { /> } - versions={versions} + versions={ + + } navigationBar={ {routes.map((route) => ( diff --git a/apps/watcher/app/layout.tsx b/apps/watcher/app/layout.tsx index 628afa40..224d2c27 100644 --- a/apps/watcher/app/layout.tsx +++ b/apps/watcher/app/layout.tsx @@ -1,12 +1,7 @@ -import { Metadata } from 'next'; import React from 'react'; import { App } from './App'; -export const metadata: Metadata = { - title: 'Watcher', -}; - const RootLayout = ({ children }: { children: React.ReactNode }) => { return ( /** diff --git a/apps/watcher/package.json b/apps/watcher/package.json index b6f78e34..2b9cd87b 100644 --- a/apps/watcher/package.json +++ b/apps/watcher/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-bridge/watcher-app", - "version": "3.1.0", + "version": "3.1.1", "private": true, "scripts": { "prettify": "prettier --write . --ignore-path ../../.gitignore", @@ -14,10 +14,10 @@ "dependencies": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/json-bigint": "^0.1.0", "@rosen-bridge/shared-contexts": "^0.0.2", - "@rosen-bridge/ui-kit": "^1.6.0", + "@rosen-bridge/ui-kit": "^1.7.0", "@rosen-ui/common-hooks": "^0.1.1", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/swr-helpers": "^0.2.0", diff --git a/build.sh b/build.sh index 7be9b8dd..818c4402 100755 --- a/build.sh +++ b/build.sh @@ -16,11 +16,9 @@ npm run build --workspace networks/bitcoin npm run build --workspace networks/cardano npm run build --workspace networks/ergo npm run build --workspace networks/ethereum -npm run build --workspace wallets/nami-wallet -npm run build --workspace wallets/lace-wallet -npm run build --workspace wallets/metamask-wallet -npm run build --workspace wallets/eternl-wallet -npm run build --workspace wallets/flint-wallet -npm run build --workspace wallets/vespr-wallet -npm run build --workspace wallets/nautilus-wallet -npm run build --workspace wallets/okx-wallet +npm run build --workspace wallets/eternl +npm run build --workspace wallets/lace +npm run build --workspace wallets/metamask +npm run build --workspace wallets/nami +npm run build --workspace wallets/nautilus +npm run build --workspace wallets/okx diff --git a/networks/bitcoin/CHANGELOG.md b/networks/bitcoin/CHANGELOG.md index ec68f781..6880dd68 100644 --- a/networks/bitcoin/CHANGELOG.md +++ b/networks/bitcoin/CHANGELOG.md @@ -1,5 +1,11 @@ # @rosen-network/bitcoin +## 2.0.0 + +### Major Changes + +- Eliminate the reliance on the @rosen-ui/wallet-api package and remove any unrelated type definitions + ## 1.1.0 ### Minor Changes diff --git a/networks/bitcoin/package.json b/networks/bitcoin/package.json index 7deb2ad6..8cc3e599 100644 --- a/networks/bitcoin/package.json +++ b/networks/bitcoin/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-network/bitcoin", - "version": "1.1.0", + "version": "2.0.0", "private": true, "description": "This is a private package utilized within Rosen Bridge UI app", "main": "dist/src/index.js", @@ -17,7 +17,6 @@ "@rosen-bridge/address-codec": "^0.3.0", "@rosen-bridge/bitcoin-utxo-selection": "^0.2.0", "@rosen-ui/constants": "^0.0.5", - "@rosen-ui/wallet-api": "^1.0.3", "axios": "^1.7.2", "bitcoinjs-lib": "^6.1.6" }, diff --git a/networks/bitcoin/src/types.ts b/networks/bitcoin/src/types.ts index c5e6e49a..8b3eaa1a 100644 --- a/networks/bitcoin/src/types.ts +++ b/networks/bitcoin/src/types.ts @@ -1,13 +1,3 @@ -import { TokenMap } from '@rosen-bridge/tokens'; -import { Wallet } from '@rosen-ui/wallet-api'; - -import { generateUnsignedTx } from './generateUnsignedTx'; -import type { - generateOpReturnData, - getAddressBalance, - submitTransaction, -} from './utils'; - export interface Status { confirmed: boolean; block_height?: number; @@ -69,13 +59,3 @@ export interface UnsignedPsbtData { }; inputSize: number; } - -export type WalletCreator = (config: WalletCreatorConfig) => Wallet; - -export type WalletCreatorConfig = { - getTokenMap(): Promise; - generateOpReturnData: typeof generateOpReturnData; - generateUnsignedTx: ReturnType; - submitTransaction: typeof submitTransaction; - getAddressBalance: typeof getAddressBalance; -}; diff --git a/networks/cardano/CHANGELOG.md b/networks/cardano/CHANGELOG.md index e72286a2..45b3aab5 100644 --- a/networks/cardano/CHANGELOG.md +++ b/networks/cardano/CHANGELOG.md @@ -1,5 +1,11 @@ # @rosen-network/cardano +## 2.0.0 + +### Major Changes + +- Eliminate the reliance on the @rosen-ui/wallet-api package and remove any unrelated type definitions + ## 1.0.1 ### Patch Changes diff --git a/networks/cardano/package.json b/networks/cardano/package.json index 17b5fc86..20f81aa9 100644 --- a/networks/cardano/package.json +++ b/networks/cardano/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-network/cardano", - "version": "1.0.1", + "version": "2.0.0", "private": true, "description": "This is a private package utilized within Rosen Bridge UI app", "main": "dist/src/index.js", @@ -15,8 +15,7 @@ "dependencies": { "@emurgo/cardano-serialization-lib-nodejs": "^11.5.0", "@rosen-bridge/cardano-utxo-selection": "^1.1.0", - "@rosen-clients/cardano-koios": "^2.0.3", - "@rosen-ui/wallet-api": "^1.0.3" + "@rosen-clients/cardano-koios": "^2.0.3" }, "devDependencies": { "typescript": "^5.0.0" diff --git a/networks/cardano/src/types.ts b/networks/cardano/src/types.ts index 4bd9f2f6..e154289c 100644 --- a/networks/cardano/src/types.ts +++ b/networks/cardano/src/types.ts @@ -1,13 +1,3 @@ -import { TokenMap } from '@rosen-bridge/tokens'; -import { CipWalletApi, Wallet } from '@rosen-ui/wallet-api'; - -import { generateUnsignedTx } from './generateUnsignedTx'; -import { - decodeWasmValue, - generateLockAuxiliaryData, - setTxWitnessSet, -} from './utils'; - export interface CardanoProtocolParams { min_fee_a: number; min_fee_b: number; @@ -19,28 +9,3 @@ export interface CardanoProtocolParams { } export const ADA_POLICY_ID = ''; - -export type WalletCreator = (config: WalletCreatorConfig) => Wallet; - -export type WalletCreatorConfig = { - getTokenMap(): Promise; - decodeWasmValue: typeof decodeWasmValue; - generateLockAuxiliaryData: typeof generateLockAuxiliaryData; - generateUnsignedTx: ReturnType; - setTxWitnessSet: typeof setTxWitnessSet; -}; - -export interface ConnectorAPI { - enable(): Promise; - isEnabled(): Promise; - experimental?: unknown; -} - -/** - * global type augmentation for wallets - */ -declare global { - interface Window { - cardano: { [key: string]: ConnectorAPI }; - } -} diff --git a/networks/ergo/CHANGELOG.md b/networks/ergo/CHANGELOG.md index 735bdc40..211c177e 100644 --- a/networks/ergo/CHANGELOG.md +++ b/networks/ergo/CHANGELOG.md @@ -1,5 +1,11 @@ # @rosen-network/ergo +## 2.0.0 + +### Major Changes + +- Eliminate the reliance on the @rosen-ui/wallet-api package and remove any unrelated type definitions + ## 1.0.0 ### Major Changes diff --git a/networks/ergo/package.json b/networks/ergo/package.json index 168019fc..c8fc7f4b 100644 --- a/networks/ergo/package.json +++ b/networks/ergo/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-network/ergo", - "version": "1.0.0", + "version": "2.0.0", "private": true, "description": "This is a private package utilized within Rosen Bridge UI app", "main": "dist/src/index.js", @@ -14,7 +14,6 @@ }, "dependencies": { "@rosen-clients/ergo-explorer": "^1.1.1", - "@rosen-ui/wallet-api": "^1.0.3", "ergo-lib-wasm-nodejs": "^0.24.1" }, "devDependencies": { diff --git a/networks/ergo/src/types.ts b/networks/ergo/src/types.ts index 5b245c8e..f698c49d 100644 --- a/networks/ergo/src/types.ts +++ b/networks/ergo/src/types.ts @@ -1,7 +1,4 @@ -import { TokenMap } from '@rosen-bridge/tokens'; -import { EipWalletApi, ErgoBoxProxy, Wallet } from '@rosen-ui/wallet-api'; - -import { generateUnsignedTx } from './generateUnsignedTx'; +import { ErgoBoxProxy } from '@rosen-ui/wallet-api'; export interface TokenInfo { id: string; @@ -22,17 +19,3 @@ export interface CoveringBoxes { covered: boolean; boxes: Array; } - -export type WalletCreator = (config: WalletCreatorConfig) => Wallet; - -export type WalletCreatorConfig = { - getTokenMap(): Promise; - generateUnsignedTx: ReturnType; -}; - -/** - * global type augmentation for nautilus wallet - */ -declare global { - let ergo: EipWalletApi; -} diff --git a/networks/ethereum/CHANGELOG.md b/networks/ethereum/CHANGELOG.md index 69460a34..d2cada61 100644 --- a/networks/ethereum/CHANGELOG.md +++ b/networks/ethereum/CHANGELOG.md @@ -1,5 +1,11 @@ # @rosen-network/ethereum +## 1.0.0 + +### Major Changes + +- Eliminate the reliance on the @rosen-ui/wallet-api package and remove any unrelated type definitions + ## 0.1.1 ### Patch Changes diff --git a/networks/ethereum/package.json b/networks/ethereum/package.json index d364e2d1..f049a7a1 100644 --- a/networks/ethereum/package.json +++ b/networks/ethereum/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-network/ethereum", - "version": "0.1.1", + "version": "1.0.0", "private": true, "description": "This is a private package utilized within Rosen Bridge UI app", "main": "dist/src/index.js", @@ -15,7 +15,6 @@ "dependencies": { "@rosen-bridge/address-codec": "^0.3.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-ui/wallet-api": "^1.0.3", "ethers": "^6.13.2" }, "devDependencies": { diff --git a/networks/ethereum/src/index.ts b/networks/ethereum/src/index.ts index 584557bb..d1e10975 100644 --- a/networks/ethereum/src/index.ts +++ b/networks/ethereum/src/index.ts @@ -1,4 +1,3 @@ export * from './constants'; export * from './generateTxParameters'; -export * from './types'; export * from './utils'; diff --git a/networks/ethereum/src/types.ts b/networks/ethereum/src/types.ts deleted file mode 100644 index 28d8e82c..00000000 --- a/networks/ethereum/src/types.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { TokenMap } from '@rosen-bridge/tokens'; -import { Wallet } from '@rosen-ui/wallet-api'; - -import { generateTxParameters } from './generateTxParameters'; -import { generateLockData } from './utils'; - -export type WalletCreator = (config: WalletCreatorConfig) => Wallet; - -export type WalletCreatorConfig = { - getTokenMap(): Promise; - generateLockData: typeof generateLockData; - generateTxParameters: ReturnType; -}; diff --git a/package-lock.json b/package-lock.json index 97a57406..63cd1db6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,13 +33,13 @@ }, "apps/guard": { "name": "@rosen-bridge/guard-app", - "version": "1.9.0", + "version": "1.9.1", "dependencies": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/shared-contexts": "^0.0.2", - "@rosen-bridge/ui-kit": "^1.6.0", + "@rosen-bridge/ui-kit": "^1.7.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/swr-helpers": "^0.2.0", "@rosen-ui/utils": "^0.4.2", @@ -223,7 +223,7 @@ }, "apps/rosen": { "name": "@rosen-bridge/rosen-app", - "version": "3.0.0", + "version": "4.0.0", "dependencies": { "@emurgo/cardano-serialization-lib-browser": "^11.5.0", "@emurgo/cardano-serialization-lib-nodejs": "^11.5.0", @@ -233,33 +233,31 @@ "@rosen-bridge/cli": "^0.2.0", "@rosen-bridge/ergo-box-selection": "^0.1.0", "@rosen-bridge/extended-typeorm": "^0.0.3", - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/minimum-fee": "^2.0.1", "@rosen-bridge/observation-extractor": "^5.0.8", "@rosen-bridge/scanner": "^5.0.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-bridge/ui-kit": "^1.6.0", + "@rosen-bridge/ui-kit": "^1.7.0", "@rosen-bridge/watcher-data-extractor": "^9.0.0", "@rosen-clients/cardano-koios": "^2.0.1", "@rosen-clients/ergo-explorer": "^1.0.2", - "@rosen-network/bitcoin": "^1.1.0", - "@rosen-network/cardano": "^1.0.1", - "@rosen-network/ergo": "^1.0.0", - "@rosen-network/ethereum": "^0.1.1", + "@rosen-network/bitcoin": "^2.0.0", + "@rosen-network/cardano": "^2.0.0", + "@rosen-network/ergo": "^2.0.0", + "@rosen-network/ethereum": "^1.0.0", "@rosen-ui/asset-calculator": "^2.0.1", "@rosen-ui/common-hooks": "^0.1.1", "@rosen-ui/constants": "^0.0.5", - "@rosen-ui/eternl-wallet": "^1.0.3", - "@rosen-ui/flint-wallet": "^1.0.3", - "@rosen-ui/lace-wallet": "^1.0.3", - "@rosen-ui/metamask-wallet": "^0.1.4", - "@rosen-ui/nami-wallet": "^1.0.3", - "@rosen-ui/nautilus-wallet": "^1.0.3", - "@rosen-ui/okx-wallet": "^0.1.0", + "@rosen-ui/eternl-wallet": "^2.0.0", + "@rosen-ui/lace-wallet": "^2.0.0", + "@rosen-ui/metamask-wallet": "^1.0.0", + "@rosen-ui/nami-wallet": "^2.0.0", + "@rosen-ui/nautilus-wallet": "^2.0.0", + "@rosen-ui/okx-wallet": "^1.0.0", "@rosen-ui/swr-helpers": "^0.2.0", "@rosen-ui/types": "^0.3.1", "@rosen-ui/utils": "^0.4.2", - "@rosen-ui/vespr-wallet": "^0.0.11", "@rosen-ui/wallet-api": "^1.0.3", "@upstash/ratelimit": "^1.2.1", "@vercel/kv": "^2.0.0", @@ -288,7 +286,7 @@ }, "apps/rosen-service": { "name": "@rosen-bridge/rosen-service", - "version": "2.1.0", + "version": "2.2.0", "license": "GPL-3.0", "dependencies": { "@rosen-bridge/abstract-extractor": "^0.3.1", @@ -584,14 +582,14 @@ }, "apps/watcher": { "name": "@rosen-bridge/watcher-app", - "version": "3.1.0", + "version": "3.1.1", "dependencies": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/json-bigint": "^0.1.0", "@rosen-bridge/shared-contexts": "^0.0.2", - "@rosen-bridge/ui-kit": "^1.6.0", + "@rosen-bridge/ui-kit": "^1.7.0", "@rosen-ui/common-hooks": "^0.1.1", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/swr-helpers": "^0.2.0", @@ -776,12 +774,11 @@ }, "networks/bitcoin": { "name": "@rosen-network/bitcoin", - "version": "1.1.0", + "version": "2.0.0", "dependencies": { "@rosen-bridge/address-codec": "^0.3.0", "@rosen-bridge/bitcoin-utxo-selection": "^0.2.0", "@rosen-ui/constants": "^0.0.5", - "@rosen-ui/wallet-api": "^1.0.3", "axios": "^1.7.2", "bitcoinjs-lib": "^6.1.6" }, @@ -791,12 +788,11 @@ }, "networks/cardano": { "name": "@rosen-network/cardano", - "version": "1.0.1", + "version": "2.0.0", "dependencies": { "@emurgo/cardano-serialization-lib-nodejs": "^11.5.0", "@rosen-bridge/cardano-utxo-selection": "^1.1.0", - "@rosen-clients/cardano-koios": "^2.0.3", - "@rosen-ui/wallet-api": "^1.0.3" + "@rosen-clients/cardano-koios": "^2.0.3" }, "devDependencies": { "typescript": "^5.0.0" @@ -804,10 +800,9 @@ }, "networks/ergo": { "name": "@rosen-network/ergo", - "version": "1.0.0", + "version": "2.0.0", "dependencies": { "@rosen-clients/ergo-explorer": "^1.1.1", - "@rosen-ui/wallet-api": "^1.0.3", "ergo-lib-wasm-nodejs": "^0.24.1" }, "devDependencies": { @@ -816,11 +811,10 @@ }, "networks/ethereum": { "name": "@rosen-network/ethereum", - "version": "0.1.1", + "version": "1.0.0", "dependencies": { "@rosen-bridge/address-codec": "^0.3.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-ui/wallet-api": "^1.0.3", "ethers": "^6.13.2" }, "devDependencies": { @@ -9620,31 +9614,27 @@ "link": true }, "node_modules/@rosen-ui/eternl-wallet": { - "resolved": "wallets/eternl-wallet", - "link": true - }, - "node_modules/@rosen-ui/flint-wallet": { - "resolved": "wallets/flint-wallet", + "resolved": "wallets/eternl", "link": true }, "node_modules/@rosen-ui/lace-wallet": { - "resolved": "wallets/lace-wallet", + "resolved": "wallets/lace", "link": true }, "node_modules/@rosen-ui/metamask-wallet": { - "resolved": "wallets/metamask-wallet", + "resolved": "wallets/metamask", "link": true }, "node_modules/@rosen-ui/nami-wallet": { - "resolved": "wallets/nami-wallet", + "resolved": "wallets/nami", "link": true }, "node_modules/@rosen-ui/nautilus-wallet": { - "resolved": "wallets/nautilus-wallet", + "resolved": "wallets/nautilus", "link": true }, "node_modules/@rosen-ui/okx-wallet": { - "resolved": "wallets/okx-wallet", + "resolved": "wallets/okx", "link": true }, "node_modules/@rosen-ui/swr-helpers": { @@ -9663,10 +9653,6 @@ "resolved": "packages/utils", "link": true }, - "node_modules/@rosen-ui/vespr-wallet": { - "resolved": "wallets/vespr-wallet", - "link": true - }, "node_modules/@rosen-ui/wallet-api": { "resolved": "wallets/wallet-api", "link": true @@ -26345,7 +26331,7 @@ }, "packages/icons": { "name": "@rosen-bridge/icons", - "version": "0.7.0", + "version": "1.0.0", "license": "GPL-3.0", "devDependencies": { "@types/react": "18.2.12", @@ -26408,12 +26394,12 @@ }, "packages/ui-kit": { "name": "@rosen-bridge/ui-kit", - "version": "1.6.0", + "version": "1.7.0", "license": "GPL-3.0", "dependencies": { "@mui/lab": "^5.0.0-alpha.134", "@mui/material": "^5.13.4", - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/shared-contexts": "^0.0.2", "@rosen-ui/common-hooks": "^0.1.1", "@rosen-ui/constants": "^0.0.5", @@ -26450,29 +26436,13 @@ "typescript": "^5.0.0" } }, - "wallets/eternl-wallet": { + "wallets/eternl": { "name": "@rosen-ui/eternl-wallet", - "version": "1.0.3", - "dependencies": { - "@rosen-bridge/icons": "^0.7.0", - "@rosen-bridge/tokens": "^1.2.1", - "@rosen-network/cardano": "^1.0.1", - "@rosen-ui/constants": "^0.0.5", - "@rosen-ui/types": "^0.3.1", - "@rosen-ui/utils": "^0.4.2", - "@rosen-ui/wallet-api": "^1.0.3" - }, - "devDependencies": { - "typescript": "^5.0.0" - } - }, - "wallets/flint-wallet": { - "name": "@rosen-ui/flint-wallet", - "version": "1.0.3", + "version": "2.0.0", "dependencies": { - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-network/cardano": "^1.0.1", + "@rosen-network/cardano": "^2.0.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/types": "^0.3.1", "@rosen-ui/utils": "^0.4.2", @@ -26482,13 +26452,13 @@ "typescript": "^5.0.0" } }, - "wallets/lace-wallet": { + "wallets/lace": { "name": "@rosen-ui/lace-wallet", - "version": "1.0.3", + "version": "2.0.0", "dependencies": { - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-network/cardano": "^1.0.1", + "@rosen-network/cardano": "^2.0.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/types": "^0.3.1", "@rosen-ui/utils": "^0.4.2", @@ -26498,14 +26468,14 @@ "typescript": "^5.0.0" } }, - "wallets/metamask-wallet": { + "wallets/metamask": { "name": "@rosen-ui/metamask-wallet", - "version": "0.1.4", + "version": "1.0.0", "dependencies": { "@metamask/sdk": "^0.28.2", - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-network/ethereum": "^0.1.1", + "@rosen-network/ethereum": "^1.0.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/types": "^0.3.1", "@rosen-ui/wallet-api": "^1.0.3" @@ -26514,13 +26484,13 @@ "typescript": "^5.0.0" } }, - "wallets/nami-wallet": { + "wallets/nami": { "name": "@rosen-ui/nami-wallet", - "version": "1.0.3", + "version": "2.0.0", "dependencies": { - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-network/cardano": "^1.0.1", + "@rosen-network/cardano": "^2.0.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/types": "^0.3.1", "@rosen-ui/utils": "^0.4.2", @@ -26530,12 +26500,12 @@ "typescript": "^5.0.0" } }, - "wallets/nautilus-wallet": { + "wallets/nautilus": { "name": "@rosen-ui/nautilus-wallet", - "version": "1.0.3", + "version": "2.0.0", "dependencies": { - "@rosen-bridge/icons": "^0.7.0", - "@rosen-network/ergo": "^1.0.0", + "@rosen-bridge/icons": "^1.0.0", + "@rosen-network/ergo": "^2.0.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/types": "^0.3.1", "@rosen-ui/utils": "^0.4.2", @@ -26546,13 +26516,13 @@ "typescript": "^5.0.0" } }, - "wallets/okx-wallet": { + "wallets/okx": { "name": "@rosen-ui/okx-wallet", - "version": "0.1.0", + "version": "1.0.0", "dependencies": { - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-network/bitcoin": "^1.1.0", + "@rosen-network/bitcoin": "^2.0.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/types": "^0.3.2", "@rosen-ui/wallet-api": "^1.0.3" @@ -26561,18 +26531,6 @@ "typescript": "^5.0.0" } }, - "wallets/vespr-wallet": { - "name": "@rosen-ui/vespr-wallet", - "version": "0.0.11", - "dependencies": { - "@rosen-bridge/icons": "^0.7.0", - "@rosen-ui/utils": "^0.4.2", - "@rosen-ui/wallet-api": "^1.0.3" - }, - "devDependencies": { - "typescript": "^5.0.0" - } - }, "wallets/wallet-api": { "name": "@rosen-ui/wallet-api", "version": "1.0.3", diff --git a/package.json b/package.json index da1406f5..c830c83e 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,8 @@ "coverage": "npm run test -- --coverage", "version": "npx changeset version && npm i && npx changeset --empty", "version:rosen": "npx changeset version --ignore @rosen-bridge/watcher-app --ignore @rosen-bridge/guard-app && npm i && npx changeset --empty", - "version:watcher": "npx changeset version --ignore=@rosen-bridge/rosen-service --ignore @rosen-bridge/rosen-app --ignore @rosen-bridge/guard-app --ignore @rosen-network/ergo --ignore @rosen-network/cardano --ignore @rosen-network/bitcoin --ignore @rosen-ui/eternl-wallet --ignore @rosen-ui/flint-wallet --ignore @rosen-ui/lace-wallet --ignore @rosen-ui/nami-wallet --ignore @rosen-ui/nautilus-wallet --ignore @rosen-ui/okx-wallet --ignore @rosen-ui/vespr-wallet --ignore @rosen-ui/asset-calculator --ignore @rosen-ui/wallet-api && npm i && npx changeset --empty", - "version:guard": "npx changeset version --ignore=@rosen-bridge/rosen-service --ignore @rosen-bridge/watcher-app --ignore @rosen-bridge/rosen-app --ignore @rosen-network/ergo --ignore @rosen-network/cardano --ignore @rosen-network/bitcoin --ignore @rosen-ui/eternl-wallet --ignore @rosen-ui/flint-wallet --ignore @rosen-ui/lace-wallet --ignore @rosen-ui/nami-wallet --ignore @rosen-ui/nautilus-wallet --ignore @rosen-ui/okx-wallet --ignore @rosen-ui/vespr-wallet --ignore @rosen-ui/asset-calculator --ignore @rosen-ui/wallet-api && npm i && npx changeset --empty" + "version:watcher": "npx changeset version --ignore=@rosen-bridge/rosen-service --ignore @rosen-bridge/rosen-app --ignore @rosen-bridge/guard-app --ignore @rosen-network/ergo --ignore @rosen-network/cardano --ignore @rosen-network/bitcoin --ignore @rosen-network/ethereum --ignore @rosen-ui/eternl-wallet --ignore @rosen-ui/lace-wallet --ignore @rosen-ui/metamask-wallet --ignore @rosen-ui/nami-wallet --ignore @rosen-ui/nautilus-wallet --ignore @rosen-ui/okx-wallet --ignore @rosen-ui/asset-calculator --ignore @rosen-ui/wallet-api && npm i && npx changeset --empty", + "version:guard": "npx changeset version --ignore=@rosen-bridge/rosen-service --ignore @rosen-bridge/watcher-app --ignore @rosen-bridge/rosen-app --ignore @rosen-network/ergo --ignore @rosen-network/cardano --ignore @rosen-network/bitcoin --ignore @rosen-network/ethereum --ignore @rosen-ui/eternl-wallet --ignore @rosen-ui/lace-wallet --ignore @rosen-ui/metamask-wallet --ignore @rosen-ui/nami-wallet --ignore @rosen-ui/nautilus-wallet --ignore @rosen-ui/okx-wallet --ignore @rosen-ui/asset-calculator --ignore @rosen-ui/wallet-api && npm i && npx changeset --empty" }, "dependencies": { "@changesets/cli": "^2.27.1" diff --git a/packages/icons/CHANGELOG.md b/packages/icons/CHANGELOG.md index eab1932d..86571c5b 100644 --- a/packages/icons/CHANGELOG.md +++ b/packages/icons/CHANGELOG.md @@ -1,5 +1,15 @@ # @rosen-bridge/icons +## 1.0.0 + +### Major Changes + +- Drop the Flint wallet icon + +### Patch Changes + +- Implement new Paste icon + ## 0.7.0 ### Minor Changes diff --git a/packages/icons/package.json b/packages/icons/package.json index 340d6b14..0dd7285b 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -2,7 +2,7 @@ "name": "@rosen-bridge/icons", "description": "A react icon set wrapping Unicons, used in Rosen apps", "private": "true", - "version": "0.7.0", + "version": "1.0.0", "type": "module", "types": "./dist/index.d.ts", "files": [ diff --git a/packages/icons/src/icons/paste.svg b/packages/icons/src/icons/paste.svg new file mode 100644 index 00000000..0055f63f --- /dev/null +++ b/packages/icons/src/icons/paste.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/icons/src/index.ts b/packages/icons/src/index.ts index 4c7767c9..63a03d1c 100644 --- a/packages/icons/src/index.ts +++ b/packages/icons/src/index.ts @@ -30,6 +30,7 @@ export { ReactComponent as MoneyWithdrawal } from './icons/money-withdrawal.svg' export { ReactComponent as Moon } from './icons/moon.svg'; export { ReactComponent as Newspaper } from './icons/newspaper.svg'; export { ReactComponent as OpenInNew } from './icons/open-in-new.svg'; +export { ReactComponent as Paste } from './icons/paste.svg'; export { ReactComponent as Pause } from './icons/pause.svg'; export { ReactComponent as PauseCircle } from './icons/pause-circle.svg'; export { ReactComponent as QrcodeScan } from './icons/qrcode-scan.svg'; diff --git a/packages/icons/src/wallets/flint.svg b/packages/icons/src/wallets/flint.svg deleted file mode 100644 index 0ebb1e31..00000000 --- a/packages/icons/src/wallets/flint.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/icons/src/wallets/index.ts b/packages/icons/src/wallets/index.ts index a0aea3d5..a8a4b7a3 100644 --- a/packages/icons/src/wallets/index.ts +++ b/packages/icons/src/wallets/index.ts @@ -1,5 +1,4 @@ export { ReactComponent as NamiIcon } from './nami.svg'; -export { ReactComponent as FlintIcon } from './flint.svg'; export { ReactComponent as EternlIcon } from './eternl.svg'; export { ReactComponent as LaceIcon } from './lace.svg'; export { ReactComponent as MetaMaskIcon } from './metamask.svg'; diff --git a/packages/ui-kit/CHANGELOG.md b/packages/ui-kit/CHANGELOG.md index 2cc33d80..8732aa86 100644 --- a/packages/ui-kit/CHANGELOG.md +++ b/packages/ui-kit/CHANGELOG.md @@ -1,5 +1,19 @@ # @rosen-bridge/ui-kit +## 1.7.0 + +### Minor Changes + +- Revise the default layout to incorporate toolbar buttons into the sidebar for mobile devices +- Create an improved dialogue that aligns with our Figma design and ensures responsiveness + +### Patch Changes + +- Review theme colors in Figma and ensure consistency by identifying and fixing any mismatches +- Implement Version component to display versions +- Updated dependencies +- Updated the @rosen-bridge/icons@1.0.0 dependency + ## 1.6.0 ### Minor Changes diff --git a/packages/ui-kit/package.json b/packages/ui-kit/package.json index a4de9cf1..e68270c5 100644 --- a/packages/ui-kit/package.json +++ b/packages/ui-kit/package.json @@ -2,7 +2,7 @@ "name": "@rosen-bridge/ui-kit", "description": "ui kit for Rosen projects", "private": true, - "version": "1.6.0", + "version": "1.7.0", "type": "module", "files": [ "dist" @@ -39,7 +39,7 @@ "dependencies": { "@mui/lab": "^5.0.0-alpha.134", "@mui/material": "^5.13.4", - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/shared-contexts": "^0.0.2", "@rosen-ui/common-hooks": "^0.1.1", "@rosen-ui/constants": "^0.0.5", diff --git a/packages/ui-kit/src/components/common/App.tsx b/packages/ui-kit/src/components/common/App.tsx index f1f09f97..b9529dcf 100644 --- a/packages/ui-kit/src/components/common/App.tsx +++ b/packages/ui-kit/src/components/common/App.tsx @@ -1,9 +1,10 @@ import { ReactNode } from 'react'; import { SnackbarProvider } from '../../contexts'; +import { useMediaQuery } from '../../hooks'; import { ThemeProvider, ThemeProviderProps } from '../../Providers'; import { styled } from '../../styling'; -import { CssBaseline } from '../base'; +import { Box, CssBaseline } from '../base'; import { AppSnackbar } from './AppSnackbar'; const Root = styled('div', { @@ -49,15 +50,33 @@ interface AppProps { } export const App = ({ children, sideBar, theme, toolbar }: AppProps) => { + const isMobile = useMediaQuery( + ('light' in theme ? theme.light : theme).breakpoints.down('tablet'), + ); return ( <> - {sideBar} + {isMobile ? ( + + {sideBar} + {toolbar} + + ) : ( + sideBar + )}
-
{toolbar}
+ {!isMobile && ( +
+ {toolbar} +
+ )} {children}
diff --git a/packages/ui-kit/src/components/common/AppBar.tsx b/packages/ui-kit/src/components/common/AppBar.tsx index 8eb0e619..6806ce90 100644 --- a/packages/ui-kit/src/components/common/AppBar.tsx +++ b/packages/ui-kit/src/components/common/AppBar.tsx @@ -1,20 +1,14 @@ import { FC, ReactNode } from 'react'; import { styled } from '../../styling'; -import { Box, CircularProgress, Typography } from '../base'; +import { Box } from '../base'; interface AppBarProps { logo?: ReactNode; - versions?: Version[]; + versions?: ReactNode; navigationBar?: ReactNode; } -interface Version { - important?: boolean; - title: string; - value?: string; -} - const Root = styled(Box)(({ theme }) => ({ position: 'relative', padding: theme.spacing(2) + ' 0', @@ -30,49 +24,16 @@ const Root = styled(Box)(({ theme }) => ({ }, })); -const Versions = styled(Box)(({ theme }) => ({ - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - [theme.breakpoints.down('tablet')]: { - flexDirection: 'row', - justifyContent: 'start', - position: 'absolute', - left: '46px', - top: '32px', - gap: theme.spacing(1), - }, -})); - /** * renders a appBar wrapper * this component set the appBar size and orientation in different screen sizes */ -export const AppBar: FC = ({ - logo, - versions = [], - navigationBar, -}) => { - const loadingVersions = versions.every((version) => version.value); +export const AppBar: FC = ({ logo, versions, navigationBar }) => { return ( {logo} {navigationBar} - - {loadingVersions ? ( - versions.map((version) => ( - - {version.title} v{version.value} - - )) - ) : ( - - )} - + {versions} ); }; diff --git a/packages/ui-kit/src/components/common/EnhancedDialog.tsx b/packages/ui-kit/src/components/common/EnhancedDialog.tsx new file mode 100644 index 00000000..31866e82 --- /dev/null +++ b/packages/ui-kit/src/components/common/EnhancedDialog.tsx @@ -0,0 +1,18 @@ +import { styled } from '../../styling'; +import { Dialog } from '../base'; + +/** + * renders an enhanced version of material ui Dialog + */ +export const EnhancedDialog = styled(Dialog)(({ theme }) => ({ + [theme.breakpoints.down('tablet')]: { + '& > .MuiDialog-container': { + 'alignItems': 'end', + '& > .MuiPaper-root': { + margin: 0, + borderBottomRightRadius: 0, + borderBottomLeftRadius: 0, + }, + }, + }, +})); diff --git a/packages/ui-kit/src/components/common/EnhancedDialogTitle.tsx b/packages/ui-kit/src/components/common/EnhancedDialogTitle.tsx index bfa02267..c35c403d 100644 --- a/packages/ui-kit/src/components/common/EnhancedDialogTitle.tsx +++ b/packages/ui-kit/src/components/common/EnhancedDialogTitle.tsx @@ -3,6 +3,7 @@ import React from 'react'; import { styled } from '@mui/material'; import { Times } from '@rosen-bridge/icons'; +import { useIsMobile } from '../../hooks'; import { DialogTitle, DialogTitleProps, IconButton, SvgIcon } from '../base'; const IconContainer = styled('div')(({ theme }) => ({ @@ -25,15 +26,22 @@ export const EnhancedDialogTitle = ({ onClose, ...props }: EnhancedDialogTitleProps) => { + const isMobile = useIsMobile(); return ( - - {icon && ( + + {!isMobile && icon && ( {icon} )} {props.children} - {onClose && ( + {!isMobile && onClose && ( diff --git a/packages/ui-kit/src/components/common/NavigationButton.tsx b/packages/ui-kit/src/components/common/NavigationButton.tsx index 27e98430..8692d77b 100644 --- a/packages/ui-kit/src/components/common/NavigationButton.tsx +++ b/packages/ui-kit/src/components/common/NavigationButton.tsx @@ -109,7 +109,7 @@ export const NavigationButton: FC = (props) => { if (badge) startIcon = ( - + {startIcon} ); diff --git a/packages/ui-kit/src/components/common/Toolbar.tsx b/packages/ui-kit/src/components/common/Toolbar.tsx index bd2afcc9..e7d0049e 100644 --- a/packages/ui-kit/src/components/common/Toolbar.tsx +++ b/packages/ui-kit/src/components/common/Toolbar.tsx @@ -1,5 +1,6 @@ import React from 'react'; +import { useIsMobile } from '../../hooks'; import { isLegacyTheme, useTheme } from '../../hooks/useTheme'; import { styled } from '../../styling'; import { Typography, Stack, Grid } from '../base'; @@ -40,6 +41,15 @@ export const Toolbar: React.FC = (props) => { const theme = useTheme(); const textAlign = isCentered ? 'center' : 'inherit'; + const isMobile = useIsMobile(); + + if (isMobile) + return ( +
+ {toolbarActions} +
+ ); + return (
diff --git a/packages/ui-kit/src/components/common/Version.tsx b/packages/ui-kit/src/components/common/Version.tsx new file mode 100644 index 00000000..328247fb --- /dev/null +++ b/packages/ui-kit/src/components/common/Version.tsx @@ -0,0 +1,94 @@ +import React, { FC, useEffect, useMemo, useRef, useState } from 'react'; + +import { useIsMobile } from '../../hooks'; +import { styled } from '../../styling'; +import { CircularProgress } from '../base'; + +interface VersionProps { + label: string; + value?: string; + sub?: Array<{ label: string; value?: string }>; +} + +const Root = styled('div', { + name: 'RosenVersion', + slot: 'Root', + overridesResolver: (props, styles) => styles.root, +})(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'start', + fontWeight: '400px', + fontSize: '12px', + lineHeight: '14.06px', + color: theme.palette.text.secondary, + [theme.breakpoints.down('tablet')]: { + flexDirection: 'row', + justifyContent: 'start', + position: 'absolute', + left: '46px', + top: '32px', + lineHeight: '12px', + gap: theme.spacing(1), + }, +})); + +export const Version: FC = ({ label, value, sub }) => { + const $timeout = useRef(); + + const isMobile = useIsMobile(); + + const [timeout, setTimeout] = useState(false); + + const loaded = useMemo(() => { + if (sub) { + return !!value && !!sub.every((item) => !!item.value); + } else { + return !!value; + } + }, [value, sub]); + + const isLoading = !(loaded || timeout); + + useEffect(() => { + clearTimeout($timeout.current); + $timeout.current = window.setTimeout(() => { + setTimeout(true); + }, 15000); + return () => { + clearTimeout($timeout.current); + }; + }, [value, sub]); + + return ( + + {isLoading ? ( + + ) : ( + <> + + {label} v{value || '?'} + + {isMobile && sub ? ( + + ( + {sub + ?.map((item) => `${item.label} v${item.value || '?'}`) + .join(', ')} + ) + + ) : ( + <> + {sub?.map((item) => ( + + {item.label} v{item.value || '?'} + + ))} + + )} + + )} + + ); +}; diff --git a/packages/ui-kit/src/components/common/index.ts b/packages/ui-kit/src/components/common/index.ts index 9db3c086..96a2e6ee 100644 --- a/packages/ui-kit/src/components/common/index.ts +++ b/packages/ui-kit/src/components/common/index.ts @@ -4,6 +4,7 @@ export * from './ApiKeyModal'; export * from './App'; export * from './AppBar'; export * from './AppLogo'; +export * from './EnhancedDialog'; export * from './EnhancedDialogTitle'; export * from './EnhancedTable'; export * from './EnhancedTableCell'; @@ -13,6 +14,7 @@ export * from './HealthParamCardSkeleton'; export * from './Id'; export * from './NavigationBar'; export * from './NavigationButton'; +export * from './Version'; export * from './QrCodeModal'; export * from './SuccessfulCopySnackbar'; export * from './SubmitButton'; diff --git a/wallets/eternl-wallet/src/connectWallet.ts b/wallets/eternl-wallet/src/connectWallet.ts deleted file mode 100644 index 7ec50ef3..00000000 --- a/wallets/eternl-wallet/src/connectWallet.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * handles the Eternl wallet connection - */ - -export const connectWallet = async (): Promise => { - const granted = await window.cardano.eternl?.enable(); - - if (!granted) { - console.error('Failed to connect!'); - return false; - } - return true; -}; diff --git a/wallets/eternl-wallet/src/eternlWalletCreator.ts b/wallets/eternl-wallet/src/eternlWalletCreator.ts deleted file mode 100644 index 90e674ae..00000000 --- a/wallets/eternl-wallet/src/eternlWalletCreator.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { WalletCreator } from '@rosen-network/cardano'; - -import { getBalanceCreator } from './getBalance'; -import { getEternlWallet } from './getEternlWallet'; -import { isEternlAvailable } from './isEternlAvailable'; -import { transferCreator } from './transfer'; - -export const eternlWalletCreator: WalletCreator = (config) => { - return Object.assign({}, getEternlWallet(), { - isAvailable: isEternlAvailable, - getBalance: getBalanceCreator(config), - transfer: transferCreator(config), - getAddress: async () => { - throw new Error('Not implemented'); - }, - }); -}; diff --git a/wallets/eternl-wallet/src/eternlWalletInfo.ts b/wallets/eternl-wallet/src/eternlWalletInfo.ts deleted file mode 100644 index 6a93bea7..00000000 --- a/wallets/eternl-wallet/src/eternlWalletInfo.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { EternlIcon } from '@rosen-bridge/icons'; -import { WalletInfo } from '@rosen-ui/wallet-api'; - -export const eternlWalletInfo: WalletInfo = { - icon: EternlIcon, - name: 'Eternl', - label: 'Eternl', - link: 'https://eternl.io/', -}; diff --git a/wallets/eternl-wallet/src/getBalance.ts b/wallets/eternl-wallet/src/getBalance.ts deleted file mode 100644 index a216cb4d..00000000 --- a/wallets/eternl-wallet/src/getBalance.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/cardano'; -import { NETWORKS } from '@rosen-ui/constants'; -import { RosenAmountValue } from '@rosen-ui/types'; -import { hexToCbor } from '@rosen-ui/utils'; - -import { getEternlWallet } from './getEternlWallet'; - -export const getBalanceCreator = - (config: WalletCreatorConfig) => - async (token: RosenChainToken): Promise => { - const context = await getEternlWallet().getApi().enable(); - const rawValue = await context.getBalance(); - const balances = await config.decodeWasmValue(rawValue); - - const amount = balances.find( - (asset) => - asset.policyId === token.policyId && - (asset.nameHex === hexToCbor(token.assetName) || !token.policyId), - ); - - if (!amount) return 0n; - - const tokenMap = await config.getTokenMap(); - - const wrappedAmount = tokenMap.wrapAmount( - token[tokenMap.getIdKey(NETWORKS.CARDANO)], - amount.quantity, - NETWORKS.CARDANO, - ).amount; - - return wrappedAmount; - }; diff --git a/wallets/eternl-wallet/src/getEternlWallet.ts b/wallets/eternl-wallet/src/getEternlWallet.ts deleted file mode 100644 index 5989a438..00000000 --- a/wallets/eternl-wallet/src/getEternlWallet.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createRawWallet } from '@rosen-ui/wallet-api'; - -import { connectWallet } from './connectWallet'; -import { eternlWalletInfo } from './eternlWalletInfo'; - -/** - * Eternl implementation of the Wallet - * interface to be able to interact with Eternl wallet - */ -export const getEternlWallet = () => { - return createRawWallet( - { - ...eternlWalletInfo, - connectWallet, - }, - () => window.cardano.eternl, - ); -}; diff --git a/wallets/eternl-wallet/src/index.ts b/wallets/eternl-wallet/src/index.ts deleted file mode 100644 index cfac4519..00000000 --- a/wallets/eternl-wallet/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './eternlWalletCreator'; -export * from './eternlWalletInfo'; diff --git a/wallets/eternl-wallet/src/isEternlAvailable.ts b/wallets/eternl-wallet/src/isEternlAvailable.ts deleted file mode 100644 index 538e0dc4..00000000 --- a/wallets/eternl-wallet/src/isEternlAvailable.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const isEternlAvailable = (): boolean => { - return typeof window.cardano !== 'undefined' && !!window.cardano?.eternl; -}; diff --git a/wallets/eternl-wallet/src/transfer.ts b/wallets/eternl-wallet/src/transfer.ts deleted file mode 100644 index a4ed8b27..00000000 --- a/wallets/eternl-wallet/src/transfer.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/cardano'; -import { Network, RosenAmountValue } from '@rosen-ui/types'; - -import { getEternlWallet } from './getEternlWallet'; - -export const transferCreator = - (config: WalletCreatorConfig) => - async ( - token: RosenChainToken, - amount: RosenAmountValue, - toChain: Network, - toAddress: string, - bridgeFee: RosenAmountValue, - networkFee: RosenAmountValue, - lockAddress: string, - ): Promise => { - const wallet = await getEternlWallet().getApi().enable(); - const policyIdHex = token.policyId; - const assetNameHex = token.assetName; - const changeAddressHex = await wallet.getChangeAddress(); - - const auxiliaryDataHex = await config.generateLockAuxiliaryData( - toChain, - toAddress, - changeAddressHex, - networkFee.toString(), - bridgeFee.toString(), - ); - - const walletUtxos = await wallet.getUtxos(); - if (!walletUtxos) throw Error(`Failed to fetch wallet utxos`); - const unsignedTxHex = await config.generateUnsignedTx( - walletUtxos, - lockAddress, - changeAddressHex, - policyIdHex, - assetNameHex, - amount, - auxiliaryDataHex, - ); - - const signedTxHex = await config.setTxWitnessSet( - unsignedTxHex, - await wallet.signTx(unsignedTxHex, false), - ); - - const result = await wallet.submitTx(signedTxHex); - return result; - }; diff --git a/wallets/eternl-wallet/CHANGELOG.md b/wallets/eternl/CHANGELOG.md similarity index 89% rename from wallets/eternl-wallet/CHANGELOG.md rename to wallets/eternl/CHANGELOG.md index cfab2f3e..f91e0229 100644 --- a/wallets/eternl-wallet/CHANGELOG.md +++ b/wallets/eternl/CHANGELOG.md @@ -1,5 +1,17 @@ # @rosen-ui/eternl-wallet +## 2.0.0 + +### Major Changes + +- Encapsulate wallet functionalities into a single class following a unified interface to simplify maintenance and enable quick addition of new wallet types by implementing the interface. + +### Patch Changes + +- Updated dependencies + - @rosen-bridge/icons@1.0.0 + - @rosen-network/cardano@2.0.0 + ## 1.0.3 ### Patch Changes diff --git a/wallets/eternl-wallet/package.json b/wallets/eternl/package.json similarity index 87% rename from wallets/eternl-wallet/package.json rename to wallets/eternl/package.json index c539c5dc..e55aa0e2 100644 --- a/wallets/eternl-wallet/package.json +++ b/wallets/eternl/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-ui/eternl-wallet", - "version": "1.0.3", + "version": "2.0.0", "private": true, "description": "This is a private package utilized within Rosen Bridge UI app", "main": "dist/src/index.js", @@ -16,9 +16,9 @@ "typescript": "^5.0.0" }, "dependencies": { - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-network/cardano": "^1.0.1", + "@rosen-network/cardano": "^2.0.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/types": "^0.3.1", "@rosen-ui/utils": "^0.4.2", diff --git a/wallets/eternl/src/index.ts b/wallets/eternl/src/index.ts new file mode 100644 index 00000000..3c5958cf --- /dev/null +++ b/wallets/eternl/src/index.ts @@ -0,0 +1 @@ +export * from './wallet'; diff --git a/wallets/eternl/src/types.ts b/wallets/eternl/src/types.ts new file mode 100644 index 00000000..cbae001e --- /dev/null +++ b/wallets/eternl/src/types.ts @@ -0,0 +1,31 @@ +import { TokenMap } from '@rosen-bridge/tokens'; +import type { + generateUnsignedTx, + decodeWasmValue, + generateLockAuxiliaryData, + setTxWitnessSet, +} from '@rosen-network/cardano'; +import { CipWalletApi } from '@rosen-ui/wallet-api'; + +export type WalletConfig = { + getTokenMap(): Promise; + decodeWasmValue: typeof decodeWasmValue; + generateLockAuxiliaryData: typeof generateLockAuxiliaryData; + generateUnsignedTx: ReturnType; + setTxWitnessSet: typeof setTxWitnessSet; +}; + +/** + * global type augmentation for the wallet + */ +declare global { + interface Window { + cardano: { + eternl: { + enable(): Promise; + isEnabled(): Promise; + experimental?: unknown; + }; + }; + } +} diff --git a/wallets/eternl/src/wallet.ts b/wallets/eternl/src/wallet.ts new file mode 100644 index 00000000..1f7e7364 --- /dev/null +++ b/wallets/eternl/src/wallet.ts @@ -0,0 +1,98 @@ +import { EternlIcon } from '@rosen-bridge/icons'; +import { RosenChainToken } from '@rosen-bridge/tokens'; +import { NETWORKS } from '@rosen-ui/constants'; +import { hexToCbor } from '@rosen-ui/utils'; +import { Wallet, WalletTransferParams } from '@rosen-ui/wallet-api'; + +import { WalletConfig } from './types'; + +export class EtrnlWallet implements Wallet { + icon = EternlIcon; + + name = 'Eternl'; + + label = 'Eternl'; + + link = 'https://eternl.io'; + + private get api() { + return window.cardano.eternl; + } + + constructor(private config: WalletConfig) {} + + async connect(): Promise { + return !!(await this.api.enable()); + } + + getAddress(): Promise { + return this.api.enable().then((wallet) => wallet.getChangeAddress()); + } + + async getBalance(token: RosenChainToken): Promise { + const context = await this.api.enable(); + + const rawValue = await context.getBalance(); + + const balances = await this.config.decodeWasmValue(rawValue); + + const amount = balances.find( + (asset) => + asset.policyId === token.policyId && + (asset.nameHex === hexToCbor(token.assetName) || !token.policyId), + ); + + if (!amount) return 0n; + + const tokenMap = await this.config.getTokenMap(); + + const wrappedAmount = tokenMap.wrapAmount( + token[tokenMap.getIdKey(NETWORKS.CARDANO)], + amount.quantity, + NETWORKS.CARDANO, + ).amount; + + return wrappedAmount; + } + + isAvailable(): boolean { + return typeof window.cardano !== 'undefined' && !!window.cardano.eternl; + } + + async transfer(params: WalletTransferParams): Promise { + const wallet = await this.api.enable(); + + const changeAddressHex = await this.getAddress(); + + const auxiliaryDataHex = await this.config.generateLockAuxiliaryData( + params.toChain, + params.address, + changeAddressHex, + params.networkFee.toString(), + params.bridgeFee.toString(), + ); + + const walletUtxos = await wallet.getUtxos(); + + if (!walletUtxos) throw Error(`Failed to fetch wallet utxos`); + + const unsignedTxHex = await this.config.generateUnsignedTx( + walletUtxos, + params.lockAddress, + changeAddressHex, + params.token.policyId, + params.token.assetName, + params.amount, + auxiliaryDataHex, + ); + + const signedTxHex = await this.config.setTxWitnessSet( + unsignedTxHex, + await wallet.signTx(unsignedTxHex, false), + ); + + const result = await wallet.submitTx(signedTxHex); + + return result; + } +} diff --git a/wallets/eternl-wallet/tsconfig.json b/wallets/eternl/tsconfig.json similarity index 100% rename from wallets/eternl-wallet/tsconfig.json rename to wallets/eternl/tsconfig.json diff --git a/wallets/flint-wallet/CHANGELOG.md b/wallets/flint-wallet/CHANGELOG.md deleted file mode 100644 index c6bf0b09..00000000 --- a/wallets/flint-wallet/CHANGELOG.md +++ /dev/null @@ -1,128 +0,0 @@ -# @rosen-ui/flint-wallet - -## 1.0.3 - -### Patch Changes - -- Fix missing dependencies and remove unused packages -- Updated the @rosen-ui/utils@0.4.2 dependency - -## 1.0.2 - -### Patch Changes - -- Update the source code to address the issues identified by the new ESLint rules configuration -- Updated dependencies - - @rosen-bridge/icons@0.7.0 - - @rosen-network/cardano@1.0.1 - -## 1.0.1 - -### Patch Changes - -- Updated the @rosen-bridge/icons@0.6.0 dependency - -## 1.0.0 - -### Major Changes - -- Modify the `transferCreator` function parameter to accept `WRAPPED-VALUE`. -- Change the output type of the `getBalance` function from an `UNWRAPPED-VALUE` to a `WRAPPED-VALUE`. - -### Patch Changes - -- Revise the wallet creation logic and update the access type for each API. -- Strengthen type safety and enforce robust typing for Chain and Network types -- Resolve the issue by replacing the incorrect token retrieval method using policyId with a more accurate approach that retrieves the token by both nameHex and policyId. - -## 0.1.3 - -### Patch Changes - -- Updated dependencies - - @rosen-ui/utils@0.3.0 - - @rosen-ui/wallet-api@1.0.2 - -## 0.1.2 - -### Patch Changes - -- Package the Cardano logic as a standalone module to ensure its independence and maintainability. -- Updated dependencies - - @rosen-network/cardano@0.1.1 - -## 0.1.1 - -### Patch Changes - -- Updated dependencies - - @rosen-ui/utils@0.2.0 - - @rosen-ui/wallet-api@1.0.1 - -## 0.1.0 - -### Minor Changes - -- Add `getAddress` public API for accessing current wallet address - -### Patch Changes - -- Updated dependencies - - @rosen-ui/wallet-api@1.0.0 - -## 0.0.5 - -### Patch Changes - -- Refactor the Flint wallet logic to reside within its own package -- Updated dependencies - - @rosen-ui/utils@0.1.2 - -## 0.0.4 - -### Patch Changes - -- Updated dependencies - - @rosen-bridge/icons@0.4.0 - - @rosen-ui/utils@0.1.1 - -## 0.0.3 - -### Patch Changes - -- Updated dependencies - - @rosen-bridge/icons@0.3.0 - -## 0.3.0 - -### Minor Changes - -- Set a maximum page size of 100 for events api -- Use the shared hooks package instead of utils package to prevent server component problems - -### Patch Changes - -- fix app crash when a token fetched from database is not found -- Update dependencies - - @rosen-ui/common-hooks@0.1.0 - - @rosen-ui/utils@0.1.0 - - @rosen-ui/eternl-wallet@0.0.2 - - @rosen-ui/flint-wallet@0.0.2 - - @rosen-ui/lace-wallet@0.0.2 - - @rosen-ui/nami-wallet@0.0.2 - - @rosen-ui/nautilus-wallet@0.0.2 - - @rosen-ui/vespr-wallet@0.0.2 - - @rosen-ui/wallet-api@0.0.2 - -## 0.2.1 - -### Patch Changes - -- Fix issue with wallet index when having multiple wallets - -## 0.2.0 - -### Minor Changes - -- Add multi-wallet support ([@Mercurial](https://github.com/Mercurial)) -- Add Eternl, Flint and Lace wallets for Cardano chain ([@Mercurial](https://github.com/Mercurial)) diff --git a/wallets/flint-wallet/package.json b/wallets/flint-wallet/package.json deleted file mode 100644 index d837f327..00000000 --- a/wallets/flint-wallet/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "@rosen-ui/flint-wallet", - "version": "1.0.3", - "private": true, - "description": "This is a private package utilized within Rosen Bridge UI app", - "main": "dist/src/index.js", - "types": "dist/src/index.d.ts", - "type": "module", - "scripts": { - "prettify": "prettier --write . --ignore-path ../../.gitignore", - "lint": "eslint --fix . && npm run prettify", - "build": "tsc --build", - "type-check": "tsc --noEmit" - }, - "devDependencies": { - "typescript": "^5.0.0" - }, - "dependencies": { - "@rosen-bridge/icons": "^0.7.0", - "@rosen-bridge/tokens": "^1.2.1", - "@rosen-network/cardano": "^1.0.1", - "@rosen-ui/constants": "^0.0.5", - "@rosen-ui/types": "^0.3.1", - "@rosen-ui/utils": "^0.4.2", - "@rosen-ui/wallet-api": "^1.0.3" - } -} diff --git a/wallets/flint-wallet/src/connectWallet.ts b/wallets/flint-wallet/src/connectWallet.ts deleted file mode 100644 index 451ccd86..00000000 --- a/wallets/flint-wallet/src/connectWallet.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * handles the Flint wallet connection - */ - -export const connectWallet = async () => { - const granted = await window.cardano.flint?.enable(); - - if (!granted) { - console.error('Failed to connect!'); - return false; - } - return true; -}; diff --git a/wallets/flint-wallet/src/flintWalletCreator.ts b/wallets/flint-wallet/src/flintWalletCreator.ts deleted file mode 100644 index 848f6c73..00000000 --- a/wallets/flint-wallet/src/flintWalletCreator.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { WalletCreator } from '@rosen-network/cardano'; - -import { getBalanceCreator } from './getBalance'; -import { getFlintWallet } from './getFlintWallet'; -import { isFlintAvailable } from './isFlintAvailable'; -import { transferCreator } from './transfer'; - -export const flintWalletCreator: WalletCreator = (config) => { - return Object.assign({}, getFlintWallet(), { - isAvailable: isFlintAvailable, - getBalance: getBalanceCreator(config), - transfer: transferCreator(config), - getAddress: async () => { - throw new Error('Not implemented'); - }, - }); -}; diff --git a/wallets/flint-wallet/src/flintWalletInfo.ts b/wallets/flint-wallet/src/flintWalletInfo.ts deleted file mode 100644 index 8dee50ed..00000000 --- a/wallets/flint-wallet/src/flintWalletInfo.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { FlintIcon } from '@rosen-bridge/icons'; -import { WalletInfo } from '@rosen-ui/wallet-api'; - -export const flintWalletInfo: WalletInfo = { - icon: FlintIcon, - name: 'Flint', - label: 'Flint', - link: 'https://flint-wallet.com/', -}; diff --git a/wallets/flint-wallet/src/getBalance.ts b/wallets/flint-wallet/src/getBalance.ts deleted file mode 100644 index 5177cc91..00000000 --- a/wallets/flint-wallet/src/getBalance.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/cardano'; -import { NETWORKS } from '@rosen-ui/constants'; -import { RosenAmountValue } from '@rosen-ui/types'; -import { hexToCbor } from '@rosen-ui/utils'; - -import { getFlintWallet } from './getFlintWallet'; - -export const getBalanceCreator = - (config: WalletCreatorConfig) => - async (token: RosenChainToken): Promise => { - const context = await getFlintWallet().getApi().enable(); - const rawValue = await context.getBalance(); - const balances = await config.decodeWasmValue(rawValue); - - const amount = balances.find( - (asset) => - asset.policyId === token.policyId && - (asset.nameHex === hexToCbor(token.assetName) || !token.policyId), - ); - - if (!amount) return 0n; - - const tokenMap = await config.getTokenMap(); - - const wrappedAmount = tokenMap.wrapAmount( - token[tokenMap.getIdKey(NETWORKS.CARDANO)], - amount.quantity, - NETWORKS.CARDANO, - ).amount; - - return wrappedAmount; - }; diff --git a/wallets/flint-wallet/src/getFlintWallet.ts b/wallets/flint-wallet/src/getFlintWallet.ts deleted file mode 100644 index 7c7eeebc..00000000 --- a/wallets/flint-wallet/src/getFlintWallet.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { createRawWallet } from '@rosen-ui/wallet-api'; - -import { connectWallet } from './connectWallet'; -import { flintWalletInfo } from './flintWalletInfo'; - -/** - * Flint implementation of the Wallet - * interface to be able to interact with Flint wallet - */ -export const getFlintWallet = () => - createRawWallet( - { - ...flintWalletInfo, - connectWallet, - }, - () => window.cardano.flint, - ); diff --git a/wallets/flint-wallet/src/index.ts b/wallets/flint-wallet/src/index.ts deleted file mode 100644 index 19cd99c7..00000000 --- a/wallets/flint-wallet/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './flintWalletCreator'; -export * from './flintWalletInfo'; diff --git a/wallets/flint-wallet/src/isFlintAvailable.ts b/wallets/flint-wallet/src/isFlintAvailable.ts deleted file mode 100644 index ca8a1f87..00000000 --- a/wallets/flint-wallet/src/isFlintAvailable.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const isFlintAvailable = (): boolean => { - return typeof window.cardano !== 'undefined' && !!window.cardano?.flint; -}; diff --git a/wallets/flint-wallet/src/transfer.ts b/wallets/flint-wallet/src/transfer.ts deleted file mode 100644 index 45142030..00000000 --- a/wallets/flint-wallet/src/transfer.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/cardano'; -import { Network, RosenAmountValue } from '@rosen-ui/types'; - -import { getFlintWallet } from './getFlintWallet'; - -export const transferCreator = - (config: WalletCreatorConfig) => - async ( - token: RosenChainToken, - amount: RosenAmountValue, - toChain: Network, - toAddress: string, - bridgeFee: RosenAmountValue, - networkFee: RosenAmountValue, - lockAddress: string, - ): Promise => { - const wallet = await getFlintWallet().getApi().enable(); - const policyIdHex = token.policyId; - const assetNameHex = token.assetName; - const changeAddressHex = await wallet.getChangeAddress(); - - const auxiliaryDataHex = await config.generateLockAuxiliaryData( - toChain, - toAddress, - changeAddressHex, - networkFee.toString(), - bridgeFee.toString(), - ); - - const walletUtxos = await wallet.getUtxos(); - if (!walletUtxos) throw Error(`Failed to fetch wallet utxos`); - const unsignedTxHex = await config.generateUnsignedTx( - walletUtxos, - lockAddress, - changeAddressHex, - policyIdHex, - assetNameHex, - amount, - auxiliaryDataHex, - ); - - const signedTxHex = await config.setTxWitnessSet( - unsignedTxHex, - await wallet.signTx(unsignedTxHex, false), - ); - - const result = await wallet.submitTx(signedTxHex); - return result; - }; diff --git a/wallets/lace-wallet/src/connectWallet.ts b/wallets/lace-wallet/src/connectWallet.ts deleted file mode 100644 index 864cea80..00000000 --- a/wallets/lace-wallet/src/connectWallet.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * handles the Lace wallet connection - */ - -export const connectWallet = async () => { - const granted = await window.cardano.lace?.enable(); - - if (!granted) { - console.error('Failed to connect!'); - return false; - } - return true; -}; diff --git a/wallets/lace-wallet/src/getBalance.ts b/wallets/lace-wallet/src/getBalance.ts deleted file mode 100644 index 78e03745..00000000 --- a/wallets/lace-wallet/src/getBalance.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/cardano'; -import { NETWORKS } from '@rosen-ui/constants'; -import { RosenAmountValue } from '@rosen-ui/types'; -import { hexToCbor } from '@rosen-ui/utils'; - -import { getLaceWallet } from './getLaceWallet'; - -export const getBalanceCreator = - (config: WalletCreatorConfig) => - async (token: RosenChainToken): Promise => { - const context = await getLaceWallet().getApi().enable(); - const rawValue = await context.getBalance(); - const balances = await config.decodeWasmValue(rawValue); - - const amount = balances.find( - (asset) => - asset.policyId === token.policyId && - (asset.nameHex === hexToCbor(token.assetName) || !token.policyId), - ); - - if (!amount) return 0n; - - const tokenMap = await config.getTokenMap(); - - const wrappedAmount = tokenMap.wrapAmount( - token[tokenMap.getIdKey(NETWORKS.CARDANO)], - amount.quantity, - NETWORKS.CARDANO, - ).amount; - - return wrappedAmount; - }; diff --git a/wallets/lace-wallet/src/getLaceWallet.ts b/wallets/lace-wallet/src/getLaceWallet.ts deleted file mode 100644 index 0f05792b..00000000 --- a/wallets/lace-wallet/src/getLaceWallet.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createRawWallet } from '@rosen-ui/wallet-api'; - -import { connectWallet } from './connectWallet'; -import { laceWalletInfo } from './laceWalletInfo'; - -/** - * Lace implementation of the Wallet - * interface to be able to interact with Lace wallet - */ -export const getLaceWallet = () => { - return createRawWallet( - { - ...laceWalletInfo, - connectWallet, - }, - () => window.cardano.lace, - ); -}; diff --git a/wallets/lace-wallet/src/index.ts b/wallets/lace-wallet/src/index.ts deleted file mode 100644 index 1a1fa6a2..00000000 --- a/wallets/lace-wallet/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './laceWalletCreator'; -export * from './laceWalletInfo'; diff --git a/wallets/lace-wallet/src/isLaceAvailable.ts b/wallets/lace-wallet/src/isLaceAvailable.ts deleted file mode 100644 index c9394659..00000000 --- a/wallets/lace-wallet/src/isLaceAvailable.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const isLaceAvailable = () => { - return typeof window.cardano !== 'undefined' && !!window.cardano?.lace; -}; diff --git a/wallets/lace-wallet/src/laceWalletCreator.ts b/wallets/lace-wallet/src/laceWalletCreator.ts deleted file mode 100644 index af5e4138..00000000 --- a/wallets/lace-wallet/src/laceWalletCreator.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { WalletCreator } from '@rosen-network/cardano'; - -import { getBalanceCreator } from './getBalance'; -import { getLaceWallet } from './getLaceWallet'; -import { isLaceAvailable } from './isLaceAvailable'; -import { transferCreator } from './transfer'; - -export const laceWalletCreator: WalletCreator = (config) => { - return Object.assign({}, getLaceWallet(), { - isAvailable: isLaceAvailable, - getBalance: getBalanceCreator(config), - transfer: transferCreator(config), - getAddress: async () => { - throw new Error('Not implemented'); - }, - }); -}; diff --git a/wallets/lace-wallet/src/laceWalletInfo.ts b/wallets/lace-wallet/src/laceWalletInfo.ts deleted file mode 100644 index a425d7ce..00000000 --- a/wallets/lace-wallet/src/laceWalletInfo.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { LaceIcon } from '@rosen-bridge/icons'; -import { WalletInfo } from '@rosen-ui/wallet-api'; - -export const laceWalletInfo: WalletInfo = { - icon: LaceIcon, - name: 'Lace', - label: 'Lace', - link: 'https://www.lace.io/', -}; diff --git a/wallets/lace-wallet/src/transfer.ts b/wallets/lace-wallet/src/transfer.ts deleted file mode 100644 index 3965ebbc..00000000 --- a/wallets/lace-wallet/src/transfer.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/cardano'; -import { Network, RosenAmountValue } from '@rosen-ui/types'; - -import { getLaceWallet } from './getLaceWallet'; - -export const transferCreator = - (config: WalletCreatorConfig) => - async ( - token: RosenChainToken, - amount: RosenAmountValue, - toChain: Network, - toAddress: string, - bridgeFee: RosenAmountValue, - networkFee: RosenAmountValue, - lockAddress: string, - ): Promise => { - const wallet = await getLaceWallet().getApi().enable(); - const policyIdHex = token.policyId; - const assetNameHex = token.assetName; - const changeAddressHex = await wallet.getChangeAddress(); - - const auxiliaryDataHex = await config.generateLockAuxiliaryData( - toChain, - toAddress, - changeAddressHex, - networkFee.toString(), - bridgeFee.toString(), - ); - - const walletUtxos = await wallet.getUtxos(); - if (!walletUtxos) throw Error(`Failed to fetch wallet utxos`); - const unsignedTxHex = await config.generateUnsignedTx( - walletUtxos, - lockAddress, - changeAddressHex, - policyIdHex, - assetNameHex, - amount, - auxiliaryDataHex, - ); - - const signedTxHex = await config.setTxWitnessSet( - unsignedTxHex, - await wallet.signTx(unsignedTxHex, false), - ); - - const result = await wallet.submitTx(signedTxHex); - return result; - }; diff --git a/wallets/lace-wallet/CHANGELOG.md b/wallets/lace/CHANGELOG.md similarity index 89% rename from wallets/lace-wallet/CHANGELOG.md rename to wallets/lace/CHANGELOG.md index 7ed3b808..86366275 100644 --- a/wallets/lace-wallet/CHANGELOG.md +++ b/wallets/lace/CHANGELOG.md @@ -1,5 +1,17 @@ # @rosen-ui/lace-wallet +## 2.0.0 + +### Major Changes + +- Encapsulate wallet functionalities into a single class following a unified interface to simplify maintenance and enable quick addition of new wallet types by implementing the interface. + +### Patch Changes + +- Updated dependencies + - @rosen-bridge/icons@1.0.0 + - @rosen-network/cardano@2.0.0 + ## 1.0.3 ### Patch Changes diff --git a/wallets/lace-wallet/package.json b/wallets/lace/package.json similarity index 87% rename from wallets/lace-wallet/package.json rename to wallets/lace/package.json index fa8c3b49..a191435b 100644 --- a/wallets/lace-wallet/package.json +++ b/wallets/lace/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-ui/lace-wallet", - "version": "1.0.3", + "version": "2.0.0", "private": true, "description": "This is a private package utilized within Rosen Bridge UI app", "main": "dist/src/index.js", @@ -16,9 +16,9 @@ "typescript": "^5.0.0" }, "dependencies": { - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-network/cardano": "^1.0.1", + "@rosen-network/cardano": "^2.0.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/types": "^0.3.1", "@rosen-ui/utils": "^0.4.2", diff --git a/wallets/lace/src/index.ts b/wallets/lace/src/index.ts new file mode 100644 index 00000000..3c5958cf --- /dev/null +++ b/wallets/lace/src/index.ts @@ -0,0 +1 @@ +export * from './wallet'; diff --git a/wallets/lace/src/types.ts b/wallets/lace/src/types.ts new file mode 100644 index 00000000..dfefef89 --- /dev/null +++ b/wallets/lace/src/types.ts @@ -0,0 +1,31 @@ +import { TokenMap } from '@rosen-bridge/tokens'; +import type { + generateUnsignedTx, + decodeWasmValue, + generateLockAuxiliaryData, + setTxWitnessSet, +} from '@rosen-network/cardano'; +import { CipWalletApi } from '@rosen-ui/wallet-api'; + +export type WalletConfig = { + getTokenMap(): Promise; + decodeWasmValue: typeof decodeWasmValue; + generateLockAuxiliaryData: typeof generateLockAuxiliaryData; + generateUnsignedTx: ReturnType; + setTxWitnessSet: typeof setTxWitnessSet; +}; + +/** + * global type augmentation for the wallet + */ +declare global { + interface Window { + cardano: { + lace: { + enable(): Promise; + isEnabled(): Promise; + experimental?: unknown; + }; + }; + } +} diff --git a/wallets/lace/src/wallet.ts b/wallets/lace/src/wallet.ts new file mode 100644 index 00000000..3536434c --- /dev/null +++ b/wallets/lace/src/wallet.ts @@ -0,0 +1,98 @@ +import { LaceIcon } from '@rosen-bridge/icons'; +import { RosenChainToken } from '@rosen-bridge/tokens'; +import { NETWORKS } from '@rosen-ui/constants'; +import { hexToCbor } from '@rosen-ui/utils'; +import { Wallet, WalletTransferParams } from '@rosen-ui/wallet-api'; + +import { WalletConfig } from './types'; + +export class LaceWallet implements Wallet { + icon = LaceIcon; + + name = 'Lace'; + + label = 'Lace'; + + link = 'https://www.lace.io/'; + + private get api() { + return window.cardano.lace; + } + + constructor(private config: WalletConfig) {} + + async connect(): Promise { + return !!(await this.api.enable()); + } + + async getAddress(): Promise { + return this.api.enable().then((wallet) => wallet.getChangeAddress()); + } + + async getBalance(token: RosenChainToken): Promise { + const context = await this.api.enable(); + + const rawValue = await context.getBalance(); + + const balances = await this.config.decodeWasmValue(rawValue); + + const amount = balances.find( + (asset) => + asset.policyId === token.policyId && + (asset.nameHex === hexToCbor(token.assetName) || !token.policyId), + ); + + if (!amount) return 0n; + + const tokenMap = await this.config.getTokenMap(); + + const wrappedAmount = tokenMap.wrapAmount( + token[tokenMap.getIdKey(NETWORKS.CARDANO)], + amount.quantity, + NETWORKS.CARDANO, + ).amount; + + return wrappedAmount; + } + + isAvailable(): boolean { + return typeof window.cardano !== 'undefined' && !!window.cardano.lace; + } + + async transfer(params: WalletTransferParams): Promise { + const wallet = await this.api.enable(); + + const changeAddressHex = await this.getAddress(); + + const auxiliaryDataHex = await this.config.generateLockAuxiliaryData( + params.toChain, + params.address, + changeAddressHex, + params.networkFee.toString(), + params.bridgeFee.toString(), + ); + + const walletUtxos = await wallet.getUtxos(); + + if (!walletUtxos) throw Error(`Failed to fetch wallet utxos`); + + const unsignedTxHex = await this.config.generateUnsignedTx( + walletUtxos, + params.lockAddress, + changeAddressHex, + params.token.policyId, + params.token.assetName, + params.amount, + auxiliaryDataHex, + ); + + const signedTxHex = await this.config.setTxWitnessSet( + unsignedTxHex, + await wallet.signTx(unsignedTxHex, false), + ); + + const result = await wallet.submitTx(signedTxHex); + + return result; + } +} diff --git a/wallets/flint-wallet/tsconfig.json b/wallets/lace/tsconfig.json similarity index 100% rename from wallets/flint-wallet/tsconfig.json rename to wallets/lace/tsconfig.json diff --git a/wallets/metamask-wallet/src/connectWallet.ts b/wallets/metamask-wallet/src/connectWallet.ts deleted file mode 100644 index 9c7434cc..00000000 --- a/wallets/metamask-wallet/src/connectWallet.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { getMetaMaskWallet } from './getMetaMaskWallet'; - -/** - * handles the MetaMask wallet connection - */ - -let waiting; - -export const connectWallet = async (): Promise => { - waiting ||= getMetaMaskWallet().getApi().connect(); - - try { - await waiting; - waiting = undefined; - return true; - } catch { - waiting = undefined; - return false; - } -}; diff --git a/wallets/metamask-wallet/src/getBalance.ts b/wallets/metamask-wallet/src/getBalance.ts deleted file mode 100644 index f5688aa3..00000000 --- a/wallets/metamask-wallet/src/getBalance.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/ethereum'; -import { tokenABI } from '@rosen-network/ethereum/dist/src/constants'; -import { NETWORKS } from '@rosen-ui/constants'; -import { RosenAmountValue } from '@rosen-ui/types'; -import { BrowserProvider, Contract } from 'ethers'; - -import { getMetaMaskWallet } from './getMetaMaskWallet'; - -export const getBalanceCreator = - (config: WalletCreatorConfig) => - async (token: RosenChainToken): Promise => { - const provider = await getMetaMaskWallet().getApi().getProvider(); - - if (!provider) return 0n; - - const accounts = await provider.request({ - method: 'eth_accounts', - }); - - if (!accounts?.length) return 0n; - - const tokenMap = await config.getTokenMap(); - - const tokenId = token[tokenMap.getIdKey(NETWORKS.ETHEREUM)]; - - let amount; - - if (tokenId == 'eth') { - amount = await provider.request({ - method: 'eth_getBalance', - params: [accounts[0], 'latest'], - }); - } else { - const browserProvider = new BrowserProvider(window.ethereum!); - - const contract = new Contract( - tokenId, - tokenABI, - await browserProvider.getSigner(), - ); - - amount = await contract.balanceOf(accounts[0]); - } - - if (!amount) return 0n; - - const wrappedAmount = tokenMap.wrapAmount( - token[tokenMap.getIdKey(NETWORKS.ETHEREUM)], - BigInt(amount), - NETWORKS.ETHEREUM, - ).amount; - - return wrappedAmount; - }; diff --git a/wallets/metamask-wallet/src/getMetaMaskWallet.ts b/wallets/metamask-wallet/src/getMetaMaskWallet.ts deleted file mode 100644 index cd1339f7..00000000 --- a/wallets/metamask-wallet/src/getMetaMaskWallet.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { MetaMaskSDK } from '@metamask/sdk'; -import { createRawWallet } from '@rosen-ui/wallet-api'; - -import { connectWallet } from './connectWallet'; -import { metaMaskWalletInfo } from './metaMaskWalletInfo'; - -export const metaMaskSDK = new MetaMaskSDK({ - dappMetadata: { - name: 'Rosen Bridge', - }, - enableAnalytics: false, -}); - -/** - * MetaMask implementation of the Wallet - * interface to be able to interact with MetaMask wallet - */ -export const getMetaMaskWallet = () => { - return createRawWallet( - { - ...metaMaskWalletInfo, - connectWallet, - }, - () => metaMaskSDK, - ); -}; diff --git a/wallets/metamask-wallet/src/global.d.ts b/wallets/metamask-wallet/src/global.d.ts deleted file mode 100644 index 5514dd83..00000000 --- a/wallets/metamask-wallet/src/global.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * global type augmentation for the wallet - */ -declare global { - interface Window { - ethereum: { - isMetaMask: boolean; - _metamask: unknown; - }; - } -} diff --git a/wallets/metamask-wallet/src/index.ts b/wallets/metamask-wallet/src/index.ts deleted file mode 100644 index f9520084..00000000 --- a/wallets/metamask-wallet/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './metaMaskWalletCreator'; -export * from './metaMaskWalletInfo'; diff --git a/wallets/metamask-wallet/src/isMetaMaskAvailable.ts b/wallets/metamask-wallet/src/isMetaMaskAvailable.ts deleted file mode 100644 index ce4efc89..00000000 --- a/wallets/metamask-wallet/src/isMetaMaskAvailable.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const isMetaMaskAvailable = (): boolean => { - return ( - typeof window.ethereum !== 'undefined' && - window.ethereum.isMetaMask && - !!window.ethereum._metamask - ); -}; diff --git a/wallets/metamask-wallet/src/metaMaskWalletCreator.ts b/wallets/metamask-wallet/src/metaMaskWalletCreator.ts deleted file mode 100644 index ab42de28..00000000 --- a/wallets/metamask-wallet/src/metaMaskWalletCreator.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { WalletCreator } from '@rosen-network/ethereum'; - -import { getBalanceCreator } from './getBalance'; -import { getMetaMaskWallet } from './getMetaMaskWallet'; -import { isMetaMaskAvailable } from './isMetaMaskAvailable'; -import { transferCreator } from './transfer'; - -export const metaMaskWalletCreator: WalletCreator = (config) => { - return Object.assign({}, getMetaMaskWallet(), { - isAvailable: isMetaMaskAvailable, - getBalance: getBalanceCreator(config), - transfer: transferCreator(config), - getAddress: async () => { - throw new Error('Not implemented'); - }, - }); -}; diff --git a/wallets/metamask-wallet/src/metaMaskWalletInfo.ts b/wallets/metamask-wallet/src/metaMaskWalletInfo.ts deleted file mode 100644 index 8d022047..00000000 --- a/wallets/metamask-wallet/src/metaMaskWalletInfo.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { MetaMaskIcon } from '@rosen-bridge/icons'; -import { WalletInfo } from '@rosen-ui/wallet-api'; - -export const metaMaskWalletInfo: WalletInfo = { - icon: MetaMaskIcon, - name: 'MetaMask', - label: 'MetaMask', - link: 'https://metamask.io/', -}; diff --git a/wallets/metamask-wallet/src/transfer.ts b/wallets/metamask-wallet/src/transfer.ts deleted file mode 100644 index 886bbae6..00000000 --- a/wallets/metamask-wallet/src/transfer.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/ethereum'; -import { NETWORKS } from '@rosen-ui/constants'; -import { Network, RosenAmountValue } from '@rosen-ui/types'; - -import { getMetaMaskWallet } from './getMetaMaskWallet'; - -export const transferCreator = - (config: WalletCreatorConfig) => - async ( - token: RosenChainToken, - amount: RosenAmountValue, - toChain: Network, - toAddress: string, - bridgeFee: RosenAmountValue, - networkFee: RosenAmountValue, - lockAddress: string, - ): Promise => { - const provider = getMetaMaskWallet().getApi().getProvider(); - - if (!provider) throw Error(`Failed to interact with metamask`); - - const accounts = await provider.request({ - method: 'eth_accounts', - }); - - if (!accounts?.length) - throw Error(`Failed to fetch accounts from metamask`); - if (!accounts[0]) - throw Error(`Failed to get address of first account from metamask`); - - const rosenData = await config.generateLockData( - toChain, - toAddress, - networkFee.toString(), - bridgeFee.toString(), - ); - - const tokenMap = await config.getTokenMap(); - const tokenId = token[tokenMap.getIdKey(NETWORKS.ETHEREUM)]; - - const transactionParameters = await config.generateTxParameters( - tokenId, - lockAddress, - accounts[0], - amount, - rosenData, - token, - ); - const result = await provider.request({ - method: 'eth_sendTransaction', - params: [transactionParameters], - }); - - return result ?? ''; - }; diff --git a/wallets/metamask-wallet/CHANGELOG.md b/wallets/metamask/CHANGELOG.md similarity index 64% rename from wallets/metamask-wallet/CHANGELOG.md rename to wallets/metamask/CHANGELOG.md index 6b95a850..dd530e16 100644 --- a/wallets/metamask-wallet/CHANGELOG.md +++ b/wallets/metamask/CHANGELOG.md @@ -1,5 +1,17 @@ # @rosen-ui/metamask-wallet +## 1.0.0 + +### Major Changes + +- Encapsulate wallet functionalities into a single class following a unified interface to simplify maintenance and enable quick addition of new wallet types by implementing the interface. + +### Patch Changes + +- Updated dependencies + - @rosen-bridge/icons@1.0.0 + - @rosen-network/ethereum@1.0.0 + ## 0.1.4 ### Patch Changes diff --git a/wallets/metamask-wallet/package.json b/wallets/metamask/package.json similarity index 87% rename from wallets/metamask-wallet/package.json rename to wallets/metamask/package.json index 28d42763..2a1ebad3 100644 --- a/wallets/metamask-wallet/package.json +++ b/wallets/metamask/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-ui/metamask-wallet", - "version": "0.1.4", + "version": "1.0.0", "private": true, "description": "This is a private package utilized within Rosen Bridge UI app", "main": "dist/src/index.js", @@ -17,9 +17,9 @@ }, "dependencies": { "@metamask/sdk": "^0.28.2", - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-network/ethereum": "^0.1.1", + "@rosen-network/ethereum": "^1.0.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/types": "^0.3.1", "@rosen-ui/wallet-api": "^1.0.3" diff --git a/wallets/metamask/src/index.ts b/wallets/metamask/src/index.ts new file mode 100644 index 00000000..3c5958cf --- /dev/null +++ b/wallets/metamask/src/index.ts @@ -0,0 +1 @@ +export * from './wallet'; diff --git a/wallets/metamask/src/types.ts b/wallets/metamask/src/types.ts new file mode 100644 index 00000000..3bb8c912 --- /dev/null +++ b/wallets/metamask/src/types.ts @@ -0,0 +1,11 @@ +import { TokenMap } from '@rosen-bridge/tokens'; +import type { + generateTxParameters, + generateLockData, +} from '@rosen-network/ethereum'; + +export type WalletConfig = { + getTokenMap(): Promise; + generateLockData: typeof generateLockData; + generateTxParameters: ReturnType; +}; diff --git a/wallets/metamask/src/wallet.ts b/wallets/metamask/src/wallet.ts new file mode 100644 index 00000000..108db4ca --- /dev/null +++ b/wallets/metamask/src/wallet.ts @@ -0,0 +1,142 @@ +import { MetaMaskSDK } from '@metamask/sdk'; +import { MetaMaskIcon } from '@rosen-bridge/icons'; +import { RosenChainToken } from '@rosen-bridge/tokens'; +import { tokenABI } from '@rosen-network/ethereum/dist/src/constants'; +import { NETWORKS } from '@rosen-ui/constants'; +import { Wallet, WalletTransferParams } from '@rosen-ui/wallet-api'; +import { BrowserProvider, Contract } from 'ethers'; + +import { WalletConfig } from './types'; + +export class MetaMaskWallet implements Wallet { + icon = MetaMaskIcon; + + name = 'MetaMask'; + + label = 'MetaMask'; + + link = 'https://metamask.io/'; + + connecWaiting?: Promise; + + private api = new MetaMaskSDK({ + dappMetadata: { + name: 'Rosen Bridge', + }, + enableAnalytics: false, + }); + + constructor(private config: WalletConfig) {} + + async connect(): Promise { + this.connecWaiting ||= this.api.connect(); + try { + await this.connecWaiting; + this.connecWaiting = undefined; + return true; + } catch { + this.connecWaiting = undefined; + return false; + } + } + + getAddress(): Promise { + throw new Error('Not implemented'); + } + + async getBalance(token: RosenChainToken): Promise { + const provider = this.api.getProvider(); + + if (!provider) return 0n; + + const accounts = await provider.request({ + method: 'eth_accounts', + }); + + if (!accounts?.length) return 0n; + + const tokenMap = await this.config.getTokenMap(); + + const tokenId = token[tokenMap.getIdKey(NETWORKS.ETHEREUM)]; + + let amount; + + if (tokenId == 'eth') { + amount = await provider.request({ + method: 'eth_getBalance', + params: [accounts[0], 'latest'], + }); + } else { + const browserProvider = new BrowserProvider(window.ethereum!); + + const contract = new Contract( + tokenId, + tokenABI, + await browserProvider.getSigner(), + ); + + amount = await contract.balanceOf(accounts[0]); + } + + if (!amount) return 0n; + + const wrappedAmount = tokenMap.wrapAmount( + token[tokenMap.getIdKey(NETWORKS.ETHEREUM)], + BigInt(amount), + NETWORKS.ETHEREUM, + ).amount; + + return wrappedAmount; + } + + isAvailable(): boolean { + return ( + typeof window.ethereum !== 'undefined' && + window.ethereum.isMetaMask && + !!window.ethereum._metamask + ); + } + + async transfer(params: WalletTransferParams): Promise { + const provider = this.api.getProvider(); + + if (!provider) throw Error(`Failed to interact with metamask`); + + const accounts = await provider.request({ + method: 'eth_accounts', + }); + + if (!accounts?.length) + throw Error(`Failed to fetch accounts from metamask`); + + if (!accounts[0]) + throw Error(`Failed to get address of first account from metamask`); + + const rosenData = await this.config.generateLockData( + params.toChain, + params.address, + params.networkFee.toString(), + params.bridgeFee.toString(), + ); + + const tokenMap = await this.config.getTokenMap(); + + const tokenId = params.token[tokenMap.getIdKey(NETWORKS.ETHEREUM)]; + + const transactionParameters = await this.config.generateTxParameters( + tokenId, + params.lockAddress, + accounts[0], + params.amount, + rosenData, + params.token, + ); + + const result = await provider.request({ + method: 'eth_sendTransaction', + params: [transactionParameters], + }); + + return result ?? ''; + } +} diff --git a/wallets/lace-wallet/tsconfig.json b/wallets/metamask/tsconfig.json similarity index 100% rename from wallets/lace-wallet/tsconfig.json rename to wallets/metamask/tsconfig.json diff --git a/wallets/nami-wallet/src/connectWallet.ts b/wallets/nami-wallet/src/connectWallet.ts deleted file mode 100644 index 370becb1..00000000 --- a/wallets/nami-wallet/src/connectWallet.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * handles the Nami wallet connection - */ - -export const connectWallet = async () => { - const granted = await window.cardano.nami?.enable(); - - if (!granted) { - console.error('Failed to connect!'); - return false; - } - return true; -}; diff --git a/wallets/nami-wallet/src/getBalance.ts b/wallets/nami-wallet/src/getBalance.ts deleted file mode 100644 index b66d63d7..00000000 --- a/wallets/nami-wallet/src/getBalance.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/cardano'; -import { NETWORKS } from '@rosen-ui/constants'; -import { RosenAmountValue } from '@rosen-ui/types'; -import { hexToCbor } from '@rosen-ui/utils'; - -import { getNamiWallet } from './getNamiWallet'; - -export const getBalanceCreator = - (config: WalletCreatorConfig) => - async (token: RosenChainToken): Promise => { - const context = await getNamiWallet().getApi().enable(); - const rawValue = await context.getBalance(); - const balances = await config.decodeWasmValue(rawValue); - - const amount = balances.find( - (asset) => - asset.policyId === token.policyId && - (asset.nameHex === hexToCbor(token.assetName) || !token.policyId), - ); - - if (!amount) return 0n; - - const tokenMap = await config.getTokenMap(); - - const wrappedAmount = tokenMap.wrapAmount( - token[tokenMap.getIdKey(NETWORKS.CARDANO)], - amount.quantity, - NETWORKS.CARDANO, - ).amount; - - return wrappedAmount; - }; diff --git a/wallets/nami-wallet/src/getNamiWallet.ts b/wallets/nami-wallet/src/getNamiWallet.ts deleted file mode 100644 index c74177c8..00000000 --- a/wallets/nami-wallet/src/getNamiWallet.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createRawWallet } from '@rosen-ui/wallet-api'; - -import { connectWallet } from './connectWallet'; -import { namiWalletInfo } from './namiWalletInfo'; - -/** - * Nami implementation of the Wallet - * interface to be able to interact with Nami wallet - */ -export const getNamiWallet = () => { - return createRawWallet( - { - ...namiWalletInfo, - connectWallet, - }, - () => window.cardano.nami, - ); -}; diff --git a/wallets/nami-wallet/src/index.ts b/wallets/nami-wallet/src/index.ts deleted file mode 100644 index 7bbf3468..00000000 --- a/wallets/nami-wallet/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './namiWalletCreator'; -export * from './namiWalletInfo'; diff --git a/wallets/nami-wallet/src/isNamiAvailable.ts b/wallets/nami-wallet/src/isNamiAvailable.ts deleted file mode 100644 index a540f3a9..00000000 --- a/wallets/nami-wallet/src/isNamiAvailable.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const isNamiAvailable = () => { - return typeof window.cardano !== 'undefined' && !!window.cardano?.nami; -}; diff --git a/wallets/nami-wallet/src/namiWalletCreator.ts b/wallets/nami-wallet/src/namiWalletCreator.ts deleted file mode 100644 index e714c849..00000000 --- a/wallets/nami-wallet/src/namiWalletCreator.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { WalletCreator } from '@rosen-network/cardano'; - -import { getBalanceCreator } from './getBalance'; -import { getNamiWallet } from './getNamiWallet'; -import { isNamiAvailable } from './isNamiAvailable'; -import { transferCreator } from './transfer'; - -export const namiWalletCreator: WalletCreator = (config) => { - return Object.assign({}, getNamiWallet(), { - isAvailable: isNamiAvailable, - getBalance: getBalanceCreator(config), - transfer: transferCreator(config), - getAddress: async () => { - throw new Error('Not implemented'); - }, - }); -}; diff --git a/wallets/nami-wallet/src/namiWalletInfo.ts b/wallets/nami-wallet/src/namiWalletInfo.ts deleted file mode 100644 index a3c8365d..00000000 --- a/wallets/nami-wallet/src/namiWalletInfo.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { NamiIcon } from '@rosen-bridge/icons'; -import { WalletInfo } from '@rosen-ui/wallet-api'; - -export const namiWalletInfo: WalletInfo = { - icon: NamiIcon, - name: 'Nami', - label: 'Nami', - link: 'https://namiwallet.io/', -}; diff --git a/wallets/nami-wallet/src/transfer.ts b/wallets/nami-wallet/src/transfer.ts deleted file mode 100644 index 7bf4bae1..00000000 --- a/wallets/nami-wallet/src/transfer.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/cardano'; -import { Network, RosenAmountValue } from '@rosen-ui/types'; - -import { getNamiWallet } from './getNamiWallet'; - -export const transferCreator = - (config: WalletCreatorConfig) => - async ( - token: RosenChainToken, - amount: RosenAmountValue, - toChain: Network, - toAddress: string, - bridgeFee: RosenAmountValue, - networkFee: RosenAmountValue, - lockAddress: string, - ): Promise => { - const wallet = await getNamiWallet().getApi().enable(); - const policyIdHex = token.policyId; - const assetNameHex = token.assetName; - const changeAddressHex = await wallet.getChangeAddress(); - - const auxiliaryDataHex = await config.generateLockAuxiliaryData( - toChain, - toAddress, - changeAddressHex, - networkFee.toString(), - bridgeFee.toString(), - ); - - const walletUtxos = await wallet.getUtxos(); - if (!walletUtxos) throw Error(`Failed to fetch wallet utxos`); - const unsignedTxHex = await config.generateUnsignedTx( - walletUtxos, - lockAddress, - changeAddressHex, - policyIdHex, - assetNameHex, - amount, - auxiliaryDataHex, - ); - - const signedTxHex = await config.setTxWitnessSet( - unsignedTxHex, - await wallet.signTx(unsignedTxHex, false), - ); - - const result = await wallet.submitTx(signedTxHex); - return result; - }; diff --git a/wallets/nami-wallet/CHANGELOG.md b/wallets/nami/CHANGELOG.md similarity index 89% rename from wallets/nami-wallet/CHANGELOG.md rename to wallets/nami/CHANGELOG.md index fee751da..23840348 100644 --- a/wallets/nami-wallet/CHANGELOG.md +++ b/wallets/nami/CHANGELOG.md @@ -1,5 +1,17 @@ # @rosen-ui/nami-wallet +## 2.0.0 + +### Major Changes + +- Encapsulate wallet functionalities into a single class following a unified interface to simplify maintenance and enable quick addition of new wallet types by implementing the interface. + +### Patch Changes + +- Updated dependencies + - @rosen-bridge/icons@1.0.0 + - @rosen-network/cardano@2.0.0 + ## 1.0.3 ### Patch Changes diff --git a/wallets/nami-wallet/package.json b/wallets/nami/package.json similarity index 87% rename from wallets/nami-wallet/package.json rename to wallets/nami/package.json index 8d049e33..71781cc9 100644 --- a/wallets/nami-wallet/package.json +++ b/wallets/nami/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-ui/nami-wallet", - "version": "1.0.3", + "version": "2.0.0", "private": true, "description": "This is a private package utilized within Rosen Bridge UI app", "main": "dist/src/index.js", @@ -16,9 +16,9 @@ "typescript": "^5.0.0" }, "dependencies": { - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-network/cardano": "^1.0.1", + "@rosen-network/cardano": "^2.0.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/types": "^0.3.1", "@rosen-ui/utils": "^0.4.2", diff --git a/wallets/nami/src/index.ts b/wallets/nami/src/index.ts new file mode 100644 index 00000000..3c5958cf --- /dev/null +++ b/wallets/nami/src/index.ts @@ -0,0 +1 @@ +export * from './wallet'; diff --git a/wallets/nami/src/types.ts b/wallets/nami/src/types.ts new file mode 100644 index 00000000..5d5d027d --- /dev/null +++ b/wallets/nami/src/types.ts @@ -0,0 +1,31 @@ +import { TokenMap } from '@rosen-bridge/tokens'; +import type { + generateUnsignedTx, + decodeWasmValue, + generateLockAuxiliaryData, + setTxWitnessSet, +} from '@rosen-network/cardano'; +import { CipWalletApi } from '@rosen-ui/wallet-api'; + +export type WalletConfig = { + getTokenMap(): Promise; + decodeWasmValue: typeof decodeWasmValue; + generateLockAuxiliaryData: typeof generateLockAuxiliaryData; + generateUnsignedTx: ReturnType; + setTxWitnessSet: typeof setTxWitnessSet; +}; + +/** + * global type augmentation for the wallet + */ +declare global { + interface Window { + cardano: { + nami: { + enable(): Promise; + isEnabled(): Promise; + experimental?: unknown; + }; + }; + } +} diff --git a/wallets/nami/src/wallet.ts b/wallets/nami/src/wallet.ts new file mode 100644 index 00000000..a41ba54c --- /dev/null +++ b/wallets/nami/src/wallet.ts @@ -0,0 +1,98 @@ +import { NamiIcon } from '@rosen-bridge/icons'; +import { RosenChainToken } from '@rosen-bridge/tokens'; +import { NETWORKS } from '@rosen-ui/constants'; +import { hexToCbor } from '@rosen-ui/utils'; +import { Wallet, WalletTransferParams } from '@rosen-ui/wallet-api'; + +import { WalletConfig } from './types'; + +export class NamiWallet implements Wallet { + icon = NamiIcon; + + name = 'Nami'; + + label = 'Nami'; + + link = 'https://namiwallet.io/'; + + private get api() { + return window.cardano.nami; + } + + constructor(private config: WalletConfig) {} + + async connect(): Promise { + return !!(await this.api.enable()); + } + + async getAddress(): Promise { + return this.api.enable().then((wallet) => wallet.getChangeAddress()); + } + + async getBalance(token: RosenChainToken): Promise { + const context = await this.api.enable(); + + const rawValue = await context.getBalance(); + + const balances = await this.config.decodeWasmValue(rawValue); + + const amount = balances.find( + (asset) => + asset.policyId === token.policyId && + (asset.nameHex === hexToCbor(token.assetName) || !token.policyId), + ); + + if (!amount) return 0n; + + const tokenMap = await this.config.getTokenMap(); + + const wrappedAmount = tokenMap.wrapAmount( + token[tokenMap.getIdKey(NETWORKS.CARDANO)], + amount.quantity, + NETWORKS.CARDANO, + ).amount; + + return wrappedAmount; + } + + isAvailable(): boolean { + return typeof window.cardano !== 'undefined' && !!window.cardano.nami; + } + + async transfer(params: WalletTransferParams): Promise { + const wallet = await this.api.enable(); + + const changeAddressHex = await this.getAddress(); + + const auxiliaryDataHex = await this.config.generateLockAuxiliaryData( + params.toChain, + params.address, + changeAddressHex, + params.networkFee.toString(), + params.bridgeFee.toString(), + ); + + const walletUtxos = await wallet.getUtxos(); + + if (!walletUtxos) throw Error(`Failed to fetch wallet utxos`); + + const unsignedTxHex = await this.config.generateUnsignedTx( + walletUtxos, + params.lockAddress, + changeAddressHex, + params.token.policyId, + params.token.assetName, + params.amount, + auxiliaryDataHex, + ); + + const signedTxHex = await this.config.setTxWitnessSet( + unsignedTxHex, + await wallet.signTx(unsignedTxHex, false), + ); + + const result = await wallet.submitTx(signedTxHex); + + return result; + } +} diff --git a/wallets/metamask-wallet/tsconfig.json b/wallets/nami/tsconfig.json similarity index 100% rename from wallets/metamask-wallet/tsconfig.json rename to wallets/nami/tsconfig.json diff --git a/wallets/nautilus-wallet/src/connectWallet.ts b/wallets/nautilus-wallet/src/connectWallet.ts deleted file mode 100644 index aef71f82..00000000 --- a/wallets/nautilus-wallet/src/connectWallet.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * handles the nautilus wallet connection - */ -export const connectWallet = async () => { - if (!window.ergoConnector?.nautilus) { - throw new Error('EXTENSION_NOT_FOUND'); - } - - if (!window.ergoConnector.nautilus?.getContext) { - return 'Wallet API has changed. Be sure to update your wallet to continue using it'; - } - - const nautilus = window.ergoConnector.nautilus; - return await nautilus.connect({ createErgoObject: false }); -}; diff --git a/wallets/nautilus-wallet/src/getBalance.ts b/wallets/nautilus-wallet/src/getBalance.ts deleted file mode 100644 index 8d0b1c31..00000000 --- a/wallets/nautilus-wallet/src/getBalance.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/ergo'; -import { NETWORKS } from '@rosen-ui/constants'; -import { RosenAmountValue } from '@rosen-ui/types'; - -import { getNautilusWallet } from './getNautilusWallet'; - -export const getBalanceCreator = - (config: WalletCreatorConfig) => - async (token: RosenChainToken): Promise => { - const context = await getNautilusWallet().getApi().getContext(); - - const tokenMap = await config.getTokenMap(); - - const tokenId = token[tokenMap.getIdKey(NETWORKS.ERGO)]; - /** - * The following condition is required because nautilus only accepts - * uppercase ERG as tokenId for the erg native token - */ - const balance = await context.get_balance( - tokenId === 'erg' ? 'ERG' : tokenId, - ); - - const amount = BigInt(balance); - - if (!amount) return 0n; - - const wrappedAmount = tokenMap.wrapAmount( - tokenId, - amount, - NETWORKS.ERGO, - ).amount; - - return wrappedAmount; - }; diff --git a/wallets/nautilus-wallet/src/getNautilusWallet.ts b/wallets/nautilus-wallet/src/getNautilusWallet.ts deleted file mode 100644 index 9fd201d1..00000000 --- a/wallets/nautilus-wallet/src/getNautilusWallet.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { createRawWallet } from '@rosen-ui/wallet-api'; - -import { connectWallet } from './connectWallet'; -import { nautilusWalletInfo } from './nautilusWalletInfo'; - -/** - * nautilus implementation of the Wallet - * interface to be able to interact with nautilus wallet - */ - -export const getNautilusWallet = () => { - return createRawWallet( - { - ...nautilusWalletInfo, - connectWallet, - }, - () => window.ergoConnector.nautilus, - ); -}; diff --git a/wallets/nautilus-wallet/src/index.ts b/wallets/nautilus-wallet/src/index.ts deleted file mode 100644 index 5fabcef6..00000000 --- a/wallets/nautilus-wallet/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './nautilusWalletCreator'; -export * from './nautilusWalletInfo'; diff --git a/wallets/nautilus-wallet/src/isNautilusAvailable.ts b/wallets/nautilus-wallet/src/isNautilusAvailable.ts deleted file mode 100644 index 02dacd84..00000000 --- a/wallets/nautilus-wallet/src/isNautilusAvailable.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const isNautilusAvailable = (): boolean => { - return ( - typeof window.ergoConnector !== 'undefined' && - !!window.ergoConnector.nautilus - ); -}; diff --git a/wallets/nautilus-wallet/src/nautilusWalletCreator.ts b/wallets/nautilus-wallet/src/nautilusWalletCreator.ts deleted file mode 100644 index 345f451b..00000000 --- a/wallets/nautilus-wallet/src/nautilusWalletCreator.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { WalletCreator } from '@rosen-network/ergo'; - -import { getBalanceCreator } from './getBalance'; -import { getNautilusWallet } from './getNautilusWallet'; -import { isNautilusAvailable } from './isNautilusAvailable'; -import { transferCreator } from './transfer'; - -export const nautilusWalletCreator: WalletCreator = (config) => { - return Object.assign({}, getNautilusWallet(), { - isAvailable: isNautilusAvailable, - getBalance: getBalanceCreator(config), - transfer: transferCreator(config), - getAddress: async () => { - throw new Error('Not implemented'); - }, - }); -}; diff --git a/wallets/nautilus-wallet/src/nautilusWalletInfo.ts b/wallets/nautilus-wallet/src/nautilusWalletInfo.ts deleted file mode 100644 index cc561be7..00000000 --- a/wallets/nautilus-wallet/src/nautilusWalletInfo.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { NautilusIcon } from '@rosen-bridge/icons'; -import { WalletInfo } from '@rosen-ui/wallet-api'; - -export const nautilusWalletInfo: WalletInfo = { - icon: NautilusIcon, - name: 'Nautilus', - label: 'Nautilus', - link: 'https://github.com/nautls/nautilus-wallet', -}; diff --git a/wallets/nautilus-wallet/src/transfer.ts b/wallets/nautilus-wallet/src/transfer.ts deleted file mode 100644 index b9a7cd6b..00000000 --- a/wallets/nautilus-wallet/src/transfer.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/ergo'; -import { Network, RosenAmountValue } from '@rosen-ui/types'; - -import { getNautilusWallet } from './getNautilusWallet'; - -export const transferCreator = - (config: WalletCreatorConfig) => - async ( - token: RosenChainToken, - amount: RosenAmountValue, - toChain: Network, - toAddress: string, - bridgeFee: RosenAmountValue, - networkFee: RosenAmountValue, - lockAddress: string, - ): Promise => { - const wallet = await getNautilusWallet().getApi().getContext(); - const changeAddress = await wallet.get_change_address(); - - const walletUtxos = await wallet.get_utxos(); - if (!walletUtxos) throw Error(`No box found`); - - const unsignedTx = await config.generateUnsignedTx( - changeAddress, - walletUtxos, - lockAddress, - toChain, - toAddress, - amount, - bridgeFee.toString(), - networkFee.toString(), - token, - ); - const signedTx = await wallet.sign_tx(unsignedTx); - const result = await wallet.submit_tx(signedTx); - return result; - }; diff --git a/wallets/nautilus-wallet/CHANGELOG.md b/wallets/nautilus/CHANGELOG.md similarity index 88% rename from wallets/nautilus-wallet/CHANGELOG.md rename to wallets/nautilus/CHANGELOG.md index 3b2c040f..2fc909d5 100644 --- a/wallets/nautilus-wallet/CHANGELOG.md +++ b/wallets/nautilus/CHANGELOG.md @@ -1,5 +1,17 @@ # @rosen-ui/nautilus-wallet +## 2.0.0 + +### Major Changes + +- Encapsulate wallet functionalities into a single class following a unified interface to simplify maintenance and enable quick addition of new wallet types by implementing the interface. + +### Patch Changes + +- Updated dependencies + - @rosen-bridge/icons@1.0.0 + - @rosen-network/ergo@2.0.0 + ## 1.0.3 ### Patch Changes diff --git a/wallets/nautilus-wallet/package.json b/wallets/nautilus/package.json similarity index 87% rename from wallets/nautilus-wallet/package.json rename to wallets/nautilus/package.json index 5b10986e..f30005aa 100644 --- a/wallets/nautilus-wallet/package.json +++ b/wallets/nautilus/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-ui/nautilus-wallet", - "version": "1.0.3", + "version": "2.0.0", "private": true, "description": "This is a private package utilized within Rosen Bridge UI app", "main": "dist/src/index.js", @@ -17,8 +17,8 @@ "typescript": "^5.0.0" }, "dependencies": { - "@rosen-bridge/icons": "^0.7.0", - "@rosen-network/ergo": "^1.0.0", + "@rosen-bridge/icons": "^1.0.0", + "@rosen-network/ergo": "^2.0.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/types": "^0.3.1", "@rosen-ui/utils": "^0.4.2", diff --git a/wallets/nautilus/src/index.ts b/wallets/nautilus/src/index.ts new file mode 100644 index 00000000..3c5958cf --- /dev/null +++ b/wallets/nautilus/src/index.ts @@ -0,0 +1 @@ +export * from './wallet'; diff --git a/wallets/nautilus-wallet/src/global.d.ts b/wallets/nautilus/src/types.ts similarity index 58% rename from wallets/nautilus-wallet/src/global.d.ts rename to wallets/nautilus/src/types.ts index 3067f879..dd3dafb6 100644 --- a/wallets/nautilus-wallet/src/global.d.ts +++ b/wallets/nautilus/src/types.ts @@ -1,5 +1,12 @@ +import { TokenMap } from '@rosen-bridge/tokens'; +import type { generateUnsignedTx } from '@rosen-network/ergo'; import { EipWalletApi } from '@rosen-ui/wallet-api'; +export type WalletConfig = { + getTokenMap(): Promise; + generateUnsignedTx: ReturnType; +}; + /** * global type augmentation for nautilus wallet */ @@ -13,5 +20,3 @@ declare global { }; } } - -export {}; diff --git a/wallets/nautilus/src/wallet.ts b/wallets/nautilus/src/wallet.ts new file mode 100644 index 00000000..c71cd773 --- /dev/null +++ b/wallets/nautilus/src/wallet.ts @@ -0,0 +1,101 @@ +import { NautilusIcon } from '@rosen-bridge/icons'; +import { RosenChainToken } from '@rosen-bridge/tokens'; +import { NETWORKS } from '@rosen-ui/constants'; +import { Wallet, WalletTransferParams } from '@rosen-ui/wallet-api'; + +import { WalletConfig } from './types'; + +export class NautilusWallet implements Wallet { + icon = NautilusIcon; + + name = 'Nautilus'; + + label = 'Nautilus'; + + link = 'https://github.com/nautls/nautilus-wallet'; + + private get api() { + return window.ergoConnector.nautilus; + } + + constructor(private config: WalletConfig) {} + + async connect(): Promise { + if (!this.api) { + throw new Error('EXTENSION_NOT_FOUND'); + } + + if (!this.api.getContext) { + console.warn('Wallet API has changed. Please update your wallet.'); + } + + return await this.api.connect({ createErgoObject: false }); + } + + async getAddress(): Promise { + return this.api.getContext().then((wallet) => wallet.get_change_address()); + } + + async getBalance(token: RosenChainToken): Promise { + const context = await this.api.getContext(); + + const tokenMap = await this.config.getTokenMap(); + + const tokenId = token[tokenMap.getIdKey(NETWORKS.ERGO)]; + + /** + * The following condition is required because nautilus only accepts + * uppercase ERG as tokenId for the erg native token + */ + const balance = await context.get_balance( + tokenId === 'erg' ? 'ERG' : tokenId, + ); + + const amount = BigInt(balance); + + if (!amount) return 0n; + + const wrappedAmount = tokenMap.wrapAmount( + tokenId, + amount, + NETWORKS.ERGO, + ).amount; + + return wrappedAmount; + } + + isAvailable(): boolean { + return ( + typeof window.ergoConnector !== 'undefined' && + !!window.ergoConnector.nautilus + ); + } + + async transfer(params: WalletTransferParams): Promise { + const wallet = await this.api.getContext(); + + const changeAddress = await this.getAddress(); + + const walletUtxos = await wallet.get_utxos(); + + if (!walletUtxos) throw Error(`No box found`); + + const unsignedTx = await this.config.generateUnsignedTx( + changeAddress, + walletUtxos, + params.lockAddress, + params.toChain, + params.address, + params.amount, + params.bridgeFee.toString(), + params.networkFee.toString(), + params.token, + ); + + const signedTx = await wallet.sign_tx(unsignedTx); + + const result = await wallet.submit_tx(signedTx); + + return result; + } +} diff --git a/wallets/nautilus-wallet/tsconfig.json b/wallets/nautilus/tsconfig.json similarity index 100% rename from wallets/nautilus-wallet/tsconfig.json rename to wallets/nautilus/tsconfig.json diff --git a/wallets/okx-wallet/CHANGELOG.md b/wallets/okx-wallet/CHANGELOG.md deleted file mode 100644 index aae52870..00000000 --- a/wallets/okx-wallet/CHANGELOG.md +++ /dev/null @@ -1,11 +0,0 @@ -# @rosen-ui/okx-wallet - -## 0.1.0 - -### Minor Changes - -- Implement the OKX wallet package - -### Patch Changes - -- Updated the @rosen-bridge/icons@0.7.0 dependency diff --git a/wallets/okx-wallet/src/connectWallet.ts b/wallets/okx-wallet/src/connectWallet.ts deleted file mode 100644 index 9931281a..00000000 --- a/wallets/okx-wallet/src/connectWallet.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * handles the OKX wallet connection - */ -export const connectWallet = async (): Promise => { - try { - await window.okxwallet.bitcoin.connect(); - return true; - } catch { - return false; - } -}; diff --git a/wallets/okx-wallet/src/getAddressCreator.ts b/wallets/okx-wallet/src/getAddressCreator.ts deleted file mode 100644 index 7f822ae1..00000000 --- a/wallets/okx-wallet/src/getAddressCreator.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const getAddressCreator = () => (): Promise => { - return window.okxwallet.bitcoin - .getAccounts() - .then((accounts: string[]) => accounts[0]); -}; diff --git a/wallets/okx-wallet/src/getBalance.ts b/wallets/okx-wallet/src/getBalance.ts deleted file mode 100644 index e4a68eb3..00000000 --- a/wallets/okx-wallet/src/getBalance.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/bitcoin'; -import { NETWORKS } from '@rosen-ui/constants'; -import { RosenAmountValue } from '@rosen-ui/types'; - -export const getBalanceCreator = - (config: WalletCreatorConfig) => - async (token: RosenChainToken): Promise => { - const amount = await window.okxwallet.bitcoin.getBalance(); - - if (!amount.confirmed) return 0n; - - const tokenMap = await config.getTokenMap(); - - const wrappedAmount = tokenMap.wrapAmount( - token[tokenMap.getIdKey(NETWORKS.BITCOIN)], - BigInt(amount.confirmed), - NETWORKS.BITCOIN, - ).amount; - - return wrappedAmount; - }; diff --git a/wallets/okx-wallet/src/getOKXWallet.ts b/wallets/okx-wallet/src/getOKXWallet.ts deleted file mode 100644 index 89f022f8..00000000 --- a/wallets/okx-wallet/src/getOKXWallet.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createRawWallet } from '@rosen-ui/wallet-api'; - -import { connectWallet } from './connectWallet'; -import { okxWalletInfo } from './okxWalletInfo'; - -/** - * OKX implementation of the Wallet - * interface to be able to interact with OKX wallet - */ -export const getOKXWallet = () => { - return createRawWallet( - { - ...okxWalletInfo, - connectWallet, - }, - () => {}, - ); -}; diff --git a/wallets/okx-wallet/src/global.d.ts b/wallets/okx-wallet/src/global.d.ts deleted file mode 100644 index 7751cfba..00000000 --- a/wallets/okx-wallet/src/global.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * global type augmentation for the wallet - */ -declare global { - interface Window { - okxwallet: { - bitcoin: { - /** - * TODO: replace the any type with an interface - * local:ergo/rosen-bridge/ui#456 - */ - // eslint-disable-next-line - [key: string]: any; - }; - }; - } -} - -export {}; diff --git a/wallets/okx-wallet/src/index.ts b/wallets/okx-wallet/src/index.ts deleted file mode 100644 index b76ffc74..00000000 --- a/wallets/okx-wallet/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './okxWalletCreator'; -export * from './okxWalletInfo'; diff --git a/wallets/okx-wallet/src/isOKXAvailable.ts b/wallets/okx-wallet/src/isOKXAvailable.ts deleted file mode 100644 index 6f5962e6..00000000 --- a/wallets/okx-wallet/src/isOKXAvailable.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const isOKXAvailable = (): boolean => { - return typeof window.okxwallet !== 'undefined' && !!window.okxwallet.bitcoin; -}; diff --git a/wallets/okx-wallet/src/okxWalletCreator.ts b/wallets/okx-wallet/src/okxWalletCreator.ts deleted file mode 100644 index 37e6abca..00000000 --- a/wallets/okx-wallet/src/okxWalletCreator.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { WalletCreator } from '@rosen-network/bitcoin'; - -import { getAddressCreator } from './getAddressCreator'; -import { getBalanceCreator } from './getBalance'; -import { getOKXWallet } from './getOKXWallet'; -import { isOKXAvailable } from './isOKXAvailable'; -import { transferCreator } from './transfer'; - -export const okxWalletCreator: WalletCreator = (config) => { - return Object.assign({}, getOKXWallet(), { - isAvailable: isOKXAvailable, - getBalance: getBalanceCreator(config), - transfer: transferCreator(config), - getAddress: getAddressCreator(), - }); -}; diff --git a/wallets/okx-wallet/src/okxWalletInfo.ts b/wallets/okx-wallet/src/okxWalletInfo.ts deleted file mode 100644 index 29ebceeb..00000000 --- a/wallets/okx-wallet/src/okxWalletInfo.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { OKXIcon } from '@rosen-bridge/icons'; -import { WalletInfo } from '@rosen-ui/wallet-api'; - -export const okxWalletInfo: WalletInfo = { - icon: OKXIcon, - name: 'OKX', - label: 'OKX', - link: 'https://www.okx.com/', -}; diff --git a/wallets/okx-wallet/src/transfer.ts b/wallets/okx-wallet/src/transfer.ts deleted file mode 100644 index 7e6ffbdb..00000000 --- a/wallets/okx-wallet/src/transfer.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { WalletCreatorConfig } from '@rosen-network/bitcoin'; -import { Network, RosenAmountValue } from '@rosen-ui/types'; - -import { getAddressCreator } from './getAddressCreator'; - -export const transferCreator = - (config: WalletCreatorConfig) => - async ( - token: RosenChainToken, - amount: RosenAmountValue, - toChain: Network, - toAddress: string, - bridgeFee: RosenAmountValue, - networkFee: RosenAmountValue, - lockAddress: string, - ): Promise => { - const userAddress = await getAddressCreator()(); - - const opReturnData = await config.generateOpReturnData( - toChain, - toAddress, - networkFee.toString(), - bridgeFee.toString(), - ); - - const psbtData = await config.generateUnsignedTx( - lockAddress, - userAddress, - amount, - opReturnData, - token, - ); - - const signedPsbtHex = await window.okxwallet.bitcoin.signPsbt( - psbtData.psbt.hex, - { - autoFinalized: false, - toSignInputs: Array.from(Array(psbtData.inputSize).keys()).map( - (index) => ({ - address: userAddress, - index: index, - }), - ), - }, - ); - - const txId = await config.submitTransaction(signedPsbtHex, 'hex'); - - return txId; - }; diff --git a/wallets/okx-wallet/tsconfig.json b/wallets/okx-wallet/tsconfig.json deleted file mode 100644 index 96ece334..00000000 --- a/wallets/okx-wallet/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.novite.json", - "compilerOptions": { - "jsx": "react-jsx", - "outDir": "dist", - "rootDir": "./" - }, - "include": ["src"] -} diff --git a/wallets/okx/CHANGELOG.md b/wallets/okx/CHANGELOG.md new file mode 100644 index 00000000..ef4f4463 --- /dev/null +++ b/wallets/okx/CHANGELOG.md @@ -0,0 +1,23 @@ +# @rosen-ui/okx-wallet + +## 1.0.0 + +### Major Changes + +- Encapsulate wallet functionalities into a single class following a unified interface to simplify maintenance and enable quick addition of new wallet types by implementing the interface. + +### Patch Changes + +- Updated dependencies + - @rosen-bridge/icons@1.0.0 + - @rosen-network/bitcoin@2.0.0 + +## 0.1.0 + +### Minor Changes + +- Implement the OKX wallet package + +### Patch Changes + +- Updated the @rosen-bridge/icons@0.7.0 dependency diff --git a/wallets/okx-wallet/package.json b/wallets/okx/package.json similarity index 86% rename from wallets/okx-wallet/package.json rename to wallets/okx/package.json index 1266c745..8415e1ee 100644 --- a/wallets/okx-wallet/package.json +++ b/wallets/okx/package.json @@ -1,6 +1,6 @@ { "name": "@rosen-ui/okx-wallet", - "version": "0.1.0", + "version": "1.0.0", "private": true, "description": "This is a private package utilized within Rosen Bridge UI app", "main": "dist/src/index.js", @@ -16,9 +16,9 @@ "typescript": "^5.0.0" }, "dependencies": { - "@rosen-bridge/icons": "^0.7.0", + "@rosen-bridge/icons": "^1.0.0", "@rosen-bridge/tokens": "^1.2.1", - "@rosen-network/bitcoin": "^1.1.0", + "@rosen-network/bitcoin": "^2.0.0", "@rosen-ui/constants": "^0.0.5", "@rosen-ui/types": "^0.3.2", "@rosen-ui/wallet-api": "^1.0.3" diff --git a/wallets/okx/src/index.ts b/wallets/okx/src/index.ts new file mode 100644 index 00000000..3c5958cf --- /dev/null +++ b/wallets/okx/src/index.ts @@ -0,0 +1 @@ +export * from './wallet'; diff --git a/wallets/okx/src/types.ts b/wallets/okx/src/types.ts new file mode 100644 index 00000000..22927d46 --- /dev/null +++ b/wallets/okx/src/types.ts @@ -0,0 +1,33 @@ +import { TokenMap } from '@rosen-bridge/tokens'; +import type { + generateUnsignedTx, + generateOpReturnData, + getAddressBalance, + submitTransaction, +} from '@rosen-network/bitcoin'; + +export type WalletConfig = { + getTokenMap(): Promise; + generateOpReturnData: typeof generateOpReturnData; + generateUnsignedTx: ReturnType; + submitTransaction: typeof submitTransaction; + getAddressBalance: typeof getAddressBalance; +}; + +/** + * global type augmentation for the wallet + */ +declare global { + interface Window { + okxwallet: { + bitcoin: { + /** + * TODO: replace the any type with an interface + * local:ergo/rosen-bridge/ui#456 + */ + // eslint-disable-next-line + [key: string]: any; + }; + }; + } +} diff --git a/wallets/okx/src/wallet.ts b/wallets/okx/src/wallet.ts new file mode 100644 index 00000000..ed7d42bd --- /dev/null +++ b/wallets/okx/src/wallet.ts @@ -0,0 +1,90 @@ +import { OKXIcon } from '@rosen-bridge/icons'; +import { RosenChainToken } from '@rosen-bridge/tokens'; +import { NETWORKS } from '@rosen-ui/constants'; +import { Wallet, WalletTransferParams } from '@rosen-ui/wallet-api'; + +import { WalletConfig } from './types'; + +export class OKXWallet implements Wallet { + icon = OKXIcon; + + name = 'OKX'; + + label = 'OKX'; + + link = 'https://www.okx.com/'; + + private get api() { + return window.okxwallet.bitcoin; + } + + constructor(private config: WalletConfig) {} + + async connect(): Promise { + try { + await this.api.connect(); + return true; + } catch { + return false; + } + } + + async getAddress(): Promise { + return this.api.getAccounts().then((accounts: string[]) => accounts[0]); + } + + async getBalance(token: RosenChainToken): Promise { + const amount = await this.api.getBalance(); + + if (!amount.confirmed) return 0n; + + const tokenMap = await this.config.getTokenMap(); + + const wrappedAmount = tokenMap.wrapAmount( + token[tokenMap.getIdKey(NETWORKS.BITCOIN)], + BigInt(amount.confirmed), + NETWORKS.BITCOIN, + ).amount; + + return wrappedAmount; + } + + isAvailable(): boolean { + return ( + typeof window.okxwallet !== 'undefined' && !!window.okxwallet.bitcoin + ); + } + + async transfer(params: WalletTransferParams): Promise { + const userAddress = await this.getAddress(); + + const opReturnData = await this.config.generateOpReturnData( + params.toChain, + params.address, + params.networkFee.toString(), + params.bridgeFee.toString(), + ); + + const psbtData = await this.config.generateUnsignedTx( + params.lockAddress, + userAddress, + params.amount, + opReturnData, + params.token, + ); + + const signedPsbtHex = await this.api.signPsbt(psbtData.psbt.hex, { + autoFinalized: false, + toSignInputs: Array.from(Array(psbtData.inputSize).keys()).map( + (index) => ({ + address: userAddress, + index: index, + }), + ), + }); + + const txId = await this.config.submitTransaction(signedPsbtHex, 'hex'); + + return txId; + } +} diff --git a/wallets/nami-wallet/tsconfig.json b/wallets/okx/tsconfig.json similarity index 100% rename from wallets/nami-wallet/tsconfig.json rename to wallets/okx/tsconfig.json diff --git a/wallets/vespr-wallet/CHANGELOG.md b/wallets/vespr-wallet/CHANGELOG.md deleted file mode 100644 index 698a8dba..00000000 --- a/wallets/vespr-wallet/CHANGELOG.md +++ /dev/null @@ -1,99 +0,0 @@ -# @rosen-ui/vespr-wallet - -## 0.0.11 - -### Patch Changes - -- Fix missing dependencies and remove unused packages -- Updated the @rosen-ui/utils@0.4.2 dependency - -## 0.0.10 - -### Patch Changes - -- Update the source code to address the issues identified by the new ESLint rules configuration -- Updated the @rosen-bridge/icons@0.7.0 dependency - -## 0.0.9 - -### Patch Changes - -- Updated the @rosen-bridge/icons@0.6.0 dependency - -## 0.0.8 - -### Patch Changes - -- Revise the wallet creation logic and update the access type for each API. - -## 0.0.7 - -### Patch Changes - -- Updated dependencies - - @rosen-ui/utils@0.3.0 - - @rosen-ui/wallet-api@1.0.2 - -## 0.0.6 - -### Patch Changes - -- Updated dependencies - - @rosen-ui/utils@0.2.0 - - @rosen-ui/wallet-api@1.0.1 - -## 0.0.5 - -### Patch Changes - -- Updated dependencies - - @rosen-ui/wallet-api@1.0.0 - -## 0.0.4 - -### Patch Changes - -- Updated dependencies - - @rosen-bridge/icons@0.4.0 - - @rosen-ui/utils@0.1.1 - -## 0.0.3 - -### Patch Changes - -- Updated dependencies - - @rosen-bridge/icons@0.3.0 - -## 0.3.0 - -### Minor Changes - -- Set a maximum page size of 100 for events api -- Use the shared hooks package instead of utils package to prevent server component problems - -### Patch Changes - -- Fix app crash when a token fetched from database is not found -- Update dependencies - - @rosen-ui/common-hooks@0.1.0 - - @rosen-ui/utils@0.1.0 - - @rosen-ui/eternl-wallet@0.0.2 - - @rosen-ui/flint-wallet@0.0.2 - - @rosen-ui/lace-wallet@0.0.2 - - @rosen-ui/nami-wallet@0.0.2 - - @rosen-ui/nautilus-wallet@0.0.2 - - @rosen-ui/vespr-wallet@0.0.2 - - @rosen-ui/wallet-api@0.0.2 - -## 0.2.1 - -### Patch Changes - -- Fix issue with wallet index when having multiple wallets - -## 0.2.0 - -### Minor Changes - -- Add multi-wallet support ([@Mercurial](https://github.com/Mercurial)) -- Add Eternl, Flint and Lace wallets for Cardano chain ([@Mercurial](https://github.com/Mercurial)) diff --git a/wallets/vespr-wallet/package.json b/wallets/vespr-wallet/package.json deleted file mode 100644 index 64bd709a..00000000 --- a/wallets/vespr-wallet/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "@rosen-ui/vespr-wallet", - "version": "0.0.11", - "private": true, - "description": "This is a private package utilized within Rosen Bridge UI app", - "main": "dist/src/index.js", - "types": "dist/src/index.d.ts", - "type": "module", - "scripts": { - "prettify": "prettier --write . --ignore-path ../../.gitignore", - "lint": "eslint --fix . && npm run prettify", - "build": "tsc --build", - "type-check": "tsc --noEmit" - }, - "devDependencies": { - "typescript": "^5.0.0" - }, - "dependencies": { - "@rosen-bridge/icons": "^0.7.0", - "@rosen-ui/utils": "^0.4.2", - "@rosen-ui/wallet-api": "^1.0.3" - } -} diff --git a/wallets/vespr-wallet/src/connectWallet.ts b/wallets/vespr-wallet/src/connectWallet.ts deleted file mode 100644 index 0531ede6..00000000 --- a/wallets/vespr-wallet/src/connectWallet.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * handles the Vespr wallet connection - */ - -export const connectWallet = async () => { - const granted = await window.cardano.vespr?.enable(); - - if (!granted) { - console.error('Failed to connect!'); - return false; - } - return true; -}; diff --git a/wallets/vespr-wallet/src/index.ts b/wallets/vespr-wallet/src/index.ts deleted file mode 100644 index f532390f..00000000 --- a/wallets/vespr-wallet/src/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { VesprIcon } from '@rosen-bridge/icons'; -import { WalletInfo, createRawWallet } from '@rosen-ui/wallet-api'; - -import { connectWallet } from './connectWallet'; - -export const walletInfo: WalletInfo = { - icon: VesprIcon, - name: 'Vespr', - label: 'Vespr', - link: 'https://vespr.xyz/', -}; - -/** - * Vespr implementation of the Wallet - * interface to be able to interact with Vespr wallet - */ -const getVesprWallet = () => - createRawWallet( - { - ...walletInfo, - connectWallet, - }, - () => window.cardano.vespr, - ); - -export const isVesprAvailable = () => - typeof window.cardano !== 'undefined' && window.cardano?.vespr; - -export default getVesprWallet; diff --git a/wallets/vespr-wallet/src/types/index.d.ts b/wallets/vespr-wallet/src/types/index.d.ts deleted file mode 100644 index d912aa88..00000000 --- a/wallets/vespr-wallet/src/types/index.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { CipWalletApi } from '@rosen-ui/wallet-api'; - -export interface ConnectorAPI { - enable(): Promise; - isEnabled(): Promise; - experimental?: unknown; -} - -/** - * global type augmentation for Vespr wallet - */ -declare global { - interface Window { - cardano: { [key: string]: ConnectorAPI }; - } -} diff --git a/wallets/vespr-wallet/tsconfig.json b/wallets/vespr-wallet/tsconfig.json deleted file mode 100644 index 96ece334..00000000 --- a/wallets/vespr-wallet/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.novite.json", - "compilerOptions": { - "jsx": "react-jsx", - "outDir": "dist", - "rootDir": "./" - }, - "include": ["src"] -} diff --git a/wallets/wallet-api/src/cardano/address.ts b/wallets/wallet-api/src/cardano/address.ts index 76d5cf5e..3dcf89e8 100644 --- a/wallets/wallet-api/src/cardano/address.ts +++ b/wallets/wallet-api/src/cardano/address.ts @@ -1,6 +1,7 @@ import { decodeHex } from '@rosen-ui/utils'; -import { Addr, RawAddr, CardanoWasm } from '../types'; +import { RawAddr } from '../types'; +import { Addr, CardanoWasm } from './types'; export function decodeAddr(raw: RawAddr, R: CardanoWasm): Addr { return R.Address.from_bytes(decodeHex(raw)).to_bech32(); diff --git a/wallets/wallet-api/src/cardano/assetEntry.ts b/wallets/wallet-api/src/cardano/assetEntry.ts index 3ac3b13e..013a4230 100644 --- a/wallets/wallet-api/src/cardano/assetEntry.ts +++ b/wallets/wallet-api/src/cardano/assetEntry.ts @@ -1,5 +1,6 @@ -import { AdaAssetName, AdaAssetNameHex, AdaPolicyId } from '../constants'; -import { AssetEntry, Lovelace } from '../types'; +import { Lovelace } from '../types'; +import { AdaAssetName, AdaAssetNameHex, AdaPolicyId } from './constants'; +import { AssetEntry } from './types'; export function AdaEntry(quantity: Lovelace): AssetEntry { return { diff --git a/wallets/wallet-api/src/constants/index.ts b/wallets/wallet-api/src/cardano/constants.ts similarity index 100% rename from wallets/wallet-api/src/constants/index.ts rename to wallets/wallet-api/src/cardano/constants.ts diff --git a/wallets/wallet-api/src/cardano/index.ts b/wallets/wallet-api/src/cardano/index.ts index d5b6937f..65aa8e14 100644 --- a/wallets/wallet-api/src/cardano/index.ts +++ b/wallets/wallet-api/src/cardano/index.ts @@ -1,3 +1,4 @@ export * from './address'; export * from './assetEntry'; export * from './serlib'; +export * from './types'; diff --git a/wallets/wallet-api/src/cardano/serlib.ts b/wallets/wallet-api/src/cardano/serlib.ts index 2d5ea213..f29739e5 100644 --- a/wallets/wallet-api/src/cardano/serlib.ts +++ b/wallets/wallet-api/src/cardano/serlib.ts @@ -1,9 +1,9 @@ import * as wasm from '@emurgo/cardano-serialization-lib-nodejs'; import { encodeHex, decodeHex } from '@rosen-ui/utils'; -import { HexString, Value, PolicyId, AssetEntry, TxOut } from '../types'; -import { CardanoWasm } from '../types'; +import { HexString, PolicyId } from '../types'; import { AdaEntry } from './assetEntry'; +import { CardanoWasm, Value, AssetEntry, TxOut } from './types'; /** * handles the decoding of the wasm values returned by diff --git a/wallets/wallet-api/src/types/cip-wallet-api.ts b/wallets/wallet-api/src/cardano/types.ts similarity index 63% rename from wallets/wallet-api/src/types/cip-wallet-api.ts rename to wallets/wallet-api/src/cardano/types.ts index e668412d..3cb51a71 100644 --- a/wallets/wallet-api/src/types/cip-wallet-api.ts +++ b/wallets/wallet-api/src/cardano/types.ts @@ -1,4 +1,37 @@ -import { HexString, Paging, RawTx, TxId } from '.'; +import { + Bech32String, + HexString, + AssetName, + PolicyId, + Hash32, + TxHash, + Paging, + RawTx, + TxId, +} from '../types'; + +export type CardanoWasm = + typeof import('@emurgo/cardano-serialization-lib-nodejs/cardano_serialization_lib'); + +export type Addr = Bech32String; + +export type AssetEntry = { + name: AssetName; + policyId: PolicyId; + nameHex: HexString; + quantity: bigint; +}; + +export type TxOut = { + txHash: TxHash; + index: number; + value: Value; + addr: Addr; + dataHash?: Hash32; + dataBin?: HexString; +}; + +export type Value = AssetEntry[]; export type EncodedTxOut = HexString; export type EncodedBalance = HexString; diff --git a/wallets/wallet-api/src/ergo/index.ts b/wallets/wallet-api/src/ergo/index.ts index 9372cb44..fcb073fe 100644 --- a/wallets/wallet-api/src/ergo/index.ts +++ b/wallets/wallet-api/src/ergo/index.ts @@ -1,12 +1 @@ -import type { RosenChainToken } from '@rosen-bridge/tokens'; - -import { Address, AssetName } from '../types'; - -/** - * ergo token info - */ -export interface ErgoToken extends RosenChainToken { - tokenId: Address; - tokenName: AssetName; - decimals: number; -} +export * from './types'; diff --git a/wallets/wallet-api/src/types/eip-wallet-api.ts b/wallets/wallet-api/src/ergo/types.ts similarity index 52% rename from wallets/wallet-api/src/types/eip-wallet-api.ts rename to wallets/wallet-api/src/ergo/types.ts index 4fb6c9b6..94970560 100644 --- a/wallets/wallet-api/src/types/eip-wallet-api.ts +++ b/wallets/wallet-api/src/ergo/types.ts @@ -1,21 +1,71 @@ import { - Paging, - TokenId, BoxId, TxId, + HexString, + TokenId, + Paging, NErg, Address, - ErgoBoxProxy, - TokenAmountProxy, - Registers, - ErgoTree, - ErgoTxProxy, - DataInput, - Input, - ContextExtension, - ErgoBoxCandidateProxy, } from '../types'; +export type ErgoBoxProxy = { + readonly boxId: BoxId; + readonly transactionId: TxId; + readonly index: number; + readonly ergoTree: ErgoTree; + readonly creationHeight: number; + readonly value: string; + readonly assets: TokenAmountProxy[]; + readonly additionalRegisters: Registers; +}; + +export declare type ErgoBoxCandidateProxy = { + readonly value: string; + readonly ergoTree: ErgoTree; + readonly creationHeight: number; + readonly assets: TokenAmountProxy[]; + readonly additionalRegisters: Registers; +}; + +export type ErgoTree = HexString; + +export type ErgoTxProxy = { + readonly id: TxId; + readonly inputs: Input[]; + readonly dataInputs: DataInput[]; + readonly outputs: ErgoBoxProxy[]; + readonly size: number; +}; + +export type Input = { + readonly boxId: BoxId; + readonly spendingProof: ProverResult; +}; + +export type DataInput = { + readonly boxId: BoxId; +}; + +export type ContextExtension = { + [key: string]: HexString; +}; + +export type ProverResult = { + readonly proof: Uint8Array; + readonly extension: ContextExtension; +}; + +export type Registers = { + [key: string]: HexString; +}; + +export type TokenAmountProxy = { + readonly tokenId: TokenId; + readonly amount: string; + readonly name?: string; + readonly decimals?: number; +}; + export type UnsignedInputProxy = { readonly boxId: BoxId; readonly transactionId: TxId; diff --git a/wallets/wallet-api/src/index.ts b/wallets/wallet-api/src/index.ts index 576ba0e7..d1f4b11e 100644 --- a/wallets/wallet-api/src/index.ts +++ b/wallets/wallet-api/src/index.ts @@ -1,15 +1,3 @@ -import { RawWallet, WalletBase } from './types'; - -export const createRawWallet = ( - wallet: WalletBase, - getApi: () => T, -): RawWallet => { - return { - ...wallet, - getApi, - }; -}; - export * from './cardano'; export * from './ergo'; export * from './types'; diff --git a/wallets/wallet-api/src/types/cardano/address.ts b/wallets/wallet-api/src/types/cardano/address.ts deleted file mode 100644 index 9102b5b9..00000000 --- a/wallets/wallet-api/src/types/cardano/address.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Bech32String } from '../common'; - -export type Addr = Bech32String; diff --git a/wallets/wallet-api/src/types/cardano/assetEntry.ts b/wallets/wallet-api/src/types/cardano/assetEntry.ts deleted file mode 100644 index 83128848..00000000 --- a/wallets/wallet-api/src/types/cardano/assetEntry.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { HexString, AssetName, PolicyId } from '../common'; - -export type AssetEntry = { - name: AssetName; - policyId: PolicyId; - nameHex: HexString; - quantity: bigint; -}; diff --git a/wallets/wallet-api/src/types/cardano/index.ts b/wallets/wallet-api/src/types/cardano/index.ts deleted file mode 100644 index 20b09228..00000000 --- a/wallets/wallet-api/src/types/cardano/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './value'; -export * from './assetEntry'; -export * from './address'; -export * from './txOut'; -export * from './loaders'; diff --git a/wallets/wallet-api/src/types/cardano/loaders.ts b/wallets/wallet-api/src/types/cardano/loaders.ts deleted file mode 100644 index 06597ce3..00000000 --- a/wallets/wallet-api/src/types/cardano/loaders.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type CardanoWasm = - typeof import('@emurgo/cardano-serialization-lib-nodejs/cardano_serialization_lib'); diff --git a/wallets/wallet-api/src/types/cardano/txOut.ts b/wallets/wallet-api/src/types/cardano/txOut.ts deleted file mode 100644 index 2f0645c2..00000000 --- a/wallets/wallet-api/src/types/cardano/txOut.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { HexString, Hash32, TxHash } from '../common'; -import { Addr } from './address'; -import { Value } from './value'; - -export type TxOut = { - txHash: TxHash; - index: number; - value: Value; - addr: Addr; - dataHash?: Hash32; - dataBin?: HexString; -}; diff --git a/wallets/wallet-api/src/types/cardano/value.ts b/wallets/wallet-api/src/types/cardano/value.ts deleted file mode 100644 index 8b6003da..00000000 --- a/wallets/wallet-api/src/types/cardano/value.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { AssetEntry } from './assetEntry'; - -export type Value = AssetEntry[]; diff --git a/wallets/wallet-api/src/types/ergo/ergoBox.ts b/wallets/wallet-api/src/types/ergo/ergoBox.ts deleted file mode 100644 index ee64b5ce..00000000 --- a/wallets/wallet-api/src/types/ergo/ergoBox.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { BoxId, TxId } from '../common'; -import { ErgoTree } from './ergoTree'; -import { Registers } from './registers'; -import { TokenAmountProxy } from './tokenAmount'; - -export type ErgoBoxProxy = { - readonly boxId: BoxId; - readonly transactionId: TxId; - readonly index: number; - readonly ergoTree: ErgoTree; - readonly creationHeight: number; - readonly value: string; - readonly assets: TokenAmountProxy[]; - readonly additionalRegisters: Registers; -}; diff --git a/wallets/wallet-api/src/types/ergo/ergoBoxCandidate.ts b/wallets/wallet-api/src/types/ergo/ergoBoxCandidate.ts deleted file mode 100644 index 87431e48..00000000 --- a/wallets/wallet-api/src/types/ergo/ergoBoxCandidate.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { ErgoTree } from './ergoTree'; -import { Registers } from './registers'; -import { TokenAmountProxy } from './tokenAmount'; - -export declare type ErgoBoxCandidateProxy = { - readonly value: string; - readonly ergoTree: ErgoTree; - readonly creationHeight: number; - readonly assets: TokenAmountProxy[]; - readonly additionalRegisters: Registers; -}; diff --git a/wallets/wallet-api/src/types/ergo/ergoTree.ts b/wallets/wallet-api/src/types/ergo/ergoTree.ts deleted file mode 100644 index c9e307a8..00000000 --- a/wallets/wallet-api/src/types/ergo/ergoTree.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { HexString } from '../common'; - -export type ErgoTree = HexString; diff --git a/wallets/wallet-api/src/types/ergo/ergoTx.ts b/wallets/wallet-api/src/types/ergo/ergoTx.ts deleted file mode 100644 index 5249e4ad..00000000 --- a/wallets/wallet-api/src/types/ergo/ergoTx.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { TxId } from '../common'; -import { ErgoBoxProxy } from './ergoBox'; -import { Input, DataInput } from './input'; - -export type ErgoTxProxy = { - readonly id: TxId; - readonly inputs: Input[]; - readonly dataInputs: DataInput[]; - readonly outputs: ErgoBoxProxy[]; - readonly size: number; -}; diff --git a/wallets/wallet-api/src/types/ergo/index.ts b/wallets/wallet-api/src/types/ergo/index.ts deleted file mode 100644 index 129ea6b1..00000000 --- a/wallets/wallet-api/src/types/ergo/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export * from './ergoBox'; -export * from './ergoBoxCandidate'; -export * from './ergoTree'; -export * from './ergoTx'; -export * from './input'; -export * from './prover'; -export * from './registers'; -export * from './tokenAmount'; diff --git a/wallets/wallet-api/src/types/ergo/input.ts b/wallets/wallet-api/src/types/ergo/input.ts deleted file mode 100644 index 51a4924f..00000000 --- a/wallets/wallet-api/src/types/ergo/input.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BoxId } from '../common'; -import { ProverResult } from './prover'; - -export type Input = { - readonly boxId: BoxId; - readonly spendingProof: ProverResult; -}; - -export type DataInput = { - readonly boxId: BoxId; -}; diff --git a/wallets/wallet-api/src/types/ergo/prover.ts b/wallets/wallet-api/src/types/ergo/prover.ts deleted file mode 100644 index 251de70e..00000000 --- a/wallets/wallet-api/src/types/ergo/prover.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { HexString } from '../common'; - -export type ContextExtension = { - [key: string]: HexString; -}; - -export type ProverResult = { - readonly proof: Uint8Array; - readonly extension: ContextExtension; -}; diff --git a/wallets/wallet-api/src/types/ergo/registers.ts b/wallets/wallet-api/src/types/ergo/registers.ts deleted file mode 100644 index 8e4f29da..00000000 --- a/wallets/wallet-api/src/types/ergo/registers.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { HexString } from '../common'; - -export type Registers = { - [key: string]: HexString; -}; diff --git a/wallets/wallet-api/src/types/ergo/tokenAmount.ts b/wallets/wallet-api/src/types/ergo/tokenAmount.ts deleted file mode 100644 index 9a0caa27..00000000 --- a/wallets/wallet-api/src/types/ergo/tokenAmount.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { TokenId } from '../common'; - -export type TokenAmountProxy = { - readonly tokenId: TokenId; - readonly amount: string; - readonly name?: string; - readonly decimals?: number; -}; diff --git a/wallets/wallet-api/src/types/index.ts b/wallets/wallet-api/src/types/index.ts index 1c9b29b2..692a439b 100644 --- a/wallets/wallet-api/src/types/index.ts +++ b/wallets/wallet-api/src/types/index.ts @@ -1,53 +1,2 @@ -import { ReactNode, FC } from 'react'; - -import { RosenChainToken } from '@rosen-bridge/tokens'; -import { Network, RosenAmountValue } from '@rosen-ui/types'; - -export enum WalletState { - NOT_CONNECTED, - CONNECTING, - CONNECTED, -} - -export interface WalletInfo { - icon: FC; - name: string; - label: string; - link: string; -} - -/** - * main wallet type for the bridge, all wallets implement - * this interface to unify access and interaction with wallets - */ -export interface WalletBase extends WalletInfo { - onConnect?: () => void; - onDisconnect?: () => void; - connectWallet: () => Promise; - hidden?: boolean; -} - -export interface Wallet extends WalletBase { - readonly getBalance: (token: RosenChainToken) => Promise; - readonly transfer: ( - token: RosenChainToken, - amount: RosenAmountValue, - toChain: Network, - address: string, - bridgeFee: RosenAmountValue, - networkFee: RosenAmountValue, - lockAddress: string, - ) => Promise; - readonly getAddress: () => Promise; - readonly isAvailable: () => boolean; -} - -export interface RawWallet extends WalletBase { - getApi: () => Api; -} - export * from './common'; -export * from './ergo'; -export * from './cardano'; -export * from './cip-wallet-api'; -export * from './eip-wallet-api'; +export * from './wallet'; diff --git a/wallets/wallet-api/src/types/wallet.ts b/wallets/wallet-api/src/types/wallet.ts new file mode 100644 index 00000000..7a7445dc --- /dev/null +++ b/wallets/wallet-api/src/types/wallet.ts @@ -0,0 +1,32 @@ +import { FC } from 'react'; + +import { RosenChainToken } from '@rosen-bridge/tokens'; +import { Network, RosenAmountValue } from '@rosen-ui/types'; + +/** + * main wallet type for the bridge, all wallets implement + * this interface to unify access and interaction with wallets + */ +export interface Wallet { + icon: FC; + name: string; + label: string; + link: string; + connect(): Promise; + getAddress(): Promise; + getBalance(token: RosenChainToken): Promise; + isAvailable(): boolean; + transfer(params: WalletTransferParams): Promise; +} + +export interface WalletTransferParams { + token: RosenChainToken; + amount: RosenAmountValue; + toChain: Network; + address: string; + bridgeFee: RosenAmountValue; + networkFee: RosenAmountValue; + lockAddress: string; +} + +export * from './common'; diff --git a/wallets/wallet-api/types/index.d.ts b/wallets/wallet-api/types/index.d.ts deleted file mode 100644 index ce2bee06..00000000 --- a/wallets/wallet-api/types/index.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { CipWalletApi, EipWalletApi } from '../src/index'; - -export interface ConnectorAPI { - enable(): Promise; - isEnabled(): Promise; - experimental?: unknown; -} - -/** - * global type augmentation for nami wallet - */ -declare global { - let cardano: { [key: string]: ConnectorAPI }; -} - -declare global { - declare let ergoConnector: { - [key: string]: { - connect: (params: { createErgoObject: boolean }) => Promise; - getContext: () => Promise; - }; - }; -}