Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Ylide forum | CSP fixes #1389

Merged
merged 45 commits into from
Dec 5, 2023
Merged
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
cf92af3
Merge pull request #1 from ElKornacio/main
ElKornacio Oct 10, 2023
4aad302
Initial
ElKornacio Oct 10, 2023
2728d39
update envs
ElKornacio Oct 11, 2023
8c08f8b
Update dev.preset.sh
ElKornacio Oct 11, 2023
39388c8
Update dev.preset.sh
ElKornacio Oct 11, 2023
30291c0
Update .env.eth
ElKornacio Oct 11, 2023
e451db3
filters, sortings, chats
ElKornacio Oct 11, 2023
1d3327a
editorjs for new threads
ElKornacio Oct 12, 2023
da9b654
walletconnect + evm chains switching
ElKornacio Oct 12, 2023
0cf1875
small fixes before mobile
ElKornacio Oct 17, 2023
09c3d74
Mobile version + tags + txDiscuss/addressDiscuss + bookmarks
ElKornacio Oct 23, 2023
1046c2a
bookmarks/watches/addrdiscuss/txdiscuss/tags
ElKornacio Oct 24, 2023
ecac16d
realtime chats + watched/bookmarked topics/threads
ElKornacio Oct 25, 2023
e1206c4
fix for single child of popovertrigger
ElKornacio Oct 25, 2023
77b4335
bookmark/watch in Thread, replies reload, fix tags selection
ElKornacio Oct 25, 2023
b4f9692
scroll on reply
ElKornacio Oct 25, 2023
8581787
Chats v2
ElKornacio Oct 26, 2023
cea068b
chats switches chain + back-arrow in bookmarks/watches
ElKornacio Oct 26, 2023
2fbadf5
remove Create Thread from txs/addrs topics
ElKornacio Oct 26, 2023
1a9dc18
Chats list -> Chats everywhere
ElKornacio Oct 26, 2023
aa4f970
Errors in chats + no watches for accountpopover
ElKornacio Oct 27, 2023
d3dc6e3
only evm chats
ElKornacio Oct 27, 2023
c5a0b1b
telegram pushes on watches + pagination fixes
ElKornacio Nov 3, 2023
48c8f3e
remote three dots from replies
ElKornacio Nov 8, 2023
f956f39
fixes
ElKornacio Nov 9, 2023
d8384e2
Merged
ElKornacio Nov 21, 2023
add8d98
Merge branch 'main' into ylide-forum
ElKornacio Nov 21, 2023
084af19
Envs for forum & CI
ElKornacio Nov 21, 2023
a2ee7fa
Forum Env variables for CI
ElKornacio Nov 21, 2023
09f365f
Add forum env variables for validation
ElKornacio Nov 21, 2023
97f68a2
Fix metadata for forum routes
ElKornacio Nov 21, 2023
1adaac5
TS fix on getPageType.ts
ElKornacio Nov 21, 2023
eb64cdc
Fix default eth envs + fix fetch types for address verificaion
ElKornacio Nov 21, 2023
f7aacab
remove token info from instance
ArminaAiren Nov 29, 2023
aabc034
soliditycheck report
ArminaAiren Nov 30, 2023
7b5333d
variables
ArminaAiren Nov 30, 2023
20bd189
fix condition
ArminaAiren Nov 30, 2023
9c45f20
goerli review
ArminaAiren Nov 30, 2023
b0ddaca
change border color, add tests
ArminaAiren Dec 1, 2023
e2dbfa4
Merge pull request #1383 from blockscout/fe-1371
isstuev Dec 2, 2023
0c53a5f
Merge pull request #1380 from blockscout/fe-1346
isstuev Dec 2, 2023
208183b
sentry: fix browser tracing integration (#1385)
tom2drum Dec 4, 2023
5b5ac02
WSS fix for CSP
ElKornacio Dec 4, 2023
9a23f4b
Merge remote-tracking branch 'upstream/ylide-forum' into ylide-forum
ElKornacio Dec 4, 2023
0c590ae
Merge branch 'main' into ylide-forum
ElKornacio Dec 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
walletconnect + evm chains switching
ElKornacio committed Oct 12, 2023
commit da9b6542b1bacd6b9c31766bde6f4d4f4dfe9c97
217 changes: 212 additions & 5 deletions lib/contexts/ylide/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { evm } from '@ylide/ethereum';
import type { AbstractWalletController, IMessage, MessageAttachment, RecipientInfo, Uint256, WalletAccount } from '@ylide/sdk';
import { EthereumProvider } from '@walletconnect/ethereum-provider';
import type { EVMWalletController } from '@ylide/ethereum';
import { evm, EVM_CHAINS, EVM_NAMES, EVM_RPCS, EVMNetwork, evmWalletFactories } from '@ylide/ethereum';
import type { AbstractWalletController, IMessage, MessageAttachment, RecipientInfo, Uint256, WalletAccount, WalletControllerFactory } from '@ylide/sdk';
import { BrowserLocalStorage, MessageContentV4, MessageContentV5, stringToSemver, Ylide, YlideKeysRegistry, YMF } from '@ylide/sdk';
import { SmartBuffer } from '@ylide/smart-buffer';
import type { ReactNode } from 'react';
@@ -11,6 +13,7 @@ import ForumPersonalApi from 'lib/api/ylideApi/ForumPersonalApi';
import ForumPublicApi from 'lib/api/ylideApi/ForumPublicApi';
import { ensurePageLoaded } from 'lib/ensurePageLoaded';

import { blockchainMeta } from './constants';
import { useYlideAccountModal, useYlideSelectWalletModal } from './modals';
import { useYlideAccounts } from './useYlideAccounts';
import { useYlideFaucet } from './useYlideFaucet';
@@ -34,6 +37,151 @@ export interface IMessageDecodedContent {

const YlideContext = createContext(undefined as unknown as ReturnType<typeof useYlideService>);

export interface WalletConnectConnection {
readonly walletName: string;
readonly provider: InstanceType<typeof EthereumProvider>;
}

const useWalletConnectState = (
ylide: Ylide,
ylideIsInitialized: boolean,
wallets: Array<AbstractWalletController>,
updateWallets: (newWallets: Array<AbstractWalletController>) => void,
) => {
const [ initialized, setInitialized ] = useState(false);
const [ connection, setConnection ] = useState<WalletConnectConnection | undefined>(undefined);
const [ url, setUrl ] = useState<string>('');

const disconnectWalletConnect = useCallback(async() => {
if (!initialized || !connection) {
return;
}

const wc = wallets.find(w => w.wallet() === 'walletconnect');

if (wc) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
await (wc as EVMWalletController).signer.provider.provider.disconnect();
// TODO: pizdec
document.location.reload();
}
}, [ connection, initialized, wallets ]);

const initWallet = useCallback(async(factory: WalletControllerFactory) => {
if (!initialized || !connection) {
return false;
}
await ylide.controllers.addWallet(
factory.wallet,
{
dev: false,
faucet: {
registrar: 1,
apiKey: { type: 'client', key: 'clfaf6c3e695452c2a' },
},
walletConnectProvider: initialized && connection ? connection.provider : null,
},
factory.blockchainGroup,
);
updateWallets([ ...ylide.controllers.wallets ]);
return true;
}, [ ylide, initialized, connection, updateWallets ]);

const init = useCallback(async() => {
const rpcMap = {
// Metamask only supports ethereum chain :(
[EVM_CHAINS[EVMNetwork.ETHEREUM]]: (EVM_RPCS[EVMNetwork.ETHEREUM].find(
r => !r.rpc.startsWith('ws'),
) as {
rpc: string;
blockLimit?: number;
lastestNotSupported?: boolean;
batchNotSupported?: boolean;
}).rpc,
};
const chains = Object.keys(rpcMap).map(Number);
let isAvailable = true;
const projectId = 'e9deead089b3383b2db777961e3fa244';
const wcTest = await EthereumProvider.init({
projectId,
chains,
// TODO: remove after fix by WalletConnect - https://github.com/WalletConnect/walletconnect-monorepo/issues/2641
// WalletConnect couldn't reproduce the issue, but we had it.
// Need further to debug, but currently it does not break anything. Propose to leave it.
optionalChains: [ 100500 ],
rpcMap,
showQrModal: true,
});
wcTest.modal?.subscribeModal(({ open }: { open: boolean }) => {
if (open) {
wcTest.modal?.closeModal();
isAvailable = false;
}
});
try {
await wcTest.enable();
} catch (err) {
isAvailable = false;
}

if (isAvailable) {
setInitialized(true);
setConnection({
walletName: wcTest.session?.peer.metadata.name || '',
provider: wcTest,
});
} else {
const wcReal = await EthereumProvider.init({
projectId,
chains,
// TODO: remove after fix by WalletConnect - https://github.com/WalletConnect/walletconnect-monorepo/issues/2641
// WalletConnect couldn't reproduce the issue, but we had it.
// Need further to debug, but currently it does not break anything. Propose to leave it.
optionalChains: [ 100500 ],
rpcMap,
showQrModal: false,
});
wcReal.on('display_uri', url => {
setInitialized(true);
setConnection(undefined);
setUrl(url);
});
wcReal.on('connect', async() => {
setInitialized(true);
setConnection({
walletName: wcReal.session?.peer.metadata.name || '',
provider: wcReal,
});
});

wcReal.enable();
}
}, []);

useEffect(() => {
if (ylideIsInitialized) {
init();
}
}, [ ylideIsInitialized, init ]);

useEffect(() => {
if (ylideIsInitialized && initialized && connection) {
const wcFactory = ylide.walletsList.find(w => w.wallet === 'walletconnect');
if (wcFactory) {
initWallet(wcFactory.factory);
}
}
}, [ ylideIsInitialized, initialized, connection, ylide, initWallet ]);

return {
initialized,
connection,
url,
disconnectWalletConnect,
};
};

const useWalletConnectRegistry = () => {
const [ registry, setRegistry ] = useState<IAppRegistry>({});
const [ loading, setLoading ] = useState(true);
@@ -60,7 +208,13 @@ const useWalletConnectRegistry = () => {

const REACT_APP_FEED_PUBLIC_KEY = '9b939eaca8b685f46d8311698669e25ec50015d96644bf671ed35264d754a977';

const useAccountController = (ylide: Ylide, keysRegistry: YlideKeysRegistry, wallets: Array<AbstractWalletController>, ylideInitialized: boolean) => {
const useAccountController = (
ylide: Ylide,
keysRegistry: YlideKeysRegistry,
wallets: Array<AbstractWalletController>,
ylideInitialized: boolean,
disconnectWalletConnect: () => void,
) => {
const { savedAccounts, addAccount, deleteAccount, setAccountAuthKey } = useYlideAccounts();
const selectWalletModal = useYlideSelectWalletModal();
const accountModal = useYlideAccountModal();
@@ -191,8 +345,11 @@ const useAccountController = (ylide: Ylide, keysRegistry: YlideKeysRegistry, wal
if (currentAccount && currentAccount.address === account.account.address) {
await account.wallet.disconnectAccount(account.account);
}
if (account.wallet.wallet() === 'walletconnect') {
disconnectWalletConnect();
}
deleteAccount(account.account);
}, [ deleteAccount, keysRegistry ]);
}, [ deleteAccount, keysRegistry, disconnectWalletConnect ]);

// export async function activateAccount(params: { account: DomainAccount }) {
// const account = params.account;
@@ -246,7 +403,41 @@ const useYlideService = () => {
const [ initialized, setInitialized ] = useState(false);
const [ wallets, setWallets ] = useState<Array<AbstractWalletController>>([]);
const walletConnectRegistry = useWalletConnectRegistry();
const accounts = useAccountController(ylide, keysRegistry, wallets, initialized);
const walletConnectState = useWalletConnectState(ylide, initialized, wallets, setWallets);
const accounts = useAccountController(ylide, keysRegistry, wallets, initialized, walletConnectState.disconnectWalletConnect);

const switchEVMChain = useCallback(async(wallet: AbstractWalletController, needNetwork: EVMNetwork) => {
try {
const bData = blockchainMeta[EVM_NAMES[needNetwork]];
if (!walletConnectState.connection) {
await (wallet as EVMWalletController).providerObject.request({
method: 'wallet_addEthereumChain',
params: [ bData.ethNetwork ],
});
}
} catch (error) {
// console.error('error: ', error);
}
if (walletConnectState.connection) {
const wc = wallets.find(w => w.wallet() === 'walletconnect');
if (wc) {
await (wallet as EVMWalletController).signer.provider.send('wallet_switchEthereumChain', [
{ chainId: '0x' + Number(EVM_CHAINS[needNetwork]).toString(16) },
]);
}
} else {
await (wallet as EVMWalletController).providerObject.request({
method: 'wallet_switchEthereumChain',
params: [ { chainId: '0x' + Number(EVM_CHAINS[needNetwork]).toString(16) } ], // chainId must be in hexadecimal numbers
});
}
}, [ walletConnectState.connection, wallets ]);

const switchEVMChainRef = React.useRef(switchEVMChain);

useEffect(() => {
switchEVMChainRef.current = switchEVMChain;
}, [ switchEVMChain ]);

const broadcastMessage = useCallback(async(account: DomainAccount, feedId: string, subject: string, content: YMF) => {
return await ylide.core.broadcastMessage({
@@ -359,18 +550,34 @@ const useYlideService = () => {
const f = async() => {
await ensurePageLoaded;
await ylide.init();
ylide.registerWalletFactory(evmWalletFactories.walletconnect);
setWallets(ylide.controllers.wallets);
setInitialized(true);
};
f();
}, [ ylide, keysRegistry ]);

useEffect(() => {
wallets.forEach(w => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
w.onNetworkSwitchRequest = async(
reason: string,
currentNetwork: EVMNetwork | undefined,
needNetwork: EVMNetwork,
) => {
switchEVMChainRef.current(w, needNetwork);
};
});
}, [ wallets ]);

return {
ylide,
keysRegistry,
wallets,
initialized,
walletConnectRegistry,
walletConnectState,
accounts,
faucet,
broadcastMessage,
1 change: 0 additions & 1 deletion ui/pages/Chat.tsx
Original file line number Diff line number Diff line change
@@ -277,7 +277,6 @@ const ChatPageContent = () => {
/>
<Flex flexDir="row" align="center" gap={ 6 }>
<SelectBlockchainDropdown
options={ [ 'GNOSIS', 'ETHEREUM', 'BNBCHAIN' ] }
value={ blockchain }
onChange={ handleBlockchainChange }
/>
12 changes: 10 additions & 2 deletions ui/pages/Thread.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
Flex, Icon, useColorModeValue, Text, HStack, Textarea, Spinner,
} from '@chakra-ui/react';
import { EVMNetwork, EVM_CHAINS, EVM_NAMES } from '@ylide/ethereum';
import { YMF } from '@ylide/sdk';
import { useRouter } from 'next/router';
import React, { useCallback, useEffect } from 'react';
@@ -92,7 +93,15 @@ const ThreadPageContent = () => {

const handleBlockchainChange = useCallback((newBlockchain: string) => {
setBlockchain(newBlockchain);
}, []);
if (account) {
const networkByName = (name: string) =>
Object.values(EVMNetwork).filter(t => !isNaN(Number(t))).find(t => EVM_NAMES[Number(t) as EVMNetwork] === name) as EVMNetwork;
const network = networkByName(newBlockchain);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
account.wallet.onNetworkSwitchRequest('', undefined, network, EVM_CHAINS[network]);
}
}, [ account ]);

useEffect(() => {
if (!initialized) {
@@ -289,7 +298,6 @@ const ThreadPageContent = () => {
/>
<Flex flexDir="row" align="center" gap={ 6 }>
<SelectBlockchainDropdown
options={ [ 'GNOSIS', 'ETHEREUM', 'BNBCHAIN' ] }
value={ blockchain }
onChange={ handleBlockchainChange }
/>
Loading