diff --git a/packages/react-app/package.json b/packages/react-app/package.json
index 67cb80f4..484f1029 100644
--- a/packages/react-app/package.json
+++ b/packages/react-app/package.json
@@ -18,6 +18,9 @@
"@ant-design/icons": "^4.2.2",
"@apollo/react-hooks": "^4.0.0",
"@craco/craco": "^6.3.0",
+ "@gnosis.pm/safe-apps-react-sdk": "^4.0.8",
+ "@gnosis.pm/safe-apps-sdk": "^6.1.1",
+ "@gnosis.pm/safe-apps-web3modal": "^6.0.1",
"@portis/web3": "^4.0.5",
"@ramp-network/ramp-instant-sdk": "^2.2.0",
"@testing-library/jest-dom": "^5.11.4",
diff --git a/packages/react-app/public/CORS b/packages/react-app/public/CORS
new file mode 100644
index 00000000..f59ec20a
--- /dev/null
+++ b/packages/react-app/public/CORS
@@ -0,0 +1 @@
+*
\ No newline at end of file
diff --git a/packages/react-app/public/manifest.json b/packages/react-app/public/manifest.json
index 6bfcddb8..b0d03c03 100644
--- a/packages/react-app/public/manifest.json
+++ b/packages/react-app/public/manifest.json
@@ -1,7 +1,8 @@
{
- "short_name": "🏗 Scaffold-Eth App",
+ "short_name": "Tip party",
"start_url": ".",
- "name": "🏗 Scaffold-Eth App",
+ "name": "Tip party",
+ "iconPath": "favicon.ico",
"icons": [
{
"src": "favicon.ico",
diff --git a/packages/react-app/src/App.jsx b/packages/react-app/src/App.jsx
index 948e165f..ea309af8 100644
--- a/packages/react-app/src/App.jsx
+++ b/packages/react-app/src/App.jsx
@@ -5,21 +5,17 @@ import { Alert, Button, Menu, Select, Space, Switch as AntdSwitch } from "antd";
import "antd/dist/antd.css";
import React, { useCallback, useEffect, useState } from "react";
import { BrowserRouter, Link, Route, Switch } from "react-router-dom";
-import Web3Modal from "web3modal";
import "./App.css";
import { Account, Contract } from "./components";
-import { INFURA_ID, NETWORK, NETWORKS } from "./constants";
-import { Transactor, Address as AddressHelper } from "./helpers";
+import { NETWORK, NETWORKS } from "./constants";
+import { Transactor, Address as AddressHelper, Web3ModalSetup } from "./helpers";
import { useBalance, useContractLoader, useExchangePrice, useGasPrice, useOnBlock, useUserSigner } from "./hooks";
import { Rooms, Home } from "./views";
// Wallets for wallet connect
-import Portis from "@portis/web3";
-import Fortmatic from "fortmatic";
-import Authereum from "authereum";
const { ethers } = require("ethers");
// 😬 Sorry for all the console logging
-const DEBUG = true;
+const DEBUG = false;
const NETWORKCHECK = true;
// Add more networks as the dapp expands to more networks
@@ -65,85 +61,11 @@ const localProvider = new ethers.providers.StaticJsonRpcProvider(localProviderUr
// 🔭 block explorer URL
const blockExplorer = targetNetwork.blockExplorer;
-// Coinbase walletLink init
-const walletLink = new WalletLink({
- appName: "coinbase",
-});
-
-// WalletLink provider
-const walletLinkProvider = walletLink.makeWeb3Provider(
- "https://eth-mainnet.alchemyapi.io/v2/qCdzfF9UqXcJYIle-Ff-BN0MII8LjLQs",
- 1,
-);
-
// Portis ID: 6255fb2b-58c8-433b-a2c9-62098c05ddc9
/*
Web3 modal helps us "connect" external wallets:
*/
-const web3Modal = new Web3Modal({
- network: "mainnet", // Optional. If using WalletConnect on xDai, change network to "xdai" and add RPC info below for xDai chain.
- cacheProvider: true, // optional
- theme: "light", // optional. Change to "dark" for a dark theme.
- providerOptions: {
- walletconnect: {
- package: WalletConnectProvider, // required
- options: {
- bridge: "https://polygon.bridge.walletconnect.org",
- infuraId: INFURA_ID,
- rpc: {
- 1: "https://eth-mainnet.alchemyapi.io/v2/qCdzfF9UqXcJYIle-Ff-BN0MII8LjLQs", // mainnet // For more WalletConnect providers: https://docs.walletconnect.org/quick-start/dapps/web3-provider#required
- 42: `https://kovan.infura.io/v3/${INFURA_ID}`,
- 100: "https://dai.poa.network", // xDai
- },
- },
- },
- portis: {
- display: {
- logo: "https://user-images.githubusercontent.com/9419140/128913641-d025bc0c-e059-42de-a57b-422f196867ce.png",
- name: "Portis",
- description: "Connect to Portis App",
- },
- package: Portis,
- options: {
- id: "6255fb2b-58c8-433b-a2c9-62098c05ddc9",
- },
- },
- fortmatic: {
- package: Fortmatic, // required
- options: {
- key: "pk_live_5A7C91B2FC585A17", // required
- },
- },
- // torus: {
- // package: Torus,
- // options: {
- // networkParams: {
- // host: "https://localhost:8545", // optional
- // chainId: 1337, // optional
- // networkId: 1337 // optional
- // },
- // config: {
- // buildEnv: "development" // optional
- // },
- // },
- // },
- "custom-walletlink": {
- display: {
- logo: "https://play-lh.googleusercontent.com/PjoJoG27miSglVBXoXrxBSLveV6e3EeBPpNY55aiUUBM9Q1RCETKCOqdOkX2ZydqVf0",
- name: "Coinbase",
- description: "Connect to Coinbase Wallet (not Coinbase App)",
- },
- package: walletLinkProvider,
- connector: async (provider, options) => {
- await provider.enable();
- return provider;
- },
- },
- authereum: {
- package: Authereum, // required
- },
- },
-});
+const web3Modal = Web3ModalSetup(targetNetwork);
function App(props) {
const mainnetProvider =
@@ -412,7 +334,7 @@ function App(props) {
);
const loadWeb3Modal = useCallback(async () => {
- const provider = await web3Modal.connect();
+ const provider = await web3Modal.requestProvider();
setInjectedProvider(new ethers.providers.Web3Provider(provider));
provider.on("chainChanged", chainId => {
@@ -436,6 +358,7 @@ function App(props) {
if (web3Modal.cachedProvider) {
loadWeb3Modal();
}
+ console.log("Checking URLS: ", injectedProvider);
}, [loadWeb3Modal]);
const [route, setRoute] = useState();
diff --git a/packages/react-app/src/components/Account/index.jsx b/packages/react-app/src/components/Account/index.jsx
index 935c954f..aaaee3f6 100644
--- a/packages/react-app/src/components/Account/index.jsx
+++ b/packages/react-app/src/components/Account/index.jsx
@@ -74,7 +74,7 @@ export default function Account({
const modalButtons = [];
if (web3Modal) {
- if (web3Modal.cachedProvider) {
+ if (web3Modal?.cachedProvider || web3Modal?.provider?.safe) {
modalButtons.push(
{isValidAddress(address) ? (
diff --git a/packages/react-app/src/components/PayButton.jsx b/packages/react-app/src/components/PayButton.jsx
index 62ca339e..66e8cefd 100644
--- a/packages/react-app/src/components/PayButton.jsx
+++ b/packages/react-app/src/components/PayButton.jsx
@@ -88,8 +88,10 @@ export default function PayButton({
const payParams = { token, ...tokenInfo[token] };
if (isETH()) {
setStatus(4);
+ console.log("pay happening ", status);
await ethPayHandler();
setStatus(3);
+ console.log("end of pay happening ", status);
} else {
if (status === 1) {
await approveTokenAllowance();
@@ -103,7 +105,9 @@ export default function PayButton({
useEffect(() => {
if (isETH()) {
+ console.log("refresh happening ", status);
refreshETH();
+ console.log("after refresh happening ", status);
} else if (tokenInfo[token]) {
const adjustedAmount = ethers.utils.parseUnits(amount || "0", tokenInfo[token].decimals);
const hasEnoughAllowance = tokenInfo[token].allowance.lt(adjustedAmount);
@@ -113,6 +117,7 @@ export default function PayButton({
}, [amount]);
useEffect(() => {
+ console.log("check it out ", status, renderButtonText());
if (!isETH()) {
setStatus(0);
refreshTokenDetails();
@@ -123,7 +128,6 @@ export default function PayButton({
const renderButtonText = () => {
let text = "Loading...";
-
switch (status) {
case 1:
text = `Approve ${appName} to transfer ${token}`;
@@ -144,7 +148,6 @@ export default function PayButton({
text = "Loading...";
break;
}
-
return text;
};
diff --git a/packages/react-app/src/constants.js b/packages/react-app/src/constants.js
index 9ed671a9..18ec5e4f 100644
--- a/packages/react-app/src/constants.js
+++ b/packages/react-app/src/constants.js
@@ -263,7 +263,7 @@ export const NETWORKS = {
name: "rinkeby",
color: "#e0d068",
chainId: 4,
- rpcUrl: `https://rinkeby.infura.io/v3/${INFURA_ID}`,
+ rpcUrl: "https://eth-rinkeby.alchemyapi.io/v2/0meerwuMivq7wbFsUFTcirfUVM79w1fW",
faucet: "https://faucet.rinkeby.io/",
blockExplorer: "https://rinkeby.etherscan.io/",
nativeCurrency: "ETH",
diff --git a/packages/react-app/src/helpers/Transactor.js b/packages/react-app/src/helpers/Transactor.js
index 2b1dca0b..f7c441a0 100644
--- a/packages/react-app/src/helpers/Transactor.js
+++ b/packages/react-app/src/helpers/Transactor.js
@@ -1,6 +1,7 @@
import { notification } from "antd";
import Notify from "bnc-notify";
import { BLOCKNATIVE_DAPPID } from "../constants";
+import { useSafeAppsSDK } from "@gnosis.pm/safe-apps-react-sdk";
const { ethers } = require("ethers");
@@ -12,9 +13,14 @@ const callbacks = {};
const DEBUG = true;
export default function Transactor(providerOrSigner, gasPrice, etherscan) {
+ const { sdk, safe } = useSafeAppsSDK();
+
if (typeof providerOrSigner !== "undefined") {
// eslint-disable-next-line consistent-return
return async (tx, callback) => {
+ console.log("Transactor tx ", tx);
+ console.log("Transactor callback ", callback);
+ console.log("providerOrSigner callback ", providerOrSigner);
let signer;
let network;
let provider;
@@ -29,26 +35,23 @@ export default function Transactor(providerOrSigner, gasPrice, etherscan) {
}
console.log("network", network);
-
var options = null;
var notify = null;
- if (navigator.onLine) {
- options = {
- dappId: BLOCKNATIVE_DAPPID, // GET YOUR OWN KEY AT https://account.blocknative.com
- system: "ethereum",
- networkId: network.chainId,
- // darkMode: Boolean, // (default: false)
- transactionHandler: txInformation => {
- if (DEBUG) console.log("HANDLE TX", txInformation);
- const possibleFunction = callbacks[txInformation.transaction.hash];
- if (typeof possibleFunction === "function") {
- possibleFunction(txInformation.transaction);
- }
- },
- };
+ options = {
+ dappId: BLOCKNATIVE_DAPPID, // GET YOUR OWN KEY AT https://account.blocknative.com
+ system: "ethereum",
+ networkId: network.chainId,
+ // darkMode: Boolean, // (default: false)
+ transactionHandler: txInformation => {
+ if (DEBUG) console.log("HANDLE TX", txInformation);
+ const possibleFunction = callbacks[txInformation.transaction.hash];
+ if (typeof possibleFunction === "function") {
+ possibleFunction(txInformation.transaction);
+ }
+ },
+ };
- notify = Notify(options);
- }
+ notify = Notify(options);
let etherscanNetwork = "";
if (network.name && network.chainId > 1) {
@@ -62,26 +65,48 @@ export default function Transactor(providerOrSigner, gasPrice, etherscan) {
try {
let result;
- if (tx instanceof Promise) {
- if (DEBUG) console.log("AWAITING TX", tx);
+ if (providerOrSigner?.provider?.provider?.wc?._peerMeta?.name === "Gnosis Safe Multisig") {
+ const accountData = providerOrSigner?.provider?.wc?._peerMeta?.accounts[0];
+ console.log("GNOSIS Safe TX", tx, callback);
result = await tx;
+ console.log("result", result);
+ // Returns a hash to identify the Safe transaction
+ const safeTxHash = await sdk.txs.send({
+ txs: [
+ {
+ to: accountData,
+ value: "0x0",
+ data: result,
+ },
+ ],
+ });
+ console.log("safeTxHash ", safeTxHash);
+ const safeTx = await sdk.txs.getBySafeTxHash(safeTxHash);
+ console.log("safeTx ", safeTx);
} else {
- if (!tx.gasPrice) {
- tx.gasPrice = gasPrice || ethers.utils.parseUnits("4.1", "gwei");
- }
- if (!tx.gasLimit) {
- tx.gasLimit = ethers.utils.hexlify(120000);
+ if (tx instanceof Promise) {
+ if (DEBUG) console.log("AWAITING TX", tx);
+ result = await tx;
+ console.log("callback result ", result);
+ } else {
+ if (!tx.gasPrice) {
+ tx.gasPrice = gasPrice || ethers.utils.parseUnits("4.1", "gwei");
+ }
+ if (!tx.gasLimit) {
+ tx.gasLimit = ethers.utils.hexlify(120000);
+ }
+ if (DEBUG) console.log("RUNNING TX", tx);
+ result = await signer.sendTransaction(tx);
}
- if (DEBUG) console.log("RUNNING TX", tx);
- result = await signer.sendTransaction(tx);
}
+
if (DEBUG) console.log("RESULT:", result);
// console.log("Notify", notify);
if (callback) {
callbacks[result.hash] = callback;
}
-
+ console.log("callback result view callbacks ", callbacks);
// if it is a valid Notify.js network, use that, if not, just send a default notification
if (notify && [1, 3, 4, 5, 42, 100].indexOf(network.chainId) >= 0) {
const { emitter } = notify.hash(result.hash);
@@ -117,6 +142,7 @@ export default function Transactor(providerOrSigner, gasPrice, etherscan) {
return result;
} catch (e) {
+ console.log("main error ", e);
if (DEBUG) console.log(e);
// Accounts for Metamask and default signer on all networks
let message =
@@ -127,7 +153,6 @@ export default function Transactor(providerOrSigner, gasPrice, etherscan) {
: e.data
? e.data
: JSON.stringify(e);
-
if (!e.error && e.message) {
message = e.message;
}
diff --git a/packages/react-app/src/helpers/Web3ModalSetup.js b/packages/react-app/src/helpers/Web3ModalSetup.js
new file mode 100644
index 00000000..6064bc0a
--- /dev/null
+++ b/packages/react-app/src/helpers/Web3ModalSetup.js
@@ -0,0 +1,86 @@
+import Fortmatic from "fortmatic";
+import WalletLink from "walletlink";
+import { SafeAppWeb3Modal } from "@gnosis.pm/safe-apps-web3modal";
+import Portis from "@portis/web3";
+import WalletConnectProvider from "@walletconnect/web3-provider";
+import { INFURA_ID } from "../constants";
+import Authereum from "authereum";
+//import Torus from "@toruslabs/torus-embed"
+
+// Coinbase walletLink init
+const walletLink = new WalletLink({
+ appName: "coinbase",
+});
+
+// WalletLink provider
+const walletLinkProvider = walletLink.makeWeb3Provider(
+ "https://eth-mainnet.alchemyapi.io/v2/qCdzfF9UqXcJYIle-Ff-BN0MII8LjLQs",
+ 1,
+);
+
+const web3ModalSetup = targetNetwork =>
+ new SafeAppWeb3Modal({
+ network: "mainnet", // Optional. If using WalletConnect on xDai, change network to "xdai" and add RPC info below for xDai chain.
+ cacheProvider: true, // optional
+ providerOptions: {
+ walletconnect: {
+ network: targetNetwork,
+ package: WalletConnectProvider, // required
+ options: {
+ rpc: {
+ 1: "https://eth-mainnet.alchemyapi.io/v2/qCdzfF9UqXcJYIle-Ff-BN0MII8LjLQs", // mainnet // For more WalletConnect providers: https://docs.walletconnect.org/quick-start/dapps/web3-provider#required
+ 42: `https://kovan.infura.io/v3/${INFURA_ID}`,
+ 100: "https://dai.poa.network", // xDai
+ 4: "https://eth-rinkeby.alchemyapi.io/v2/0meerwuMivq7wbFsUFTcirfUVM79w1fW",
+ },
+ },
+ },
+ portis: {
+ display: {
+ logo: "https://user-images.githubusercontent.com/9419140/128913641-d025bc0c-e059-42de-a57b-422f196867ce.png",
+ name: "Portis",
+ description: "Connect to Portis App",
+ },
+ package: Portis,
+ options: {
+ id: "6255fb2b-58c8-433b-a2c9-62098c05ddc9",
+ },
+ },
+ fortmatic: {
+ package: Fortmatic, // required
+ options: {
+ key: "pk_live_5A7C91B2FC585A17", // required
+ },
+ },
+ // torus: {
+ // package: Torus,
+ // options: {
+ // networkParams: {
+ // host: "https://localhost:8545", // optional
+ // chainId: 1337, // optional
+ // networkId: 1337 // optional
+ // },
+ // config: {
+ // buildEnv: "development" // optional
+ // },
+ // },
+ // },
+ "custom-walletlink": {
+ display: {
+ logo: "https://play-lh.googleusercontent.com/PjoJoG27miSglVBXoXrxBSLveV6e3EeBPpNY55aiUUBM9Q1RCETKCOqdOkX2ZydqVf0",
+ name: "Coinbase",
+ description: "Connect to Coinbase Wallet (not Coinbase App)",
+ },
+ package: walletLinkProvider,
+ connector: async (provider, options) => {
+ await provider.enable();
+ return provider;
+ },
+ },
+ authereum: {
+ package: Authereum, // required
+ },
+ },
+ });
+
+export default web3ModalSetup;
diff --git a/packages/react-app/src/helpers/index.js b/packages/react-app/src/helpers/index.js
index 9871b50b..486fe18e 100644
--- a/packages/react-app/src/helpers/index.js
+++ b/packages/react-app/src/helpers/index.js
@@ -1,2 +1,3 @@
export { default as Transactor } from "./Transactor";
export { default as Address } from "./Address";
+export { default as Web3ModalSetup } from "./Web3ModalSetup";
diff --git a/packages/react-app/src/index.jsx b/packages/react-app/src/index.jsx
index 10e56111..71d462a4 100644
--- a/packages/react-app/src/index.jsx
+++ b/packages/react-app/src/index.jsx
@@ -2,6 +2,7 @@ import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client";
import React from "react";
import { ThemeSwitcherProvider } from "react-css-theme-switcher";
import ReactDOM from "react-dom";
+import SafeProvider from "@gnosis.pm/safe-apps-react-sdk";
import App from "./App";
import "./index.css";
@@ -22,7 +23,9 @@ const client = new ApolloClient({
ReactDOM.render(
-
+
+
+
,
document.getElementById("root"),
diff --git a/packages/react-app/src/views/HostRoom.jsx b/packages/react-app/src/views/HostRoom.jsx
index 173bb468..cc3a6d97 100644
--- a/packages/react-app/src/views/HostRoom.jsx
+++ b/packages/react-app/src/views/HostRoom.jsx
@@ -10,6 +10,7 @@ import * as storage from "../utils/storage";
import { useTokenImport } from "../hooks";
//import useWindowSize from 'react-use/lib/useWindowSize'
import Confetti from "react-confetti";
+import { useSafeAppsSDK } from "@gnosis.pm/safe-apps-react-sdk";
import "./HostRoom.css";
export default function HostRoom({
@@ -48,6 +49,7 @@ export default function HostRoom({
const [loadedTokenList, setLoadedTokenList] = useState({});
const { readContracts, writeContracts } = contracts;
+ const { sdk, safe } = useSafeAppsSDK();
const subs = useRef([]);
@@ -205,11 +207,13 @@ export default function HostRoom({
};
const ethPayHandler = async () => {
+ console.log("Beginning ethPayHandler ", tx, userSigner.provider);
const result = tx(
writeContracts.TokenDistributor.splitEth(allAddresses, room, {
value: ethers.utils.parseEther(amount),
}),
async update => {
+ console.log("into ethPayHandler update", update);
await handleResponseHash(update);
console.log("📡 Transaction Update:", update);
if (update && (update.status === "confirmed" || update.status === 1)) {
@@ -274,6 +278,7 @@ export default function HostRoom({
};
const handleResponseHash = async result => {
+ console.log("handleResponseHash ", result);
if (result.hash && selectedChainId && room) {
await storage.registerTransactionForRoom(room, result.hash, selectedChainId);
}
@@ -487,7 +492,6 @@ export default function HostRoom({
href="#"
onClick={e => {
e.preventDefault();
-
setImportToken(true);
}}
>