Skip to content

Commit

Permalink
Merge pull request #3 from hicommonwealth/snap.aave
Browse files Browse the repository at this point in the history
Snap.aave
  • Loading branch information
dillchen authored Jul 15, 2021
2 parents 0fff387 + f4f219c commit 63dacd9
Show file tree
Hide file tree
Showing 142 changed files with 5,897 additions and 1,140 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ yarn-error.log
coverage/
*.sw*
.env
.yalc
yalc.lock
*yalc*

# Database downloads
latest.dump
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ We also use certain environment variables to configure the application itself:
To download and restore the production database, and run migrations:

```
pg_dump $(heroku config:get DATABASE_URL --app commonwealthapp) --verbose --exclude-table-data="public.\"Sessions\"" --exclude-table-data="public.\"DiscussionDrafts\"" --exclude-table-data="public.\"LoginTokens\"" --exclude-table-data="public.\"Notifications\"" --exclude-table-data="public.\"SocialAccounts\"" --exclude-table-data="public.\"Webhooks\"" --exclude-table-data="public.\"ChainEvents\"" --no-privileges --no-owner -f latest.dump
pg_dump $(heroku config:get DATABASE_URL --app commonwealthapp) --verbose --exclude-table-data="public.\"Sessions\"" --exclude-table-data="public.\"DiscussionDrafts\"" --exclude-table-data="public.\"LoginTokens\"" --exclude-table-data="public.\"Notifications\"" --exclude-table-data="public.\"EdgewareLockdropEverythings\"" --exclude-table-data="public.\"EdgewareLockdropBalances\"" --exclude-table-data="public.\"EdgewareLockdropEvents\"" --exclude-table-data="public.\"SocialAccounts\"" --exclude-table-data="public.\"Webhooks\"" --exclude-table-data="public.\"ChainEvents\"" --no-privileges --no-owner -f latest.dump
npx sequelize db:drop
npx sequelize db:create
Expand Down
5 changes: 5 additions & 0 deletions client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,13 @@
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, shrink-to-fit=no">
<meta name="apple-mobile-web-app-capable" content="yes" />

<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-KRWH69V');</script>
<!-- End Google Tag Manager -->

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-136522342-5"></script>

<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
Expand Down
59 changes: 57 additions & 2 deletions client/scripts/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import $ from 'jquery';
import { FocusManager } from 'construct-ui';
import moment from 'moment';
import mixpanel from 'mixpanel-browser';
import _ from 'underscore';

import app, { ApiStatus, LoginState } from 'state';
import {
Expand All @@ -34,6 +35,7 @@ import ConfirmInviteModal from 'views/modals/confirm_invite_modal';
import LoginModal from 'views/modals/login_modal';
import { alertModalWithText } from 'views/modals/alert_modal';
import { AaveTypes, MarlinTypes, MolochTypes } from '@commonwealth/chain-events';
import { formatSpace } from './helpers/snapshot_utils/snapshot_utils';

// Prefetch commonly used pages
import(/* webpackPrefetch: true */ 'views/pages/landing');
Expand Down Expand Up @@ -82,6 +84,8 @@ export async function initAppState(updateSelectedNode = true): Promise<void> {
privacyEnabled: community.privacyEnabled,
featuredTopics: community.featured_topics,
topics: community.topics,
stagesEnabled: community.stagesEnabled,
additionalStages: community.additionalStages,
customDomain: community.customDomain,
adminsAndMods: [],
}));
Expand Down Expand Up @@ -115,7 +119,15 @@ export async function initAppState(updateSelectedNode = true): Promise<void> {
app.config.chains.getAll().find((c) => c.customDomain === host) !== undefined
|| app.config.communities.getAll().find((c) => c.customDomain === host) !== undefined
);

app.snapshot.client.getSpaces().then((response) => {
console.log(response);
app.snapshot.spaces = _.object(
Object.entries(response).map((space) => [
space[0],
formatSpace(space[0], space[1])
])
);
});
resolve();
}).catch((err: any) => {
app.loadingError = err.responseJSON?.error || 'Error loading application state';
Expand All @@ -130,10 +142,12 @@ export async function deinitChainOrCommunity() {
app.chain.networkStatus = ApiStatus.Disconnected;
app.chain.deinitServer();
await app.chain.deinit();
console.log('Finished deinitializing chain');
app.chain = null;
}
if (app.community) {
await app.community.deinit();
console.log('Finished deinitializing community');
app.community = null;
}
app.user.setSelectedNode(null);
Expand Down Expand Up @@ -309,6 +323,34 @@ export async function selectNode(n?: NodeInfo, deferred = false): Promise<boolea
'./controllers/chain/ethereum/commonwealth/adapter'
)).default;
newChain = new Commonwealth(n, app);
} else if (n.chain.network === ChainNetwork.Yearn) {
const Yearn = (await import(
/* webpackMode: "lazy" */
/* webpackChunkName: "commonwealth-main" */
'./controllers/chain/ethereum/snapshot/adapter'
)).default;
newChain = new Yearn(n, app);
} else if (n.chain.network === ChainNetwork.Fei) {
const Fei = (await import(
/* webpackMode: "lazy" */
/* webpackChunkName: "commonwealth-main" */
'./controllers/chain/ethereum/snapshot/adapter'
)).default;
newChain = new Fei(n, app);
} else if (n.chain.network === ChainNetwork.Sushi) {
const Snapshot = (await import(
/* webpackMode: "lazy" */
/* webpackChunkName: "commonwealth-main" */
'./controllers/chain/ethereum/snapshot/adapter'
)).default;
newChain = new Snapshot(n, app);
} else if (n.chain.network === ChainNetwork.Demo) {
const Snapshot = (await import(
/* webpackMode: "lazy" */
/* webpackChunkName: "commonwealth-main" */
'./controllers/chain/ethereum/snapshot/adapter'
)).default;
newChain = new Snapshot(n, app);
} else {
throw new Error('Invalid chain');
}
Expand All @@ -317,9 +359,14 @@ export async function selectNode(n?: NodeInfo, deferred = false): Promise<boolea
const finalizeInitialization = await newChain.initServer();

// If the user is still on the initializing node, finalize the
// initialization; otherwise, abort and return false
// initialization; otherwise, abort, deinit, and return false.
//
// Also make sure the state is sufficiently reset so that the
// next redraw cycle will reinitialize any needed chain.
if (!finalizeInitialization) {
console.log('Chain loading aborted');
app.chainPreloading = false;
app.chain = null;
return false;
} else {
app.chain = newChain;
Expand Down Expand Up @@ -608,16 +655,20 @@ $(() => {
'/:scope/discussions/:topic': importRoute('views/pages/discussions', { scoped: true, deferChain: true }),
'/:scope/search': importRoute('views/pages/search', { scoped: true, deferChain: true }),
'/:scope/members': importRoute('views/pages/members', { scoped: true, deferChain: true }),
'/:scope/snapshot-proposals/:snapshotId': importRoute('views/pages/snapshot_proposals', { scoped: true, deferChain: true }),
'/:scope/snapshot-proposal/:snapshotId/:identifier': importRoute('views/pages/view_snapshot_proposal', { scoped: true }),
'/:scope/chat': importRoute('views/pages/chat', { scoped: true, deferChain: true }),
'/:scope/referenda': importRoute('views/pages/referenda', { scoped: true }),
'/:scope/proposals': importRoute('views/pages/proposals', { scoped: true }),
'/:scope/treasury': importRoute('views/pages/treasury', { scoped: true }),
'/:scope/bounties': importRoute('views/pages/bounties', { scoped: true }),
'/:scope/tips': importRoute('views/pages/tips', { scoped: true }),
'/:scope/proposal/:type/:identifier': importRoute('views/pages/view_proposal/index', { scoped: true }),
'/:scope/council': importRoute('views/pages/council', { scoped: true }),
'/:scope/delegate': importRoute('views/pages/delegate', { scoped: true, }),
'/:scope/login': importRoute('views/pages/login', { scoped: true, deferChain: true }),
'/:scope/new/thread': importRoute('views/pages/new_thread', { scoped: true, deferChain: true }),
'/:scope/new/snapshot-proposal/:snapshotId': importRoute('views/pages/new_snapshot_proposal', { scoped: true, deferChain: true }),
'/:scope/new/proposal/:type': importRoute('views/pages/new_proposal/index', { scoped: true }),
'/:scope/admin': importRoute('views/pages/admin', { scoped: true }),
'/:scope/spec_settings': importRoute('views/pages/spec_settings', { scoped: true, deferChain: true }),
Expand All @@ -638,6 +689,10 @@ $(() => {
'/:scope/finishNearLogin': importRoute('views/pages/finish_near_login', { scoped: true }),
});

const script = document.createElement('noscript');
m.render(script, m.trust('<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-KRWH69V" height="0" width="0" style="display:none;visibility:hidden"></iframe>'));
document.body.insertBefore(script, document.body.firstChild);

// initialize construct-ui focus manager
FocusManager.showFocusOnlyOnTab();

Expand Down
4 changes: 2 additions & 2 deletions client/scripts/controllers/chain/community/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ class Community extends ICommunityAdapter<Coin, OffchainAccount> {
}

const {
threads, comments, reactions, topics, admins, activeUsers, numPrevotingThreads, numVotingThreads
threads, comments, reactions, topics, admins, activeUsers, numVotingThreads
} = response.result;
this.app.threads.initialize(threads, numPrevotingThreads, numVotingThreads, true);
this.app.threads.initialize(threads, numVotingThreads, true);
this.app.comments.initialize(comments, true);
this.app.reactions.initialize(reactions, true);
this.app.topics.initialize(topics, true);
Expand Down
63 changes: 63 additions & 0 deletions client/scripts/controllers/chain/ethereum/snapshot/adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { EthereumCoin } from 'adapters/chain/ethereum/types';

import { ERC20__factory } from 'eth/types';
import EthereumAccount from 'controllers/chain/ethereum/account';
import EthereumAccounts from 'controllers/chain/ethereum/accounts';
import { ChainBase, IChainAdapter, NodeInfo } from 'models';

import ChainEntityController from 'controllers/server/chain_entities';
import { IApp } from 'state';

import SnapshotTokenChain from './chain';
import SnapshotApi from './api';

export default class Snapshot extends IChainAdapter<EthereumCoin, EthereumAccount> {
public readonly base = ChainBase.Ethereum;
// TODO: ensure this chainnetwork -> chainclass
public readonly class;
public readonly contractAddress: string;
public readonly isToken = true;

public chain: SnapshotTokenChain;
public accounts: EthereumAccounts;
public hasToken: boolean = false;

constructor(meta: NodeInfo, app: IApp) {
super(meta, app);
this.chain = new SnapshotTokenChain(this.app);
this.accounts = new EthereumAccounts(this.app);
this.class = meta.chain.network;
this.contractAddress = meta.address;
}

public async initApi() {
await this.chain.resetApi(this.meta);
await this.chain.initMetadata();
await this.accounts.init(this.chain);
const api = new SnapshotApi(ERC20__factory.connect, this.meta.address, this.chain.api.currentProvider as any);
await api.init();
this.chain.contractApi = api;
await super.initApi();
}

public async initData() {
await this.chain.initEventLoop();
await super.initData();
await this.activeAddressHasToken(this.app.user?.activeAccount?.address);
}

public async deinit() {
await super.deinit();
this.accounts.deinit();
this.chain.deinitMetadata();
this.chain.deinitEventLoop();
this.chain.deinitApi();
}

public async activeAddressHasToken(activeAddress?: string) {
if (!activeAddress) return false;
const account = this.accounts.get(activeAddress);
const balance = await account.tokenBalance(this.contractAddress);
this.hasToken = balance && !balance.isZero();
}
}
5 changes: 5 additions & 0 deletions client/scripts/controllers/chain/ethereum/snapshot/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ERC20 } from 'eth/types';

import ContractApi from 'controllers/chain/ethereum/contractApi';

export default class SnapshotApi extends ContractApi<ERC20> { }
8 changes: 8 additions & 0 deletions client/scripts/controllers/chain/ethereum/snapshot/chain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import EthereumChain from '../chain';
import ContractApi from './api';

// Thin wrapper over EthereumChain to guarantee the `init()` implementation
// on the Governance module works as expected.
export default class SnapshotTokenChain extends EthereumChain {
public contractApi: ContractApi;
}
1 change: 0 additions & 1 deletion client/scripts/controllers/chain/substrate/bounty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
VotingType, VotingUnit, ChainEntity, ChainEvent,
} from 'models';
import { SubstrateTypes } from '@commonwealth/chain-events';
import { formatAddressShort } from '../../../../../shared/utils';
import SubstrateChain from './shared';
import SubstrateAccounts, { SubstrateAccount } from './account';
import SubstrateBountyTreasury from './bountyTreasury';
Expand Down
4 changes: 4 additions & 0 deletions client/scripts/controllers/chain/substrate/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { IChainAdapter, ChainBase, NodeInfo, ChainNetwork } from 'models';
import { IApp } from 'state';
import { SubstrateCoin } from 'adapters/chain/substrate/types';
import SubstratePhragmenElections from './phragmen_elections';
import SubstrateTreasuryTips from './treasury_tips';
import SubstrateIdentities from './identities';
import SubstrateChain from './shared';

Expand All @@ -23,6 +24,7 @@ class Substrate extends IChainAdapter<SubstrateCoin, SubstrateAccount> {
public treasury: SubstrateTreasury;
public bounties: SubstrateBountyTreasury;
public identities: SubstrateIdentities;
public tips: SubstrateTreasuryTips;
public readonly chainEntities = new ChainEntityController();

public readonly base = ChainBase.Substrate;
Expand All @@ -46,6 +48,7 @@ class Substrate extends IChainAdapter<SubstrateCoin, SubstrateAccount> {
this.democracy = new SubstrateDemocracy(this.app);
this.treasury = new SubstrateTreasury(this.app);
this.bounties = new SubstrateBountyTreasury(this.app);
this.tips = new SubstrateTreasuryTips(this.app);
this.identities = new SubstrateIdentities(this.app);
}

Expand Down Expand Up @@ -75,6 +78,7 @@ class Substrate extends IChainAdapter<SubstrateCoin, SubstrateAccount> {
this.democracy,
this.treasury,
this.bounties,
this.tips,
this.identities,
].map((m) => m.initialized ? m.deinit() : Promise.resolve()));
this.accounts.deinit();
Expand Down
Loading

0 comments on commit 63dacd9

Please sign in to comment.