diff --git a/src/components/base/WalletConnection.tsx b/src/components/base/WalletConnection.tsx
index c43fce6..f1372ea 100644
--- a/src/components/base/WalletConnection.tsx
+++ b/src/components/base/WalletConnection.tsx
@@ -40,7 +40,7 @@ const WalletConnection: React.FC<{
onClick={connectAeternityWallet}
{...buttonProps}
>
- Connect SuperHero Wallet
+ Connect æternity Wallet
,
);
}
diff --git a/src/components/navigation/AEWalletSelect.tsx b/src/components/navigation/AEWalletSelect.tsx
new file mode 100644
index 0000000..1097def
--- /dev/null
+++ b/src/components/navigation/AEWalletSelect.tsx
@@ -0,0 +1,87 @@
+import { Box, Button, Modal, Typography } from '@mui/material';
+
+import * as Aeternity from 'src/services/aeternity';
+import useWalletContext from 'src/hooks/useWalletContext';
+import SuperHeroIcon from 'src/components/base/icons/superhero';
+import MetaMaskIcon from 'src/components/base/icons/metamask';
+import { SUPERHERO_WALLET_URL } from 'src/constants';
+import Logger from 'src/services/logger';
+
+const style = {
+ position: 'absolute',
+ top: '50%',
+ left: '50%',
+ transform: 'translate(-50%, -50%)',
+ width: 400,
+ bgcolor: 'background.paper',
+ border: '2px solid #000',
+ boxShadow: 24,
+ p: 4,
+};
+
+const AEWalletSelect = () => {
+ const {
+ showAeWalletSelect,
+ setShowAeWalletSelect,
+ aeternityWalletDetected,
+ ethereumWalletDetected,
+ setConnecting,
+ setAeternityAddress,
+ handleWalletConnectError,
+ } = useWalletContext();
+
+ const handleConnectButtonClick = async (wallet: 'metamask' | 'superhero') => {
+ try {
+ setConnecting(true);
+ const address = await Aeternity.connect(wallet, (accounts) => {
+ if (accounts.length > 0) {
+ setAeternityAddress(accounts[0].address);
+ }
+ });
+ setAeternityAddress(address);
+ } catch (e) {
+ Logger.error(e);
+ handleWalletConnectError((e as Error).message);
+ } finally {
+ setConnecting(false);
+ setShowAeWalletSelect(false);
+ }
+ };
+
+ return (
+ setShowAeWalletSelect(false)}>
+
+
+ Select a wallet
+
+ Please select a wallet to connect to the application:
+
+ {aeternityWalletDetected && (
+
+ )}
+ {ethereumWalletDetected && (
+
+ )}
+ {!aeternityWalletDetected && (
+
+ )}
+
+
+
+ );
+};
+
+export default AEWalletSelect;
diff --git a/src/context/WalletContext.ts b/src/context/WalletContext.ts
index 0ca0625..b76cbac 100644
--- a/src/context/WalletContext.ts
+++ b/src/context/WalletContext.ts
@@ -7,6 +7,13 @@ export interface IWalletContext {
connectEthereumWallet: () => Promise;
connectAeternityWallet: () => Promise;
disconnectWallet: () => void;
+ showAeWalletSelect: boolean;
+ setShowAeWalletSelect: (show: boolean) => void;
+ aeternityWalletDetected: boolean;
+ ethereumWalletDetected: boolean;
+ setConnecting: (connecting: boolean) => void;
+ setAeternityAddress: (address: string) => void;
+ handleWalletConnectError: (message: string) => void;
}
const contextStub = {
@@ -20,6 +27,19 @@ const contextStub = {
disconnectWallet: async () => {
// stub
},
+ showAeWalletSelect: false,
+ setShowAeWalletSelect: (show: boolean) => {
+ // stub
+ },
+ aeternityWalletDetected: false,
+ ethereumWalletDetected: false,
+ setConnecting: (connecting: boolean) => {
+ // stub
+ },
+ setAeternityAddress: (address: string) => {},
+ handleWalletConnectError: (message: string) => {
+ // stub
+ },
};
const WalletContext = createContext(contextStub);
diff --git a/src/context/WalletProvider.tsx b/src/context/WalletProvider.tsx
index 11727ba..d47336c 100644
--- a/src/context/WalletProvider.tsx
+++ b/src/context/WalletProvider.tsx
@@ -13,6 +13,7 @@ const WalletProvider: React.FC<{ children: ReactNode }> = (props) => {
const [connecting, setConnecting] = useState(false);
const [ethereumAddress, setEthereumAddress] = useState(undefined);
const [aeternityAddress, setAeternityAddress] = useState(undefined);
+ const [showAeWalletSelect, setShowAeWalletSelect] = useState(false);
const isEthWalletDetectionEnded = useRef(false);
const isAeWalletDetectionEnded = useRef(false);
@@ -43,32 +44,12 @@ const WalletProvider: React.FC<{ children: ReactNode }> = (props) => {
}
});
}
-
- if (aeternityWalletDetected.current) {
- Aeternity.Sdk.onAddressChange = ({ current }) => {
- setAeternityAddress(Object.keys(current)[0]);
- };
- }
})();
}, []);
const connectAeternityWallet = useCallback(async () => {
if (isAeWalletDetectionEnded.current) {
- if (!aeternityWalletDetected.current) {
- handleWalletConnectError('æternity wallet extension not found');
- return;
- }
-
- try {
- setConnecting(true);
- const address = await Aeternity.connect();
- setAeternityAddress(address);
- } catch (e) {
- Logger.error(e);
- handleWalletConnectError((e as Error).message);
- } finally {
- setConnecting(false);
- }
+ setShowAeWalletSelect(true);
} else {
setTimeout(connectAeternityWallet, 100);
}
@@ -149,6 +130,13 @@ const WalletProvider: React.FC<{ children: ReactNode }> = (props) => {
connectAeternityWallet,
connectEthereumWallet,
disconnectWallet,
+ showAeWalletSelect,
+ setShowAeWalletSelect,
+ aeternityWalletDetected: aeternityWalletDetected.current,
+ ethereumWalletDetected: ethereumWalletDetected.current,
+ setConnecting,
+ setAeternityAddress,
+ handleWalletConnectError,
}}
>
{props.children}
diff --git a/src/index.tsx b/src/index.tsx
index 64b0c3d..dce6593 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -8,6 +8,7 @@ import Router from './Routes';
import AppProvider from './context/AppProvider';
import WalletProvider from './context/WalletProvider';
import { SnackbarProvider } from 'notistack';
+import AEWalletSelect from './components/navigation/AEWalletSelect';
const container = document.getElementById('root');
if (!container) {
@@ -24,6 +25,7 @@ const App = () => (
+
diff --git a/src/services/aeternity.ts b/src/services/aeternity.ts
index f5c54bb..2c56c8f 100644
--- a/src/services/aeternity.ts
+++ b/src/services/aeternity.ts
@@ -4,50 +4,56 @@ import {
SUBSCRIPTION_TYPES,
walletDetector,
isAddressValid,
- AeSdkAepp,
+ AeSdk,
Contract,
+ AccountMetamaskFactory,
+ WalletConnectorFrame,
+ AccountBase,
} from '@aeternity/aepp-sdk';
+type Wallet = Parameters[1]>[0]['newWallet'];
import Constants from 'src/constants';
-export const Sdk = new AeSdkAepp({
+let connector: WalletConnectorFrame;
+
+export const Sdk = new AeSdk({
nodes: [{ name: Constants.isMainnet ? 'mainnet' : 'testnet', instance: new Node(Constants.aeternity.rpc) }],
- name: 'Bridge Aepp',
- onNetworkChange: async ({ networkId }) => {
- const [{ name }] = (await Sdk.getNodesInPool()).filter((node) => node.nodeNetworkId === networkId);
- Sdk.selectNode(name);
- console.log('setNetworkId', networkId);
- },
- onAddressChange: ({ current }) => console.log(Object.keys(current)[0]),
- onDisconnect: () => console.log('Aepp is disconnected'),
});
-export const connect = async (): Promise => {
- return new Promise((resolve, reject) => {
- const handleWallets = async ({ wallets, newWallet }: any) => {
- try {
- walletDetectionTimeout && clearTimeout(walletDetectionTimeout);
- newWallet ||= Object.values(wallets)[0];
- if (newWallet) {
- const walletInfo = await Sdk.connectToWallet(newWallet.getConnection());
- const {
- address: { current },
- } = await Sdk.subscribeAddress(SUBSCRIPTION_TYPES.subscribe, 'connected');
- const address = Object.keys(current)[0];
- console.log(walletInfo, current);
- resolve(address);
- }
+export const connect = async (
+ wallet: 'metamask' | 'superhero',
+ onAccountChange?: (accounts: AccountBase[]) => void,
+): Promise => {
+ if (wallet === 'metamask') {
+ const factory = new AccountMetamaskFactory();
+ await factory.installSnap();
+
+ Sdk.addAccount(await factory.initialize(0), { select: true });
+ console.log('Metamask account', Sdk.address);
+ return Sdk.address;
+ } else {
+ const wallet = await new Promise((resolveWallet) => {
+ const scannerConnection = new BrowserWindowMessageConnection();
+ const stopScan = walletDetector(scannerConnection, ({ newWallet }) => {
+ resolveWallet(newWallet);
stopScan();
- reject();
- } catch (e) {
- reject(e);
- }
- };
+ });
+ });
+ connector = await WalletConnectorFrame.connect('Bridge Aepp', wallet.getConnection());
- const scannerConnection = new BrowserWindowMessageConnection();
- const walletDetectionTimeout = setTimeout(() => reject(new Error('æternity wallet extension not found')), 5000);
- const stopScan = walletDetector(scannerConnection, handleWallets);
- });
+ return new Promise(async (resolveConnect) => {
+ connector.addListener('accountsChange', async (accounts: AccountBase[]) => {
+ Sdk.addAccount(accounts[0], { select: true });
+ onAccountChange && onAccountChange(accounts);
+ resolveConnect(Sdk.address);
+ });
+ connector.addListener('networkIdChange', async (networkId: string) => {
+ Sdk.selectNode(networkId);
+ });
+ connector.addListener('disconnect', () => alert('Aepp is disconnected'));
+ await connector.subscribeAccounts(SUBSCRIPTION_TYPES.subscribe, 'current');
+ });
+ }
};
export const detectWallet = async (): Promise => {
@@ -77,4 +83,4 @@ export const initializeContract = async (options: {
});
};
-export { isAddressValid, Contract };
+export { isAddressValid, Contract, connector };