├── src ├── pages │ ├── Options │ │ ├── index.css │ │ ├── Options.css │ │ ├── Options.tsx │ │ ├── index.html │ │ └── index.jsx │ ├── App │ │ ├── constants │ │ │ ├── index.ts │ │ │ └── constants.ts │ │ ├── pages │ │ │ ├── home │ │ │ │ ├── index.ts │ │ │ │ └── home.tsx │ │ │ ├── onboarding │ │ │ │ ├── index.ts │ │ │ │ ├── onboarding.tsx │ │ │ │ └── intro.tsx │ │ │ ├── new-accounts │ │ │ │ ├── index.ts │ │ │ │ └── new-account.tsx │ │ │ ├── deploy-account │ │ │ │ └── index.ts │ │ │ ├── keyring │ │ │ │ └── index.ts │ │ │ └── transfer-asset │ │ │ │ ├── index.ts │ │ │ │ └── transfer-asset.tsx │ │ ├── hooks │ │ │ ├── index.ts │ │ │ ├── redux-hooks.ts │ │ │ ├── onWindowEnter.ts │ │ │ └── keyring-hooks.ts │ │ ├── components │ │ │ ├── header │ │ │ │ ├── index.ts │ │ │ │ └── header.tsx │ │ │ ├── account-info │ │ │ │ ├── index.ts │ │ │ │ └── account-info.tsx │ │ │ ├── account-activity │ │ │ │ ├── index.ts │ │ │ │ └── account-activity.tsx │ │ │ ├── account-balance-info │ │ │ │ ├── index.ts │ │ │ │ └── account-balance-info.tsx │ │ │ └── transfer-asset-button │ │ │ │ ├── index.ts │ │ │ │ └── transfer-asset-button.tsx │ │ ├── index.html │ │ ├── index.css │ │ ├── protected-route.tsx │ │ ├── index.jsx │ │ └── app.tsx │ ├── Background │ │ ├── constants │ │ │ ├── index.ts │ │ │ └── constants.ts │ │ ├── types │ │ │ ├── scw-implementation.ts │ │ │ ├── keyrings.ts │ │ │ ├── chrome-messages.ts │ │ │ ├── asset.ts │ │ │ ├── account.ts │ │ │ ├── network.ts │ │ │ └── common.ts │ │ ├── index.ts │ │ ├── redux-slices │ │ │ ├── selectors │ │ │ │ ├── signingRequestSelectors.ts │ │ │ │ ├── networkSelectors.ts │ │ │ │ ├── transactionsSelectors.ts │ │ │ │ ├── keyringsSelectors.ts │ │ │ │ ├── dappPermissionSelectors.ts │ │ │ │ └── accountSelectors.ts │ │ │ ├── network.ts │ │ │ ├── keyrings.ts │ │ │ ├── index.ts │ │ │ ├── permissions.ts │ │ │ ├── account.ts │ │ │ ├── signing.ts │ │ │ └── transactions.ts │ │ ├── main.ts │ │ ├── services │ │ │ ├── main.ts │ │ │ ├── types.ts │ │ │ └── base.ts │ │ └── utils │ │ │ └── index.ts │ ├── Popup │ │ ├── pages │ │ │ ├── home │ │ │ │ ├── index.ts │ │ │ │ └── home.tsx │ │ │ ├── dapp-permission │ │ │ │ ├── index.ts │ │ │ │ └── dapp-permission.tsx │ │ │ ├── sign-message │ │ │ │ ├── index.ts │ │ │ │ ├── sign-message.css │ │ │ │ └── sign-message.tsx │ │ │ └── sign-transaction-request │ │ │ │ ├── index.ts │ │ │ │ └── sign-transaction-request.tsx │ │ ├── components │ │ │ ├── origin-info │ │ │ │ ├── index.ts │ │ │ │ └── origin-info.tsx │ │ │ ├── account-info │ │ │ │ ├── index.ts │ │ │ │ └── account-info.tsx │ │ │ ├── deploy-account │ │ │ │ ├── index.ts │ │ │ │ └── deploy-account.tsx │ │ │ └── sign-confirmation │ │ │ │ ├── index.ts │ │ │ │ └── sign-confirmation.tsx │ │ ├── index.html │ │ ├── index.css │ │ ├── index.tsx │ │ └── Popup.tsx │ ├── Account │ │ ├── account-api │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── account-api.ts │ │ ├── components │ │ │ ├── onboarding │ │ │ │ ├── index.ts │ │ │ │ └── onboarding.tsx │ │ │ ├── sign-message │ │ │ │ ├── index.ts │ │ │ │ └── sign-message.tsx │ │ │ ├── transaction │ │ │ │ ├── index.ts │ │ │ │ ├── post-transaction-confirmation.tsx │ │ │ │ ├── transaction.tsx │ │ │ │ ├── transaction-confirmation.tsx │ │ │ │ └── pre-transaction-confirmation.tsx │ │ │ ├── PrimaryButton.tsx │ │ │ └── types.ts │ │ ├── index.ts │ │ └── useAccountApi.ts │ └── Content │ │ ├── window-provider │ │ ├── runtime-type-checks.ts │ │ └── eip-1193.ts │ │ ├── types.ts │ │ ├── index.ts │ │ └── inject.ts ├── assets │ └── img │ │ ├── logo.png │ │ ├── icon-34.png │ │ ├── icon-128.png │ │ └── dapp_favicon_default@2x.png ├── custom.d.ts ├── containers │ └── Greetings │ │ └── Greetings.jsx ├── helpers │ ├── omit.ts │ ├── ensureError.ts │ └── getEthereumGlobal.ts ├── manifest.json └── exconfig.ts ├── .vscode └── settings.json ├── .eslintrc ├── .prettierrc ├── utils ├── env.js ├── build.js ├── autoReloadClients │ └── backgroundClient.js └── webserver.js ├── .babelrc ├── contracts └── Greeter.sol ├── deploy └── deploy.ts ├── tsconfig.json ├── .gitignore ├── scripts └── localSendMoney.ts ├── LICENSE ├── hardhat.config.ts ├── package.json └── test └── Lock.js /src/pages/Options/index.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } -------------------------------------------------------------------------------- /src/pages/App/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | -------------------------------------------------------------------------------- /src/pages/Background/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | -------------------------------------------------------------------------------- /src/pages/Background/types/scw-implementation.ts: -------------------------------------------------------------------------------- 1 | export type SCWImplementation = string; 2 | -------------------------------------------------------------------------------- /src/pages/App/pages/home/index.ts: -------------------------------------------------------------------------------- 1 | import Home from './home'; 2 | 3 | export default Home; 4 | -------------------------------------------------------------------------------- /src/pages/Popup/pages/home/index.ts: -------------------------------------------------------------------------------- 1 | import Home from './home'; 2 | 3 | export default Home; 4 | -------------------------------------------------------------------------------- /src/pages/App/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './keyring-hooks'; 2 | export * from './redux-hooks'; 3 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "react-app", 3 | "globals": { 4 | "chrome": "readonly" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/assets/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eth-infinitism/trampoline/HEAD/src/assets/img/logo.png -------------------------------------------------------------------------------- /src/pages/App/components/header/index.ts: -------------------------------------------------------------------------------- 1 | import Header from './header'; 2 | 3 | export default Header; 4 | -------------------------------------------------------------------------------- /src/assets/img/icon-34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eth-infinitism/trampoline/HEAD/src/assets/img/icon-34.png -------------------------------------------------------------------------------- /src/assets/img/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eth-infinitism/trampoline/HEAD/src/assets/img/icon-128.png -------------------------------------------------------------------------------- /src/pages/Account/account-api/index.ts: -------------------------------------------------------------------------------- 1 | import AccountApi from './account-api'; 2 | 3 | export default AccountApi; 4 | -------------------------------------------------------------------------------- /src/pages/App/pages/onboarding/index.ts: -------------------------------------------------------------------------------- 1 | import Onboarding from './onboarding'; 2 | 3 | export default Onboarding; 4 | -------------------------------------------------------------------------------- /src/pages/App/pages/new-accounts/index.ts: -------------------------------------------------------------------------------- 1 | import NewAccount from './new-account'; 2 | 3 | export default NewAccount; 4 | -------------------------------------------------------------------------------- /src/pages/Account/components/onboarding/index.ts: -------------------------------------------------------------------------------- 1 | import Onboarding from './onboarding'; 2 | 3 | export default Onboarding; 4 | -------------------------------------------------------------------------------- /src/pages/Background/types/keyrings.ts: -------------------------------------------------------------------------------- 1 | export type Keyring = { 2 | id: string | null; 3 | addresses: string[]; 4 | }; 5 | -------------------------------------------------------------------------------- /src/pages/Popup/components/origin-info/index.ts: -------------------------------------------------------------------------------- 1 | import OriginInfo from './origin-info'; 2 | 3 | export default OriginInfo; 4 | -------------------------------------------------------------------------------- /src/pages/Account/components/sign-message/index.ts: -------------------------------------------------------------------------------- 1 | import SignMessage from './sign-message'; 2 | 3 | export default SignMessage; 4 | -------------------------------------------------------------------------------- /src/pages/Account/index.ts: -------------------------------------------------------------------------------- 1 | const ActiveAccountImplementation: string = 'active'; 2 | 3 | export { ActiveAccountImplementation }; 4 | -------------------------------------------------------------------------------- /src/pages/App/components/account-info/index.ts: -------------------------------------------------------------------------------- 1 | import AccountInfo from './account-info'; 2 | 3 | export default AccountInfo; 4 | -------------------------------------------------------------------------------- /src/pages/App/pages/deploy-account/index.ts: -------------------------------------------------------------------------------- 1 | import DeployAccount from './deploy-account'; 2 | 3 | export default DeployAccount; 4 | -------------------------------------------------------------------------------- /src/pages/App/pages/keyring/index.ts: -------------------------------------------------------------------------------- 1 | import InitializeKeyring from './initialize-keyring'; 2 | 3 | export { InitializeKeyring }; 4 | -------------------------------------------------------------------------------- /src/pages/App/pages/transfer-asset/index.ts: -------------------------------------------------------------------------------- 1 | import TransferAsset from './transfer-asset'; 2 | 3 | export default TransferAsset; 4 | -------------------------------------------------------------------------------- /src/pages/Popup/components/account-info/index.ts: -------------------------------------------------------------------------------- 1 | import AccountInfo from './account-info'; 2 | 3 | export default AccountInfo; 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5", 4 | "requirePragma": false, 5 | "arrowParens": "always" 6 | } -------------------------------------------------------------------------------- /src/pages/Popup/pages/dapp-permission/index.ts: -------------------------------------------------------------------------------- 1 | import DappPermission from './dapp-permission'; 2 | 3 | export default DappPermission; 4 | -------------------------------------------------------------------------------- /src/pages/Popup/components/deploy-account/index.ts: -------------------------------------------------------------------------------- 1 | import DeployAccount from './deploy-account'; 2 | 3 | export default DeployAccount; 4 | -------------------------------------------------------------------------------- /src/pages/Popup/pages/sign-message/index.ts: -------------------------------------------------------------------------------- 1 | import SignMessageRequest from './sign-message'; 2 | 3 | export default SignMessageRequest; 4 | -------------------------------------------------------------------------------- /src/assets/img/dapp_favicon_default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eth-infinitism/trampoline/HEAD/src/assets/img/dapp_favicon_default@2x.png -------------------------------------------------------------------------------- /src/pages/App/components/account-activity/index.ts: -------------------------------------------------------------------------------- 1 | import AccountActivity from './account-activity'; 2 | 3 | export default AccountActivity; 4 | -------------------------------------------------------------------------------- /src/pages/Popup/components/sign-confirmation/index.ts: -------------------------------------------------------------------------------- 1 | import SignConfirmation from './sign-confirmation'; 2 | 3 | export default SignConfirmation; 4 | -------------------------------------------------------------------------------- /src/pages/App/components/account-balance-info/index.ts: -------------------------------------------------------------------------------- 1 | import AccountBalanceInfo from './account-balance-info'; 2 | 3 | export default AccountBalanceInfo; 4 | -------------------------------------------------------------------------------- /src/pages/App/components/transfer-asset-button/index.ts: -------------------------------------------------------------------------------- 1 | import TransferAssetButton from './transfer-asset-button'; 2 | 3 | export default TransferAssetButton; 4 | -------------------------------------------------------------------------------- /src/pages/Popup/pages/sign-transaction-request/index.ts: -------------------------------------------------------------------------------- 1 | import SignTransactionRequest from './sign-transaction-request'; 2 | 3 | export default SignTransactionRequest; 4 | -------------------------------------------------------------------------------- /utils/env.js: -------------------------------------------------------------------------------- 1 | // tiny wrapper with default env vars 2 | module.exports = { 3 | NODE_ENV: process.env.NODE_ENV || 'development', 4 | PORT: process.env.PORT || 8080, 5 | }; 6 | -------------------------------------------------------------------------------- /src/pages/Options/Options.css: -------------------------------------------------------------------------------- 1 | .OptionsContainer { 2 | width: 100%; 3 | height: 50vh; 4 | font-size: 2rem; 5 | display: flex; 6 | align-items: center; 7 | justify-content: center; 8 | } 9 | -------------------------------------------------------------------------------- /src/custom.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.svg' { 2 | const content: string; 3 | export default content; 4 | } 5 | 6 | declare module '*.png' { 7 | const content: string; 8 | export default content; 9 | } 10 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", 4 | "@babel/preset-react" 5 | // "react-app" 6 | ], 7 | "plugins": [ 8 | // "@babel/plugin-proposal-class-properties", 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /src/pages/App/hooks/redux-hooks.ts: -------------------------------------------------------------------------------- 1 | import { RootState } from '../../Background/redux-slices'; 2 | import { TypedUseSelectorHook, useSelector } from 'react-redux'; 3 | 4 | export const useBackgroundSelector: TypedUseSelectorHook = 5 | useSelector; 6 | -------------------------------------------------------------------------------- /src/pages/Popup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Popup 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/pages/Options/Options.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './Options.css'; 3 | 4 | interface Props { 5 | title: string; 6 | } 7 | 8 | const Options: React.FC = ({ title }: Props) => { 9 | return
{title} Page
; 10 | }; 11 | 12 | export default Options; 13 | -------------------------------------------------------------------------------- /src/pages/Options/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Settings 7 | 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/pages/Popup/pages/sign-message/sign-message.css: -------------------------------------------------------------------------------- 1 | .sign-message-pre-tag { 2 | white-space: pre-wrap; /* Since CSS 2.1 */ 3 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 4 | white-space: -pre-wrap; /* Opera 4-6 */ 5 | white-space: -o-pre-wrap; /* Opera 7 */ 6 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 7 | } 8 | -------------------------------------------------------------------------------- /src/pages/Background/index.ts: -------------------------------------------------------------------------------- 1 | import startMain from './main'; 2 | /** 3 | * @metamask/browser-passworder uses window.crypto and since 4 | * background script is a service worker window is not available anymore. 5 | * Below is a quick but dirty fix for now. 6 | */ 7 | // global.window = { 8 | // crypto: crypto, 9 | // }; 10 | 11 | startMain(); 12 | -------------------------------------------------------------------------------- /src/pages/Options/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import Options from './Options'; 5 | import './index.css'; 6 | 7 | const container = document.getElementById('app-container'); 8 | const root = createRoot(container); // createRoot(container!) if you use TypeScript 9 | root.render(); 10 | -------------------------------------------------------------------------------- /src/pages/Background/types/chrome-messages.ts: -------------------------------------------------------------------------------- 1 | export const AllowedQueryParamPage = { 2 | signTransaction: '/sign-transaction', 3 | dappPermission: '/dapp-permission', 4 | signData: '/sign-data', 5 | personalSignData: '/personal-sign', 6 | } as const; 7 | 8 | export type AllowedQueryParamPageType = 9 | (typeof AllowedQueryParamPage)[keyof typeof AllowedQueryParamPage]; 10 | -------------------------------------------------------------------------------- /src/pages/Account/components/transaction/index.ts: -------------------------------------------------------------------------------- 1 | import PreTransactionConfirmation from './pre-transaction-confirmation'; 2 | import TransactionConfirmation from './transaction-confirmation'; 3 | import PostTransactionConfirmation from './post-transaction-confirmation'; 4 | 5 | export { 6 | PreTransactionConfirmation, 7 | TransactionConfirmation, 8 | PostTransactionConfirmation, 9 | }; 10 | -------------------------------------------------------------------------------- /src/pages/Background/redux-slices/selectors/signingRequestSelectors.ts: -------------------------------------------------------------------------------- 1 | import { createSelector } from '@reduxjs/toolkit'; 2 | import { RootState } from '..'; 3 | 4 | const getSigningState = (state: RootState) => state.signing; 5 | 6 | export const selectCurrentPendingSignDataRequest = createSelector( 7 | getSigningState, 8 | (signing) => { 9 | return signing.signDataRequest; 10 | } 11 | ); 12 | -------------------------------------------------------------------------------- /src/pages/App/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Trampoline is a chrome extension boilerplate code to showcase your own 8 | Smart Contract Wallets 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | -------------------------------------------------------------------------------- /src/pages/Popup/pages/home/home.tsx: -------------------------------------------------------------------------------- 1 | import React, { useCallback, useEffect } from 'react'; 2 | 3 | const Home = () => { 4 | const openExpandedView = useCallback(() => { 5 | const url = chrome.runtime.getURL('app.html'); 6 | chrome.tabs.create({ 7 | url, 8 | }); 9 | }, []); 10 | 11 | useEffect(() => { 12 | openExpandedView(); 13 | }, [openExpandedView]); 14 | 15 | return
Home
; 16 | }; 17 | 18 | export default Home; 19 | -------------------------------------------------------------------------------- /contracts/Greeter.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.8.0; 3 | 4 | contract Greeter { 5 | string greeting; 6 | 7 | constructor(string memory _greeting) { 8 | greeting = _greeting; 9 | } 10 | 11 | function greet() public view returns (string memory) { 12 | return greeting; 13 | } 14 | 15 | function setGreeting(string memory _greeting) public { 16 | greeting = _greeting; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /deploy/deploy.ts: -------------------------------------------------------------------------------- 1 | import { HardhatRuntimeEnvironment } from 'hardhat/types'; 2 | import { DeployFunction } from 'hardhat-deploy/types'; 3 | 4 | const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { 5 | const accounts = await hre.getUnnamedAccounts(); 6 | await hre.deployments.deploy('Greeter', { 7 | from: accounts[0], 8 | deterministicDeployment: true, 9 | args: ['Test'], 10 | log: true, 11 | }); 12 | }; 13 | export default func; 14 | -------------------------------------------------------------------------------- /src/containers/Greetings/Greetings.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import icon from '../../assets/img/icon-128.png'; 3 | 4 | class GreetingComponent extends Component { 5 | state = { 6 | name: 'dev', 7 | }; 8 | 9 | render() { 10 | return ( 11 |
12 |

Hello, {this.state.name}!

13 | extension icon 14 |
15 | ); 16 | } 17 | } 18 | 19 | export default GreetingComponent; 20 | -------------------------------------------------------------------------------- /src/pages/Background/redux-slices/selectors/networkSelectors.ts: -------------------------------------------------------------------------------- 1 | import { createSelector } from '@reduxjs/toolkit'; 2 | import { RootState } from '..'; 3 | 4 | const getNetworkState = (state: RootState) => state.network; 5 | 6 | export const getActiveNetwork = createSelector( 7 | getNetworkState, 8 | (network) => network.activeNetwork 9 | ); 10 | 11 | export const getSupportedNetworks = createSelector( 12 | getNetworkState, 13 | (network) => network.supportedNetworks 14 | ); 15 | -------------------------------------------------------------------------------- /src/helpers/omit.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Removes a key from an object without modifying it. 3 | * 4 | * This can be an improvement over `{ ...obj, key: undefined }` since it 5 | * actually removes the key and doesn't introduce `undefined` into the type 6 | * information. 7 | */ 8 | export default function omit< 9 | Obj extends Record, 10 | K extends keyof Obj 11 | >(obj: Obj, key: K): Omit { 12 | const newObj = { ...obj }; 13 | delete newObj[key]; 14 | 15 | return newObj; 16 | } 17 | -------------------------------------------------------------------------------- /src/pages/Popup/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | background: #f2f4f6; 9 | position: relative; 10 | height: 100vh; 11 | } 12 | 13 | code { 14 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 15 | monospace; 16 | } 17 | -------------------------------------------------------------------------------- /src/helpers/ensureError.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * By convention, exceptions should always be `Error`s, but it's only a 3 | * convention, so we don't actually get any type information on exceptions. 4 | * This functions wraps an exception and just returns it unchanged if it's 5 | * an `Error`, otherwise it wraps it in an `Error`. 6 | */ 7 | export default function ensureError(e: E): E extends Error ? E : Error { 8 | if (e instanceof Error) { 9 | return e as E extends Error ? E : Error; 10 | } 11 | 12 | return new Error( 13 | `Wrapped original non-error exception: ${JSON.stringify(e)}`, 14 | ) as E extends Error ? E : Error; 15 | } 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": false, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "module": "CommonJS", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "noEmit": false, 16 | "jsx": "react", 17 | "typeRoots": ["./src/types"] 18 | }, 19 | "include": ["src", "deploy"], 20 | "exclude": ["build", "node_modules", "dist"], 21 | "files": ["./hardhat.config.ts"] 22 | } 23 | -------------------------------------------------------------------------------- /src/pages/App/index.css: -------------------------------------------------------------------------------- 1 | /* 2 | Josh's Custom CSS Reset 3 | https://www.joshwcomeau.com/css/custom-css-reset/ 4 | */ 5 | *, 6 | *::before, 7 | *::after { 8 | box-sizing: border-box; 9 | } 10 | * { 11 | margin: 0; 12 | } 13 | html, 14 | body { 15 | height: 100%; 16 | background: #f2f4f6; 17 | } 18 | body { 19 | line-height: 1.5; 20 | -webkit-font-smoothing: antialiased; 21 | } 22 | img, 23 | picture, 24 | video, 25 | canvas, 26 | svg { 27 | display: block; 28 | max-width: 100%; 29 | } 30 | input, 31 | button, 32 | textarea, 33 | select { 34 | font: inherit; 35 | } 36 | p, 37 | h1, 38 | h2, 39 | h3, 40 | h4, 41 | h5, 42 | h6 { 43 | overflow-wrap: break-word; 44 | } 45 | #root, 46 | #__next { 47 | isolation: isolate; 48 | } 49 | -------------------------------------------------------------------------------- /src/pages/App/pages/onboarding/onboarding.tsx: -------------------------------------------------------------------------------- 1 | import { Container } from '@mui/material'; 2 | import React, { useEffect } from 'react'; 3 | import { redirect } from 'react-router-dom'; 4 | import { getAddressCount } from '../../../Background/redux-slices/selectors/accountSelectors'; 5 | import { useBackgroundSelector } from '../../hooks'; 6 | import Intro from './intro'; 7 | 8 | const Onboarding = () => { 9 | const hasAccounts = useBackgroundSelector( 10 | (state) => getAddressCount(state) > 0 11 | ); 12 | 13 | useEffect(() => { 14 | if (hasAccounts) { 15 | redirect('/'); 16 | } 17 | }, [hasAccounts]); 18 | 19 | return ( 20 | 21 | 22 | 23 | ); 24 | }; 25 | 26 | export default Onboarding; 27 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "Trampoline Example", 4 | "description": "Trampoline is a chrome extension boilerplate code to showcase your own Smart Contract Wallets", 5 | "options_page": "options.html", 6 | "background": { 7 | "persistent": true, 8 | "scripts": ["ex_background.bundle.js"] 9 | }, 10 | "browser_action": { 11 | "default_title": "Taho", 12 | "default_icon": "icon-34.png", 13 | "default_popup": "popup.html" 14 | }, 15 | "icons": { 16 | "128": "icon-128.png" 17 | }, 18 | "content_scripts": [ 19 | { 20 | "matches": ["http://*/*", "https://*/*", ""], 21 | "js": ["ex_contentScript.bundle.js"] 22 | } 23 | ], 24 | "web_accessible_resources": ["popup.html", "*.js", "*.json"] 25 | } 26 | -------------------------------------------------------------------------------- /src/pages/Background/constants/constants.ts: -------------------------------------------------------------------------------- 1 | import AccountApi from '../../Account/account-api'; 2 | import { AccountImplementationType } from '../../Account/account-api/types'; 3 | import { ActiveAccountImplementation } from '../../Account/'; 4 | 5 | const AccountImplementation: AccountImplementationType = AccountApi; 6 | 7 | const AccountImplementations: { 8 | [name: string]: AccountImplementationType; 9 | } = { 10 | [ActiveAccountImplementation]: AccountImplementation, 11 | }; 12 | 13 | export const PROVIDER_BRIDGE_TARGET = 'aa-extension-provider-bridge'; 14 | export const WINDOW_PROVIDER_TARGET = 'aa-extension-window-provider'; 15 | export const EXTERNAL_PORT_NAME = 'aa-extension-external'; 16 | 17 | export const AA_EXTENSION_CONFIG = 'aa-extension_getConfig'; 18 | 19 | export { ActiveAccountImplementation, AccountImplementations }; 20 | -------------------------------------------------------------------------------- /src/pages/Account/components/transaction/post-transaction-confirmation.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import { 3 | PostTransactionConfirmation, 4 | PostTransactionConfirmationtProps, 5 | } from '../types'; 6 | import { CircularProgress, Container } from '@mui/material'; 7 | 8 | const PostTransactionConfirmationComponent: PostTransactionConfirmation = ({ 9 | onComplete, 10 | }: PostTransactionConfirmationtProps) => { 11 | useEffect(() => { 12 | onComplete(); 13 | }, [onComplete]); 14 | return ( 15 | 23 | 24 | 25 | ); 26 | }; 27 | 28 | export default PostTransactionConfirmationComponent; 29 | -------------------------------------------------------------------------------- /src/pages/Account/components/PrimaryButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { useCallback, useState } from 'react'; 2 | 3 | import { Button } from '@mui/material'; 4 | import { ComponentProps } from 'react'; 5 | import useOnWindowEnter from '../../App/hooks/onWindowEnter'; 6 | 7 | /** `Button` wrapper which is auto-clicked when the user presses enter. */ 8 | const PrimaryButton = (props: ComponentProps) => { 9 | const [ref, setRef] = useState(null); 10 | const click = useCallback(() => ref?.click(), [ref]); 11 | useOnWindowEnter(click); 12 | 13 | return ( 14 |