on master help sign in
fix: fix bridge
commit9791ce4fd18ecb40a862aaee2aa327d816370290 authorpkova <pyry@urbit.org> dateTue 12 Sep 2023, 19:24 (3 years ago) parente7448a0
9 files changed+97−92
package.json+9−7 src/lib/reticket.js+3 src/lib/txn.ts+19−18 src/lib/useEthereumTransaction.js+2−2 src/lib/useRoller.ts+20−20 src/store/network.jsx−14 src/views/Login/LoginSelector.tsx+12−1 src/views/Login/Mnemonic.tsx+14−29 src/views/Points.tsx+18−1
package.json+9−7
@@ -83,13 +83,14 @@
8383 "secure-ls": "^1.2.6",
8484 "styled-components": "^5.3.0",
8585 "styled-system": "^5.1.5",
86+ "truffle": "^5.11.4",
8687 "typescript": "^4.3.2",
8788 "urbit-key-generation": "^0.19.0",
8889 "urbit-ob": "^4.1.4",
8990 "urbit-paper-renderer": "^2.0.13",
90− "web3": "^1.8.0",
91− "web3-core": "^1.8.0",
92− "web3-utils": "^1.8.0",
91+ "web3": "^1.10.2",
92+ "web3-core": "^1.10.2",
93+ "web3-utils": "^1.10.2",
9394 "zustand": "^3.5.9"
9495 },
9596 "devDependencies": {
@@ -109,7 +110,7 @@
109110 "eslint-config-prettier": "^5.1.0",
110111 "eslint-config-react-app": "^7.0.1",
111112 "eslint-plugin-prettier": "^3.4.1",
112− "ganache-cli": "^6.2.1",
113+ "ganache": "^7.9.1",
113114 "husky": "^2.4.0",
114115 "npm-run-all": "^4.1.3",
115116 "prettier": "^1.19.1",
@@ -124,7 +125,7 @@
124125 },
125126 "scripts": {
126127 "preview:mainnet": "VITE_MAINNET=true vite preview --port 3000",
127− "start": "vite",
128+ "start": "vite --clearScreen false",
128129 "build": "VITE_MAINNET=true vite build",
129130 "build:goerli": "VITE_GOERLI=true vite build",
130131 "test": "echo 'TODO: set up vitest'",
@@ -132,7 +133,8 @@
132133 "zip": "BRIDGE_VERSION=${VITE_BRIDGE_VERSION:-$npm_package_version}; zip -ur bridge-$BRIDGE_VERSION.zip README.md bridge-https.py checksums.txt && cd build && zip -ur ../bridge-$BRIDGE_VERSION.zip ./* && cd ..",
133134 "release": "npm install && npm run build && npm run checksum && npm run zip",
134135 "release:goerli": "export VITE_BRIDGE_VERSION=$npm_package_version\"r\"; npm install && npm run build:goerli && npm run checksum && npm run zip",
135− "pilot:ganache": "ganache-cli --blockTime 1 --networkId 5 --host '0.0.0.0' -m 'benefit crew supreme gesture quantum web media hazard theory mercy wing kitten' > /dev/null &",
136+ "pilot:ganache": "ganache --blockTime 1 --chain.chainId=1337 --chain.networkId=5 --chain.hardfork=merge --host '0.0.0.0' -m 'benefit crew supreme gesture quantum web media hazard theory mercy wing kitten' > /dev/null &",
137+ "pilot:truffle": "truffle deploy",
136138 "pilot:setup": "npm run pilot:ganache && truffle deploy",
137139 "pilot": "HTTPS=true npm-run-all pilot:setup start pilot:cleanup --continue-on-error",
138140 "pilot-invites": "WITH_TEST_STATE=INVITES npm run pilot",
@@ -142,7 +144,7 @@
142144 "pilot-l2": "BROWSER=NONE WITH_TEST_STATE=L2 HTTPS=false NODE_ENV=development npm-run-all pilot:setup start pilot:cleanup --continue-on-error",
143145 "pilot-l2-local": "BROWSER=NONE VITE_L2=true HTTPS=false NODE_ENV=development npm run start --continue-on-error",
144146 "pilot-goerli": "VITE_GOERLI=true HTTPS=true npm-run-all start --continue-on-error",
145− "pilot:cleanup": "pkill -f ganache-cli",
147+ "pilot:cleanup": "pkill -f ganache",
146148 "lint:check": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
147149 "lint:fix": "eslint --fix 'src/**/*.{js,jsx,ts,tsx}'",
148150 "analyze": "source-map-explorer 'build/static/js/*.js'"
src/lib/reticket.js+3
@@ -172,6 +172,7 @@ export async function reticketPointBetweenWallets({
172172 gasLimit: txs[i].gas,
173173 txnSigner,
174174 txnSender,
175+ web3,
175176 });
176177 txPairs.push({
177178 raw: hexify(stx.serialize()),
@@ -242,6 +243,7 @@ export async function reticketPointBetweenWallets({
242243 gasPriceData,
243244 gasLimit,
244245 nonce: inviteNonce,
246+ web3,
245247 });
246248 sendSignedTransaction(web3, stx);
247249
@@ -272,6 +274,7 @@ export async function reticketPointBetweenWallets({
272274 gasPriceData,
273275 gasLimit,
274276 nonce: inviteNonce,
277+ web3,
275278 });
276279 sendSignedTransaction(web3, stx);
277280 } catch (err) {
src/lib/txn.ts+19−18
@@ -60,17 +60,10 @@ interface signTransactionProps {
6060 gasLimit: number;
6161 txnSigner?: (args: ITxData) => Promise<string>;
6262 txnSender?: (args: ITxData) => Promise<string>;
63+ web3: Web3;
6364}
6465
65−const _web3 = () => {
66− const ENDPOINT = `https://mainnet.infura.io/v3/${
67− import.meta.env.VITE_INFURA_ENDPOINT
68− }`;
69− return new Web3(new Web3.providers.HttpProvider(ENDPOINT));
70−};
71−
72−const estimateGasLimit = async (utx: TransactionConfig) => {
73− const web3 = _web3();
66+const estimateGasLimit = async (utx: TransactionConfig, web3: Web3) => {
7467 const estimate = await web3.eth.estimateGas(utx);
7568 return web3.utils
7669 .toBN(estimate)
@@ -78,8 +71,7 @@ const estimateGasLimit = async (utx: TransactionConfig) => {
7871 .divn(100); // 20% cushion
7972};
8073
81−const getMaxFeePerGas = async () => {
82− const web3 = _web3();
74+const getMaxFeePerGas = async (web3: Web3) => {
8375 const fee = await web3.eth.getGasPrice();
8476 return (Number(fee) * 1.2).toFixed(0); // 20% cushion
8577};
@@ -96,10 +88,11 @@ const signTransaction = async ({
9688 gasLimit, // TODO: do we need the default values anymore? now that the estiamte is loaded dynamically
9789 txnSigner, // optionally inject a transaction signing function,
9890 txnSender, // and a sending function, for wallets that need these passed in.
91+ web3,
9992}: signTransactionProps) => {
10093 const from = wallet.address;
101− const estimate = await estimateGasLimit({ ...txn, from });
102− const maxFeePerGas = await getMaxFeePerGas();
94+ const estimate = await estimateGasLimit({ ...txn, from }, web3);
95+ const maxFeePerGas = await getMaxFeePerGas(web3);
10396
10497 const txParams: EIP1559TxData = {
10598 data: toHex(txn.data),
@@ -115,14 +108,22 @@ const signTransaction = async ({
115108 };
116109
117110 const chain =
118− networkType === NETWORK_TYPES.GOERLI ? Chain.Goerli : Chain.Mainnet;
111+ (networkType === NETWORK_TYPES.GOERLI) ||
112+ (networkType === NETWORK_TYPES.LOCAL) ? Chain.Goerli : Chain.Mainnet;
113+
114+ const common = new Common({
115+ chain,
116+ hardfork: Hardfork.Merge,
117+ });
118+
119+ if (networkType === NETWORK_TYPES.LOCAL) {
120+ common._chainParams.chainId = 1337;
121+ common._chainParams.name = "ganache";
122+ }
119123
120124 const txConfig: TxOptions = {
121125 freeze: false,
122− common: new Common({
123− chain,
124− hardfork: Hardfork.Merge,
125− }),
126+ common: common,
126127 };
127128
128129 let stx = EIP1559Transaction.fromTxData(txParams, txConfig);
src/lib/useEthereumTransaction.js+2−2
@@ -139,6 +139,7 @@ export default function useEthereumTransaction(
139139 gasLimit,
140140 txnSigner,
141141 txnSender,
142+ web3: _web3,
142143 })
143144 )
144145 );
@@ -281,13 +282,12 @@ export default function useEthereumTransaction(
281282 setError(undefined);
282283 const [nonce, chainId] = await Promise.all([
283284 _web3.eth.getTransactionCount(_wallet.address),
284− _web3.eth.net.getId(),
285+ _web3.eth.getChainId(),
285286 ]);
286287
287288 if (!mounted) {
288289 return;
289290 }
290−
291291 setNonce(nonce);
292292 setChainId(chainId);
293293 } catch (error) {
src/lib/useRoller.ts+20−20
@@ -145,35 +145,35 @@ export default function useRoller() {
145145 }
146146
147147 const pointNum = Number(point);
148+ const rawDetails = await api.getPoint(pointNum);
149+ const isL2 = isL2Spawn(rawDetails?.dominion);
150+
148151 try {
149− const rawDetails = await api.getPoint(pointNum);
150− const isL2 = isL2Spawn(rawDetails?.dominion);
151− const l2Quota = isL2 ? await api.getRemainingQuota(pointNum) : 0;
152− const l2Allowance = isL2 ? await api.getAllowance(pointNum) : 0;
152+ if (isL2) {
153+ const l2Quota = isL2 ? await api.getRemainingQuota(pointNum) : 0;
154+ const l2Allowance = isL2 ? await api.getAllowance(pointNum) : 0;
153155
154− const details = toL1Details(rawDetails);
156+ const details = toL1Details(rawDetails);
155157
158+ return new Point({
159+ value: pointNum,
160+ details,
161+ address: _wallet.address,
162+ l2Quota,
163+ l2Allowance,
164+ });
165+ }
166+
167+ const _contracts = need.contracts(contracts);
168+ const details = await azimuth.azimuth.getPoint(_contracts, point);
156169 return new Point({
157170 value: pointNum,
158171 details,
159172 address: _wallet.address,
160− l2Quota,
161− l2Allowance,
162173 });
174+
163175 } catch (e) {
164176 console.warn(e);
165−
166− // Try getting the details from L1
167− try {
168− const _contracts = need.contracts(contracts);
169− const details = await azimuth.azimuth.getPoint(_contracts, point);
170− return new Point({
171− value: pointNum,
172− details,
173− address: _wallet.address,
174− });
175− } catch (e) {
176− console.warn(e);
177177 // Just return a placeholder Point
178178 const details: L1Point = toL1Details();
179179 return new Point({
@@ -182,7 +182,7 @@ export default function useRoller() {
182182 address: _wallet.address,
183183 isPlaceholder: true,
184184 });
185− }
185+
186186 }
187187 },
188188 [api, wallet, contracts]
src/store/network.jsx−14
@@ -25,20 +25,6 @@ function _useNetwork(initialNetworkType = null) {
2525 const [web3, setWeb3] = useState(Nothing());
2626 const [contracts, setContracts] = useState(Nothing());
2727
28− useEffect(() => {
29− (async () => {
30− const provider = await detectEthereumProvider();
31− if (provider) {
32− try {
33− setMetamask(true);
34− setNetworkType(chainIdToNetworkType(window.ethereum.chainId));
35− } catch (e) {
36− console.log('Metamask denied');
37− }
38− }
39− })();
40− }, []);
41−
4228 useEffect(() => {
4329 (async () => {
4430 // given a web3 provider and contract addresses,
src/views/Login/LoginSelector.tsx+12−1
@@ -18,7 +18,7 @@ import { useHistory } from 'store/history';
1818import { useWallet } from 'store/wallet';
1919import { useNetwork } from 'store/network';
2020
21−import { WALLET_TYPES } from 'lib/constants';
21+import { WALLET_TYPES, ETHEREUM_LOCAL_CHAIN_ID } from 'lib/constants';
2222import { useWalletConnect } from 'lib/useWalletConnect';
2323import { MetamaskWallet } from 'lib/metamask';
2424import { expectedChainId } from 'lib/network';
@@ -101,6 +101,17 @@ export default function LoginSelector({
101101 */
102102 if (window.ethereum.chainId !== expectedChainId()) {
103103 console.log(`unexpected chain: ${window.ethereum.chainId}`);
104+
105+ if (expectedChainId() === ETHEREUM_LOCAL_CHAIN_ID) {
106+ await window.ethereum.request({
107+ method: "wallet_addEthereumChain",
108+ params: [{chainId: ETHEREUM_LOCAL_CHAIN_ID,
109+ chainName: "Ganache",
110+ rpcUrls: ["http://127.0.0.1:8545"]
111+ }]
112+ });
113+ }
114+
104115 await window.ethereum.request({
105116 method: 'wallet_switchEthereumChain',
106117 params: [{ chainId: expectedChainId() }],
src/views/Login/Mnemonic.tsx+14−29
@@ -25,7 +25,6 @@ import HeaderPane from 'components/L2/Window/HeaderPane';
2525import BodyPane from 'components/L2/Window/BodyPane';
2626import AdvancedOptions from 'components/L2/Headers/AdvancedOptions';
2727import { Row } from '@tlon/indigo-react';
28−import { debounce } from 'lodash';
2928
3029interface MnemonicProps {
3130 className?: string;
@@ -35,6 +34,19 @@ interface MnemonicProps {
3534export default function Mnemonic({ className, goHome }: MnemonicProps) {
3635 useLoginView(WALLET_TYPES.MNEMONIC);
3736
37+ const onSubmit = (values, valid) => {
38+ setWalletHdPath(values.hdpath);
39+ setAuthMnemonic(Just(values.mnemonic));
40+ setWallet(
41+ walletFromMnemonic(
42+ values.mnemonic,
43+ values.hdpath,
44+ values.passphrase,
45+ skipValidation
46+ )
47+ );
48+ };
49+
3850 const {
3951 setWallet,
4052 setAuthMnemonic,
@@ -58,33 +70,6 @@ export default function Mnemonic({ className, goHome }: MnemonicProps) {
5870 });
5971 }, [skipValidation]);
6072
61− // when the properties change, re-derive wallet and set global state
62− const debouncedOnValues = debounce(({ valid, values }) => {
63− if (valid) {
64− setWalletHdPath(values.hdpath);
65− setAuthMnemonic(Just(values.mnemonic));
66− setWallet(
67− walletFromMnemonic(
68− values.mnemonic,
69− values.hdpath,
70− values.passphrase,
71− skipValidation
72− )
73− );
74− } else {
75− setAuthMnemonic(Nothing());
76− setWallet(Nothing());
77− }
78− }, ONE_SECOND);
79−
80− const onValues = useCallback(debouncedOnValues, [
81− setAuthMnemonic,
82− setWallet,
83− setWalletHdPath,
84− skipValidation,
85− debouncedOnValues,
86− ]);
87−
8873 const initialValues = {
8974 hdpath: DEFAULT_HD_PATH,
9075 useAdvanced: false,
@@ -123,7 +108,7 @@ export default function Mnemonic({ className, goHome }: MnemonicProps) {
123108 <Grid className={cn(className, 'input-form')}>
124109 <BridgeForm
125110 validate={validate}
126− onValues={onValues}
111+ onSubmit={onSubmit}
127112 afterSubmit={goHome}
128113 initialValues={initialValues}>
129114 {({ handleSubmit }: any) => (
src/views/Points.tsx+18−1
@@ -65,6 +65,7 @@ function ActionButtons({ actions = [] }: ActionButtonProps) {
6565
6666export default function Points() {
6767 const { wallet }: any = useWallet();
68+ const { web3 }: any = useNetwork();
6869 const { pop, push, names }: any = useHistory();
6970 const { setPointCursor }: any = usePointCursor();
7071 const { controlledPoints, getDetails }: any = usePointCache();
@@ -74,12 +75,28 @@ export default function Points() {
7475 rejectedPoints,
7576 addRejectedPoint,
7677 ] = useRejectedIncomingPointTransfers();
77− const { pointList } = useRollerStore();
78+ const { pointList, setEthBalance } = useRollerStore();
7879 const {
7980 syncStarReleaseDetails,
8081 starReleaseDetails,
8182 }: any = useStarReleaseCache();
8283
84+ useEffect(() => {
85+ const getEthBalance = async () => {
86+ const _web3 = web3.getOrElse(null);
87+ const _wallet = wallet.getOrElse(null);
88+
89+ if (_web3 && _wallet) {
90+ const newBalance = _web3.utils.fromWei(
91+ await _web3.eth.getBalance(_wallet.address)
92+ );
93+ setEthBalance(newBalance);
94+ }
95+ };
96+
97+ getEthBalance();
98+ }, [setEthBalance, wallet, web3]);
99+
83100 const outgoingPoints = useMemo(
84101 () => pointList.filter(({ isOutgoing }) => isOutgoing),
85102 [pointList]