Skip to content

Commit

Permalink
FE and helper changes to force correct wallet network
Browse files Browse the repository at this point in the history
  • Loading branch information
ianrowan committed Feb 13, 2024
1 parent c05f6e9 commit 4298268
Show file tree
Hide file tree
Showing 13 changed files with 95 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ class CoinbaseWebWalletController implements IWebWallet<string> {
}

// ACTIONS
public async enable() {
public async enable(forceChainId?: string) {
console.log('Attempting to enable Coinbase');
this._enabling = true;
try {
// default to ETH
const chainId = this.getChainId();
const chainId = forceChainId ?? this.getChainId();

// ensure we're on the correct chain

Expand Down Expand Up @@ -199,43 +199,36 @@ class CoinbaseWebWalletController implements IWebWallet<string> {
);
}

public async switchNetwork() {
public async switchNetwork(chainId?: string) {
try {
// Get current chain ID
const currentChainId = await this._web3.eth.getChainId();
const communityChain = this.getChainId();
const chainIdHex = `0x${parseInt(communityChain, 10).toString(16)}`;
if (currentChainId !== communityChain) {
try {
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: `0x${chainIdHex}` }],
const communityChain = chainId ?? this.getChainId();
const chainIdHex = parseInt(communityChain, 10).toString(16);
try {
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: `0x${chainIdHex}` }],
});
} catch (error) {
if (error.code === 4902) {
const chains = await $.getJSON('https://chainid.network/chains.json');
const baseChain = chains.find((c) => c.chainId === communityChain);
// Check if the string contains '${' and '}'
const rpcUrl = baseChain.rpc.filter((r) => !/\${.*?}/.test(r));
const url =
rpcUrl.length > 0 ? rpcUrl[0] : app.chain.meta.node.altWalletUrl;
await this._web3.givenProvider.request({
method: 'wallet_addEthereumChain',
params: [
{
chainId: chainIdHex,
chainName: baseChain.name,
nativeCurrency: baseChain.nativeCurrency,
rpcUrls: [url],
},
],
});
} catch (error) {
if (error.code === 4902) {
const chains = await $.getJSON(
'https://chainid.network/chains.json',
);
const baseChain = chains.find((c) => c.chainId === communityChain);
// Check if the string contains '${' and '}'
const rpcUrl = baseChain.rpc.filter((r) => !/\${.*?}/.test(r));
const url =
rpcUrl.length > 0 ? rpcUrl[0] : app.chain.meta.node.altWalletUrl;
await this._web3.givenProvider.request({
method: 'wallet_addEthereumChain',
params: [
{
chainId: chainIdHex,
chainName: baseChain.name,
nativeCurrency: baseChain.nativeCurrency,
rpcUrls: [url],
},
],
});
}
}
} else {
console.log('Metamask is already connected to the desired chain.');
}
} catch (error) {
console.error('Error checking and switching chain:', error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ class MetamaskWebWalletController implements IWebWallet<string> {
}

// ACTIONS
public async enable() {
public async enable(forceChainId?: string) {
// TODO: use https://docs.metamask.io/guide/rpc-api.html#other-rpc-methods to switch active
// chain according to currently active node, if one exists
console.log('Attempting to enable Metamask');
this._enabling = true;
try {
// default to ETH
const chainId = this.getChainId();
const chainId = forceChainId ?? this.getChainId();

// ensure we're on the correct chain

Expand Down Expand Up @@ -209,43 +209,36 @@ class MetamaskWebWalletController implements IWebWallet<string> {
// TODO: chainChanged, disconnect events
}

public async switchNetwork() {
public async switchNetwork(chainId?: string) {
try {
// Get current chain ID
const currentChainId = await this._web3.eth.getChainId();
const communityChain = this.getChainId();
const chainIdHex = `0x${parseInt(communityChain, 10).toString(16)}`;
if (currentChainId !== communityChain) {
try {
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: `0x${chainIdHex}` }],
const communityChain = chainId ?? this.getChainId();
const chainIdHex = parseInt(communityChain, 10).toString(16);
try {
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: `0x${chainIdHex}` }],
});
} catch (error) {
if (error.code === 4902) {
const chains = await $.getJSON('https://chainid.network/chains.json');
const baseChain = chains.find((c) => c.chainId === communityChain);
// Check if the string contains '${' and '}'
const rpcUrl = baseChain.rpc.filter((r) => !/\${.*?}/.test(r));
const url =
rpcUrl.length > 0 ? rpcUrl[0] : app.chain.meta.node.altWalletUrl;
await this._web3.givenProvider.request({
method: 'wallet_addEthereumChain',
params: [
{
chainId: chainIdHex,
chainName: baseChain.name,
nativeCurrency: baseChain.nativeCurrency,
rpcUrls: [url],
},
],
});
} catch (error) {
if (error.code === 4902) {
const chains = await $.getJSON(
'https://chainid.network/chains.json',
);
const baseChain = chains.find((c) => c.chainId === communityChain);
// Check if the string contains '${' and '}'
const rpcUrl = baseChain.rpc.filter((r) => !/\${.*?}/.test(r));
const url =
rpcUrl.length > 0 ? rpcUrl[0] : app.chain.meta.node.altWalletUrl;
await this._web3.givenProvider.request({
method: 'wallet_addEthereumChain',
params: [
{
chainId: chainIdHex,
chainName: baseChain.name,
nativeCurrency: baseChain.nativeCurrency,
rpcUrls: [url],
},
],
});
}
}
} else {
console.log('Metamask is already connected to the desired chain.');
}
} catch (error) {
console.error('Error checking and switching chain:', error);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { String } from 'aws-sdk/clients/acm';
import { communityStakesAbi } from './Abi/CommunityStakesAbi';
import ContractBase from './ContractBase';
import NamespaceFactory from './NamespaceFactory';
Expand Down Expand Up @@ -111,6 +110,7 @@ class CommunityStakes extends ContractBase {
if (!this.initialized || !this.walletEnabled) {
await this.initialize(true);
}

const namespaceAddress = await this.getNamespaceAddress(name);
const totalPrice = await this.contract.methods
.getBuyPriceAfterFee(namespaceAddress, id.toString(), amount.toString())
Expand Down Expand Up @@ -142,6 +142,7 @@ class CommunityStakes extends ContractBase {
if (!this.initialized || !this.walletEnabled) {
await this.initialize(true);
}

const namespaceAddress = await this.getNamespaceAddress(name);
let txReceipt;
try {
Expand Down Expand Up @@ -226,7 +227,7 @@ class CommunityStakes extends ContractBase {
* @param walletAddress user wallet address
* @returns string balance in ETH
*/
async getUserEthBalance(walletAddress: String): Promise<string> {
async getUserEthBalance(walletAddress: string): Promise<string> {
if (!this.initialized) {
await this.initialize();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ abstract class ContractBase {
this.rpc = rpc;
}

async initialize(withWallet: boolean = false): Promise<void> {
async initialize(
withWallet: boolean = false,
chainId?: string,
): Promise<void> {
if (!this.initialized) {
try {
let provider = this.rpc;
Expand All @@ -30,8 +33,9 @@ abstract class ContractBase {
)[0];

if (!this.wallet.api) {
await this.wallet.enable();
await this.wallet.enable(chainId);
}
await this.wallet.switchNetwork(chainId);
provider = this.wallet.api.givenProvider;
this.walletEnabled = true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { String } from 'aws-sdk/clients/apigateway';
import { AbiItem } from 'web3-utils';
import { namespaceFactoryAbi } from './Abi/NamespaceFactoryAbi';
import { reservationHookAbi } from './Abi/ReservationHookAbi';
Expand All @@ -21,8 +22,11 @@ class NamespaceFactory extends ContractBase {
* Initializes wallet and contracts.
* This must be called after instantiation before other methods are available.
*/
async initialize(withWallet: boolean = false): Promise<void> {
await super.initialize(withWallet);
async initialize(
withWallet: boolean = false,
chainId?: string,
): Promise<void> {
await super.initialize(withWallet, chainId);
const addr = await this.contract.methods.reservationHook().call();
if (addr.toLowerCase() !== '0x0000000000000000000000000000000000000000') {
this.reservationHook = new this.web3.eth.Contract(
Expand Down Expand Up @@ -81,9 +85,10 @@ class NamespaceFactory extends ContractBase {
name: string,
walletAddress: string,
feeManager: string,
chainId: String,
): Promise<any> {
if (!this.initialized || !this.walletEnabled) {
await this.initialize(true);
await this.initialize(true, chainId);
}
// Check if name is available
const namespaceStatus = await this.checkNamespaceReservation(name);
Expand Down Expand Up @@ -115,10 +120,12 @@ class NamespaceFactory extends ContractBase {
name: string,
stakesId: number,
walletAddress: string,
chainId: string,
): Promise<any> {
if (!this.initialized || !this.walletEnabled) {
await this.initialize(true);
await this.initialize(true, chainId);
}

let txReceipt;
try {
txReceipt = await this.contract.methods
Expand Down
4 changes: 3 additions & 1 deletion packages/commonwealth/client/scripts/models/IWebWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface IWebWallet<AccountT extends { address: string } | string> {
enabling: boolean;
accounts: readonly AccountT[];
api?: any;
enable: () => Promise<void>;
enable: (forceChainId: string) => Promise<void>;
reset?: () => Promise<void>;

getChainId(): string | null;
Expand All @@ -24,6 +24,8 @@ interface IWebWallet<AccountT extends { address: string } | string> {
canvasSessionPayload: SessionPayload,
): Promise<string>;

switchNetwork?(chainId?: string): Promise<void>;

chain: ChainBase;
defaultNetwork: ChainNetwork;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const CreateCommunity = () => {
handleCompleteBasicInformationStep,
onChangeStep,
showCommunityStakeStep,
selectedChainId,
} = useCreateCommunity();

useBrowserAnalyticsTrack({
Expand Down Expand Up @@ -64,6 +65,7 @@ const CreateCommunity = () => {
createdCommunityName={createdCommunityName}
createdCommunityId={createdCommunityId}
selectedAddress={selectedAddress}
chainId={selectedChainId}
/>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ interface CommunityStakeStepProps {
createdCommunityName: string;
createdCommunityId: string;
selectedAddress: AddressInfo;
chainId: string;
}

const CommunityStakeStep = ({
goToSuccessStep,
createdCommunityName,
createdCommunityId,
selectedAddress,
chainId,
}: CommunityStakeStepProps) => {
const [enableStakePage, setEnableStakePage] = useState(true);
const [communityStakeData, setCommunityStakeData] = useState({
Expand All @@ -42,6 +44,7 @@ const CommunityStakeStep = ({
communityStakeData={communityStakeData}
selectedAddress={selectedAddress}
createdCommunityId={createdCommunityId}
chainId={chainId}
/>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ const SignStakeTransactions = ({
communityStakeData,
selectedAddress,
createdCommunityId,
chainId,
}: SignStakeTransactionsProps) => {
const { handleReserveCommunityNamespace, reserveNamespaceData } =
useReserveCommunityNamespace({
communityId: createdCommunityId,
namespace: communityStakeData.namespace,
symbol: communityStakeData.symbol,
userAddress: selectedAddress.address,
chainId,
});

const { handleLaunchCommunityStake, launchStakeData } =
Expand All @@ -35,6 +37,7 @@ const SignStakeTransactions = ({
communityId: createdCommunityId,
goToSuccessStep,
selectedAddress: selectedAddress.address,
chainId,
});

const isPreventLeaveEnabled = reserveNamespaceData.state !== 'not-started';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ interface UseLaunchCommunityStakeProps {
communityId: string;
goToSuccessStep: () => void;
selectedAddress: string;
chainId: string;
}

const useLaunchCommunityStake = ({
namespace,
communityId,
goToSuccessStep,
selectedAddress,
chainId,
}: UseLaunchCommunityStakeProps) => {
const [launchStakeData, setLaunchStakeData] =
useState<ActionState>(defaultActionState);
Expand All @@ -34,6 +36,7 @@ const useLaunchCommunityStake = ({
namespace,
commonProtocol.STAKE_ID,
selectedAddress,
chainId,
);

await updateCommunityStake({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ interface UseReserveCommunityNamespaceProps {
namespace: string;
symbol: string;
userAddress: string;
chainId: string;
}

const useReserveCommunityNamespace = ({
communityId,
namespace,
symbol,
userAddress,
chainId,
}: UseReserveCommunityNamespaceProps) => {
const [reserveNamespaceData, setReserveNamespaceData] =
useState<ActionState>(defaultActionState);
Expand All @@ -34,6 +36,7 @@ const useReserveCommunityNamespace = ({
namespace,
userAddress,
userAddress,
chainId,
);

await updateCommunity({
Expand Down
Loading

0 comments on commit 4298268

Please sign in to comment.