diff --git a/src/actions/arcActions.ts b/src/actions/arcActions.ts index 390b05b69..6e02d5966 100644 --- a/src/actions/arcActions.ts +++ b/src/actions/arcActions.ts @@ -1,4 +1,5 @@ -import { Address, DAO, IProposalCreateOptions, IProposalOutcome, ITransactionState, ITransactionUpdate, ReputationFromTokenScheme, Scheme } from "@daostack/client"; +import { Address, DAO, IProposalCreateOptions, IProposalOutcome, ITransactionState, + ITransactionUpdate, ReputationFromTokenScheme, Scheme } from "@daostack/client"; import { IAsyncAction } from "actions/async"; import { getArc } from "arc"; import { toWei } from "lib/util"; @@ -38,11 +39,28 @@ export const operationNotifierObserver = (dispatch: Redux.Dispatch, tx ]; }; +export function saveSignalDescription(signalDescription: any): ThunkAction { + return async (_getState: () => IRootState) => { + const arc = getArc(); + let ipfsDataToSave: object = {}; + if (signalDescription.key && signalDescription.value !== undefined) { + if (!arc.ipfsProvider) { + throw Error("No ipfsProvider set on Arc instance - cannot save data on IPFS"); + } + ipfsDataToSave = { + key: signalDescription.key, + value: signalDescription.value, + }; + } + return await arc.ipfs.addAndPinString(Buffer.from(JSON.stringify(ipfsDataToSave))); + }; +} + export function createProposal(proposalOptions: IProposalCreateOptions): ThunkAction { return async (dispatch: Redux.Dispatch, _getState: () => IRootState) => { try { const arc = getArc(); - + const dao = new DAO(proposalOptions.dao, arc); const observer = operationNotifierObserver(dispatch, "Create proposal"); diff --git a/src/components/Account/AccountImage.tsx b/src/components/Account/AccountImage.tsx index 74b70c13a..216fb7e04 100644 --- a/src/components/Account/AccountImage.tsx +++ b/src/components/Account/AccountImage.tsx @@ -8,12 +8,13 @@ interface IProps { accountAddress: string; profile?: IProfileState; width: number; + style?: any; } export default class AccountImage extends React.Component { public render(): RenderOutput { - const { accountAddress, profile, width } = this.props; + const { accountAddress, profile, width, style } = this.props; let url; if (profile && profile.image && profile.image[0] && profile.image[0].contentUrl) { @@ -25,6 +26,6 @@ export default class AccountImage extends React.Component { }); } - return (); + return (); } } diff --git a/src/components/Dao/DaoHeader.scss b/src/components/Dao/DaoHeader.scss new file mode 100644 index 000000000..9c60afd5c --- /dev/null +++ b/src/components/Dao/DaoHeader.scss @@ -0,0 +1,102 @@ +.headerWrap { + background: white; + margin: 8rem 2.5% 0 0; + padding: 25px; + padding-top: 94px; + position: relative; + border-radius: 20px 20px 0 0; + z-index: 9999999999; +} + +.reputationHolders { + display: block; + position: absolute; + font-size: 10px; + font-weight: normal; + color: $gray-1; + white-space: nowrap; +} + +.daoName { + font-size: 24px; + color: #689bd6; +} + +.daoInfo { + margin-left: 100px; + top: 15px; + position: absolute; +} + +.daoDescription { + font-family: $body-font; + color: $black; + font-weight: 500; + font-size: 13px; + width: 75%; +} + +.circularSquare { + border-radius: 50%; + border-color: white; + border-style: solid +} + +.daoImg { + top: -40px !important; + left: 5px !important; + position: absolute; +} + +.daoHeadingGroup { + .header { + margin: unset; + } + p { + margin-top: unset; + } +} + + +.holdings { + padding: 15px; + border: 1px solid #dbd7d7; + border-radius: 7px; + float: right; + position: relative; + top: -75px; +} + +.holdings .holdingsAmount { + margin-top: 5px; + color: #565a5d; + font-size: 12px +} + +.holdings .holdingsAmount .holdingsName { + float: right; + margin-left: 25px; +} + +.holdingsNumber { + margin-right: 10px; +} + +.holdingsList { + list-style: none; + padding-inline-start: 0px; +} + +@media only screen and (max-width: 650px) { + .daoImg { + top: -75px; + left: 75px; + position: absolute; + } +} + +@media only screen and (max-width: 768px) { + .holdings { + top: unset; + } +} diff --git a/src/components/Dao/DaoHeader.tsx b/src/components/Dao/DaoHeader.tsx new file mode 100644 index 000000000..023b8011e --- /dev/null +++ b/src/components/Dao/DaoHeader.tsx @@ -0,0 +1,169 @@ +import * as React from "react"; +import { IDAOState, Scheme, Token } from "@daostack/client"; +import { getArc } from "arc"; +import { first } from "rxjs/operators"; + +import { formatTokens, supportedTokens, fromWei, baseTokenName, ethErrorHandler, genName } from "lib/util"; +import withSubscription, { ISubscriptionProps } from "components/Shared/withSubscription"; +import AccountImage from "components/Account/AccountImage"; + +import BN = require("bn.js"); +import * as css from "./DaoHeader.scss"; + +const styles = { + circularSquare: { + borderRadius: "50%", + borderColor: "white", + borderStyle: "solid", + }, +}; + +interface ISignal { + id: string; + data: any | string; +} + +interface IExternalProps { + daoState: IDAOState | any; + signal?: ISignal | any; +} + +type IProps = IExternalProps & ISubscriptionProps<[Scheme[], ISignal, IDAOState | any]>; + +class DaoHeaderComponent extends React.Component { + + render() { + const { daoState, signal } = this.props; + const { name, memberCount, address, reputationTotalSupply } = daoState; + const data = { + daoImg: "/assets/images/generic-user-avatar.png", + reputationHolders: memberCount, + description: ` + ${name} is an independent, global community of people working together to build and promote Decentralized Autonomous Organizations (DAOs). + It’s the perfect place to get involved with DAOstack. + `, + }; + + const SupportedTokens = (): any => { + const tokensSupported = (tokenAddress: any) => { + return ; + }; + return Object.keys(supportedTokens()).map(tokensSupported); + }; + + const REP = fromWei(reputationTotalSupply).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: 2 }); + + return ( +
+
+ {/* Logo will go here instead of AccountImage this is just a placeholder */} + +
+
+ + { signal.name ? signal.name : name } + + + { data.reputationHolders } Reputation Holders + +
+ +
+ Holdings +
    +
  • + { REP } REP +
  • + + +
+
+ +
+
+ This is the { name } Header +
+

+ { data.description } +

+
+
+ ); + } +} +/***** DAO ETH Balance *****/ +interface IEthProps extends ISubscriptionProps { + dao: IDAOState; +} + +const ETHBalance = (props: IEthProps) => { + const { data } = props; + return
  • {formatTokens(data)} {baseTokenName()}
  • ; +}; + +const SubscribedEthBalance = withSubscription({ + wrappedComponent: ETHBalance, + loadingComponent:
  • ... {baseTokenName()}
  • , + errorComponent: null, + checkForUpdate: (oldProps: IEthProps, newProps: IEthProps) => { + return oldProps.dao.address !== newProps.dao.address; + }, + createObservable: (props: IEthProps) => { + const arc = getArc(); + return arc.dao(props.dao.address).ethBalance().pipe(ethErrorHandler()); + }, +}); + +/***** Token Balance *****/ +interface ITokenProps extends ISubscriptionProps { + dao: IDAOState; + tokenAddress: string; +} + +const TokenBalance = (props: ITokenProps) => { + const { data, error, isLoading, tokenAddress } = props; + + const tokenData = supportedTokens()[tokenAddress]; + if (isLoading || error || ((data === null || isNaN(data) || data.isZero()) && tokenData.symbol !== genName())) { + return null; + } + + return ( +
  • + {formatTokens(data, tokenData["symbol"], tokenData["decimals"])} +
  • + ); +}; + +const SubscribedTokenBalance = withSubscription({ + wrappedComponent: TokenBalance, + checkForUpdate: (oldProps: ITokenProps, newProps: ITokenProps) => { + return oldProps.dao.address !== newProps.dao.address || oldProps.tokenAddress !== newProps.tokenAddress; + }, + createObservable: async (props: ITokenProps) => { + // General cache priming for the DAO we do here + // prime the cache: get all members fo this DAO - + const daoState = props.dao; + + await daoState.dao.members({ first: 1000, skip: 0 }).pipe(first()).toPromise(); + + const arc = getArc(); + const token = new Token(props.tokenAddress, arc); + return token.balanceOf(daoState.address).pipe(ethErrorHandler()); + }, +}); + +const DaoHeader = withSubscription({ + wrappedComponent: DaoHeaderComponent, + checkForUpdate: [], + createObservable: (props: IExternalProps) => { + const dao = props.daoState.dao; + return dao.schemes({}, { fetchAllData: true, subscribe: true }); + }, +}); + +export default DaoHeader; diff --git a/src/components/Dao/DaoSchemesPage.scss b/src/components/Dao/DaoSchemesPage.scss index 37d11b23f..439e00b13 100644 --- a/src/components/Dao/DaoSchemesPage.scss +++ b/src/components/Dao/DaoSchemesPage.scss @@ -41,6 +41,17 @@ padding-top: 30px; } +.daoHeaderBackground { + // @TODO Image is repeating, check this later when using real image + // background-image: url(/assets/images/bg-test.jpeg); + width: 100vw; + position: fixed; + display: flex; + height: 30%; + top:0; + right: 0; + z-index: 9999999; +} @media only screen and (max-width: 425px) { .wrapper h1 { diff --git a/src/components/Dao/DaoSchemesPage.tsx b/src/components/Dao/DaoSchemesPage.tsx index 874668db7..c03338afa 100644 --- a/src/components/Dao/DaoSchemesPage.tsx +++ b/src/components/Dao/DaoSchemesPage.tsx @@ -10,9 +10,13 @@ import { BreadcrumbsItem } from "react-breadcrumbs-dynamic"; import { RouteComponentProps } from "react-router-dom"; import * as Sticky from "react-stickynode"; import { CSSTransition, TransitionGroup } from "react-transition-group"; +import gql from "graphql-tag"; +import { getArc } from "arc"; +import { combineLatest } from "rxjs"; import * as css from "./DaoSchemesPage.scss"; import ProposalSchemeCard from "./ProposalSchemeCard"; import SimpleSchemeCard from "./SimpleSchemeCard"; +import DAOHeader from "./DaoHeader"; const Fade = ({ children, ...props }: any) => ( ( ); +const DAOHeaderBackground = (props: { backgroundImage: string }) => ( + daoHeaderBackground +); + type IExternalProps = { daoState: IDAOState; } & RouteComponentProps; -type IProps = IExternalProps & ISubscriptionProps; +interface ISignal { + id: string; + data: any | string; +} + +type IProps = IExternalProps & ISubscriptionProps<[Scheme[], ISignal[] | any]>; class DaoSchemesPage extends React.Component { @@ -48,8 +65,13 @@ class DaoSchemesPage extends React.Component { public render() { const { data } = this.props; const dao = this.props.daoState; - const allSchemes = data; - + const [allSchemes, signalsData] = data; + const { signals } = signalsData.data; + const signal = signals.length > 0 ? signals[0] : null; + const daoHeaderBackground = signal ? JSON.parse(signal.data).Header : null; + // TODO: + // Once backend issues are fix we will remove hardcoded background + const backgroundImage = daoHeaderBackground ? daoHeaderBackground : "https://i.picsum.photos/id/1006/1081/350.jpg"; const contributionReward = allSchemes.filter((scheme: Scheme) => scheme.staticState.name === "ContributionReward"); const knownSchemes = allSchemes.filter((scheme: Scheme) => scheme.staticState.name !== "ContributionReward" && KNOWN_SCHEME_NAMES.indexOf(scheme.staticState.name) >= 0); const unknownSchemes = allSchemes.filter((scheme: Scheme) => KNOWN_SCHEME_NAMES.indexOf(scheme.staticState.name) === -1 ); @@ -79,7 +101,8 @@ class DaoSchemesPage extends React.Component { return (
    {dao.name} - + { signal && backgroundImage && } + { signal && }

    All Plugins

    @@ -104,7 +127,21 @@ export default withSubscription({ errorComponent: (props) => {props.error.message}, checkForUpdate: [], createObservable: (props: IExternalProps) => { + const arc = getArc(); const dao = props.daoState.dao; - return dao.schemes({}, { fetchAllData: true, subscribe: true }); + const schemes = dao.schemes({}, { fetchAllData: true, subscribe: true }); + // const DAOAddress = props.daoState.address; + // Currently only one dao has signal data + const DAOAddress = dao.id; + const signalQuery = gql` + { + signals(where: { id: "${DAOAddress}" } ) { + id + data + } + } + `; + const signalSchemeData = arc.getObservable(signalQuery); + return combineLatest(schemes, signalSchemeData); }, }); diff --git a/src/components/Proposal/Create/SchemeForms/CreateKnownGenericSchemeProposal.tsx b/src/components/Proposal/Create/SchemeForms/CreateKnownGenericSchemeProposal.tsx index 87afd72d2..0f1cf1508 100644 --- a/src/components/Proposal/Create/SchemeForms/CreateKnownGenericSchemeProposal.tsx +++ b/src/components/Proposal/Create/SchemeForms/CreateKnownGenericSchemeProposal.tsx @@ -38,11 +38,13 @@ const mapStateToProps = (state: IRootState, ownProps: IStateProps) => { interface IDispatchProps { createProposal: typeof arcActions.createProposal; + saveSignalData: typeof arcActions.saveSignalDescription; showNotification: typeof showNotification; } const mapDispatchToProps = { createProposal: arcActions.createProposal, + saveSignalData: arcActions.saveSignalDescription, showNotification, }; @@ -98,7 +100,6 @@ class CreateKnownSchemeProposal extends React.Component { private handleSubmit = async (values: IFormValues, { setSubmitting }: any ): Promise => { if (!await enableWalletProvider({ showNotification: this.props.showNotification })) { return; } - const currentAction = this.state.currentAction; const callValues = []; @@ -107,24 +108,35 @@ class CreateKnownSchemeProposal extends React.Component { values[field.name] = callValue; callValues.push(callValue); } - let callData = ""; try { - callData = this.props.genericSchemeInfo.encodeABI(currentAction, callValues); + + if(values.key) { + const ipfsValue = { + key: values.key, + value: "", + }; + if(currentAction.id !== "deleteSignalType") { + ipfsValue.value = values.value; + currentAction.abi.inputs.pop(); + } + const ipfsData = await this.props.saveSignalData(ipfsValue); + callData = this.props.genericSchemeInfo.encodeABI(currentAction, [ipfsData]); + } else { + callData = this.props.genericSchemeInfo.encodeABI(currentAction, callValues); + } } catch (err) { showNotification(NotificationStatus.Failure, err.message); setSubmitting(false); return; } setSubmitting(false); - let ethValue = new BN(0); if (this.props.genericSchemeInfo.specs.name === "Standard Bounties") { const calcBountEth = await this.getBountyEth(values); ethValue = ethValue.add(calcBountEth); } - const proposalValues = { ...values, callData, diff --git a/src/genericSchemeRegistry/index.ts b/src/genericSchemeRegistry/index.ts index 384a0bab9..0f42a5b2c 100644 --- a/src/genericSchemeRegistry/index.ts +++ b/src/genericSchemeRegistry/index.ts @@ -11,6 +11,7 @@ const ensRegistrarInfo = require("./schemes/EnsRegistrar.json"); const ensRegistryInfo = require("./schemes/ENSRegistry.json"); const ensPublicResolverInfo = require("./schemes/ENSPublicResolver.json"); const registryLookupInfo = require("./schemes/RegistryLookup.json"); +const signals = require("./schemes/Signals.json"); const KNOWNSCHEMES = [ dutchXInfo, @@ -20,6 +21,7 @@ const KNOWNSCHEMES = [ ensPublicResolverInfo, gpInfo, registryLookupInfo, + signals, ]; const SCHEMEADDRESSES: {[network: string]: { [address: string]: any}} = { diff --git a/src/genericSchemeRegistry/schemes/Signals.json b/src/genericSchemeRegistry/schemes/Signals.json new file mode 100644 index 000000000..86ba86b07 --- /dev/null +++ b/src/genericSchemeRegistry/schemes/Signals.json @@ -0,0 +1,122 @@ +{ + "name": "Signals Scheme", + "addresses": { + "main": [ + "0xe06d896da40b73cb02650220e480e20f38e7be18" + ], + "rinkeby": [ + "0xe06d896da40b73cb02650220e480e20f38e7be18" + ], + "private": [ + "0xe06d896da40b73cb02650220e480e20f38e7be18" + ] + }, + "actions": [ + { + "id": "createSignalData", + "label": "Create Signal Attribute", + "description": "Create a signal attribute", + "notes": "docs/link", + "fields": [ + { + "name": "key", + "label": "Attribute to add", + "placeholder": "Attribute type to add e.g. Header, Icon" + }, + { + "name": "value", + "label": "Attribute value", + "placeholder": "Attribute value", + "defaultValue": "" + } + ], + "abi": { + "constant": false, + "inputs": [ + { + "internalType": "string", + "name": "_descriptionHash", + "type": "string" + }, + { + "internalType": "string", + "name": "_descriptionHash", + "type": "string" + } + ], + "name": "signal", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + }, + { + "id": "updateSignalType", + "label": "Update Signal Attribute", + "description": "Update a signal attribute", + "notes": "docs/link", + "fields": [ + { + "name": "key", + "label": "Attribute to update", + "placeholder": "Attribute type to add e.g. Header, Icon" + }, + { + "name": "value", + "label": "Attribute value", + "placeholder": "Attribute value", + "defaultValue": "" + } + ], + "abi": { + "constant": false, + "inputs": [ + { + "internalType": "string", + "name": "_descriptionHash", + "type": "string" + }, + { + "internalType": "string", + "name": "_descriptionHash", + "type": "string" + } + ], + "name": "signal", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + }, + { + "id": "deleteSignalType", + "label": "Delete Signal Attribute", + "description": "Delete a signal attribute", + "notes": "docs/link", + "fields": [ + { + "name": "key", + "label": "Attribute to delete", + "placeholder": "Attribute type to add e.g. Header, Icon" + } + ], + "abi": { + "constant": false, + "inputs": [ + { + "internalType": "string", + "name": "_descriptionHash", + "type": "string" + } + ], + "name": "signal", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + } + ] +} \ No newline at end of file diff --git a/src/settings.ts b/src/settings.ts index 2c458b736..143acf044 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,12 +1,15 @@ // disables some UI elements for a less resource-intensive page load export const ETHDENVER_OPTIMIZATION = true; // if this is true, we do get the contractInfos from a locally stored file in ./data instead of from the subgraph -export const USE_CONTRACTINFOS_CACHE = false; +export const USE_CONTRACTINFOS_CACHE = false; import BurnerConnectProvider from "@burner-wallet/burner-connect-provider"; import WalletConnectProvider from "@walletconnect/web3-provider"; +const Torus = require("@toruslabs/torus-embed"); + const Portis = require("@portis/web3"); const Fortmatic = require("fortmatic"); +const SubgraphEndpoints = require("./subgraph_endpoints.json"); function isMobileBrowser(): boolean { // if (!window) { @@ -15,7 +18,7 @@ function isMobileBrowser(): boolean { let check = false; // from here: https://detectmobilebrowsers.com/ // eslint-disable-next-line no-useless-escape - (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true; })(navigator.userAgent||navigator.vendor||(window as any).opera); + (function(a){if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true; })(navigator.userAgent||navigator.vendor||(window as any).opera); return check; } @@ -28,10 +31,14 @@ function getWeb3ConnectProviderOptions(network: string) { case "rinkeby": return { network: "rinkeby", + torus: { + package: Torus, + options: { network: "rinkeby" }, + }, walletconnect: { package: isMobileBrowser() ? null : WalletConnectProvider, options: { - infuraId: "e0cdf3bfda9b468fa908aa6ab03d5ba2", + infuraId: process.env.INFURA_ID, }, }, burnerconnect: { @@ -61,27 +68,72 @@ function getWeb3ConnectProviderOptions(network: string) { }, }, }; - case "xdai": + case "kovan": return { - network: "xdai", + network: "kovan", + torus: { + package: Torus, + options: { network: "kovan" }, + }, + walletconnect: { + package: isMobileBrowser() ? null : WalletConnectProvider, + options: { + infuraId: process.env.INFURA_ID, + }, + }, burnerconnect: { package: BurnerConnectProvider, options: { - defaultNetwork: "100", + defaultNetwork: "42", defaultWallets: [ - { origin: "https://buffidao.com/", name: "BuffiDAO" }, - { origin: "https://judge.buffidao.com/", name: "Judges BuffiDAO Wallet" }, + { origin: "https://denver-demo.burnerfactory.com/", name: "Denver Demo Wallet" }, ], }, }, + portis: { + package: Portis, + options: { + id: "aae9cff5-6e61-4b68-82dc-31a5a46c4a86", + }, + }, + fortmatic: { + package: Fortmatic, + options: { + key: "pk_test_659B5B486EF199E4", + }, + }, + squarelink: { + options: { + id: null as any, + }, + }, + }; + case "xdai": + return { + network: "xdai", + torus: { + package: Torus, + options: { + networkParams: { + host: "https://xdai.poanetwork.dev", + chainId: 100, + networkName: "xdai", + network: "xdai", + }, + }, + }, }; case "mainnet": return { network: "mainnet", + torus: { + package: Torus, + options: { network: "mainnet" }, + }, walletconnect: { package: isMobileBrowser() ? null : WalletConnectProvider, options: { - infuraId: "e0cdf3bfda9b468fa908aa6ab03d5ba2", + infuraId: process.env.INFURA_ID, }, }, burnerconnect: { @@ -116,8 +168,8 @@ function getWeb3ConnectProviderOptions(network: string) { export const settings = { ganache: { - graphqlHttpProvider: "http://127.0.0.1:8000/subgraphs/name/daostack", - graphqlWsProvider: "ws://127.0.0.1:8001/subgraphs/name/daostack", + graphqlHttpProvider: SubgraphEndpoints.http_ganache, + graphqlWsProvider: SubgraphEndpoints.ws_ganache, graphqlSubscribeToQueries: false, web3Provider: "ws://127.0.0.1:8545", web3ProviderRead: "ws://127.0.0.1:8545", @@ -126,36 +178,46 @@ export const settings = { web3ConnectProviderOptions: {}, }, rinkeby: { - graphqlHttpProvider: process.env.ARC_GRAPHQLHTTPPROVIDER || "https://api.thegraph.com/subgraphs-daostack/name/daostack/v38_3_rinkeby", - graphqlWsProvider: process.env.ARC_GRAPHQLWSPROVIDER || "wss://api.thegraph.com/subgraphs-daostack/name/daostack/v38_3_rinkeby", + graphqlHttpProvider: process.env.ARC_GRAPHQLHTTPPROVIDER || SubgraphEndpoints.http_rinkeby, + graphqlWsProvider: process.env.ARC_GRAPHQLWSPROVIDER || SubgraphEndpoints.ws_rinkeby, + // graphqlHttpProvider: process.env.ARC_GRAPHQLHTTPPROVIDER || SubgraphEndpoints.http_signal, + // graphqlWsProvider: process.env.ARC_GRAPHQLWSPROVIDER || SubgraphEndpoints.ws_signal, graphqlSubscribeToQueries: false, - web3Provider: process.env.ARC_WEB3PROVIDER || "wss://rinkeby.infura.io/ws/v3/e0cdf3bfda9b468fa908aa6ab03d5ba2", - web3ProviderRead: process.env.ARC_WEB3PROVIDERREAD || "wss://rinkeby.infura.io/ws/v3/e0cdf3bfda9b468fa908aa6ab03d5ba2", + web3Provider: process.env.ARC_WEB3PROVIDER || `wss://rinkeby.infura.io/ws/v3/${process.env.INFURA_ID}`, + web3ProviderRead: process.env.ARC_WEB3PROVIDERREAD || `wss://rinkeby.infura.io/ws/v3/${process.env.INFURA_ID}`, ipfsProvider: process.env.ARC_IPFSPROVIDER || "https://api.thegraph.com:443/ipfs-daostack/api/v0", txSenderServiceUrl: "https://tx-sender-service.herokuapp.com/send-tx", web3ConnectProviderOptions: getWeb3ConnectProviderOptions("rinkeby"), }, + kovan: { + graphqlHttpProvider: process.env.ARC_GRAPHQLHTTPPROVIDER || SubgraphEndpoints.http_kovan, + graphqlWsProvider: process.env.ARC_GRAPHQLWSPROVIDER || SubgraphEndpoints.ws_kovan, + graphqlSubscribeToQueries: false, + web3Provider: process.env.ARC_WEB3PROVIDER || `wss://kovan.infura.io/ws/v3/${process.env.INFURA_ID}`, + web3ProviderRead: process.env.ARC_WEB3PROVIDERREAD || `wss://kovan.infura.io/ws/v3/${process.env.INFURA_ID}`, + ipfsProvider: process.env.ARC_IPFSPROVIDER || "https://api.thegraph.com:443/ipfs-daostack/api/v0", + txSenderServiceUrl: "https://tx-sender-service.herokuapp.com/send-tx", + web3ConnectProviderOptions: getWeb3ConnectProviderOptions("kovan"), + }, xdai: { - graphqlHttpProvider: process.env.ARC_GRAPHQLHTTPPROVIDER || "https://api.thegraph.com/subgraphs-daostack/name/daostack/v38_3_xdai", - graphqlWsProvider: process.env.ARC_GRAPHQLWSPROVIDER || "wss://api.thegraph.com/subgraphs-daostack/name/daostack/v38_3_xdai", + graphqlHttpProvider: process.env.ARC_GRAPHQLHTTPPROVIDER || SubgraphEndpoints.http_xdai, + graphqlWsProvider: process.env.ARC_GRAPHQLWSPROVIDER || SubgraphEndpoints.ws_xdai, graphqlSubscribeToQueries: false, - web3Provider: process.env.ARC_WEB3PROVIDER || "https://poa.api.nodesmith.io/v1/dai/jsonrpc?apiKey=128059b9320a462699aef283a7ae2546", + web3Provider: process.env.ARC_WEB3PROVIDER || "wss://poa.api.nodesmith.io/v1/dai/jsonrpc?apiKey=128059b9320a462699aef283a7ae2546", web3ProviderRead: process.env.ARC_WEB3PROVIDERREAD || "wss://poa.api.nodesmith.io/v1/dai/jsonrpc/ws?apiKey=128059b9320a462699aef283a7ae2546", ipfsProvider: process.env.ARC_IPFSPROVIDER || "https://api.thegraph.com:443/ipfs-daostack/api/v0", txSenderServiceUrl: "", web3ConnectProviderOptions: getWeb3ConnectProviderOptions("xdai"), }, main: { - graphqlHttpProvider: process.env.ARC_GRAPHQLHTTPPROVIDER || "https://api.thegraph.com/subgraphs-daostack/name/daostack/v38_3", - graphqlWsProvider: process.env.ARC_GRAPHQLWSPROVIDER || "wss://api.thegraph.com/subgraphs-daostack/name/daostack/v38_3", + graphqlHttpProvider: process.env.ARC_GRAPHQLHTTPPROVIDER || SubgraphEndpoints.http_main, + graphqlWsProvider: process.env.ARC_GRAPHQLWSPROVIDER || SubgraphEndpoints.ws_main, graphqlSubscribeToQueries: false, - web3Provider: process.env.ARC_WEB3PROVIDER || "wss://mainnet.infura.io/ws/v3/e0cdf3bfda9b468fa908aa6ab03d5ba2", - web3ProviderRead: process.env.ARC_WEB3PROVIDERREAD || "wss://mainnet.infura.io/ws/v3/e0cdf3bfda9b468fa908aa6ab03d5ba2", + web3Provider: process.env.ARC_WEB3PROVIDER || `wss://mainnet.infura.io/ws/v3/${process.env.INFURA_ID}`, + web3ProviderRead: process.env.ARC_WEB3PROVIDERREAD || `wss://mainnet.infura.io/ws/v3/${process.env.INFURA_ID}`, ipfsProvider: process.env.ARC_IPFSPROVIDER || "https://api.thegraph.com:443/ipfs-daostack/api/v0", // txSenderServiceUrl: "https://tx-sender-service-mainnet.herokuapp.com/send-tx", txSenderServiceUrl: "", web3ConnectProviderOptions: getWeb3ConnectProviderOptions("mainnet"), }, }; - - diff --git a/src/subgraph_endpoints.json b/src/subgraph_endpoints.json new file mode 100644 index 000000000..a101c8326 --- /dev/null +++ b/src/subgraph_endpoints.json @@ -0,0 +1,14 @@ +{ + "http_main": "https://api.thegraph.com/subgraphs-daostack/name/daostack/v39_4", + "ws_main": "wss://api.thegraph.com/subgraphs-daostack/name/daostack/v39_4", + "http_rinkeby": "https://api.thegraph.com/subgraphs-daostack/name/daostack/v39_4_rinkeby", + "ws_rinkeby": "wss://api.thegraph.com/subgraphs-daostack/name/daostack/v39_4_rinkeby", + "http_signal": "https://api.thegraph.com/subgraphs/name/apeunit/daostack-alchemy-signalscheme", + "ws_signal": "wss://api.thegraph.com/subgraphs/name/apeunit/daostack-alchemy-signalscheme", + "http_kovan": "https://api.thegraph.com/subgraphs-daostack/name/daostack/v39_4_kovan", + "ws_kovan": "wss://api.thegraph.com/subgraphs-daostack/name/daostack/v39_4_kovan", + "http_xdai": "https://api.thegraph.com/subgraphs-daostack/name/daostack/v39_4_xdai", + "ws_xdai": "wss://api.thegraph.com/subgraphs-daostack/name/daostack/v39_4_xdai", + "http_ganache": "http://127.0.0.1:8000/subgraphs/name/daostack", + "ws_ganache": "ws://127.0.0.1:8001/subgraphs/name/daostack" +} \ No newline at end of file