diff --git a/.changeset/smart-years-compete.md b/.changeset/smart-years-compete.md new file mode 100644 index 00000000..e10afb7b --- /dev/null +++ b/.changeset/smart-years-compete.md @@ -0,0 +1,5 @@ +--- +'@rosen-bridge/rosen-app': patch +--- + +Decouple the network type from the wallets to enable the separation of networks within their packages, thereby improving code quality diff --git a/apps/rosen/app/_hooks/useWallet.tsx b/apps/rosen/app/_hooks/useWallet.tsx index ad117fef..87665d07 100644 --- a/apps/rosen/app/_hooks/useWallet.tsx +++ b/apps/rosen/app/_hooks/useWallet.tsx @@ -4,12 +4,15 @@ import { useCallback, useContext, useEffect, + useMemo, useState, } from 'react'; import { useSnackbar } from '@rosen-bridge/ui-kit'; import { Wallet } from '@rosen-ui/wallet-api'; +import * as availableWallets from '@/_wallets'; + import { useNetwork } from './useNetwork'; /** @@ -41,6 +44,13 @@ export const WalletProvider = ({ children }: PropsWithChildren) => { const [selected, setSelected] = useState(); + const wallets = useMemo(() => { + if (!selectedSource) return []; + return Object.values(availableWallets).filter((wallet) => { + return wallet.supportedChains.includes(selectedSource.name); + }); + }, [selectedSource]); + const select = useCallback( async (wallet: Wallet) => { try { @@ -69,11 +79,13 @@ export const WalletProvider = ({ children }: PropsWithChildren) => { const name = localStorage.getItem('rosen:wallet:' + selectedSource.name); - const wallet = selectedSource.wallets.find( - (wallet) => wallet.name === name && wallet.isAvailable(), - ); + if (!name) return; + + const wallet = availableWallets[ + name as keyof typeof availableWallets + ] as Wallet; - if (!wallet) return; + if (!wallet || !wallet.isAvailable()) return; if ((await wallet.isConnected?.()) === false) return; @@ -93,7 +105,7 @@ export const WalletProvider = ({ children }: PropsWithChildren) => { const state = { select, selected, - wallets: selectedSource?.wallets || [], + wallets, }; return ( diff --git a/apps/rosen/app/_networks/binance/client.ts b/apps/rosen/app/_networks/binance/client.ts index 4b762285..1ee53ff6 100644 --- a/apps/rosen/app/_networks/binance/client.ts +++ b/apps/rosen/app/_networks/binance/client.ts @@ -1,13 +1,10 @@ import { BinanceIcon } from '@rosen-bridge/icons'; import { NETWORK_LABELS, NETWORKS } from '@rosen-ui/constants'; -import { MetaMaskWallet } from '@rosen-ui/metamask-wallet'; import { unwrap } from '@/_safeServerAction'; -import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; import { BinanceNetwork as BinanceNetworkType } from '@/_types'; import { getMaxTransfer } from './getMaxTransfer'; -import { generateLockData, generateTxParameters } from './server'; /** * the main object for Binance network @@ -17,13 +14,6 @@ import { generateLockData, generateTxParameters } from './server'; export const BinanceNetwork: BinanceNetworkType = { name: NETWORKS.BINANCE, label: NETWORK_LABELS.BINANCE, - wallets: [ - new MetaMaskWallet({ - getTokenMap, - generateLockData: unwrap(generateLockData), - generateTxParameters: unwrap(generateTxParameters), - }), - ], nextHeightInterval: 200, logo: BinanceIcon, lockAddress: process.env.NEXT_PUBLIC_BINANCE_LOCK_ADDRESS!, diff --git a/apps/rosen/app/_networks/bitcoin/client.ts b/apps/rosen/app/_networks/bitcoin/client.ts index 628a64a5..a5964352 100644 --- a/apps/rosen/app/_networks/bitcoin/client.ts +++ b/apps/rosen/app/_networks/bitcoin/client.ts @@ -1,27 +1,11 @@ import { BitcoinIcon } from '@rosen-bridge/icons'; import { NETWORK_LABELS, NETWORKS } from '@rosen-ui/constants'; -import { OKXWallet } from '@rosen-ui/okx-wallet'; import { unwrap } from '@/_safeServerAction'; -import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; import { BitcoinNetwork as BitcoinNetworkType } from '@/_types'; import { LOCK_ADDRESSES } from '../../../configs'; import { getMaxTransfer } from './getMaxTransfer'; -import { - generateOpReturnData, - generateUnsignedTx, - submitTransaction, - getAddressBalance, -} from './server'; - -const config = { - getTokenMap, - generateOpReturnData: unwrap(generateOpReturnData), - generateUnsignedTx: unwrap(generateUnsignedTx), - getAddressBalance: unwrap(getAddressBalance), - submitTransaction: unwrap(submitTransaction), -}; /** * the main object for Bitcoin network @@ -32,7 +16,6 @@ export const BitcoinNetwork: BitcoinNetworkType = { name: NETWORKS.BITCOIN, label: NETWORK_LABELS.BITCOIN, logo: BitcoinIcon, - wallets: [new OKXWallet(config)], nextHeightInterval: 1, lockAddress: LOCK_ADDRESSES.BITCOIN, getMaxTransfer: unwrap(getMaxTransfer), diff --git a/apps/rosen/app/_networks/cardano/client.ts b/apps/rosen/app/_networks/cardano/client.ts index cf9fc9ca..2fb9e78b 100644 --- a/apps/rosen/app/_networks/cardano/client.ts +++ b/apps/rosen/app/_networks/cardano/client.ts @@ -1,29 +1,11 @@ import { CardanoIcon } from '@rosen-bridge/icons'; import { NETWORK_LABELS, NETWORKS } from '@rosen-ui/constants'; -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'; import { CardanoNetwork as CardanoNetworkType } from '@/_types'; import { LOCK_ADDRESSES } from '../../../configs'; import { getMaxTransfer } from './getMaxTransfer'; -import { - decodeWasmValue, - generateLockAuxiliaryData, - generateUnsignedTx, - setTxWitnessSet, -} from './server'; - -const config = { - getTokenMap, - decodeWasmValue: unwrap(decodeWasmValue), - generateLockAuxiliaryData: unwrap(generateLockAuxiliaryData), - generateUnsignedTx: unwrap(generateUnsignedTx), - setTxWitnessSet: unwrap(setTxWitnessSet), -}; /** * the main object for Cardano network @@ -33,11 +15,6 @@ const config = { export const CardanoNetwork: CardanoNetworkType = { name: NETWORKS.CARDANO, label: NETWORK_LABELS.CARDANO, - wallets: [ - new EtrnlWallet(config), - new LaceWallet(config), - new NamiWallet(config), - ], nextHeightInterval: 30, logo: CardanoIcon, lockAddress: LOCK_ADDRESSES.CARDANO, diff --git a/apps/rosen/app/_networks/ergo/client.ts b/apps/rosen/app/_networks/ergo/client.ts index ff00052f..df8202d4 100644 --- a/apps/rosen/app/_networks/ergo/client.ts +++ b/apps/rosen/app/_networks/ergo/client.ts @@ -1,19 +1,11 @@ import { ErgoIcon } from '@rosen-bridge/icons'; import { NETWORK_LABELS, NETWORKS } from '@rosen-ui/constants'; -import { NautilusWallet } from '@rosen-ui/nautilus-wallet'; import { unwrap } from '@/_safeServerAction'; -import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; import { ErgoNetwork as ErgoNetworkType } from '@/_types'; import { LOCK_ADDRESSES } from '../../../configs'; import { getMaxTransfer } from './getMaxTransfer'; -import { generateUnsignedTx } from './server'; - -const config = { - getTokenMap, - generateUnsignedTx: unwrap(generateUnsignedTx), -}; /** * the main object for Ergo network @@ -23,7 +15,6 @@ const config = { export const ErgoNetwork: ErgoNetworkType = { name: NETWORKS.ERGO, label: NETWORK_LABELS.ERGO, - wallets: [new NautilusWallet(config)], logo: ErgoIcon, nextHeightInterval: 5, lockAddress: LOCK_ADDRESSES.ERGO, diff --git a/apps/rosen/app/_networks/ethereum/client.ts b/apps/rosen/app/_networks/ethereum/client.ts index 86c6c30c..c2f8e71e 100644 --- a/apps/rosen/app/_networks/ethereum/client.ts +++ b/apps/rosen/app/_networks/ethereum/client.ts @@ -1,14 +1,11 @@ import { EthereumIcon } from '@rosen-bridge/icons'; import { NETWORK_LABELS, NETWORKS } from '@rosen-ui/constants'; -import { MetaMaskWallet } from '@rosen-ui/metamask-wallet'; import { unwrap } from '@/_safeServerAction'; -import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; import { EthereumNetwork as EthereumNetworkType } from '@/_types'; import { LOCK_ADDRESSES } from '../../../configs'; import { getMaxTransfer } from './getMaxTransfer'; -import { generateLockData, generateTxParameters } from './server'; /** * the main object for Ethereum network @@ -18,13 +15,6 @@ import { generateLockData, generateTxParameters } from './server'; export const EthereumNetwork: EthereumNetworkType = { name: NETWORKS.ETHEREUM, label: NETWORK_LABELS.ETHEREUM, - wallets: [ - new MetaMaskWallet({ - getTokenMap, - generateLockData: unwrap(generateLockData), - generateTxParameters: unwrap(generateTxParameters), - }), - ], logo: EthereumIcon, nextHeightInterval: 50, lockAddress: LOCK_ADDRESSES.ETHEREUM, diff --git a/apps/rosen/app/_networks/ethereum/server.ts b/apps/rosen/app/_networks/ethereum/server.ts deleted file mode 100644 index fb0ec10e..00000000 --- a/apps/rosen/app/_networks/ethereum/server.ts +++ /dev/null @@ -1,20 +0,0 @@ -'use server'; - -import { - generateLockData as generateLockDataCore, - generateTxParameters as generateTxParametersCore, -} from '@rosen-network/evm'; - -import { wrap } from '@/_safeServerAction'; -import { getTokenMap } from '@/_tokenMap/getServerTokenMap'; - -export const generateLockData = wrap(generateLockDataCore, { - traceKey: 'generateLockData', -}); - -export const generateTxParameters = wrap( - generateTxParametersCore(getTokenMap()), - { - traceKey: 'generateTxParameters', - }, -); diff --git a/apps/rosen/app/_types/network.ts b/apps/rosen/app/_types/network.ts index 25bb4de5..4aac8876 100644 --- a/apps/rosen/app/_types/network.ts +++ b/apps/rosen/app/_types/network.ts @@ -1,5 +1,4 @@ import { Network, RosenAmountValue } from '@rosen-ui/types'; -import { Wallet } from '@rosen-ui/wallet-api'; interface GetMaxTransferParams { balance: RosenAmountValue; @@ -16,7 +15,6 @@ export interface BaseNetwork< name: NetworkName; logo: string; label: string; - wallets: Wallet[]; nextHeightInterval: number; lockAddress: string; // THIS FUNCTION WORKS WITH WRAPPED-VALUE diff --git a/apps/rosen/app/_wallets/eternl/index.ts b/apps/rosen/app/_wallets/eternl/index.ts new file mode 100644 index 00000000..3c5958cf --- /dev/null +++ b/apps/rosen/app/_wallets/eternl/index.ts @@ -0,0 +1 @@ +export * from './wallet'; diff --git a/apps/rosen/app/_networks/cardano/server.ts b/apps/rosen/app/_wallets/eternl/server.ts similarity index 100% rename from apps/rosen/app/_networks/cardano/server.ts rename to apps/rosen/app/_wallets/eternl/server.ts diff --git a/apps/rosen/app/_wallets/eternl/wallet.ts b/apps/rosen/app/_wallets/eternl/wallet.ts new file mode 100644 index 00000000..7411928d --- /dev/null +++ b/apps/rosen/app/_wallets/eternl/wallet.ts @@ -0,0 +1,19 @@ +import { EtrnlWallet } from '@rosen-ui/eternl-wallet'; + +import { unwrap } from '@/_safeServerAction'; +import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; + +import { + decodeWasmValue, + generateLockAuxiliaryData, + generateUnsignedTx, + setTxWitnessSet, +} from './server'; + +export const eternl = new EtrnlWallet({ + getTokenMap, + decodeWasmValue: unwrap(decodeWasmValue), + generateLockAuxiliaryData: unwrap(generateLockAuxiliaryData), + generateUnsignedTx: unwrap(generateUnsignedTx), + setTxWitnessSet: unwrap(setTxWitnessSet), +}); diff --git a/apps/rosen/app/_wallets/index.ts b/apps/rosen/app/_wallets/index.ts new file mode 100644 index 00000000..b674854c --- /dev/null +++ b/apps/rosen/app/_wallets/index.ts @@ -0,0 +1,6 @@ +export * from './eternl'; +export * from './lace'; +export * from './metamask'; +export * from './nami'; +export * from './nautilus'; +export * from './okx'; diff --git a/apps/rosen/app/_wallets/lace/index.ts b/apps/rosen/app/_wallets/lace/index.ts new file mode 100644 index 00000000..3c5958cf --- /dev/null +++ b/apps/rosen/app/_wallets/lace/index.ts @@ -0,0 +1 @@ +export * from './wallet'; diff --git a/apps/rosen/app/_wallets/lace/server.ts b/apps/rosen/app/_wallets/lace/server.ts new file mode 100644 index 00000000..e0659d3a --- /dev/null +++ b/apps/rosen/app/_wallets/lace/server.ts @@ -0,0 +1,28 @@ +'use server'; + +import { + decodeWasmValue as decodeWasmValueCore, + generateLockAuxiliaryData as generateLockAuxiliaryDataCore, + generateUnsignedTx as generateUnsignedTxCore, + setTxWitnessSet as setTxWitnessSetCore, +} from '@rosen-network/cardano'; + +import { wrap } from '@/_safeServerAction'; +import { getTokenMap } from '@/_tokenMap/getServerTokenMap'; + +export const decodeWasmValue = wrap(decodeWasmValueCore, { + cache: Infinity, + traceKey: 'decodeWasmValue', +}); + +export const generateLockAuxiliaryData = wrap(generateLockAuxiliaryDataCore, { + traceKey: 'generateLockAuxiliaryData', +}); + +export const generateUnsignedTx = wrap(generateUnsignedTxCore(getTokenMap()), { + traceKey: 'generateUnsignedTx', +}); + +export const setTxWitnessSet = wrap(setTxWitnessSetCore, { + traceKey: 'setTxWitnessSet', +}); diff --git a/apps/rosen/app/_wallets/lace/wallet.ts b/apps/rosen/app/_wallets/lace/wallet.ts new file mode 100644 index 00000000..8b14149f --- /dev/null +++ b/apps/rosen/app/_wallets/lace/wallet.ts @@ -0,0 +1,19 @@ +import { LaceWallet } from '@rosen-ui/lace-wallet'; + +import { unwrap } from '@/_safeServerAction'; +import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; + +import { + decodeWasmValue, + generateLockAuxiliaryData, + generateUnsignedTx, + setTxWitnessSet, +} from './server'; + +export const lace = new LaceWallet({ + getTokenMap, + decodeWasmValue: unwrap(decodeWasmValue), + generateLockAuxiliaryData: unwrap(generateLockAuxiliaryData), + generateUnsignedTx: unwrap(generateUnsignedTx), + setTxWitnessSet: unwrap(setTxWitnessSet), +}); diff --git a/apps/rosen/app/_wallets/metamask/index.ts b/apps/rosen/app/_wallets/metamask/index.ts new file mode 100644 index 00000000..3c5958cf --- /dev/null +++ b/apps/rosen/app/_wallets/metamask/index.ts @@ -0,0 +1 @@ +export * from './wallet'; diff --git a/apps/rosen/app/_networks/binance/server.ts b/apps/rosen/app/_wallets/metamask/server.ts similarity index 100% rename from apps/rosen/app/_networks/binance/server.ts rename to apps/rosen/app/_wallets/metamask/server.ts diff --git a/apps/rosen/app/_wallets/metamask/wallet.ts b/apps/rosen/app/_wallets/metamask/wallet.ts new file mode 100644 index 00000000..94f69618 --- /dev/null +++ b/apps/rosen/app/_wallets/metamask/wallet.ts @@ -0,0 +1,12 @@ +import { MetaMaskWallet } from '@rosen-ui/metamask-wallet'; + +import { unwrap } from '@/_safeServerAction'; +import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; + +import { generateLockData, generateTxParameters } from './server'; + +export const metamask = new MetaMaskWallet({ + getTokenMap, + generateLockData: unwrap(generateLockData), + generateTxParameters: unwrap(generateTxParameters), +}); diff --git a/apps/rosen/app/_wallets/nami/index.ts b/apps/rosen/app/_wallets/nami/index.ts new file mode 100644 index 00000000..3c5958cf --- /dev/null +++ b/apps/rosen/app/_wallets/nami/index.ts @@ -0,0 +1 @@ +export * from './wallet'; diff --git a/apps/rosen/app/_wallets/nami/server.ts b/apps/rosen/app/_wallets/nami/server.ts new file mode 100644 index 00000000..e0659d3a --- /dev/null +++ b/apps/rosen/app/_wallets/nami/server.ts @@ -0,0 +1,28 @@ +'use server'; + +import { + decodeWasmValue as decodeWasmValueCore, + generateLockAuxiliaryData as generateLockAuxiliaryDataCore, + generateUnsignedTx as generateUnsignedTxCore, + setTxWitnessSet as setTxWitnessSetCore, +} from '@rosen-network/cardano'; + +import { wrap } from '@/_safeServerAction'; +import { getTokenMap } from '@/_tokenMap/getServerTokenMap'; + +export const decodeWasmValue = wrap(decodeWasmValueCore, { + cache: Infinity, + traceKey: 'decodeWasmValue', +}); + +export const generateLockAuxiliaryData = wrap(generateLockAuxiliaryDataCore, { + traceKey: 'generateLockAuxiliaryData', +}); + +export const generateUnsignedTx = wrap(generateUnsignedTxCore(getTokenMap()), { + traceKey: 'generateUnsignedTx', +}); + +export const setTxWitnessSet = wrap(setTxWitnessSetCore, { + traceKey: 'setTxWitnessSet', +}); diff --git a/apps/rosen/app/_wallets/nami/wallet.ts b/apps/rosen/app/_wallets/nami/wallet.ts new file mode 100644 index 00000000..bee54488 --- /dev/null +++ b/apps/rosen/app/_wallets/nami/wallet.ts @@ -0,0 +1,19 @@ +import { NamiWallet } from '@rosen-ui/nami-wallet'; + +import { unwrap } from '@/_safeServerAction'; +import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; + +import { + decodeWasmValue, + generateLockAuxiliaryData, + generateUnsignedTx, + setTxWitnessSet, +} from './server'; + +export const nami = new NamiWallet({ + getTokenMap, + decodeWasmValue: unwrap(decodeWasmValue), + generateLockAuxiliaryData: unwrap(generateLockAuxiliaryData), + generateUnsignedTx: unwrap(generateUnsignedTx), + setTxWitnessSet: unwrap(setTxWitnessSet), +}); diff --git a/apps/rosen/app/_wallets/nautilus/index.ts b/apps/rosen/app/_wallets/nautilus/index.ts new file mode 100644 index 00000000..3c5958cf --- /dev/null +++ b/apps/rosen/app/_wallets/nautilus/index.ts @@ -0,0 +1 @@ +export * from './wallet'; diff --git a/apps/rosen/app/_networks/ergo/server.ts b/apps/rosen/app/_wallets/nautilus/server.ts similarity index 100% rename from apps/rosen/app/_networks/ergo/server.ts rename to apps/rosen/app/_wallets/nautilus/server.ts diff --git a/apps/rosen/app/_wallets/nautilus/wallet.ts b/apps/rosen/app/_wallets/nautilus/wallet.ts new file mode 100644 index 00000000..958cf3bb --- /dev/null +++ b/apps/rosen/app/_wallets/nautilus/wallet.ts @@ -0,0 +1,11 @@ +import { NautilusWallet } from '@rosen-ui/nautilus-wallet'; + +import { unwrap } from '@/_safeServerAction'; +import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; + +import { generateUnsignedTx } from './server'; + +export const nautilus = new NautilusWallet({ + getTokenMap, + generateUnsignedTx: unwrap(generateUnsignedTx), +}); diff --git a/apps/rosen/app/_wallets/okx/index.ts b/apps/rosen/app/_wallets/okx/index.ts new file mode 100644 index 00000000..3c5958cf --- /dev/null +++ b/apps/rosen/app/_wallets/okx/index.ts @@ -0,0 +1 @@ +export * from './wallet'; diff --git a/apps/rosen/app/_networks/bitcoin/server.ts b/apps/rosen/app/_wallets/okx/server.ts similarity index 100% rename from apps/rosen/app/_networks/bitcoin/server.ts rename to apps/rosen/app/_wallets/okx/server.ts diff --git a/apps/rosen/app/_wallets/okx/wallet.ts b/apps/rosen/app/_wallets/okx/wallet.ts new file mode 100644 index 00000000..c46c7cb1 --- /dev/null +++ b/apps/rosen/app/_wallets/okx/wallet.ts @@ -0,0 +1,19 @@ +import { OKXWallet } from '@rosen-ui/okx-wallet'; + +import { unwrap } from '@/_safeServerAction'; +import { getTokenMap } from '@/_tokenMap/getClientTokenMap'; + +import { + generateOpReturnData, + generateUnsignedTx, + submitTransaction, + getAddressBalance, +} from './server'; + +export const okx = new OKXWallet({ + getTokenMap, + generateOpReturnData: unwrap(generateOpReturnData), + generateUnsignedTx: unwrap(generateUnsignedTx), + getAddressBalance: unwrap(getAddressBalance), + submitTransaction: unwrap(submitTransaction), +});