Skip to content

Commit 2b88b2d

Browse files
roienatanOren Sokolowsky
and
Oren Sokolowsky
authored
Support multiple networks (#2264)
* init * init continue * init more * add getNetworkByDAO function * add getArcByDAOAddress + getArcByAddress * fix. + usage * more * . * added network in dao sidebar ; more fixed ; lint fixes * fix xGen/GEN ; better UI for DAO network label ; better documentaion for some new functions * metamask fixes ; account balances wrapper ; more bugs fixes * more * many more fixes ; added NETWORKS env var * generic way to handle DAOs from multiple networks ; fix ganache arc issue * more fixes and tests fixes * remove feed page * fix 3box issue * added select to switch between daos ; improvement to dao name styles * added member daos to the following daos list ; fix tests * fix logout ; better error message when wrong network * fix failling tests * specify which network to redeem all * fetch all daos in a loop fix undefined followed dao * init * init continue * init more * add getNetworkByDAO function * add getArcByDAOAddress + getArcByAddress * fix. + usage * more * . * added network in dao sidebar ; more fixed ; lint fixes * fix xGen/GEN ; better UI for DAO network label ; better documentaion for some new functions * metamask fixes ; account balances wrapper ; more bugs fixes * more * many more fixes ; added NETWORKS env var * generic way to handle DAOs from multiple networks ; fix ganache arc issue * more fixes and tests fixes * remove feed page * added select to switch between daos ; improvement to dao name styles * added member daos to the following daos list ; fix tests * fix logout ; better error message when wrong network * fix failling tests * specify which network to redeem all * fetch all daos in a loop fix undefined followed dao * fix search daos * exclude duplicate searched daos * don't auto logout when wrong network ; remove bubble around dao network * updated daocreator v1.0.14 ; show only current network holdings ; show current network in account menu ; can login or connect to any network (that in the Networks env var) from everywhere in Alchemy * better styles for DAO name: enable hover to reveal name when DAO name is long without new lines * same formatting to sections titles in the account menu * fix BreadcrumbsItem select position * listen to network changes in MetaMask * comments * check if window.ethereum exist before using it * more comments * update daocreator 1.0.17 * pass NETWORKS array to DAO creator ; fix crash when changing metamask to unsupported network Co-authored-by: Oren Sokolowsky <[email protected]>
1 parent f89277c commit 2b88b2d

File tree

85 files changed

+1031
-1732
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+1031
-1732
lines changed

Diff for: package-lock.json

+126-105
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+12-11
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,25 @@
5252
]
5353
},
5454
"scripts": {
55-
"analyze": "NODE_ENV=production NETWORK=main ANALYZE=1 node --max_old_space_size=4096 node_modules/.bin/webpack --config webpack.prod.config.js --progress --colors",
56-
"analyze:build": "NODE_ENV=production ANALYZE=1 NETWORK=private node --max_old_space_size=4096 node_modules/.bin/webpack --config webpack.prod.config.js",
55+
"analyze:build": "NODE_ENV=production ANALYZE=1 NETWORKS=private node --max_old_space_size=4096 node_modules/.bin/webpack --config webpack.prod.config.js",
56+
"analyze": "NODE_ENV=production NETWORKS=main ANALYZE=1 node --max_old_space_size=4096 node_modules/.bin/webpack --config webpack.prod.config.js --progress --colors",
5757
"build": "webpack --config webpack.prod.config.js",
5858
"build-dev": "node --max_old_space_size=4096 ./node_modules/webpack/bin/webpack.js --config webpack.dev.config.js",
59-
"build-travis": "cross-env NODE_ENV=production NETWORK=main node --max_old_space_size=4096 ./node_modules/webpack/bin/webpack.js --config webpack.prod.config.js",
59+
"build-travis": "cross-env NODE_ENV=production NETWORKS=main node --max_old_space_size=4096 ./node_modules/webpack/bin/webpack.js --config webpack.prod.config.js",
6060
"fetch-contracts": "cross-env NODE_ENV=production ./node_modules/.bin/ts-node scripts/fetchContracts.ts",
6161
"heroku-postbuild": "npm run build",
6262
"lint": "eslint --ext .js,.ts,.tsx ./src ./test",
6363
"lint-andFix": "npm run lint -- --fix",
6464
"postinstall": "rimraf ./src/**/*.scss.d.ts",
6565
"service-status": "node scripts/serviceStatus.js",
66-
"start": "cross-env NODE_ENV=development SHOW_ALL_DAOS=true NETWORK=private node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.dev.config.js",
67-
"start-dev-profiling": "cross-env NODE_ENV=dev-profiling SHOW_ALL_DAOS=true NETWORK=rinkeby webpack-dev-server --config webpack.dev.config.js",
68-
"start-docker": "cross-env NODE_ENV=production SHOW_ALL_DAOS=true NETWORK=private node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.docker.config.js",
69-
"start-prod": "cross-env NODE_ENV=production SHOW_ALL_DAOS=false NETWORK=main node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.dev.config.js",
70-
"start-staging-kovan": "cross-env NODE_ENV=production SHOW_ALL_DAOS=true NETWORK=kovan node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.dev.config.js",
71-
"start-staging-rinkeby": "cross-env NODE_ENV=production SHOW_ALL_DAOS=true NETWORK=rinkeby node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.dev.config.js",
72-
"start-staging-xdai": "cross-env NODE_ENV=production SHOW_ALL_DAOS=true NETWORK=xdai node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.dev.config.js",
66+
"start": "cross-env NODE_ENV=development SHOW_ALL_DAOS=true NETWORKS=private node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.dev.config.js",
67+
"start-dev-profiling": "cross-env NODE_ENV=dev-profiling SHOW_ALL_DAOS=true NETWORKS=rinkeby webpack-dev-server --config webpack.dev.config.js",
68+
"start-docker": "cross-env NODE_ENV=production SHOW_ALL_DAOS=true NETWORKS=private node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.docker.config.js",
69+
"start-prod": "cross-env NODE_ENV=production SHOW_ALL_DAOS=false NETWORKS=main node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.dev.config.js",
70+
"start-staging-kovan": "cross-env NODE_ENV=production SHOW_ALL_DAOS=true NETWORKS=kovan node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.dev.config.js",
71+
"start-staging-rinkeby": "cross-env NODE_ENV=production SHOW_ALL_DAOS=true NETWORKS=rinkeby node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.dev.config.js",
72+
"start-staging-rinkeby-xdai": "cross-env NODE_ENV=production SHOW_ALL_DAOS=true NETWORKS=rinkeby*xdai node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.dev.config.js",
73+
"start-staging-xdai": "cross-env NODE_ENV=production SHOW_ALL_DAOS=true NETWORKS=xdai node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.dev.config.js",
7374
"start-staging": "npm run start-staging-rinkeby",
7475
"storybook": "start-storybook",
7576
"test": "wdio ./test/integration/wdio.conf.js",
@@ -82,7 +83,7 @@
8283
"3box": "1.20.2",
8384
"@burner-wallet/burner-connect-provider": "^0.1.1",
8485
"@daostack/arc.js": "0.2.76",
85-
"@dorgtech/daocreator-ui": "^1.0.13",
86+
"@dorgtech/daocreator-ui": "1.0.17",
8687
"@fortawesome/fontawesome-svg-core": "^1.2.10",
8788
"@fortawesome/free-brands-svg-icons": "^5.6.1",
8889
"@fortawesome/react-fontawesome": "^0.1.3",

Diff for: src/App.tsx

+41-28
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ import { ConnectedRouter } from "react-router-redux";
1212
import { ThroughProvider } from "react-through";
1313
import * as css from "./layouts/App.scss";
1414
import { history, default as store } from "./configureStore";
15+
import { Networks, targetNetworks } from "./lib/util";
16+
import Arc from "@daostack/arc.js";
17+
18+
declare global {
19+
// eslint-disable-next-line @typescript-eslint/interface-name-prefix
20+
interface Window {
21+
arcs: {[key: string]: Arc};
22+
daos: {[key: string]: {[key: string]: string}};
23+
}
24+
}
1525

1626
export class App extends React.Component<{}, {
1727
arcIsInitialized: boolean;
@@ -42,42 +52,46 @@ export class App extends React.Component<{}, {
4252
}
4353

4454
public async componentDidMount (): Promise<void> {
55+
const networks = targetNetworks();
56+
window.arcs = {};
57+
window.daos = {};
4558
// Do this here because we need to have initialized Arc first. This will
4659
// not create a provider for the app, rather will just initialize Arc with a
4760
// readonly provider with no account, internal only to it.
4861
const totalNumberOfAttempts = 3; /// we will try 3 times to init arc before actually throwing an error
4962
let numberOfAttempts = 0;
50-
let success = false;
51-
const initArc = async () => {
52-
success = await initializeArc();
53-
if (!success) {
54-
throw Error("Initialize arc failed for an unknown reason (see the console)...");
55-
}
56-
this.setState({ arcIsInitialized: true });
57-
};
58-
while (!success) {
59-
try {
60-
await initArc();
61-
} catch (err) {
62-
this.setState({ retryingArc: true });
63-
// eslint-disable-next-line no-console
64-
numberOfAttempts += 1;
65-
// retry
66-
if (numberOfAttempts >= totalNumberOfAttempts) {
67-
const msg = "Could not connect to the network; please retry later...";
68-
this.setState({ error: msg});
69-
throw Error(msg);
63+
for (const network of networks) {
64+
let success = false;
65+
const initArc = async (network: Networks) => {
66+
success = await initializeArc(network);
67+
if (!success) {
68+
throw Error("Initialize arc failed for an unknown reason (see the console)...");
69+
}
70+
};
71+
while (!success) {
72+
try {
73+
await initArc(network as Networks);
74+
} catch (err) {
75+
this.setState({ retryingArc: true });
76+
numberOfAttempts += 1;
77+
// retry
78+
if (numberOfAttempts >= totalNumberOfAttempts) {
79+
const msg = "Could not connect to the network; please retry later...";
80+
this.setState({ error: msg});
81+
throw Error(msg);
82+
}
83+
// eslint-disable-next-line no-console
84+
console.error("Could not connect..");
85+
// eslint-disable-next-line no-console
86+
console.error(err);
87+
// eslint-disable-next-line no-console
88+
console.log(`retrying (attempt ${numberOfAttempts} of ${totalNumberOfAttempts})`);
89+
await sleep(2000);
7090
}
71-
// eslint-disable-next-line no-console
72-
console.error("Could not connect..");
73-
// eslint-disable-next-line no-console
74-
console.error(err);
75-
// eslint-disable-next-line no-console
76-
console.log(`retrying (attempt ${numberOfAttempts} of ${totalNumberOfAttempts})`);
77-
await sleep(2000);
7891
}
7992
}
8093

94+
this.setState({ arcIsInitialized: true });
8195

8296
let GOOGLE_ANALYTICS_ID: string;
8397
switch (process.env.NODE_ENV) {
@@ -122,7 +136,6 @@ export class App extends React.Component<{}, {
122136
<Route path="/" exact component={AppContainer}/>
123137
<Route path="/dao" component={AppContainer}/>
124138
<Route path="/daos" component={AppContainer}/>
125-
<Route path="/feed" component={AppContainer}/>
126139
<Route path="/profile" component={AppContainer}/>
127140
<Route path="/redemptions" component={AppContainer}/>
128141
<Route path="/daos/create" component={AppContainer} />

Diff for: src/actions/arcActions.ts

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Address, DAO, IProposalCreateOptions, IProposalOutcome, ITransactionState, ITransactionUpdate, ReputationFromTokenScheme, Scheme } from "@daostack/arc.js";
22
import { IAsyncAction } from "actions/async";
3-
import { getArc } from "arc";
4-
import { toWei } from "lib/util";
3+
import { toWei, getArcByDAOAddress } from "lib/util";
54
import { IRedemptionState } from "lib/proposalHelpers";
65
import { IRootState } from "reducers/index";
76
import { NotificationStatus, showNotification } from "reducers/notifications";
@@ -38,10 +37,10 @@ export const operationNotifierObserver = (dispatch: Redux.Dispatch<any, any>, tx
3837
];
3938
};
4039

41-
export function createProposal(proposalOptions: IProposalCreateOptions): ThunkAction<any, IRootState, null> {
40+
export function createProposal(proposalOptions: IProposalCreateOptions, daoAvatarAddress: string): ThunkAction<any, IRootState, null> {
4241
return async (dispatch: Redux.Dispatch<any, any>, _getState: () => IRootState) => {
4342
try {
44-
const arc = getArc();
43+
const arc = getArcByDAOAddress(daoAvatarAddress);
4544

4645
const dao = new DAO(proposalOptions.dao, arc);
4746

@@ -57,7 +56,7 @@ export function createProposal(proposalOptions: IProposalCreateOptions): ThunkAc
5756

5857
export function executeProposal(avatarAddress: string, proposalId: string, _accountAddress: string) {
5958
return async (dispatch: Redux.Dispatch<any, any>) => {
60-
const arc = getArc();
59+
const arc = getArcByDAOAddress(avatarAddress);
6160
const observer = operationNotifierObserver(dispatch, "Execute proposal");
6261
const proposalObj = await arc.dao(avatarAddress).proposal(proposalId);
6362

@@ -86,7 +85,7 @@ export type VoteAction = IAsyncAction<"ARC_VOTE", {
8685

8786
export function voteOnProposal(daoAvatarAddress: string, proposalId: string, voteOption: IProposalOutcome) {
8887
return async (dispatch: Redux.Dispatch<any, any>, _getState: () => IRootState) => {
89-
const arc = getArc();
88+
const arc = getArcByDAOAddress(daoAvatarAddress);
9089
const proposalObj = await arc.dao(daoAvatarAddress).proposal(proposalId);
9190
const observer = operationNotifierObserver(dispatch, "Vote");
9291
await proposalObj.vote(voteOption).subscribe(...observer);
@@ -106,17 +105,17 @@ export type StakeAction = IAsyncAction<"ARC_STAKE", {
106105

107106
export function stakeProposal(daoAvatarAddress: string, proposalId: string, prediction: number, stakeAmount: number) {
108107
return async (dispatch: Redux.Dispatch<any, any>, ) => {
109-
const arc = getArc();
108+
const arc = getArcByDAOAddress(daoAvatarAddress);
110109
const proposalObj = await arc.dao(daoAvatarAddress).proposal(proposalId);
111110
const observer = operationNotifierObserver(dispatch, "Stake");
112111
await proposalObj.stake(prediction, toWei(stakeAmount)).subscribe(...observer);
113112
};
114113
}
115114

116115
// Approve transfer of 100000 GENs from accountAddress to the GenesisProtocol contract for use in staking
117-
export function approveStakingGens(spender: Address) {
116+
export function approveStakingGens(spender: Address, daoId: any) {
118117
return async (dispatch: Redux.Dispatch<any, any>, ) => {
119-
const arc = getArc();
118+
const arc = getArcByDAOAddress(daoId);
120119
const observer = operationNotifierObserver(dispatch, "Approve GEN");
121120
await arc.approveForStaking(spender, toWei(100000)).subscribe(...observer);
122121
};
@@ -137,7 +136,7 @@ export type RedeemAction = IAsyncAction<"ARC_REDEEM", {
137136

138137
export function redeemProposal(daoAvatarAddress: string, proposalId: string, accountAddress: string) {
139138
return async (dispatch: Redux.Dispatch<any, any>) => {
140-
const arc = getArc();
139+
const arc = getArcByDAOAddress(daoAvatarAddress);
141140
const proposalObj = await arc.dao(daoAvatarAddress).proposal(proposalId);
142141
const observer = operationNotifierObserver(dispatch, "Reward");
143142
await proposalObj.claimRewards(accountAddress).subscribe(...observer);
@@ -146,7 +145,7 @@ export function redeemProposal(daoAvatarAddress: string, proposalId: string, acc
146145

147146
export function redeemReputationFromToken(scheme: Scheme, addressToRedeem: string, privateKey: string|undefined, redeemerAddress: Address|undefined, redemptionSucceededCallback: () => void) {
148147
return async (dispatch: Redux.Dispatch<any, any>) => {
149-
const arc = getArc();
148+
const arc = getArcByDAOAddress(redeemerAddress);
150149

151150
// ensure that scheme.ReputationFromToken is set
152151
await scheme.fetchStaticState();

Diff for: src/actions/web3Actions.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as Sentry from "@sentry/browser";
22
import { getProfile } from "actions/profilesActions";
3-
import { getWeb3ProviderInfo } from "arc";
3+
import { getWeb3ProviderInfo, getProviderNetworkName } from "arc";
44
import Analytics from "lib/analytics";
55
import { ActionTypes, IWeb3State } from "reducers/web3Reducer";
66

@@ -9,10 +9,11 @@ import { IAsyncAction } from "./async";
99

1010
export type ConnectAction = IAsyncAction<"WEB3_CONNECT", void, IWeb3State>;
1111

12-
export function setCurrentAccount(accountAddress: string) {
12+
export function setCurrentAccount(accountAddress: string, network?: string) {
1313
return async (dispatch: Redux.Dispatch<any, any>, _getState: Function) => {
1414
const payload = {
1515
currentAccountAddress: accountAddress,
16+
networkName: network || await getProviderNetworkName(),
1617
};
1718

1819
const action = {

0 commit comments

Comments
 (0)