Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/npm_and_yarn/tar-6.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
montelaidev authored May 3, 2024
2 parents 1e077d0 + 3670ccc commit d5beefc
Show file tree
Hide file tree
Showing 19 changed files with 2,763 additions and 429 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@metamask/snap-account-abstraction-keyring-monorepo",
"version": "0.2.2",
"version": "0.3.0",
"private": true,
"description": "An account abstraction keyring snap that integrates with MetaMask accounts.",
"keywords": [
Expand Down
9 changes: 8 additions & 1 deletion packages/site/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.3.0]

### Added

- Deployment of verifying paymaster from frontend ([#71](https://github.com/MetaMask/snap-account-abstraction-keyring/pull/71))

## [0.2.2]

### Changed
Expand All @@ -29,7 +35,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Initial release.

[Unreleased]: https://github.com/MetaMask/snap-account-abstraction-keyring/compare/v0.2.2...HEAD
[Unreleased]: https://github.com/MetaMask/snap-account-abstraction-keyring/compare/v0.3.0...HEAD
[0.3.0]: https://github.com/MetaMask/snap-account-abstraction-keyring/compare/v0.2.2...v0.3.0
[0.2.2]: https://github.com/MetaMask/snap-account-abstraction-keyring/compare/v0.2.1...v0.2.2
[0.2.1]: https://github.com/MetaMask/snap-account-abstraction-keyring/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/MetaMask/snap-account-abstraction-keyring/compare/v0.1.0...v0.2.0
Expand Down
26 changes: 22 additions & 4 deletions packages/site/package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "@metamask/snap-account-abstraction-keyring-site",
"version": "0.2.2",
"version": "0.3.0",
"private": true,
"license": "(MIT-0 OR Apache-2.0)",
"scripts": {
"build": "rimraf .cache && cross-env GATSBY_TELEMETRY_DISABLED=1 gatsby build --prefix-paths",
"clean": "rimraf public .cache",
"lint": "yarn lint:eslint && yarn lint:misc && yarn lint:deps && yarn lint:types && yarn lint:changelog",
"lint:deps": "depcheck",
"lint:deps": "depcheck --ignores='@lavamoat/allow-scripts,@svgr/webpack,gatsby-plugin-styled-components,gatsby-plugin-svgr,gatsby-plugin-webfonts,react-scripts'",
"lint:eslint": "eslint . --cache --ext js,jsx,ts,tsx",
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
"lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' --check",
Expand All @@ -30,20 +30,21 @@
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@metamask/keyring-api": "^5.0.0",
"@lavamoat/allow-scripts": "^3.0.4",
"@metamask/keyring-api": "^6.0.0",
"@metamask/providers": "^16.0.0",
"@mui/icons-material": "^5.14.0",
"@mui/material": "^5.14.0",
"@types/react-helmet": "^6.1.6",
"crypto-browserify": "^3.12.0",
"ethers": "5.7.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-helmet": "^6.1.0",
"react-icons": "^4.8.0",
"react-is": "^18.2.0",
"semver": "^7.5.4",
"styled-components": "5.3.9",
"uuid": "^9.0.0",
"webpack": "^5.88.2"
},
"devDependencies": {
Expand Down Expand Up @@ -78,5 +79,22 @@
},
"engines": {
"node": ">=18.6.0"
},
"lavamoat": {
"allowScripts": {
"gatsby": false,
"gatsby>@parcel/cache>lmdb": false,
"gatsby>@pmmmwh/react-refresh-webpack-plugin>core-js-pure": false,
"gatsby>core-js": false,
"gatsby>gatsby-cli": false,
"gatsby>gatsby-sharp>sharp": false,
"gatsby>gatsby-telemetry": false,
"gatsby>lmdb": false,
"gatsby>lmdb>msgpackr>msgpackr-extract": false,
"gatsby>memoizee>es5-ext": false,
"react-scripts>tailwindcss>postcss-load-config>ts-node>@swc/core": false,
"eslint-plugin-jest>jest>jest-cli>jest-config>ts-node>@swc/core": false,
"react-scripts>react-app-polyfill>core-js": false
}
}
}
78 changes: 15 additions & 63 deletions packages/site/src/components/ChainConfig.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
/* eslint-disable @typescript-eslint/no-misused-promises */
import type {
KeyringRequest,
KeyringSnapRpcClient,
} from '@metamask/keyring-api';
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import * as uuid from 'uuid';

import { ErrorContainer } from './ErrorContainer';
import { StyledBox } from './styledComponents';
import { defaultSnapOrigin } from '../config';
import { SuccessContainer } from './SuccessContainer';
import { TextField } from './TextField';
import { getChainConfigs, saveChainConfig } from '../utils';
import { chainIdToName } from '../utils/chains';

const ChainConfigErrorContainer = styled.div`
color: #721c24;
`;

const ChainConfigSuccessContainer = styled.div`
color: #155724;
`;

const ChainConfigContainer = styled.div`
width: 100%;
margin: 0 auto;
Expand Down Expand Up @@ -52,16 +42,6 @@ const ChainDescription = styled.p`
margin: 5px 2.5% 5px 16px;
`;

const TextField = styled.input`
width: calc(95% - 16px);
padding: 10px;
margin: 8px 2.5% 8px 16px;
background: transparent;
border-radius: 5px;
box-sizing: border-box;
border: 1px solid #bbc0c5;
`;

const Select = styled.select`
width: calc(95% - 16px);
padding-top: 8px;
Expand Down Expand Up @@ -99,35 +79,17 @@ export type ChainConfigs = {
[chainId: string]: ChainConfig;
};

export const ChainConfigComponent = ({
client,
}: {
client: KeyringSnapRpcClient;
}) => {
export const ChainConfigComponent = () => {
const [chainConfigs, setChainConfigs] = useState<ChainConfigs>({});
const [chainSelected, setChainSelected] = useState<string>('');
const [successMessage, setSuccessMessage] = useState<string | null>();
const [error, setError] = useState<Error | undefined>();

useEffect(() => {
const getChainConfigs = async () => {
try {
const configs = await window.ethereum.request({
method: 'wallet_invokeSnap',
params: {
snapId: defaultSnapOrigin,
request: { method: 'snap.internal.getConfigs' },
},
});

setChainConfigs(configs as ChainConfigs);
// eslint-disable-next-line @typescript-eslint/no-shadow
} catch (error) {
setError(error as Error);
}
};
// eslint-disable-next-line @typescript-eslint/no-shadow
getChainConfigs().catch((error) => setError(error));
getChainConfigs()
.then((configs) => setChainConfigs(configs))
// eslint-disable-next-line @typescript-eslint/no-shadow
.catch((error) => setError(error));
}, []);

useEffect(() => {
Expand Down Expand Up @@ -167,16 +129,10 @@ export const ChainConfigComponent = ({
return;
}
try {
const request: KeyringRequest = {
id: uuid.v4(),
scope: '',
account: uuid.v4(),
request: {
method: 'snap.internal.setConfig',
params: chainConfigs[chainSelected] as ChainConfig,
},
};
await client.submitRequest(request);
await saveChainConfig({
chainId: chainSelected,
chainConfig: chainConfigs[chainSelected] as ChainConfig,
});
setSuccessMessage('Chain Config Updated');
// eslint-disable-next-line @typescript-eslint/no-shadow
} catch (error) {
Expand All @@ -189,12 +145,8 @@ export const ChainConfigComponent = ({
<ChainConfigItem>
<ChainConfigHeader>{'Chain Configuration'}</ChainConfigHeader>
<ChainConfigContent isOpen>
<ChainConfigErrorContainer>
{error && <p>{error.message}</p>}
</ChainConfigErrorContainer>
<ChainConfigSuccessContainer>
{successMessage && <p>{successMessage}</p>}
</ChainConfigSuccessContainer>
{error && <ErrorContainer error={error.message} />}
{successMessage && <SuccessContainer message={successMessage} />}
<Select
value={chainSelected ?? ''}
onChange={(event) => {
Expand Down
10 changes: 10 additions & 0 deletions packages/site/src/components/ErrorContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import styled from 'styled-components';

const ErrorBox = styled.div`
color: #721c24;
`;

export const ErrorContainer = ({ error }: { error: string }) => {
return <ErrorBox>{error}</ErrorBox>;
};
148 changes: 148 additions & 0 deletions packages/site/src/components/PaymasterDeployer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { ethers } from 'ethers';
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';

import type { ChainConfigs } from './ChainConfig';
import { ErrorContainer } from './ErrorContainer';
import { SuccessContainer } from './SuccessContainer';
import { TextField } from './TextField';
import verifyingPaymaster from '../../../snap/artifacts/contracts/samples/VerifyingPaymaster.sol/VerifyingPaymaster.json';
import { getChainConfigs, saveChainConfig } from '../utils';

const PaymasterDeployerContainer = styled.div`
width: 100%;
margin: 0 auto 20px auto;
border: 1px solid #eaeaea;
border-radius: 4px;
padding: 8px;
width: 100%;
`;

const PaymasterDeployerHeader = styled.div`
margin: 8px;
font-weight: bold;
cursor: pointer;
display: flex;
justify-content: space-between;
font-size: 16px;
`;

const PaymasterDeployerContent = styled.div`
display: ${({ isOpen }: { isOpen: boolean }) => (isOpen ? 'block' : 'none')};
padding: 0px 8px;
`;

export const PaymasterDeployer = () => {
const [paymasterAddress, setPaymasterAddress] = useState<string | null>(null);
const [paymasterSecretKey, setPaymasterSecretKey] = useState<string | null>(
null,
);
const [configs, setConfigs] = useState<ChainConfigs>({});
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<Error | undefined>();
const [successMessage, setSuccessMessage] = useState<string | null>();

useEffect(() => {
getChainConfigs()
.then((chainConfigs: ChainConfigs) => {
setConfigs(chainConfigs);
})
// eslint-disable-next-line @typescript-eslint/no-shadow
.catch((error) => {
setError(error);
});
}, []);

const deployPaymaster = async () => {
// clear state
setPaymasterAddress(null);
setPaymasterSecretKey(null);
setError(undefined);
setLoading(true);

if (!paymasterSecretKey) {
setError(new Error('Please provide a secret key'));
return;
}

let hexSecretKey;
// eslint-disable-next-line no-negated-condition
if (!paymasterSecretKey.startsWith('0x')) {
hexSecretKey = `0x${paymasterSecretKey}`;
} else {
hexSecretKey = paymasterSecretKey;
}

try {
// eslint-disable-next-line no-new
new ethers.Wallet(hexSecretKey);
} catch {
setError(new Error('Invalid secret key'));
return;
}

try {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - MetaMask provider would work for Web3Provider
const provider = new ethers.providers.Web3Provider(window.ethereum);
const { chainId } = await provider.getNetwork();
const signer = new ethers.Wallet(paymasterSecretKey, provider);
const paymasterFactory = new ethers.ContractFactory(
verifyingPaymaster.abi,
verifyingPaymaster.bytecode,
signer,
);
const paymaster = await paymasterFactory.deploy(
configs[chainId]?.entryPoint,
await signer.getAddress(),
);
await paymaster.deployed();

setPaymasterAddress(paymaster.address);

await saveChainConfig({
chainId: chainId.toString(),
chainConfig: {
customVerifyingPaymasterAddress: paymaster.address,
customVerifyingPaymasterSK: hexSecretKey,
},
});
setSuccessMessage(
`Verifying Paymaster Deployed to ${paymasterAddress as string}`,
);
// eslint-disable-next-line @typescript-eslint/no-shadow
} catch (error) {
setError(error as Error);
} finally {
setLoading(false);
}
};

return (
<PaymasterDeployerContainer>
<PaymasterDeployerHeader>
Deploy Verifying Paymaster
</PaymasterDeployerHeader>
{error && <ErrorContainer error={error.message} />}
{successMessage && <SuccessContainer message={successMessage} />}
<PaymasterDeployerContent isOpen>
<TextField
id={'verify-paymaster-admin-secret-key'}
placeholder={'Verifying Paymaster Secret Key in Hex Format'}
value={paymasterSecretKey as string}
onChange={(event) => setPaymasterSecretKey(event.target.value)}
/>
<button
type="button"
// eslint-disable-next-line @typescript-eslint/no-misused-promises
onClick={async () => {
await deployPaymaster();
}}
disabled={!paymasterSecretKey || loading}
>
{loading ? 'Deploying' : 'Deploy Paymaster'}
</button>
</PaymasterDeployerContent>
</PaymasterDeployerContainer>
);
};
10 changes: 10 additions & 0 deletions packages/site/src/components/SuccessContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import styled from 'styled-components';

const SuccessBox = styled.div`
color: #155724;
`;

export const SuccessContainer = ({ message }: { message: string }) => {
return <SuccessBox>{message}</SuccessBox>;
};
11 changes: 11 additions & 0 deletions packages/site/src/components/TextField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import styled from 'styled-components';

export const TextField = styled.input`
width: calc(95% - 16px);
padding: 10px;
margin: 8px 2.5% 8px 16px;
background: transparent;
border-radius: 5px;
box-sizing: border-box;
border: 1px solid #bbc0c5;
`;
Loading

0 comments on commit d5beefc

Please sign in to comment.