├── .afterAllArtifactBuild.js ├── .afterPack.js ├── .eslintrc.js ├── .github ├── ISSUE_TEMPLATE │ ├── bug-report.md │ ├── config.yml │ └── feature-idea.md └── workflows │ ├── release.yml │ ├── sign_and_release.yml │ └── test.yml ├── .gitignore ├── .npmrc ├── .nvmrc ├── .prettierrc.js ├── .vscode └── settings.json ├── LICENSE ├── PRIVACY.md ├── README.md ├── alephium-wallet.nix ├── assets └── icon.png ├── default.nix ├── index.html ├── license-header.js ├── locales ├── bg-BG │ └── translation.json ├── de-DE │ └── translation.json ├── en-US │ └── translation.json ├── es-ES │ └── translation.json ├── fr-FR │ └── translation.json ├── id-ID │ └── translation.json ├── it-IT │ └── translation.json ├── pt-PT │ └── translation.json ├── ru-RU │ └── translation.json ├── tr-TR │ └── translation.json └── vi-VN │ └── translation.json ├── package-lock.json ├── package.json ├── public ├── electron.js ├── favicon.ico ├── icons │ ├── apple-touch-icon.png │ ├── logo-192.png │ ├── logo-32.png │ ├── logo-48.png │ └── logo-512.png ├── preload.js └── robots.txt ├── scripts └── syncTranslationFiles.js ├── shell.nix ├── src ├── App.tsx ├── animations │ └── index.ts ├── api │ ├── addresses.ts │ ├── client.ts │ ├── fetchRetry.ts │ └── transactions.ts ├── components │ ├── ActionLink.tsx │ ├── AddressBadge.tsx │ ├── AddressColorIndicator.tsx │ ├── AddressMetadataForm.tsx │ ├── AddressRow.tsx │ ├── AlefSymbol.tsx │ ├── Amount.tsx │ ├── AppHeader.tsx │ ├── AppSpinner.tsx │ ├── AssetBadge.tsx │ ├── AssetLogo.tsx │ ├── Badge.tsx │ ├── Banner.tsx │ ├── Box.tsx │ ├── Button.tsx │ ├── Buttons │ │ ├── ClipboardButton.tsx │ │ ├── DeleteButton.tsx │ │ ├── FooterButton.tsx │ │ └── ShortcutButtons.tsx │ ├── Card.tsx │ ├── Card3D.tsx │ ├── CheckMark.tsx │ ├── CursorHighlight.tsx │ ├── DataList.tsx │ ├── DefaultAddressSwitch.tsx │ ├── DeltaPercentage.tsx │ ├── Dividers │ │ └── HorizontalDivider.tsx │ ├── DotIcon.tsx │ ├── Ellipsed.tsx │ ├── ExpandableSection.tsx │ ├── FloatingLogo.tsx │ ├── FocusableContent.tsx │ ├── HashEllipsed.tsx │ ├── HiddenLabel.tsx │ ├── HistoricWorthChart.tsx │ ├── IOList.tsx │ ├── InfoBox.tsx │ ├── InfoMessage.tsx │ ├── InputFieldsColumn.tsx │ ├── Inputs │ │ ├── AddressSelect.tsx │ │ ├── ColorPicker.tsx │ │ ├── ColoredLabelInput.tsx │ │ ├── CompactToggle.tsx │ │ ├── InlineLabelValueInput.tsx │ │ ├── Input.tsx │ │ ├── InputArea.tsx │ │ ├── MultiSelect.tsx │ │ ├── Option.tsx │ │ ├── Select.tsx │ │ ├── SelectOptionAddress.tsx │ │ ├── SelectOptionAsset.tsx │ │ ├── SelectOptionItemContent.tsx │ │ ├── TextAreaTags.tsx │ │ ├── Toggle.tsx │ │ ├── WalletPassphrase.tsx │ │ └── index.tsx │ ├── Lock.tsx │ ├── NFTCard.tsx │ ├── NFTThumbnail.tsx │ ├── NavItem.tsx │ ├── NetworkSwitch.tsx │ ├── PageComponents │ │ ├── PageContainers.tsx │ │ ├── PageHeadings.tsx │ │ ├── PanelTitle.tsx │ │ ├── SideBar.tsx │ │ └── VerticalDivider.tsx │ ├── Paragraph.tsx │ ├── PasswordConfirmation.tsx │ ├── Popup.tsx │ ├── QRCode.tsx │ ├── Scrollbar.tsx │ ├── SkeletonLoader.tsx │ ├── SnackbarManager.tsx │ ├── Spinner.tsx │ ├── SplashScreen.tsx │ ├── TabBar.tsx │ ├── Table.tsx │ ├── TableCellAmount.tsx │ ├── TableTabBar.tsx │ ├── ThemeSwitcher.tsx │ ├── TimeSince.tsx │ ├── ToggleSection.tsx │ ├── Tooltip.tsx │ ├── Tooltips.tsx │ ├── TransactionList.tsx │ ├── TransactionalInfo.tsx │ ├── Truncate.tsx │ ├── UpdateWalletBanner.tsx │ └── WalletSwitcher.tsx ├── contexts │ ├── analytics.tsx │ ├── global.tsx │ ├── scroll.tsx │ ├── steps.tsx │ ├── wallet.tsx │ └── walletconnect.tsx ├── hooks │ ├── redux.ts │ ├── useAddressGeneration.tsx │ ├── useAnimationFrame.ts │ ├── useFocusOnMount.tsx │ ├── useGasSettings.tsx │ ├── useIdleForTooLong.ts │ ├── useLatestGitHubRelease.ts │ ├── useStateObject.ts │ └── useTransactionUI.tsx ├── i18n.ts ├── images │ ├── alef.svg │ ├── alephium_logo_light.svg │ ├── alephium_logo_monochrome.svg │ ├── athmospheric_glow.svg │ ├── brand-icon-discord.svg │ ├── brand-icon-github.svg │ ├── brand-icon-twitter.svg │ ├── dot.svg │ ├── lock_body.svg │ ├── lock_handle.svg │ ├── logotype.svg │ ├── main_address_badge.svg │ ├── mountain.svg │ ├── ribbon.svg │ └── wallet-connect-logo.svg ├── index.css ├── index.tsx ├── modals │ ├── AddressDetailsModal.tsx │ ├── AddressOptionsModal.tsx │ ├── AddressSweepModal.tsx │ ├── BottomModal.tsx │ ├── CSVExportModal.tsx │ ├── CenteredModal.tsx │ ├── ConfirmModal.tsx │ ├── ConsolidateUTXOsModal.tsx │ ├── ContactFormModal.tsx │ ├── ModalContainer.tsx │ ├── ModalPortal.tsx │ ├── NewAddressModal.tsx │ ├── NotificationsModal.tsx │ ├── ReceiveModal.tsx │ ├── SecretPhraseModal.tsx │ ├── SendModals │ │ ├── AddressInputs.tsx │ │ ├── AlphAmountInfoBox.tsx │ │ ├── AssetAmountsInput.tsx │ │ ├── CallContract │ │ │ ├── AddressesTxModalContent.tsx │ │ │ ├── BuildTxModalContent.tsx │ │ │ ├── CheckTxModalContent.tsx │ │ │ └── index.tsx │ │ ├── CheckAddressesBox.tsx │ │ ├── CheckAmountsBox.tsx │ │ ├── CheckFeeLockTimeBox.tsx │ │ ├── CheckModalContent.tsx │ │ ├── DeployContract │ │ │ ├── AddressesTxModalContent.tsx │ │ │ ├── BuildTxModalContent.tsx │ │ │ ├── CheckTxModalContent.tsx │ │ │ └── index.tsx │ │ ├── GasSettings.tsx │ │ ├── InfoRow.tsx │ │ ├── InputsSection.tsx │ │ ├── SendModal.tsx │ │ ├── StepsProgress.tsx │ │ └── Transfer │ │ │ ├── AddressesTxModalContent.tsx │ │ │ ├── BuildTxModalContent.tsx │ │ │ ├── CheckTxModalContent.tsx │ │ │ └── index.tsx │ ├── SettingsModal │ │ ├── DevToolsSettingsSection.tsx │ │ ├── EditWalletNameModal.tsx │ │ ├── GeneralSettingsSection.tsx │ │ ├── NetworkSettingsSection.tsx │ │ ├── WalletsSettingsSection.tsx │ │ └── index.tsx │ ├── SideModal.tsx │ ├── SignUnsignedTx │ │ └── index.tsx │ ├── TransactionDetailsModal.tsx │ ├── UpdateWalletModal.tsx │ ├── WalletConnectModal.tsx │ ├── WalletConnectModal │ │ └── DAppMetadataBoxProps.tsx │ ├── WalletQRCodeExportModal.tsx │ └── WalletRemovalModal.tsx ├── pages │ ├── HomePage │ │ ├── NewWalletActions.tsx │ │ ├── UnlockPanel.tsx │ │ └── index.tsx │ ├── LockedWalletLayout.tsx │ ├── NewWallet │ │ ├── CheckWordsIntroPage.tsx │ │ ├── CheckWordsPage.tsx │ │ ├── CreateWalletPage.tsx │ │ ├── ImportWordsPage.tsx │ │ ├── NewWalletLayout.tsx │ │ ├── WalletWelcomePage.tsx │ │ └── WalletWordsPage.tsx │ └── UnlockedWallet │ │ ├── AddressesPage │ │ ├── AddressGridRow.tsx │ │ ├── AddressesTabContent.tsx │ │ ├── AdvancedOperationsSideModal.tsx │ │ ├── ContactsTabContent.tsx │ │ ├── OperationBox.tsx │ │ ├── TabContent.tsx │ │ └── index.tsx │ │ ├── OverviewPage │ │ ├── AddressesContactsList.tsx │ │ ├── AmountsOverviewPanel.tsx │ │ ├── AssetsList.tsx │ │ ├── GreetingMessages.tsx │ │ ├── TimeOfDayMessage.tsx │ │ └── index.tsx │ │ ├── TransfersPage │ │ ├── FiltersPanel.tsx │ │ └── index.tsx │ │ ├── UnlockedWalletLayout.tsx │ │ └── UnlockedWalletPage.tsx ├── routes │ ├── UnlockedWalletRoutes.tsx │ └── index.tsx ├── serviceWorker.js ├── setupTests.js ├── storage │ ├── addresses │ │ ├── addressMetadataPersistentStorage.ts │ │ ├── addressesActions.ts │ │ ├── addressesAdapters.ts │ │ ├── addressesSelectors.ts │ │ ├── addressesSlice.ts │ │ ├── addressesStorageUtils.ts │ │ ├── contactsPersistentStorage.ts │ │ └── contactsSlice.ts │ ├── analytics │ │ └── analyticsPersistentStorage.ts │ ├── assets │ │ ├── assetsActions.ts │ │ ├── assetsAdapter.ts │ │ ├── assetsInfoSlice.ts │ │ ├── assetsSelectors.ts │ │ ├── nftsSlice.tsx │ │ └── priceApiSlice.ts │ ├── auth │ │ └── authActions.ts │ ├── dApps │ │ └── dAppActions.ts │ ├── encryptedPersistentStorage.ts │ ├── global │ │ ├── globalActions.ts │ │ ├── globalSlice.ts │ │ └── snackbarSlice.ts │ ├── settings │ │ ├── networkActions.ts │ │ ├── networkSlice.ts │ │ ├── settingsActions.ts │ │ ├── settingsPersistentStorage.ts │ │ ├── settingsSlice.ts │ │ └── settingsStorageUtils.ts │ ├── statelessEncryptedPersistentStorage.ts │ ├── store.ts │ ├── transactions │ │ ├── confirmedTransactionsSlice.ts │ │ ├── pendingTransactionsPersistentStorage.ts │ │ ├── pendingTransactionsSlice.ts │ │ ├── transactionsActions.ts │ │ ├── transactionsAdapters.ts │ │ ├── transactionsSelectors.ts │ │ ├── transactionsStorageUtils.ts │ │ └── transactionsUtils.ts │ └── wallets │ │ ├── activeWalletSlice.ts │ │ ├── walletActions.ts │ │ ├── walletPersistentStorage.ts │ │ └── walletStorageUtils.ts ├── style │ ├── fonts │ │ ├── Inter.var.woff2 │ │ └── RobotoMono-var.ttf │ ├── globalStyles.ts │ ├── resets.ts │ ├── tags.ts │ └── themes.ts ├── tests │ ├── App.test.tsx │ ├── fixtures │ │ ├── address.json │ │ ├── transactions.json │ │ └── wallet.json │ ├── index.tsx │ ├── links.test.ts │ ├── migration.test.ts │ ├── pages │ │ └── HomePage.test.tsx │ └── settings.test.ts ├── types │ ├── addresses.ts │ ├── assets.ts │ ├── chart.ts │ ├── components.d.ts │ ├── contacts.ts │ ├── i18next.d.ts │ ├── network.ts │ ├── numbers.d.ts │ ├── settings.d.ts │ ├── snackbar.ts │ ├── transactions.ts │ ├── wallet.ts │ └── window.d.ts ├── utils │ ├── addresses.ts │ ├── app-data.ts │ ├── bip39.ts │ ├── colors.ts │ ├── constants.ts │ ├── contacts.ts │ ├── csvExport.ts │ ├── currencies.ts │ ├── form-validation.ts │ ├── hooks.ts │ ├── links.ts │ ├── migration.ts │ ├── misc.ts │ ├── pointer.ts │ ├── settings.ts │ ├── transactions.ts │ └── wallet.ts ├── vite-env.d.ts └── workers │ ├── addressDiscovery.ts │ ├── deriveAddressesFromIndexes.ts │ └── deriveAddressesInGroups.ts ├── tsconfig.json └── vite.config.ts /.afterAllArtifactBuild.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 - 2023 The Alephium Authors 2 | // This file is part of the alephium project. 3 | // 4 | // The library is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Lesser General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // The library is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Lesser General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Lesser General Public License 15 | // along with the library. If not, see . 16 | 17 | const crypto = require('crypto') 18 | const fs = require('fs') 19 | const path = require('path') 20 | 21 | function getFileChecksum(path) { 22 | return new Promise((resolve, reject) => { 23 | const hash = crypto.createHash('sha256') 24 | 25 | fs.createReadStream(path) 26 | .on('error', reject) 27 | .on('data', (chunk) => hash.update(chunk)) 28 | .on('close', () => resolve(hash.digest('hex'))) 29 | }) 30 | } 31 | 32 | exports.default = async function ({ artifactPaths }) { 33 | const checksums = [] 34 | 35 | for (let i = 0; i < artifactPaths.length; i++) { 36 | const artifactPath = artifactPaths[i] 37 | 38 | if (!artifactPath.endsWith('.blockmap') && !artifactPath.endsWith('.snap') && !artifactPath.endsWith('.zip')) { 39 | const checksumFilePath = `${artifactPath}.checksum` 40 | const checksum = await getFileChecksum(artifactPath) 41 | 42 | fs.writeFileSync(checksumFilePath, `${checksum} ${path.parse(artifactPath).base}`) 43 | 44 | checksums.push(checksumFilePath) 45 | } 46 | } 47 | 48 | return checksums 49 | } 50 | -------------------------------------------------------------------------------- /.afterPack.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 - 2023 The Alephium Authors 2 | // This file is part of the alephium project. 3 | // 4 | // The library is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Lesser General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // The library is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Lesser General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Lesser General Public License 15 | // along with the library. If not, see . 16 | 17 | // The hook is a temporary fix to set the right icon size for the deb archive. 18 | // The hook only applies to the `deb` target. 19 | // The hook will set the icon size to 512 for all icons with a size of 0. 20 | // The hook can be removed once: 21 | // 1. The proper fix (https://github.com/develar/app-builder/pull/71) is merged. 22 | // 2. New versions of app-builder and app-builder-bin are released. 23 | // 3. A version of electron-builder with the fixed app-builder-bin is released. 24 | // 4. The electron-builder dev dependency is updated. 25 | exports.default = async function (context) { 26 | context.targets.forEach((target) => { 27 | if (target.name !== 'deb') { 28 | return 29 | } 30 | 31 | target.helper.iconPromise.value = target.helper.iconPromise.value.then((icons) => 32 | icons.map((icon) => ({ ...icon, size: icon.size === 0 ? 512 : icon.size })) 33 | ) 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F41B Bug report" 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Environment** 27 | - OS: [e.g. Windows] 28 | - Version [e.g. 1.0.1] 29 | 30 | **Additional context** 31 | Add any other context about the problem here. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: 🤔 Questions and Help 3 | url: https://discord.gg/dT3hDTtABD 4 | about: This issue tracker is not for support questions. Please refer to the Alephium community's Discord. 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-idea.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F3A8 Feature idea" 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | 8 | jobs: 9 | unit-tests: 10 | runs-on: ubuntu-latest 11 | 12 | strategy: 13 | matrix: 14 | node-version: [16] 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Use Node.js ${{ matrix.node-version }} 19 | uses: actions/setup-node@v1 20 | with: 21 | node-version: ${{ matrix.node-version }} 22 | - run: npm ci 23 | - run: npm run lint 24 | - run: npm audit --production 25 | - run: npm test 26 | 27 | electron-tests: 28 | runs-on: ${{ matrix.os }} 29 | strategy: 30 | matrix: 31 | os: [macos-latest, windows-latest, ubuntu-latest] 32 | steps: 33 | - uses: actions/checkout@v2 34 | - id: get-os 35 | run: | 36 | os=$(echo ${{ matrix.os }} | cut -d- -f1) 37 | echo "::set-output name=os::$os" 38 | shell: bash 39 | - run: echo "${{ steps.get-os.outputs.os }}" 40 | shell: bash 41 | - name: Use Node.js 42 | uses: actions/setup-node@v1 43 | with: 44 | node-version: '16.x' 45 | - run: npm ci 46 | shell: bash 47 | - run: npm run-script electron-pack-${{ steps.get-os.outputs.os }} 48 | shell: bash 49 | env: 50 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | dist 3 | node_modules 4 | .DS_Store 5 | alephium-*.zip 6 | coverage 7 | .env 8 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v16 2 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: false, 3 | trailingComma: 'none', 4 | singleQuote: true, 5 | printWidth: 120, 6 | tabWidth: 2 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "typescript.preferences.importModuleSpecifier": "non-relative", 4 | "editor.codeActionsOnSave": { 5 | "source.fixAll.eslint": true 6 | }, 7 | "eslint.validate": ["javascript", "typescript"], 8 | "cSpell.language": "en,fr" 9 | } 10 | -------------------------------------------------------------------------------- /PRIVACY.md: -------------------------------------------------------------------------------- 1 | # Alephium privacy policy 2 | 3 | Last Updated: June 05, 2020 4 | 5 | Alephium recognizes that people who use Alephium value their privacy. This privacy policy (“Policy”) describes how Alephium (“Company”, “we”, “our”, or “us”) collects, uses, shares, and stores personal information of users of our website, extension and our mobile application, (collectively the “Site”). This Policy applies to the Site, applications, products and services (collectively, “Services”) on or in which it is posted, linked, or referenced. 6 | 7 | By using the Services, you accept the terms of this Policy and our Terms of Use, and consent to our collection, use, disclosure, and retention of your information as described in this Policy. If you have not done so already, please also review our terms of use. The terms of use contain provisions that limit our liability to you and require you to resolve any dispute with us on an individual basis and not as part of any class or representative action. IF YOU DO NOT AGREE WITH ANY PART OF THIS PRIVACY POLICY OR OUR TERMS OF USE, THEN PLEASE DO NOT USE ANY OF THE SERVICES. 8 | 9 | Please note that this Policy does not apply to information collected through third-party websites or services that you may access through the Services or that you submit to us through email, text message or other electronic message or offline. 10 | 11 | ## WHAT WE COLLECT 12 | 13 | We do not collect any personal information. 14 | -------------------------------------------------------------------------------- /alephium-wallet.nix: -------------------------------------------------------------------------------- 1 | { lib, stdenv , fetchurl , appimageTools , makeWrapper , electron }: 2 | 3 | appimageTools.wrapType1 rec { 4 | name = "alephium-wallet"; 5 | version = "2.0.2"; 6 | 7 | src = fetchurl { 8 | url = "https://github.com/alephium/desktop-wallet/releases/download/v${version}/Alephium-${version}.AppImage"; 9 | sha256 = "9853c2aafa3b608a4f2f623129accb499ba25a1201ecb82c7a4c773d6a51f65b"; 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alephium/desktop-wallet/91f03586f36c4d76fed0a94ac4c4824c17df9a88/assets/icon.png -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | with import {}; { 2 | sdlEnv = stdenv.mkDerivation { 3 | name = "alephium-wallet"; 4 | shellHook = '' 5 | ''; 6 | buildInputs = [ 7 | python nodejs electron 8 | ]; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 15 | 16 | Alephium Wallet 17 | 18 | 19 | 20 |
21 | 22 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /license-header.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alephium/desktop-wallet/91f03586f36c4d76fed0a94ac4c4824c17df9a88/public/favicon.ico -------------------------------------------------------------------------------- /public/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alephium/desktop-wallet/91f03586f36c4d76fed0a94ac4c4824c17df9a88/public/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /public/icons/logo-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alephium/desktop-wallet/91f03586f36c4d76fed0a94ac4c4824c17df9a88/public/icons/logo-192.png -------------------------------------------------------------------------------- /public/icons/logo-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alephium/desktop-wallet/91f03586f36c4d76fed0a94ac4c4824c17df9a88/public/icons/logo-32.png -------------------------------------------------------------------------------- /public/icons/logo-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alephium/desktop-wallet/91f03586f36c4d76fed0a94ac4c4824c17df9a88/public/icons/logo-48.png -------------------------------------------------------------------------------- /public/icons/logo-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alephium/desktop-wallet/91f03586f36c4d76fed0a94ac4c4824c17df9a88/public/icons/logo-512.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /scripts/syncTranslationFiles.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | const glob = require('glob') 20 | const fs = require('fs') 21 | 22 | const sourceOfTruthFile = 'locales/en-US/translation.json' 23 | 24 | const sync = () => { 25 | const source = JSON.parse(fs.readFileSync(sourceOfTruthFile, { encoding: 'utf-8' })) 26 | const allTranslationFiles = glob.sync('locales/**/*.json').filter((path) => path !== sourceOfTruthFile) 27 | 28 | allTranslationFiles.forEach((filepath) => { 29 | try { 30 | const data = JSON.parse(fs.readFileSync(filepath, { encoding: 'utf-8' })) 31 | const newData = {} 32 | 33 | Object.keys(data).forEach((key) => { 34 | if (source[key]) newData[key] = data[key] 35 | }) 36 | 37 | Object.keys(source).forEach((key) => { 38 | if (!newData[key]) newData[key] = source[key] 39 | }) 40 | 41 | fs.writeFileSync(filepath, JSON.stringify(newData, null, 2)) // Null and 2 arguments to format the JSON in the file 42 | } catch (e) { 43 | console.error('Error occurred while parsing file "' + filepath + '"') 44 | } 45 | }) 46 | } 47 | 48 | sync() 49 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | with import {}; 2 | let 3 | alephium-wallet = pkgs.callPackage ./alephium-wallet.nix {}; 4 | in 5 | pkgs.mkShell { 6 | name = "alephium-wallet"; 7 | buildInputs = [ alephium-wallet ]; 8 | } 9 | -------------------------------------------------------------------------------- /src/animations/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | const transition = { duration: 0.3 } 20 | 21 | export const fadeIn = { 22 | initial: { opacity: 0 }, 23 | animate: { opacity: 1 }, 24 | transition 25 | } 26 | 27 | export const fadeOut = { 28 | exit: { opacity: 0 }, 29 | transition 30 | } 31 | 32 | export const fadeInOut = { 33 | ...fadeIn, 34 | ...fadeOut 35 | } 36 | 37 | export const fadeInBottom = { 38 | initial: { opacity: 0, y: 10 }, 39 | animate: { opacity: 1, y: 0 }, 40 | transition 41 | } 42 | 43 | export const slowTransition = { 44 | transition: { duration: 0.8 } 45 | } 46 | 47 | export const fastTransition = { 48 | transition: { type: 'spring', damping: 40, stiffness: 500 } 49 | } 50 | 51 | export const fadeInSlowly = { 52 | ...fadeIn, 53 | ...slowTransition 54 | } 55 | 56 | export const fadeOutFast = { 57 | ...fadeOut, 58 | ...fastTransition 59 | } 60 | 61 | export const fadeInOutFast = { 62 | ...fadeInOut, 63 | ...fastTransition 64 | } 65 | 66 | export const fadeInOutScaleFast = { 67 | initial: { opacity: 0, scale: 0.9 }, 68 | animate: { opacity: 1, scale: 1 }, 69 | exit: { opacity: 0, scale: 0.95 }, 70 | ...fastTransition 71 | } 72 | -------------------------------------------------------------------------------- /src/api/client.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { ExplorerProvider, NodeProvider } from '@alephium/web3' 20 | 21 | import { exponentialBackoffFetchRetry } from '@/api/fetchRetry' 22 | import { defaultSettings } from '@/storage/settings/settingsPersistentStorage' 23 | import { NetworkSettings } from '@/types/settings' 24 | 25 | export class Client { 26 | explorer: ExplorerProvider 27 | node: NodeProvider 28 | 29 | constructor() { 30 | const { nodeHost, explorerApiHost } = defaultSettings.network 31 | const { explorer, node } = this.getClients(nodeHost, explorerApiHost) 32 | 33 | this.explorer = explorer 34 | this.node = node 35 | } 36 | 37 | init(nodeHost: NetworkSettings['nodeHost'], explorerApiHost: NetworkSettings['explorerApiHost']) { 38 | const { explorer, node } = this.getClients(nodeHost, explorerApiHost) 39 | 40 | this.explorer = explorer 41 | this.node = node 42 | } 43 | 44 | private getClients(nodeHost: NetworkSettings['nodeHost'], explorerApiHost: NetworkSettings['explorerApiHost']) { 45 | return { 46 | explorer: new ExplorerProvider(explorerApiHost, undefined, exponentialBackoffFetchRetry), 47 | node: new NodeProvider(nodeHost, undefined, exponentialBackoffFetchRetry) 48 | } 49 | } 50 | } 51 | 52 | const client = new Client() 53 | 54 | export default client 55 | -------------------------------------------------------------------------------- /src/api/fetchRetry.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import fetchRetry from 'fetch-retry' 20 | 21 | export const exponentialBackoffFetchRetry = fetchRetry(fetch, { 22 | retryOn: [429], 23 | retries: 10, 24 | retryDelay: (attempt) => Math.pow(2, attempt) * 1000 25 | }) 26 | -------------------------------------------------------------------------------- /src/api/transactions.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { transactionSign } from '@alephium/web3' 20 | 21 | import client from '@/api/client' 22 | import { Address, AddressHash } from '@/types/addresses' 23 | import { CsvExportQueryParams } from '@/types/transactions' 24 | 25 | export const buildSweepTransactions = async (fromAddress: Address, toAddressHash: AddressHash) => { 26 | const { unsignedTxs } = await client.node.transactions.postTransactionsSweepAddressBuild({ 27 | fromPublicKey: fromAddress.publicKey, 28 | toAddress: toAddressHash 29 | }) 30 | 31 | return { 32 | unsignedTxs, 33 | fees: unsignedTxs.reduce((acc, tx) => acc + BigInt(tx.gasPrice) * BigInt(tx.gasAmount), BigInt(0)) 34 | } 35 | } 36 | 37 | export const signAndSendTransaction = async (fromAddress: Address, txId: string, unsignedTx: string) => { 38 | const signature = transactionSign(txId, fromAddress.privateKey) 39 | const data = await client.node.transactions.postTransactionsSubmit({ unsignedTx, signature }) 40 | 41 | return { ...data, signature } 42 | } 43 | 44 | export const fetchCsv = async ({ addressHash, ...timeRangeQueryParams }: CsvExportQueryParams) => 45 | await client.explorer.addresses.getAddressesAddressExportTransactionsCsv(addressHash, timeRangeQueryParams, { 46 | format: 'text' 47 | }) 48 | -------------------------------------------------------------------------------- /src/components/ActionLink.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { colord } from 'colord' 20 | import styled, { css } from 'styled-components' 21 | 22 | import { HasTooltip } from '@/components/Tooltip' 23 | 24 | interface ActionLinkProps { 25 | onClick: () => void 26 | Icon?: LucideIconType 27 | iconPosition?: 'right' | 'left' 28 | withBackground?: boolean 29 | className?: string 30 | } 31 | 32 | const ActionLink: FC> = ({ className, Icon, children, onClick, tooltip }) => ( 33 | 41 | ) 42 | 43 | export default styled(ActionLink)` 44 | color: ${({ theme }) => theme.global.accent}; 45 | cursor: pointer; 46 | display: inline-flex; 47 | align-items: center; 48 | font-size: inherit; 49 | font-weight: inherit; 50 | flex-direction: ${({ iconPosition }) => (iconPosition === 'left' ? 'row-reverse' : 'row')}; 51 | gap: 5px; 52 | padding: 0; 53 | 54 | &:hover { 55 | color: ${({ theme }) => colord(theme.global.accent).darken(0.1).toRgbString()}; 56 | } 57 | 58 | &:focus-visible { 59 | text-decoration: underline; 60 | } 61 | 62 | ${({ withBackground }) => 63 | withBackground && 64 | css` 65 | background-color: ${({ theme }) => theme.bg.accent}; 66 | padding: 8px; 67 | border-radius: var(--radius-medium); 68 | `} 69 | ` 70 | 71 | const IconContainer = styled.div` 72 | display: flex; 73 | ` 74 | -------------------------------------------------------------------------------- /src/components/AddressRow.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | import AddressBadge from '@/components/AddressBadge' 22 | import AddressColorIndicator from '@/components/AddressColorIndicator' 23 | import { TableRow } from '@/components/Table' 24 | import { Address } from '@/types/addresses' 25 | 26 | interface AddressRowProps { 27 | address: Address 28 | disableAddressCopy?: boolean 29 | onClick?: (address: Address) => void 30 | className?: string 31 | } 32 | 33 | const AddressRow: FC = ({ address, disableAddressCopy, onClick, children, className }) => ( 34 | onClick && onClick(address)} 39 | onKeyPress={() => onClick && onClick(address)} 40 | className={className} 41 | > 42 | 43 | 44 | 47 | {children} 48 | 49 | 50 | ) 51 | 52 | export default AddressRow 53 | 54 | const Row = styled.div` 55 | display: flex; 56 | align-items: center; 57 | flex-grow: 1; 58 | gap: 15px; 59 | ` 60 | 61 | const Label = styled.div` 62 | font-size: 14px; 63 | font-weight: var(--fontWeight-medium); 64 | max-width: 200px; 65 | min-width: 0; 66 | ` 67 | -------------------------------------------------------------------------------- /src/components/AlefSymbol.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | import alefSymbol from '@/images/alef.svg' 22 | 23 | interface AlefSymbolProps { 24 | color?: string 25 | className?: string 26 | } 27 | 28 | const AlefSymbol = ({ className, color }: AlefSymbolProps) => ( 29 | 30 |  ALPH 31 | 32 | 33 | ) 34 | 35 | export default styled(AlefSymbol)` 36 | height: 1em; 37 | ` 38 | 39 | const HiddenForCopying = styled.span` 40 | font-size: 0; 41 | ` 42 | 43 | const AlefSymbolSVG = styled.span<{ color?: string }>` 44 | display: inline-block; 45 | font-size: 1em; 46 | width: 1em; 47 | height: 1em; 48 | -webkit-mask: url(${alefSymbol}) no-repeat 100% 100%; 49 | mask: url(${alefSymbol}) no-repeat 100% 100%; 50 | -webkit-mask-size: cover; 51 | mask-size: cover; 52 | background-color: ${({ color, theme }) => color || theme.font.primary}; 53 | ` 54 | -------------------------------------------------------------------------------- /src/components/AppSpinner.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | import Spinner from '@/components/Spinner' 22 | 23 | interface AppSpinnerProps { 24 | className?: string 25 | } 26 | 27 | const AppSpinner = ({ className }: AppSpinnerProps) => ( 28 |
29 | 30 |
31 | ) 32 | 33 | export default styled(AppSpinner)` 34 | position: absolute; 35 | top: 0; 36 | bottom: 0; 37 | left: 0; 38 | right: 0; 39 | display: flex; 40 | justify-content: center; 41 | align-items: center; 42 | color: var(--color-black); 43 | background-color: rgba(0, 0, 0, 0.2); 44 | backdrop-filter: blur(3px); 45 | z-index: 2; 46 | ` 47 | -------------------------------------------------------------------------------- /src/components/AssetBadge.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { Asset } from '@alephium/sdk' 20 | import styled from 'styled-components' 21 | 22 | import AssetLogo from '@/components/AssetLogo' 23 | import { useAppSelector } from '@/hooks/redux' 24 | import { selectAssetInfoById, selectNFTById } from '@/storage/assets/assetsSelectors' 25 | 26 | interface AssetBadgeProps { 27 | assetId: Asset['id'] 28 | simple?: boolean 29 | className?: string 30 | } 31 | 32 | const AssetBadge = ({ assetId, simple, className }: AssetBadgeProps) => { 33 | const assetInfo = useAppSelector((s) => selectAssetInfoById(s, assetId)) 34 | const nftInfo = useAppSelector((s) => selectNFTById(s, assetId)) 35 | 36 | return ( 37 |
42 | 49 | {!simple && assetInfo?.symbol && {assetInfo.symbol}} 50 |
51 | ) 52 | } 53 | 54 | export default styled(AssetBadge)` 55 | display: flex; 56 | align-items: center; 57 | gap: 10px; 58 | ` 59 | 60 | const AssetSymbol = styled.div` 61 | font-weight: var(--fontWeight-semiBold); 62 | ` 63 | -------------------------------------------------------------------------------- /src/components/Banner.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { motion } from 'framer-motion' 20 | import styled from 'styled-components' 21 | 22 | export default styled(motion.div)` 23 | display: flex; 24 | align-items: center; 25 | justify-content: center; 26 | 27 | height: 50px; 28 | 29 | color: var(--color-white); 30 | background-color: ${({ theme }) => theme.global.accent}; 31 | ` 32 | -------------------------------------------------------------------------------- /src/components/Box.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { motion } from 'framer-motion' 20 | import styled from 'styled-components' 21 | 22 | const Box = styled(motion.div)` 23 | background-color: ${({ theme }) => theme.bg.primary}; 24 | border: 1px solid ${({ theme }) => theme.border.primary}; 25 | border-radius: var(--radius-big); 26 | box-shadow: ${({ theme }) => theme.shadow.primary}; 27 | width: 100%; 28 | ` 29 | 30 | export default Box 31 | -------------------------------------------------------------------------------- /src/components/Buttons/DeleteButton.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { X } from 'lucide-react' 20 | import styled from 'styled-components' 21 | 22 | import Button, { ButtonProps } from '@/components/Button' 23 | 24 | const DeleteButton = (props: ButtonProps) => 29 | 30 | ) 31 | 32 | export default FooterButton 33 | 34 | const ModalFooter = styled.div` 35 | position: sticky; 36 | bottom: 0; 37 | background-color: ${({ theme }) => colord(theme.bg.background1).alpha(0.5).toHex()}; 38 | backdrop-filter: blur(10px); 39 | display: flex; 40 | justify-content: center; 41 | margin-top: var(--spacing-6); 42 | margin: var(--spacing-6) calc(-1 * var(--spacing-4)) 0; 43 | ` 44 | -------------------------------------------------------------------------------- /src/components/Card.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { motion } from 'framer-motion' 20 | import styled from 'styled-components' 21 | 22 | const Card = styled(motion.div)<{ isPlaceholder?: boolean }>` 23 | width: 230px; 24 | border: 1px ${({ isPlaceholder }) => (isPlaceholder ? 'dashed' : 'solid')} ${({ theme }) => theme.border.primary}; 25 | border-radius: var(--radius-big); 26 | background-color: ${({ theme, isPlaceholder }) => (isPlaceholder ? theme.bg.secondary : theme.bg.primary)}; 27 | box-shadow: ${({ theme }) => theme.shadow.primary}; 28 | overflow: hidden; 29 | ` 30 | 31 | export default Card 32 | -------------------------------------------------------------------------------- /src/components/CheckMark.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { Check } from 'lucide-react' 20 | import styled from 'styled-components' 21 | 22 | interface CheckMarkProps { 23 | className?: string 24 | } 25 | 26 | const CheckMark = ({ className }: CheckMarkProps) => ( 27 |
28 | 29 |
30 | ) 31 | 32 | export default styled(CheckMark)` 33 | height: 16px; 34 | width: 16px; 35 | display: flex; 36 | align-items: center; 37 | justify-content: center; 38 | background-color: ${({ theme }) => theme.global.accent}; 39 | color: var(--color-white); 40 | border-radius: 40px; 41 | padding: 3px; 42 | ` 43 | -------------------------------------------------------------------------------- /src/components/DataList.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | export default styled.div` 22 | border: 1px solid ${({ theme }) => theme.border.primary}; 23 | border-radius: var(--radius-small); 24 | background-color: ${({ theme }) => theme.bg.primary}; 25 | box-shadow: ${({ theme }) => theme.shadow.primary}; 26 | ` 27 | 28 | export const DataListRow = styled.div` 29 | display: grid; 30 | grid-auto-columns: minmax(0, 1fr); 31 | grid-auto-flow: column; 32 | height: var(--tableCellHeight); 33 | 34 | &:not(:last-child) { 35 | border-bottom: 1px solid ${({ theme }) => theme.border.primary}; 36 | } 37 | ` 38 | 39 | export const DataListCell = styled.div` 40 | padding: 0 var(--spacing-4); 41 | display: flex; 42 | align-items: center; 43 | ` 44 | -------------------------------------------------------------------------------- /src/components/Dividers/HorizontalDivider.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | export default styled.div<{ narrow?: boolean; secondary?: boolean }>` 22 | background-color: ${({ theme, secondary }) => (secondary ? theme.border.secondary : theme.border.primary)}; 23 | height: 1px; 24 | width: 100%; 25 | ` 26 | -------------------------------------------------------------------------------- /src/components/DotIcon.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | import { ReactComponent as DotSvg } from '@/images/dot.svg' 22 | 23 | interface DotIconProps { 24 | color: string 25 | size?: number 26 | strokeColor?: string 27 | className?: string 28 | } 29 | 30 | const defaultSize = 8 31 | 32 | const DotIcon = ({ className }: DotIconProps) => 33 | 34 | export default styled(DotIcon)` 35 | fill: ${({ color }) => color}; 36 | width: ${({ size }) => size ?? defaultSize}px; 37 | height: ${({ size }) => size ?? defaultSize}px; 38 | stroke: ${({ strokeColor }) => strokeColor}; 39 | transition: all 0.3s ease-out; 40 | ` 41 | -------------------------------------------------------------------------------- /src/components/Ellipsed.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { HTMLAttributes, useCallback, useEffect, useRef, useState } from 'react' 20 | import styled from 'styled-components' 21 | 22 | import { useWindowResize } from '@/utils/hooks' 23 | 24 | interface EllipsedProps extends HTMLAttributes { 25 | text: string 26 | className?: string 27 | } 28 | 29 | const Ellipsed = ({ text, className }: EllipsedProps) => { 30 | const el = useRef(null) 31 | const charWidth = useRef() 32 | const [_text, setText] = useState(text) 33 | 34 | const handleResize = useCallback(() => { 35 | if (el?.current === null) return 36 | 37 | if (charWidth.current === undefined) { 38 | charWidth.current = el.current.scrollWidth / text.length 39 | } 40 | 41 | const visibleChars = Math.floor(el.current.clientWidth / charWidth.current) 42 | const half = visibleChars / 2 43 | 44 | setText( 45 | visibleChars >= text.length 46 | ? text 47 | : text.slice(0, Math.floor(half)) + 48 | (visibleChars == text.length ? '' : '...') + 49 | text.slice(-Math.ceil(half) + 3) 50 | ) 51 | }, [text]) 52 | 53 | useWindowResize(handleResize) 54 | 55 | useEffect(() => { 56 | handleResize() 57 | }, [handleResize]) 58 | 59 | return ( 60 |
61 | {text} 62 |
{_text}
63 |
64 | ) 65 | } 66 | 67 | export default styled(Ellipsed)` 68 | font-family: 'Roboto Mono'; 69 | overflow: hidden; 70 | ` 71 | 72 | const HiddenText = styled.div` 73 | visibility: hidden; 74 | height: 0; 75 | ` 76 | -------------------------------------------------------------------------------- /src/components/FloatingLogo.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | import { ReactComponent as AlephiumLogoSVG } from '@/images/alephium_logo_monochrome.svg' 22 | import { deviceBreakPoints } from '@/style/globalStyles' 23 | 24 | export default styled(AlephiumLogoSVG)<{ position?: 'top' | 'bottom' }>` 25 | position: fixed; 26 | left: var(--spacing-5); 27 | width: 35px; 28 | height: auto; 29 | ${({ position }) => (position === 'bottom' ? 'bottom: var(--spacing-5)' : 'top: 50px')}; 30 | 31 | path { 32 | fill: ${({ theme }) => 33 | (theme.name === 'light' ? 'rgba(0, 0, 0, 0.04)' : 'rgba(255, 255, 255, 0.03)') + ' !important'}; 34 | } 35 | 36 | @media ${deviceBreakPoints.mobile} { 37 | display: none; 38 | } 39 | ` 40 | -------------------------------------------------------------------------------- /src/components/HashEllipsed.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { HTMLAttributes } from 'react' 20 | import { useTranslation } from 'react-i18next' 21 | import styled from 'styled-components' 22 | 23 | import ClipboardButton from '@/components/Buttons/ClipboardButton' 24 | import Ellipsed from '@/components/Ellipsed' 25 | 26 | interface HashEllipsedProps extends HTMLAttributes { 27 | hash: string 28 | tooltipText?: string 29 | disableA11y?: boolean 30 | disableCopy?: boolean 31 | className?: string 32 | } 33 | 34 | const HashEllipsed = ({ 35 | hash, 36 | disableA11y = false, 37 | disableCopy = false, 38 | tooltipText, 39 | className, 40 | ...props 41 | }: HashEllipsedProps) => { 42 | const { t } = useTranslation() 43 | 44 | return disableCopy ? ( 45 | 46 | 47 | 48 | ) : ( 49 | 55 | 56 | 57 | ) 58 | } 59 | 60 | export default HashEllipsed 61 | 62 | const Container = styled.div` 63 | display: flex; 64 | align-items: center; 65 | overflow: hidden; 66 | ` 67 | -------------------------------------------------------------------------------- /src/components/HiddenLabel.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | interface HiddenLabelProps { 22 | text: string 23 | } 24 | 25 | const HiddenLabel = ({ text, ...props }: HiddenLabelProps) =>
{text}
26 | 27 | export default styled(HiddenLabel)` 28 | position: absolute; 29 | left: -10000px; 30 | top: auto; 31 | width: 1px; 32 | height: 1px; 33 | overflow: hidden; 34 | ` 35 | -------------------------------------------------------------------------------- /src/components/InputFieldsColumn.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | export const InputFieldsColumn = styled.div` 22 | display: flex; 23 | flex-direction: column; 24 | ` 25 | -------------------------------------------------------------------------------- /src/components/Inputs/ColoredLabelInput.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { useEffect, useState } from 'react' 20 | import styled from 'styled-components' 21 | 22 | import ColorPicker from '@/components/Inputs/ColorPicker' 23 | import Input from '@/components/Inputs/Input' 24 | 25 | export type ColoredLabelInputValue = { 26 | title: string 27 | color: string 28 | } 29 | 30 | interface ColoredLabelInputProps { 31 | value: ColoredLabelInputValue 32 | onChange: ({ title, color }: ColoredLabelInputValue) => void 33 | disabled?: boolean 34 | label?: string 35 | id?: string 36 | maxLength?: number 37 | className?: string 38 | } 39 | 40 | const ColoredLabelInput = ({ label, onChange, value, className, id, maxLength }: ColoredLabelInputProps) => { 41 | const [title, setTitle] = useState(value.title) 42 | const [color, setColor] = useState(value.color) 43 | 44 | useEffect(() => { 45 | onChange({ title, color }) 46 | }, [title, color, onChange]) 47 | 48 | return ( 49 |
50 | setTitle(e.target.value)} 54 | value={title} 55 | id={id} 56 | color={color} 57 | maxLength={maxLength} 58 | /> 59 | 60 |
61 | ) 62 | } 63 | 64 | export default styled(ColoredLabelInput)` 65 | display: flex; 66 | gap: 17px; 67 | width: 100%; 68 | align-items: center; 69 | position: relative; 70 | ` 71 | -------------------------------------------------------------------------------- /src/components/Inputs/CompactToggle.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import Button, { ButtonProps } from '@/components/Button' 20 | 21 | interface CompactToggleProps extends ButtonProps { 22 | toggled: boolean 23 | onToggle: (value: boolean) => void 24 | IconOn: LucideIconType 25 | IconOff: LucideIconType 26 | } 27 | 28 | const CompactToggle = ({ toggled, onToggle, IconOn, IconOff, ...props }: CompactToggleProps) => ( 29 | 32 | ) 33 | 34 | export default CompactToggle 35 | -------------------------------------------------------------------------------- /src/components/Inputs/InlineLabelValueInput.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { ReactNode } from 'react' 20 | import styled from 'styled-components' 21 | 22 | interface InlineLabelValueInputProps { 23 | label: ReactNode 24 | InputComponent: ReactNode 25 | description?: string 26 | children?: ReactNode 27 | className?: string 28 | } 29 | 30 | const InlineLabelValueInput = ({ 31 | label, 32 | InputComponent, 33 | description, 34 | children, 35 | className 36 | }: InlineLabelValueInputProps) => ( 37 | 38 | 39 | 40 | {description && {description}} 41 | {children} 42 | 43 | {InputComponent} 44 | 45 | ) 46 | 47 | export default InlineLabelValueInput 48 | 49 | const KeyValueInputContainer = styled.div` 50 | display: flex; 51 | padding: var(--spacing-4) var(--spacing-3); 52 | gap: var(--spacing-8); 53 | width: 100%; 54 | ` 55 | 56 | const KeyContainer = styled.div` 57 | flex: 2.5; 58 | display: flex; 59 | flex-direction: column; 60 | justify-content: center; 61 | gap: var(--spacing-1); 62 | ` 63 | 64 | const Label = styled.label` 65 | font-weight: var(--fontWeight-semiBold); 66 | ` 67 | 68 | const DescriptionContainer = styled.div` 69 | color: ${({ theme }) => theme.font.tertiary}; 70 | ` 71 | 72 | const InputContainer = styled.div` 73 | display: flex; 74 | align-items: center; 75 | justify-content: flex-end; 76 | flex: 1; 77 | ` 78 | -------------------------------------------------------------------------------- /src/components/Inputs/InputArea.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { motion, MotionProps } from 'framer-motion' 20 | import { KeyboardEventHandler, MouseEventHandler, MutableRefObject, ReactNode } from 'react' 21 | import styled from 'styled-components' 22 | 23 | interface InputAreaProps extends MotionProps { 24 | children: ReactNode | ReactNode[] 25 | onKeyDown?: KeyboardEventHandler 26 | onInput?: () => void 27 | onMouseDown?: MouseEventHandler 28 | className?: string 29 | innerRef?: MutableRefObject 30 | tabIndex?: number 31 | } 32 | 33 | const InputArea = ({ onKeyDown, onInput, children, className, onMouseDown, ...rest }: InputAreaProps) => ( 34 | 35 | {children} 36 | 37 | ) 38 | 39 | export default styled(InputArea)` 40 | position: relative; 41 | display: flex; 42 | align-items: center; 43 | height: var(--inputHeight); 44 | width: 100%; 45 | cursor: pointer; 46 | ` 47 | -------------------------------------------------------------------------------- /src/components/Inputs/Option.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled, { css } from 'styled-components' 20 | 21 | import InputArea from '@/components/Inputs/InputArea' 22 | 23 | interface OptionProps { 24 | isSelected: boolean 25 | onSelect: () => void 26 | className?: string 27 | } 28 | 29 | const Option: FC = ({ className, isSelected, onSelect, children }) => ( 30 | 31 | 32 | {children} 33 | 34 | ) 35 | 36 | export default styled(Option)` 37 | display: flex; 38 | gap: 12px; 39 | align-items: center; 40 | 41 | padding: var(--spacing-3); 42 | background-color: ${({ theme }) => theme.bg.primary}; 43 | color: inherit; 44 | 45 | &:not(:last-child) { 46 | border-bottom: 1px solid ${({ theme }) => theme.border.primary}; 47 | } 48 | 49 | &:hover { 50 | background-color: ${({ theme }) => theme.bg.secondary}; 51 | } 52 | ` 53 | 54 | const Circle = styled.div<{ filled: boolean }>` 55 | background-color: ${({ filled, theme }) => (filled ? theme.global.accent : theme.bg.secondary)}; 56 | height: 15px; 57 | width: 15px; 58 | border-radius: var(--radius-full); 59 | border: 1px solid ${({ theme }) => theme.border.primary}; 60 | display: flex; 61 | align-items: center; 62 | justify-content: center; 63 | 64 | &::before { 65 | ${({ filled }) => 66 | filled && 67 | css` 68 | content: ''; 69 | display: block; 70 | height: 7px; 71 | width: 7px; 72 | background-color: var(--color-white); 73 | border-radius: var(--radius-full); 74 | `} 75 | } 76 | ` 77 | -------------------------------------------------------------------------------- /src/components/Inputs/SelectOptionAddress.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | import AddressBadge from '@/components/AddressBadge' 22 | import Amount from '@/components/Amount' 23 | import SelectOptionItemContent from '@/components/Inputs/SelectOptionItemContent' 24 | import { Address } from '@/types/addresses' 25 | 26 | interface SelectOptionAddressProps { 27 | address: Address 28 | isSelected?: boolean 29 | className?: string 30 | } 31 | 32 | const SelectOptionAddress = ({ address, isSelected, className }: SelectOptionAddressProps) => ( 33 | } 37 | SecondaryContent={ 38 | 43 | } 44 | /> 45 | ) 46 | 47 | export default SelectOptionAddress 48 | 49 | const AddressBadgeStyled = styled(AddressBadge)` 50 | max-width: 200px; 51 | ` 52 | 53 | const AmountStyled = styled(Amount)` 54 | flex: 1; 55 | font-weight: var(--fontWeight-semiBold); 56 | ` 57 | -------------------------------------------------------------------------------- /src/components/Inputs/SelectOptionItemContent.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { ReactNode } from 'react' 20 | import styled from 'styled-components' 21 | 22 | interface SelectOptionItemContentProps { 23 | MainContent: ReactNode 24 | SecondaryContent?: ReactNode 25 | className?: string 26 | displaysCheckMarkWhenSelected?: boolean 27 | } 28 | 29 | const SelectOptionItemContent = ({ 30 | MainContent: ContentLeft, 31 | SecondaryContent: ContentRight, 32 | className 33 | }: SelectOptionItemContentProps) => ( 34 |
35 | {ContentLeft} 36 | {ContentRight} 37 |
38 | ) 39 | 40 | export default styled(SelectOptionItemContent)` 41 | display: flex; 42 | align-items: center; 43 | justify-content: space-between; 44 | gap: 20px; 45 | width: ${({ displaysCheckMarkWhenSelected }) => (displaysCheckMarkWhenSelected ? 90 : 100)}%; 46 | ` 47 | 48 | const OptionMainContent = styled.div` 49 | font-weight: var(--fontWeight-semiBold); 50 | ` 51 | 52 | const OptionSecondaryContent = styled.div` 53 | * { 54 | color: ${({ theme }) => theme.font.secondary} !important; 55 | } 56 | ` 57 | -------------------------------------------------------------------------------- /src/components/Lock.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import dayjs from 'dayjs' 20 | import { Lock as LockIcon, Unlock } from 'lucide-react' 21 | import { useTranslation } from 'react-i18next' 22 | import styled from 'styled-components' 23 | 24 | interface LockProps { 25 | unlockAt?: Date 26 | className?: string 27 | } 28 | 29 | const Lock = ({ unlockAt, className }: LockProps) => { 30 | const { t } = useTranslation() 31 | 32 | if (!unlockAt) return null 33 | 34 | const lockTimeInPast = unlockAt < new Date() 35 | const tooltipContent = `${lockTimeInPast ? t`Unlocked at` : t`Unlocks at`} ${dayjs(unlockAt).format( 36 | 'DD/MM/YYYY hh:mm A' 37 | )}` 38 | 39 | return ( 40 | 41 | {lockTimeInPast ? : } 42 | 43 | ) 44 | } 45 | 46 | export default styled(Lock)` 47 | display: flex; 48 | ` 49 | 50 | const UnlockIconStyled = styled(Unlock)` 51 | width: 1em; 52 | ` 53 | 54 | const LockIconStyled = styled(LockIcon)` 55 | width: 1em; 56 | ` 57 | -------------------------------------------------------------------------------- /src/components/NFTThumbnail.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | import { NFT } from '@/types/assets' 22 | 23 | interface NFTThumbnailProps { 24 | nft: NFT 25 | className?: string 26 | } 27 | 28 | const NFTThumbnail = ({ nft, className }: NFTThumbnailProps) => ( 29 | 30 | ) 31 | 32 | export default NFTThumbnail 33 | 34 | const NFTThumbnailStyled = styled.img` 35 | width: 100px; 36 | height: 100px; 37 | border-radius: var(--radius-medium); 38 | object-fit: cover; 39 | ` 40 | -------------------------------------------------------------------------------- /src/components/NavItem.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { useLocation, useNavigate } from 'react-router-dom' 20 | import styled, { useTheme } from 'styled-components' 21 | 22 | import Button from '@/components/Button' 23 | 24 | interface NavItemProps { 25 | Icon: LucideIconType 26 | label: string 27 | to?: string 28 | onClick?: () => void 29 | } 30 | 31 | const NavItem = ({ Icon, label, to, onClick }: NavItemProps) => { 32 | const navigate = useNavigate() 33 | const location = useLocation() 34 | const theme = useTheme() 35 | 36 | const isActive = to !== undefined && location.pathname.startsWith(to) 37 | 38 | const handleClick = () => { 39 | if (to) { 40 | navigate(to) 41 | } else if (onClick) { 42 | onClick() 43 | } 44 | } 45 | 46 | return ( 47 | 60 | ) 61 | } 62 | 63 | const ButtonStyled = styled(Button)<{ isActive: boolean }>` 64 | &:not(:hover) { 65 | opacity: ${({ isActive }) => (isActive ? 1 : 0.5)} !important; 66 | } 67 | 68 | &:hover { 69 | border-color: ${({ theme }) => theme.border.primary}; 70 | } 71 | ` 72 | 73 | export default NavItem 74 | -------------------------------------------------------------------------------- /src/components/PageComponents/PageHeadings.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | export const PageH1 = styled.h1` 22 | font-size: 18px; 23 | font-weight: var(--fontWeight-medium); 24 | margin: 0; 25 | ` 26 | 27 | export const PageH2 = styled.h2` 28 | font-size: 16px; 29 | font-weight: var(--fontWeight-medium); 30 | margin-top: var(--spacing-8); 31 | margin-bottom: var(--spacing-5); 32 | ` 33 | -------------------------------------------------------------------------------- /src/components/PageComponents/VerticalDivider.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | export default styled.div` 22 | width: 1px; 23 | min-height: var(--spacing-4); 24 | height: 100%; 25 | background-color: ${({ theme }) => theme.border.primary}; 26 | ` 27 | -------------------------------------------------------------------------------- /src/components/Paragraph.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { HTMLMotionProps, motion } from 'framer-motion' 20 | import styled, { css } from 'styled-components' 21 | 22 | import { sectionChildrenVariants } from '@/components/PageComponents/PageContainers' 23 | 24 | interface ParagraphProps { 25 | centered?: boolean 26 | secondary?: boolean 27 | } 28 | 29 | const Paragraph: FC & ParagraphProps> = ({ 30 | centered, 31 | secondary, 32 | children, 33 | className, 34 | style, 35 | ...props 36 | }) => ( 37 | 45 | {children} 46 | 47 | ) 48 | 49 | export default Paragraph 50 | 51 | const StyledParagraph = styled(motion.p)` 52 | white-space: pre-wrap; 53 | font-weight: var(--fontWeight-medium); 54 | width: 100%; 55 | line-height: 1.5em; 56 | 57 | ${({ centered }) => 58 | centered && 59 | css` 60 | text-align: center; 61 | `} 62 | 63 | ${({ secondary, theme }) => 64 | secondary && 65 | css` 66 | color: ${theme.font.secondary}; 67 | `} 68 | ` 69 | -------------------------------------------------------------------------------- /src/components/SkeletonLoader.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { CSSProperties } from 'react' 20 | import styled from 'styled-components' 21 | 22 | interface SkeletonLoaderProps { 23 | height?: string 24 | width?: string 25 | style?: CSSProperties 26 | className?: string 27 | } 28 | 29 | const SkeletonLoader = ({ className, style }: SkeletonLoaderProps) => ( 30 |
31 | 32 |
33 | ) 34 | 35 | export default styled(SkeletonLoader)` 36 | background-color: rgba(255, 255, 255, 0.05); 37 | width: ${({ width }) => width || '100%'}; 38 | height: ${({ height }) => height || '20px'}; 39 | border-radius: var(--radius-big); 40 | overflow: hidden; 41 | ` 42 | 43 | const AnimatedBackground = styled.div` 44 | width: 100%; 45 | height: 100%; 46 | 47 | background-image: linear-gradient(-90deg, rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.05), rgba(0, 0, 0, 0.05)); 48 | background-size: 400% 400%; 49 | animation: gradientAnimation 1.5s ease-in-out infinite; 50 | 51 | @keyframes gradientAnimation { 52 | 0% { 53 | background-position: 0% 0%; 54 | } 55 | 100% { 56 | background-position: -135% 0%; 57 | } 58 | } 59 | ` 60 | -------------------------------------------------------------------------------- /src/components/Spinner.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { motion } from 'framer-motion' 20 | import { Loader } from 'lucide-react' 21 | 22 | const Spinner = ({ size = '25px' }: { size?: string }) => ( 23 | 24 | ) 25 | 26 | const RotatingLoader = motion(Loader) 27 | 28 | export default Spinner 29 | -------------------------------------------------------------------------------- /src/components/TableCellAmount.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled, { css } from 'styled-components' 20 | 21 | export default styled.div<{ color?: string }>` 22 | display: flex; 23 | flex-direction: column; 24 | align-items: flex-end; 25 | flex-grow: 1; 26 | min-width: 6em; 27 | flex-basis: 120px; 28 | gap: 6px; 29 | font-weight: var(--fontWeight-semiBold); 30 | 31 | ${({ color }) => 32 | color && 33 | css` 34 | color: ${color}; 35 | `} 36 | ` 37 | -------------------------------------------------------------------------------- /src/components/TableTabBar.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled, { css } from 'styled-components' 20 | 21 | import TabBar, { Tab, TabBarProps } from '@/components/TabBar' 22 | 23 | const TableTabBar = (props: TabBarProps) => 24 | 25 | export default styled(TableTabBar)` 26 | background-color: ${({ theme }) => theme.bg.secondary}; 27 | ` 28 | 29 | const TableTab = styled(Tab)` 30 | min-width: 60px; 31 | background-color: ${({ isActive, theme }) => (isActive ? theme.bg.primary : theme.bg.tertiary)}; 32 | border: none; 33 | 34 | border-bottom: 1px solid ${({ theme }) => theme.border.secondary}; 35 | margin-bottom: 0; 36 | 37 | ${({ isActive, theme }) => 38 | isActive && 39 | css` 40 | border-bottom: 1px solid transparent; 41 | `} 42 | 43 | &:not(:last-child) { 44 | border-right: 1px solid ${({ theme }) => theme.border.primary}; 45 | } 46 | 47 | &:first-child, 48 | &:last-child { 49 | border-radius: 0; 50 | } 51 | ` 52 | -------------------------------------------------------------------------------- /src/components/TimeSince.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import dayjs from 'dayjs' 20 | import styled from 'styled-components' 21 | 22 | interface TimeSinceProps { 23 | timestamp: number 24 | faded?: boolean 25 | className?: string 26 | } 27 | 28 | const TimeSince = ({ timestamp, className }: TimeSinceProps) => ( 29 |
{dayjs(timestamp).fromNow()}
30 | ) 31 | 32 | export default styled(TimeSince)` 33 | ${({ faded, theme }) => (faded ? `color: ${theme.font.tertiary}` : '')}; 34 | overflow: hidden; 35 | text-overflow: ellipsis; 36 | ` 37 | -------------------------------------------------------------------------------- /src/components/Tooltip.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import 'react-tooltip/dist/react-tooltip.css' 20 | 21 | import { Tooltip } from 'react-tooltip' 22 | import styled from 'styled-components' 23 | 24 | export type HasTooltip = T & { tooltip?: string } 25 | 26 | export default styled(Tooltip)` 27 | background-color: rgb(10, 10, 10); 28 | color: #fff; 29 | z-index: 1; 30 | ` 31 | -------------------------------------------------------------------------------- /src/components/Tooltips.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import Tooltip from '@/components/Tooltip' 20 | 21 | const Tooltips = () => ( 22 | <> 23 | 24 | 25 | 26 | 27 | ) 28 | 29 | export default Tooltips 30 | -------------------------------------------------------------------------------- /src/components/Truncate.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { HTMLAttributes } from 'react' 20 | import styled from 'styled-components' 21 | 22 | const Truncate = ({ ...props }: HTMLAttributes) =>
23 | 24 | export default styled(Truncate)` 25 | white-space: nowrap; 26 | overflow: hidden; 27 | text-overflow: ellipsis; 28 | ` 29 | -------------------------------------------------------------------------------- /src/contexts/scroll.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { MotionValue } from 'framer-motion' 20 | import { createContext, useContext } from 'react' 21 | 22 | export type ScrollDirection = 'up' | 'down' | undefined 23 | 24 | export interface ScrollContextType { 25 | scrollY?: MotionValue 26 | scrollDirection?: MotionValue 27 | } 28 | 29 | const ScrollContext = createContext({ 30 | scrollY: undefined, 31 | scrollDirection: undefined 32 | }) 33 | 34 | export const ScrollContextProvider = ScrollContext.Provider 35 | 36 | export const useScrollContext = () => useContext(ScrollContext) 37 | -------------------------------------------------------------------------------- /src/hooks/redux.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux' 20 | 21 | import type { AppDispatch, RootState } from '@/storage/store' 22 | 23 | // Use throughout your app instead of plain `useDispatch` and `useSelector`. 24 | // See: https://redux-toolkit.js.org/tutorials/typescript#define-typed-hooks 25 | export const useAppDispatch = () => useDispatch() 26 | export const useAppSelector: TypedUseSelectorHook = useSelector 27 | -------------------------------------------------------------------------------- /src/hooks/useAnimationFrame.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { useEffect, useRef } from 'react' 20 | 21 | const useAnimationFrame = (callback: (deltaTime: number) => void) => { 22 | // Use useRef for mutable variables that we want to persist 23 | // without triggering a re-render on their change 24 | const requestRef = useRef() 25 | const previousTimeRef = useRef() 26 | 27 | const animate = (time: number) => { 28 | if (previousTimeRef.current != undefined) { 29 | const deltaTime = time - previousTimeRef.current 30 | callback(deltaTime) 31 | } 32 | previousTimeRef.current = time 33 | requestRef.current = requestAnimationFrame(animate) 34 | } 35 | 36 | useEffect(() => { 37 | requestRef.current = requestAnimationFrame(animate) 38 | return () => cancelAnimationFrame(requestRef.current ?? 0) 39 | // eslint-disable-next-line react-hooks/exhaustive-deps 40 | }, []) // Make sure the effect runs only once 41 | } 42 | 43 | export default useAnimationFrame 44 | -------------------------------------------------------------------------------- /src/hooks/useFocusOnMount.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { useEffect, useRef } from 'react' 20 | 21 | export default function (skipFocusOnMount?: boolean) { 22 | const ref = useRef(null) 23 | 24 | useEffect(() => { 25 | if (skipFocusOnMount) return 26 | setTimeout(() => ref.current?.focus(), 0) 27 | }, [ref, skipFocusOnMount]) 28 | 29 | return ref 30 | } 31 | -------------------------------------------------------------------------------- /src/hooks/useStateObject.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { Dispatch, SetStateAction, useCallback, useState } from 'react' 20 | 21 | type Setter = Dispatch> 22 | type SetterSingle = (name: string) => (value: unknown) => void 23 | 24 | const useStateObject = (initialObj: T): [T, Setter, SetterSingle] => { 25 | const [obj, setObj] = useState(initialObj) 26 | 27 | const setObjProps = useCallback( 28 | (name: string) => (value: unknown) => { 29 | const nObj = Object.assign({}, obj, { [name]: value }) 30 | setObj(nObj) 31 | }, 32 | [obj, setObj] 33 | ) 34 | 35 | return [obj, setObj, setObjProps] 36 | } 37 | 38 | export default useStateObject 39 | -------------------------------------------------------------------------------- /src/hooks/useTransactionUI.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { TransactionInfoType } from '@alephium/sdk' 20 | import { colord } from 'colord' 21 | import { ArrowDown, ArrowLeftRight, ArrowUp, CircleEllipsis, Repeat } from 'lucide-react' 22 | import { useTranslation } from 'react-i18next' 23 | import { useTheme } from 'styled-components' 24 | 25 | export const useTransactionUI = (infoType: TransactionInfoType) => { 26 | const theme = useTheme() 27 | const { t } = useTranslation() 28 | 29 | return { 30 | label: { 31 | in: t('Received'), 32 | out: t('Sent'), 33 | move: t('Moved'), 34 | pending: t('Pending'), 35 | swap: t('Swapped') 36 | }[infoType], 37 | Icon: { 38 | in: ArrowDown, 39 | out: ArrowUp, 40 | move: ArrowLeftRight, 41 | pending: CircleEllipsis, 42 | swap: Repeat 43 | }[infoType], 44 | iconColor: { 45 | in: theme.global.valid, 46 | out: theme.font.highlight, 47 | move: theme.font.secondary, 48 | pending: theme.font.secondary, 49 | swap: theme.global.complementary 50 | }[infoType], 51 | iconBgColor: { 52 | in: colord(theme.global.valid).alpha(0.08).toRgbString(), 53 | out: colord(theme.font.highlight).alpha(0.08).toRgbString(), 54 | move: colord(theme.font.secondary).alpha(0.08).toRgbString(), 55 | pending: colord(theme.font.secondary).alpha(0.08).toRgbString(), 56 | swap: colord(theme.global.complementary).alpha(0.08).toRgbString() 57 | }[infoType] 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/i18n.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import i18next from 'i18next' 20 | import { initReactI18next } from 'react-i18next' 21 | 22 | import bg from '../locales/bg-BG/translation.json' 23 | import de from '../locales/de-DE/translation.json' 24 | import en from '../locales/en-US/translation.json' 25 | import es from '../locales/es-ES/translation.json' 26 | import fr from '../locales/fr-FR/translation.json' 27 | import id from '../locales/id-ID/translation.json' 28 | import it from '../locales/it-IT/translation.json' 29 | import pt from '../locales/pt-PT/translation.json' 30 | import ru from '../locales/ru-RU/translation.json' 31 | import tr from '../locales/tr-TR/translation.json' 32 | import vi from '../locales/vi-VN/translation.json' 33 | 34 | i18next.use(initReactI18next).init({ 35 | resources: { 36 | 'en-US': { translation: en }, 37 | 'bg-BG': { translation: bg }, 38 | 'es-ES': { translation: es }, 39 | 'de-DE': { translation: de }, 40 | 'id-ID': { translation: id }, 41 | 'it-IT': { translation: it }, 42 | 'fr-FR': { translation: fr }, 43 | 'pt-PT': { translation: pt }, 44 | 'ru-RU': { translation: ru }, 45 | 'tr-TR': { translation: tr }, 46 | 'vi-VN': { translation: vi } 47 | }, 48 | lng: 'en-US', 49 | fallbackLng: 'en-US', 50 | interpolation: { 51 | escapeValue: false 52 | } 53 | }) 54 | 55 | export default i18next 56 | -------------------------------------------------------------------------------- /src/images/alef.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/images/alephium_logo_monochrome.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/images/brand-icon-discord.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/images/brand-icon-github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/images/brand-icon-twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/images/dot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/lock_body.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/images/lock_handle.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/images/main_address_badge.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/images/mountain.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/images/ribbon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/wallet-connect-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | /* GLOBAL SETTINGS */ 2 | 3 | body { 4 | font-size: inherit; 5 | margin: 0; 6 | font-family: 'Inter', sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | overflow-y: auto; 10 | height: 100%; 11 | width: 100%; 12 | font-weight: 500; 13 | font-size: 13px; 14 | font-feature-settings: 'calt' off; 15 | } 16 | 17 | #root { 18 | min-height: 100%; 19 | display: flex; 20 | } 21 | 22 | * { 23 | box-sizing: border-box; 24 | } 25 | 26 | h1 { 27 | font-size: 2.3em; 28 | margin-top: 30px; 29 | margin-bottom: 40px; 30 | } 31 | 32 | h2 { 33 | font-weight: 600; 34 | font-size: 1.1em; 35 | } 36 | 37 | h3 { 38 | font-weight: 600; 39 | font-size: 0.9em; 40 | } 41 | 42 | input, 43 | button { 44 | outline: none; 45 | border: none; 46 | background: transparent; 47 | font-family: 'Inter', sans-serif; 48 | } 49 | 50 | a { 51 | text-decoration: none; 52 | color: inherit; 53 | } 54 | 55 | #app-header { 56 | -webkit-app-region: drag; 57 | } 58 | 59 | /* FONTS */ 60 | 61 | @font-face { 62 | font-family: 'Inter'; 63 | src: url('./style/fonts/Inter.var.woff2') format('woff2'); 64 | font-weight: 100 1000; 65 | } 66 | 67 | @font-face { 68 | font-family: 'Roboto Mono'; 69 | src: url('./style/fonts/RobotoMono-var.ttf') format('truetype'); 70 | font-weight: 100 1000; 71 | } 72 | -------------------------------------------------------------------------------- /src/modals/BottomModal.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { motion } from 'framer-motion' 20 | import styled from 'styled-components' 21 | 22 | import { fastTransition } from '@/animations' 23 | import Scrollbar from '@/components/Scrollbar' 24 | import useFocusOnMount from '@/hooks/useFocusOnMount' 25 | import ModalContainer, { ModalContainerProps } from '@/modals/ModalContainer' 26 | 27 | interface BottomModalProps extends ModalContainerProps { 28 | label: string 29 | contentHeight?: number 30 | className?: string 31 | } 32 | 33 | const BottomModal = ({ onClose, children, label, contentHeight, className }: BottomModalProps) => { 34 | const elRef = useFocusOnMount() 35 | 36 | return ( 37 | 38 | 46 | 47 |
48 | {children} 49 |
50 |
51 |
52 |
53 | ) 54 | } 55 | 56 | export default BottomModal 57 | 58 | const Content = styled(motion.div)` 59 | display: flex; 60 | flex-direction: column; 61 | margin-top: auto; 62 | /* height: auto; */ 63 | height: 100%; 64 | max-height: 95%; 65 | width: 100%; 66 | position: relative; 67 | overflow: auto; 68 | ` 69 | -------------------------------------------------------------------------------- /src/modals/ConfirmModal.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { useTranslation } from 'react-i18next' 20 | 21 | import InfoBox from '@/components/InfoBox' 22 | import CenteredModal, { CenteredModalProps, ModalFooterButton, ModalFooterButtons } from '@/modals/CenteredModal' 23 | 24 | interface ConfirmModalProps extends CenteredModalProps { 25 | Icon?: LucideIconType 26 | onConfirm: () => void 27 | } 28 | 29 | const ConfirmModal: FC = ({ onConfirm, Icon, children, ...props }) => { 30 | const { t } = useTranslation() 31 | 32 | return ( 33 | 34 | {children} 35 | 36 | 37 | {t('Cancel')} 38 | 39 | {t('Confirm')} 40 | 41 | 42 | ) 43 | } 44 | 45 | export default ConfirmModal 46 | -------------------------------------------------------------------------------- /src/modals/ModalPortal.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { AnimatePresence } from 'framer-motion' 20 | import { createPortal } from 'react-dom' 21 | 22 | import Tooltips from '@/components/Tooltips' 23 | 24 | const ModalPortal: FC = ({ children }) => 25 | createPortal( 26 | <> 27 | {children} 28 | 29 | , 30 | document.body 31 | ) 32 | 33 | export default ModalPortal 34 | -------------------------------------------------------------------------------- /src/modals/SendModals/AlphAmountInfoBox.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { formatAmountForDisplay } from '@alephium/sdk' 20 | import { useTranslation } from 'react-i18next' 21 | import styled from 'styled-components' 22 | 23 | import AlefSymbol from '@/components/AlefSymbol' 24 | import InfoBox, { InfoBoxProps } from '@/components/InfoBox' 25 | 26 | interface AlphAmountInfoBoxProps extends InfoBoxProps { 27 | amount: bigint 28 | label?: string 29 | fullPrecision?: boolean 30 | } 31 | 32 | const AlphAmountInfoBox = ({ amount, label, fullPrecision = false, ...props }: AlphAmountInfoBoxProps) => { 33 | const { t } = useTranslation() 34 | 35 | return ( 36 | 37 | 38 | {formatAmountForDisplay({ amount, fullPrecision, displayDecimals: !fullPrecision ? 7 : undefined })}{' '} 39 | 40 | 41 | 42 | ) 43 | } 44 | 45 | export default AlphAmountInfoBox 46 | 47 | const Amount = styled.div` 48 | display: flex; 49 | ` 50 | -------------------------------------------------------------------------------- /src/modals/SendModals/CallContract/CheckTxModalContent.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { useTranslation } from 'react-i18next' 20 | 21 | import FooterButton from '@/components/Buttons/FooterButton' 22 | import InfoBox from '@/components/InfoBox' 23 | import { useAppSelector } from '@/hooks/redux' 24 | import CheckAddressesBox from '@/modals/SendModals/CheckAddressesBox' 25 | import CheckAmountsBox from '@/modals/SendModals/CheckAmountsBox' 26 | import CheckFeeLockTimeBox from '@/modals/SendModals/CheckFeeLockTimeBox' 27 | import CheckModalContent from '@/modals/SendModals/CheckModalContent' 28 | import { CallContractTxData, CheckTxProps } from '@/types/transactions' 29 | 30 | const CallContractCheckTxModalContent = ({ data, fees, onSubmit }: CheckTxProps) => { 31 | const { t } = useTranslation() 32 | const settings = useAppSelector((s) => s.settings) 33 | 34 | return ( 35 | <> 36 | 37 | {data.assetAmounts && } 38 | 39 | 40 | 41 | 42 | 43 | {t(settings.passwordRequirement ? 'Confirm' : 'Send')} 44 | 45 | 46 | ) 47 | } 48 | 49 | export default CallContractCheckTxModalContent 50 | -------------------------------------------------------------------------------- /src/modals/SendModals/CheckFeeLockTimeBox.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import dayjs from 'dayjs' 20 | import { useTranslation } from 'react-i18next' 21 | import styled from 'styled-components' 22 | 23 | import Amount from '@/components/Amount' 24 | import Box from '@/components/Box' 25 | import HorizontalDivider from '@/components/Dividers/HorizontalDivider' 26 | import InfoRow from '@/modals/SendModals/InfoRow' 27 | import { formatDateForDisplay } from '@/utils/misc' 28 | 29 | interface CheckFeeLockTimeBoxProps { 30 | fee: bigint 31 | lockTime?: Date 32 | className?: string 33 | } 34 | 35 | const CheckFeeLockTimeBox = ({ fee, lockTime, className }: CheckFeeLockTimeBoxProps) => { 36 | const { t } = useTranslation() 37 | 38 | return ( 39 | 40 | 41 | 42 | 43 | {lockTime && ( 44 | <> 45 | 46 | 47 | 48 | {formatDateForDisplay(lockTime)} 49 | ({dayjs(lockTime).fromNow()}) 50 | 51 | 52 | 53 | )} 54 | 55 | ) 56 | } 57 | 58 | export default CheckFeeLockTimeBox 59 | 60 | const UnlocksAt = styled.div` 61 | display: flex; 62 | gap: var(--spacing-1); 63 | ` 64 | 65 | const FromNow = styled.div` 66 | color: ${({ theme }) => theme.font.secondary}; 67 | ` 68 | -------------------------------------------------------------------------------- /src/modals/SendModals/CheckModalContent.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | export default styled.div` 22 | display: flex; 23 | flex-direction: column; 24 | padding-top: 10px; 25 | gap: 20px; 26 | ` 27 | -------------------------------------------------------------------------------- /src/modals/SendModals/InfoRow.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import styled from 'styled-components' 20 | 21 | interface InfoRowProps { 22 | label: string 23 | className?: string 24 | } 25 | 26 | const InfoRow: FC = ({ label, className, children }) => ( 27 |
28 | 29 |
{children}
30 |
31 | ) 32 | 33 | export default styled(InfoRow)` 34 | display: flex; 35 | justify-content: space-between; 36 | padding: 18px 15px; 37 | ` 38 | 39 | const Label = styled.div` 40 | font-weight: var(--fontWeight-semiBold); 41 | color: ${({ theme }) => theme.font.secondary}; 42 | ` 43 | -------------------------------------------------------------------------------- /src/modals/SendModals/InputsSection.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { ReactNode } from 'react' 20 | import styled from 'styled-components' 21 | 22 | interface InputsSectionProps { 23 | title: string 24 | HeaderActions?: ReactNode 25 | className?: string 26 | } 27 | 28 | const InputsSection: FC = ({ title, className, HeaderActions, children }) => ( 29 |
30 |
31 | {title} 32 | {HeaderActions} 33 |
34 | {children} 35 |
36 | ) 37 | 38 | export default InputsSection 39 | 40 | const Title = styled.div` 41 | font-size: 15px; 42 | font-weight: var(--fontWeight-semiBold); 43 | ` 44 | 45 | const Header = styled.div` 46 | margin-left: 10px; 47 | display: flex; 48 | align-items: center; 49 | justify-content: space-between; 50 | height: 50px; 51 | ` 52 | -------------------------------------------------------------------------------- /src/modals/WalletConnectModal/DAppMetadataBoxProps.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { useTranslation } from 'react-i18next' 20 | 21 | import Box from '@/components/Box' 22 | import HorizontalDivider from '@/components/Dividers/HorizontalDivider' 23 | import { useWalletConnectContext, WalletConnectContextProps } from '@/contexts/walletconnect' 24 | import InfoRow from '@/modals/SendModals/InfoRow' 25 | 26 | interface DAppMetadataBoxProps { 27 | metadata: WalletConnectContextProps['connectedDAppMetadata'] 28 | className?: string 29 | } 30 | 31 | const DAppMetadataBox = ({ metadata, className }: DAppMetadataBoxProps) => { 32 | const { t } = useTranslation() 33 | const { requiredChainInfo } = useWalletConnectContext() 34 | 35 | if (!metadata) return null 36 | 37 | return ( 38 | 39 | {metadata.name} 40 | 41 | {metadata.description} 42 | 43 | {metadata.url} 44 | 45 | {requiredChainInfo?.networkId} 46 | 47 | {requiredChainInfo?.addressGroup?.toString() ?? t('all')} 48 | 49 | ) 50 | } 51 | 52 | export default DAppMetadataBox 53 | -------------------------------------------------------------------------------- /src/pages/HomePage/NewWalletActions.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { useTranslation } from 'react-i18next' 20 | import { useNavigate } from 'react-router-dom' 21 | import styled from 'styled-components' 22 | 23 | import ActionLink from '@/components/ActionLink' 24 | import Button from '@/components/Button' 25 | import { Section } from '@/components/PageComponents/PageContainers' 26 | import Paragraph from '@/components/Paragraph' 27 | 28 | interface NewWalletActionsProps { 29 | onExistingWalletLinkClick?: () => void 30 | } 31 | 32 | const NewWalletActions = ({ onExistingWalletLinkClick }: NewWalletActionsProps) => { 33 | const navigate = useNavigate() 34 | const { t } = useTranslation() 35 | 36 | return ( 37 | <> 38 | 39 | {t('Please choose whether you want to create a new wallet or import an existing one.')} 40 | 41 |
42 | 43 | 44 | {onExistingWalletLinkClick && ( 45 | {t('Use an existing wallet')} 46 | )} 47 |
48 | 49 | ) 50 | } 51 | 52 | export default NewWalletActions 53 | 54 | const ActionLinkStyled = styled(ActionLink)` 55 | font-weight: var(--fontWeight-medium); 56 | font-size: 12px; 57 | font-family: inherit; 58 | height: var(--inputHeight); 59 | ` 60 | -------------------------------------------------------------------------------- /src/pages/LockedWalletLayout.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { motion, MotionProps } from 'framer-motion' 20 | import styled from 'styled-components' 21 | 22 | import SideBar from '@/components/PageComponents/SideBar' 23 | import Scrollbar from '@/components/Scrollbar' 24 | import { ReactComponent as AlephiumLogotype } from '@/images/logotype.svg' 25 | 26 | interface LockedWalletLayoutProps extends MotionProps { 27 | className?: string 28 | animateSideBar?: boolean 29 | } 30 | 31 | const LockedWalletLayout: FC = ({ children, animateSideBar, ...props }) => ( 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | {children} 40 | 41 | 42 | ) 43 | 44 | export default styled(LockedWalletLayout)` 45 | display: flex; 46 | flex: 1; 47 | height: 100%; 48 | background-color: ${({ theme }) => theme.bg.background1}; 49 | ` 50 | 51 | const Logo = styled.div` 52 | padding: 5px; 53 | ` 54 | 55 | const AlephiumLogotypeStyled = styled(AlephiumLogotype)` 56 | fill: ${({ theme }) => theme.font.primary}; 57 | color: ${({ theme }) => theme.font.primary}; 58 | ` 59 | 60 | const CenteredContainer = styled.div` 61 | display: flex; 62 | align-items: center; 63 | min-height: 100%; 64 | ` 65 | -------------------------------------------------------------------------------- /src/pages/NewWallet/NewWalletLayout.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import AppHeader from '@/components/AppHeader' 20 | import { StepsContextProvider } from '@/contexts/steps' 21 | import { WalletContextProvider } from '@/contexts/wallet' 22 | import LockedWalletLayout from '@/pages/LockedWalletLayout' 23 | 24 | interface NewWalletLayoutProps { 25 | steps: JSX.Element[] 26 | baseUrl: 'import' | 'create' 27 | } 28 | 29 | const NewWalletLayout = ({ steps, baseUrl }: NewWalletLayoutProps) => ( 30 | 31 | 32 | 33 | 34 | 35 | 36 | ) 37 | 38 | export default NewWalletLayout 39 | -------------------------------------------------------------------------------- /src/pages/UnlockedWallet/OverviewPage/TimeOfDayMessage.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import dayjs from 'dayjs' 20 | import { useTranslation } from 'react-i18next' 21 | 22 | const TimeOfDayMessage = () => { 23 | const { t } = useTranslation() 24 | 25 | const hour = dayjs().hour() 26 | 27 | return ( 28 | 29 | { 30 | hour >= 0 && hour < 5 31 | ? '🌝 ' + t('Good night.') 32 | : hour >= 5 && hour < 12 33 | ? '🌅 ' + t('Good morning.') 34 | : hour >= 12 && hour < 18 35 | ? '🌞 ' + t('Good afternoon.') 36 | : hour >= 18 && hour < 21 37 | ? '🌇 ' + t('Good evening.') 38 | : '🌝 ' + t('Good night.') // handle hour 21 to 23 and overflow to 0 to cover all hours 39 | } 40 | 41 | ) 42 | } 43 | 44 | export default TimeOfDayMessage 45 | -------------------------------------------------------------------------------- /src/routes/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { Route, Routes } from 'react-router-dom' 20 | 21 | import HomePage from '@/pages/HomePage' 22 | import CheckWordsIntroPage from '@/pages/NewWallet/CheckWordsIntroPage' 23 | import CheckWordsPage from '@/pages/NewWallet/CheckWordsPage' 24 | import CreateWalletPage from '@/pages/NewWallet/CreateWalletPage' 25 | import ImportWordsPage from '@/pages/NewWallet/ImportWordsPage' 26 | import NewWalletLayout from '@/pages/NewWallet/NewWalletLayout' 27 | import WalletWelcomePage from '@/pages/NewWallet/WalletWelcomePage' 28 | import WalletWordsPage from '@/pages/NewWallet/WalletWordsPage' 29 | import UnlockedWalletRoutes from '@/routes/UnlockedWalletRoutes' 30 | 31 | const createWalletSteps = [ 32 | , 33 | , 34 | , 35 | , 36 | 37 | ] 38 | const importWalletSteps = [ 39 | , 40 | , 41 | 42 | ] 43 | 44 | const Router = () => ( 45 | 46 | } /> 47 | } /> 48 | } /> 49 | } /> 50 | 51 | ) 52 | 53 | export default Router 54 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 20 | // allows you to do things like: 21 | // expect(element).toHaveTextContent(/react/i) 22 | // learn more: https://github.com/testing-library/jest-dom 23 | 24 | import '@testing-library/jest-dom' 25 | 26 | import { ThemeConsumer } from 'styled-components' 27 | 28 | import { lightTheme } from './style/themes' 29 | 30 | beforeEach(() => { 31 | ThemeConsumer._currentValue = lightTheme // Make `theme` prop available in all components 32 | }) 33 | -------------------------------------------------------------------------------- /src/storage/addresses/addressesAdapters.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { createEntityAdapter } from '@reduxjs/toolkit' 20 | 21 | import { Address, BalanceHistory } from '@/types/addresses' 22 | import { Contact } from '@/types/contacts' 23 | 24 | export const addressesAdapter = createEntityAdapter
({ 25 | selectId: (address) => address.hash, 26 | sortComparer: (a, b) => { 27 | // Always keep main address to the top of the list 28 | if (a.isDefault) return -1 29 | if (b.isDefault) return 1 30 | return (b.lastUsed ?? 0) - (a.lastUsed ?? 0) 31 | } 32 | }) 33 | 34 | export const contactsAdapter = createEntityAdapter({ 35 | sortComparer: (a, b) => a.name.localeCompare(b.name) 36 | }) 37 | 38 | export const balanceHistoryAdapter = createEntityAdapter({ 39 | selectId: ({ date }) => date, 40 | sortComparer: (a, b) => a.date.localeCompare(b.date) 41 | }) 42 | -------------------------------------------------------------------------------- /src/storage/addresses/contactsSlice.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { createSlice, EntityState } from '@reduxjs/toolkit' 20 | 21 | import { 22 | contactDeletedFromPeristentStorage, 23 | contactsLoadedFromPersistentStorage, 24 | contactStoredInPersistentStorage 25 | } from '@/storage/addresses/addressesActions' 26 | import { contactsAdapter } from '@/storage/addresses/addressesAdapters' 27 | import { activeWalletDeleted, walletLocked, walletSwitched } from '@/storage/wallets/walletActions' 28 | import { Contact } from '@/types/contacts' 29 | 30 | type ContactsState = EntityState 31 | 32 | const initialState: ContactsState = contactsAdapter.getInitialState() 33 | 34 | export const contactsSlice = createSlice({ 35 | name: 'contacts', 36 | initialState, 37 | reducers: {}, 38 | extraReducers(builder) { 39 | builder 40 | .addCase(walletLocked, resetState) 41 | .addCase(walletSwitched, resetState) 42 | .addCase(activeWalletDeleted, resetState) 43 | .addCase(contactStoredInPersistentStorage, contactsAdapter.upsertOne) 44 | .addCase(contactsLoadedFromPersistentStorage, contactsAdapter.setAll) 45 | .addCase(contactDeletedFromPeristentStorage, contactsAdapter.removeOne) 46 | } 47 | }) 48 | 49 | export default contactsSlice 50 | 51 | // Reducers helper functions 52 | 53 | const resetState = () => initialState 54 | -------------------------------------------------------------------------------- /src/storage/analytics/analyticsPersistentStorage.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { nanoid } from 'nanoid' 20 | 21 | export type AnalyticsId = string 22 | 23 | class AnalyticsStorage { 24 | private static localStorageKey = 'analytics' 25 | 26 | private generateAnalyticsId(): AnalyticsId { 27 | const analyticsId = nanoid() 28 | 29 | window.localStorage.setItem(AnalyticsStorage.localStorageKey, analyticsId) 30 | 31 | return analyticsId 32 | } 33 | 34 | load(): AnalyticsId { 35 | const rawData = window.localStorage.getItem(AnalyticsStorage.localStorageKey) 36 | 37 | return rawData || this.generateAnalyticsId() 38 | } 39 | } 40 | 41 | const Storage = new AnalyticsStorage() 42 | 43 | export default Storage 44 | -------------------------------------------------------------------------------- /src/storage/assets/assetsAdapter.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { AssetInfo } from '@alephium/sdk' 20 | import { createEntityAdapter } from '@reduxjs/toolkit' 21 | 22 | import { NFT } from '@/types/assets' 23 | 24 | export const assetsInfoAdapter = createEntityAdapter({ 25 | sortComparer: (a, b) => a.name.localeCompare(b.name) 26 | }) 27 | 28 | export const nftsAdapter = createEntityAdapter({ 29 | sortComparer: (a, b) => (a.name && b.name ? a.name.localeCompare(b.name) : a.id.localeCompare(b.id)) 30 | }) 31 | -------------------------------------------------------------------------------- /src/storage/assets/assetsSelectors.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { createSelector } from '@reduxjs/toolkit' 20 | 21 | import { assetsInfoAdapter, nftsAdapter } from '@/storage/assets/assetsAdapter' 22 | import { networkPresets } from '@/storage/settings/settingsPersistentStorage' 23 | import { RootState } from '@/storage/store' 24 | 25 | export const { selectAll: selectAllAssetsInfo, selectById: selectAssetInfoById } = 26 | assetsInfoAdapter.getSelectors((state) => state.assetsInfo) 27 | 28 | export const selectIsTokensMetadataUninitialized = createSelector( 29 | [(state: RootState) => state.assetsInfo.status, (state: RootState) => state.network.settings.networkId], 30 | (status, networkId) => 31 | (networkId === networkPresets.mainnet.networkId || networkId === networkPresets.testnet.networkId) && 32 | status === 'uninitialized' 33 | ) 34 | 35 | export const { 36 | selectAll: selectAllNFTs, 37 | selectById: selectNFTById, 38 | selectIds: selectNFTIds 39 | } = nftsAdapter.getSelectors((state) => state.nfts) 40 | -------------------------------------------------------------------------------- /src/storage/assets/nftsSlice.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { createSlice, EntityState } from '@reduxjs/toolkit' 20 | 21 | import { syncUnknownTokensInfo } from '@/storage/assets/assetsActions' 22 | import { nftsAdapter } from '@/storage/assets/assetsAdapter' 23 | import { customNetworkSettingsSaved, networkPresetSwitched } from '@/storage/settings/networkActions' 24 | import { NFT } from '@/types/assets' 25 | 26 | type NFTsState = EntityState 27 | 28 | const initialState: NFTsState = nftsAdapter.getInitialState() 29 | 30 | const nftsSlice = createSlice({ 31 | name: 'nfts', 32 | initialState, 33 | reducers: {}, 34 | extraReducers(builder) { 35 | builder 36 | .addCase(syncUnknownTokensInfo.fulfilled, (state, action) => { 37 | const nfts = action.payload.nfts 38 | 39 | nftsAdapter.upsertMany(state, nfts) 40 | }) 41 | .addCase(networkPresetSwitched, resetState) 42 | .addCase(customNetworkSettingsSaved, resetState) 43 | } 44 | }) 45 | 46 | export default nftsSlice 47 | 48 | const resetState = () => initialState 49 | -------------------------------------------------------------------------------- /src/storage/auth/authActions.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { createAction } from '@reduxjs/toolkit' 20 | 21 | export const passwordValidationFailed = createAction('auth/passwordValidationFailed') 22 | -------------------------------------------------------------------------------- /src/storage/dApps/dAppActions.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { createAction } from '@reduxjs/toolkit' 20 | 21 | import { Message } from '@/types/snackbar' 22 | 23 | export const walletConnectPairingFailed = createAction('dApps/walletConnectPairingFailed') 24 | 25 | export const walletConnectProposalApprovalFailed = createAction('dApps/walletConnectProposalApprovalFailed') 26 | -------------------------------------------------------------------------------- /src/storage/encryptedPersistentStorage.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import posthog from 'posthog-js' 20 | 21 | import { loadingDataFromLocalStorageFailed, storingDataToLocalStorageFailed } from '@/storage/global/globalActions' 22 | import { 23 | EncryptedStorageProps, 24 | StatelessPersistentEncryptedStorage 25 | } from '@/storage/statelessEncryptedPersistentStorage' 26 | import { store } from '@/storage/store' 27 | 28 | export class PersistentEncryptedStorage extends StatelessPersistentEncryptedStorage { 29 | load() { 30 | try { 31 | return this._load(getEncryptedStoragePropsFromActiveWallet()) 32 | } catch (e) { 33 | console.error(e) 34 | store.dispatch(loadingDataFromLocalStorageFailed()) 35 | posthog.capture('Error', { message: 'Could not load data from local storage' }) 36 | } 37 | } 38 | 39 | protected _store(data: string) { 40 | try { 41 | this._storeStateless(data, getEncryptedStoragePropsFromActiveWallet()) 42 | } catch (e) { 43 | console.error(e) 44 | store.dispatch(storingDataToLocalStorageFailed()) 45 | posthog.capture('Error', { message: 'Could not store data from local storage' }) 46 | } 47 | } 48 | } 49 | 50 | export const getEncryptedStoragePropsFromActiveWallet = (): EncryptedStorageProps => { 51 | const { id, mnemonic, passphrase } = store.getState().activeWallet 52 | 53 | if (!id || !mnemonic) throw new Error('Active wallet not found.') 54 | 55 | return { walletId: id, mnemonic, passphrase } 56 | } 57 | -------------------------------------------------------------------------------- /src/storage/settings/networkActions.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { createAction } from '@reduxjs/toolkit' 20 | 21 | import { NetworkName, NetworkPreset, NetworkStatus } from '@/types/network' 22 | import { NetworkSettings } from '@/types/settings' 23 | 24 | export const networkPresetSwitched = createAction('network/networkPresetSwitched') 25 | 26 | export const customNetworkSettingsSaved = createAction('network/customNetworkSettingsSaved') 27 | 28 | export const apiClientInitSucceeded = createAction<{ 29 | networkId: NetworkSettings['networkId'] 30 | networkName: NetworkName 31 | }>('network/apiClientInitSucceeded') 32 | 33 | export const apiClientInitFailed = createAction<{ networkName: NetworkName; networkStatus: NetworkStatus }>( 34 | 'network/apiClientInitFailed' 35 | ) 36 | -------------------------------------------------------------------------------- /src/storage/settings/settingsActions.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { createAction } from '@reduxjs/toolkit' 20 | 21 | import { Language, Settings, ThemeType } from '@/types/settings' 22 | 23 | export const languageChangeStarted = createAction('settings/languageChangeStarted') 24 | 25 | export const languageChangeFinished = createAction('settings/languageChangeFinished') 26 | 27 | export const systemLanguageMatchSucceeded = createAction('settings/systemLanguageMatchSucceeded') 28 | 29 | export const systemLanguageMatchFailed = createAction('settings/systemLanguageMatchFailed') 30 | 31 | export const themeSettingsChanged = createAction('settings/themeSettingsChanged') 32 | 33 | export const themeToggled = createAction('settings/themeToggled') 34 | 35 | export const discreetModeToggled = createAction('settings/discreetModeToggled') 36 | 37 | export const passwordRequirementToggled = createAction('settings/passwordRequirementToggled') 38 | 39 | export const devToolsToggled = createAction('settings/devToolsToggled') 40 | 41 | export const languageChanged = createAction('settings/languageChanged') 42 | 43 | export const walletLockTimeChanged = createAction( 44 | 'settings/walletLockTimeChanged' 45 | ) 46 | 47 | export const analyticsToggled = createAction('settings/analyticsToggled') 48 | 49 | export const fiatCurrencyChanged = createAction('settings/fiatCurrencyChanged') 50 | -------------------------------------------------------------------------------- /src/storage/settings/settingsStorageUtils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { themeSettingsChanged, themeToggled } from '@/storage/settings/settingsActions' 20 | import { store } from '@/storage/store' 21 | import { ThemeSettings, ThemeType } from '@/types/settings' 22 | import { AlephiumWindow } from '@/types/window' 23 | 24 | const _window = window as unknown as AlephiumWindow 25 | const electron = _window.electron 26 | 27 | export const switchTheme = (theme: ThemeSettings) => { 28 | electron?.theme.setNativeTheme(theme) 29 | store.dispatch(themeSettingsChanged(theme)) 30 | } 31 | 32 | export const toggleTheme = (theme: ThemeType) => { 33 | electron?.theme.setNativeTheme(theme) 34 | store.dispatch(themeToggled(theme)) 35 | } 36 | -------------------------------------------------------------------------------- /src/storage/transactions/pendingTransactionsPersistentStorage.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { 20 | EncryptedStorageProps, 21 | StatelessPersistentEncryptedStorage 22 | } from '@/storage/statelessEncryptedPersistentStorage' 23 | import { PendingTransaction } from '@/types/transactions' 24 | 25 | class PendingTransactionsStorage extends StatelessPersistentEncryptedStorage { 26 | load(encryptedStorageProps: EncryptedStorageProps) { 27 | return this._load(encryptedStorageProps) as PendingTransaction[] 28 | } 29 | 30 | store(transactions: PendingTransaction[], encryptedStorageProps: EncryptedStorageProps) { 31 | this._storeStateless(JSON.stringify(transactions), encryptedStorageProps) 32 | } 33 | } 34 | 35 | const version = '1' 36 | const Storage = new PendingTransactionsStorage('pending-transactions', version) 37 | 38 | export default Storage 39 | -------------------------------------------------------------------------------- /src/storage/transactions/transactionsAdapters.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { explorer } from '@alephium/web3' 20 | import { createEntityAdapter } from '@reduxjs/toolkit' 21 | 22 | import { PendingTransaction } from '@/types/transactions' 23 | 24 | export const confirmedTransactionsAdapter = createEntityAdapter({ 25 | selectId: (transaction) => transaction.hash, 26 | sortComparer: (a, b) => b.timestamp - a.timestamp 27 | }) 28 | 29 | export const pendingTransactionsAdapter = createEntityAdapter({ 30 | selectId: (transaction) => transaction.hash, 31 | sortComparer: (a, b) => b.timestamp - a.timestamp 32 | }) 33 | -------------------------------------------------------------------------------- /src/storage/transactions/transactionsStorageUtils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { MempoolTransaction } from '@alephium/web3/dist/src/api/api-explorer' 20 | import posthog from 'posthog-js' 21 | 22 | import { getEncryptedStoragePropsFromActiveWallet } from '@/storage/encryptedPersistentStorage' 23 | import { store } from '@/storage/store' 24 | import PendingTransactionsStorage from '@/storage/transactions/pendingTransactionsPersistentStorage' 25 | import { 26 | loadingPendingTransactionsFailed, 27 | storedPendingTransactionsLoaded 28 | } from '@/storage/transactions/transactionsActions' 29 | import { PendingTransaction } from '@/types/transactions' 30 | 31 | export const getStoredPendingTransactions = () => { 32 | const encryptedStorageProps = getEncryptedStoragePropsFromActiveWallet() 33 | 34 | return PendingTransactionsStorage.load(encryptedStorageProps) 35 | } 36 | 37 | export const restorePendingTransactions = ( 38 | mempoolTxHashes: MempoolTransaction['hash'][], 39 | storedPendingTxs: PendingTransaction[] 40 | ) => { 41 | try { 42 | const encryptedStorageProps = getEncryptedStoragePropsFromActiveWallet() 43 | const usefulPendingTxs = storedPendingTxs.filter((tx) => mempoolTxHashes.includes(tx.hash)) 44 | 45 | store.dispatch(storedPendingTransactionsLoaded(usefulPendingTxs)) 46 | PendingTransactionsStorage.store(usefulPendingTxs, encryptedStorageProps) 47 | } catch (e) { 48 | console.error(e) 49 | store.dispatch(loadingPendingTransactionsFailed()) 50 | posthog.capture('Error', { message: 'Restoring pending transactions' }) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/storage/wallets/activeWalletSlice.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { createSlice } from '@reduxjs/toolkit' 20 | 21 | import { 22 | activeWalletDeleted, 23 | newWalletNameStored, 24 | walletLocked, 25 | walletSaved, 26 | walletSwitched, 27 | walletUnlocked 28 | } from '@/storage/wallets/walletActions' 29 | import { ActiveWallet } from '@/types/wallet' 30 | 31 | type ActiveWalletState = Partial 32 | 33 | const initialState: ActiveWalletState = { 34 | id: undefined, 35 | name: undefined, 36 | mnemonic: undefined, 37 | passphrase: undefined 38 | } 39 | 40 | const activeWalletSlice = createSlice({ 41 | name: 'activeWallet', 42 | initialState, 43 | reducers: {}, 44 | extraReducers(builder) { 45 | builder 46 | .addCase(walletSaved, (_, action) => action.payload.wallet) 47 | .addCase(walletUnlocked, (_, action) => action.payload.wallet) 48 | .addCase(walletSwitched, (_, action) => action.payload.wallet) 49 | .addCase(walletLocked, resetState) 50 | .addCase(activeWalletDeleted, resetState) 51 | .addCase(newWalletNameStored, (state, action) => { 52 | state.name = action.payload 53 | }) 54 | } 55 | }) 56 | 57 | export default activeWalletSlice 58 | 59 | // Reducers helper functions 60 | 61 | const resetState = () => initialState 62 | -------------------------------------------------------------------------------- /src/storage/wallets/walletActions.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { createAction } from '@reduxjs/toolkit' 20 | 21 | import { Message } from '@/types/snackbar' 22 | import { GeneratedWallet, StoredWallet, UnlockedWallet } from '@/types/wallet' 23 | 24 | export const walletCreationFailed = createAction('wallets/walletCreationFailed') 25 | 26 | export const walletNameStorageFailed = createAction('wallets/walletNameStorageFailed') 27 | 28 | export const walletDeleted = createAction('wallets/walletDeleted') 29 | 30 | export const walletSaved = createAction('wallets/walletSaved') 31 | 32 | export const walletLocked = createAction('wallets/walletLocked') 33 | 34 | export const walletUnlocked = createAction('wallets/walletUnlocked') 35 | 36 | export const walletSwitched = createAction('wallets/walletSwitched') 37 | 38 | export const activeWalletDeleted = createAction('wallets/activeWalletDeleted') 39 | 40 | export const newWalletNameStored = createAction('wallets/newWalletNameStored') 41 | -------------------------------------------------------------------------------- /src/storage/wallets/walletStorageUtils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { Wallet } from '@alephium/sdk' 20 | 21 | import { syncAddressesData } from '@/storage/addresses/addressesActions' 22 | import AddressMetadataStorage from '@/storage/addresses/addressMetadataPersistentStorage' 23 | import { store } from '@/storage/store' 24 | import { walletSaved } from '@/storage/wallets/walletActions' 25 | import WalletStorage from '@/storage/wallets/walletPersistentStorage' 26 | import { StoredWallet } from '@/types/wallet' 27 | import { getInitialAddressSettings } from '@/utils/addresses' 28 | import { getWalletInitialAddress } from '@/utils/wallet' 29 | 30 | interface SaveNewWalletProps { 31 | walletName: string 32 | password: string 33 | wallet: Wallet 34 | } 35 | 36 | export const saveNewWallet = ({ walletName, password, wallet }: SaveNewWalletProps): StoredWallet['id'] => { 37 | const initialAddressSettings = getInitialAddressSettings() 38 | const storedWallet = WalletStorage.store(walletName, password, wallet) 39 | 40 | store.dispatch( 41 | walletSaved({ 42 | wallet: { ...storedWallet, mnemonic: wallet.mnemonic }, 43 | initialAddress: { ...getWalletInitialAddress(wallet), ...initialAddressSettings } 44 | }) 45 | ) 46 | 47 | AddressMetadataStorage.store({ index: 0, settings: initialAddressSettings }) 48 | store.dispatch(syncAddressesData()) 49 | 50 | return storedWallet.id 51 | } 52 | -------------------------------------------------------------------------------- /src/style/fonts/Inter.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alephium/desktop-wallet/91f03586f36c4d76fed0a94ac4c4824c17df9a88/src/style/fonts/Inter.var.woff2 -------------------------------------------------------------------------------- /src/style/fonts/RobotoMono-var.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alephium/desktop-wallet/91f03586f36c4d76fed0a94ac4c4824c17df9a88/src/style/fonts/RobotoMono-var.ttf -------------------------------------------------------------------------------- /src/style/resets.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | import { css } from 'styled-components' 19 | 20 | export default css` 21 | * { 22 | box-sizing: border-box; 23 | } 24 | 25 | input, 26 | button { 27 | outline: none; 28 | border: none; 29 | background: transparent; 30 | } 31 | 32 | a { 33 | text-decoration: none; 34 | color: inherit; 35 | } 36 | ` 37 | -------------------------------------------------------------------------------- /src/style/tags.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { css } from 'styled-components' 20 | 21 | export default css` 22 | .tagify__tag__removeBtn { 23 | display: none; 24 | } 25 | 26 | .tagify__input::before { 27 | line-height: 16px; 28 | } 29 | 30 | .tags-dropdown { 31 | position: fixed; 32 | bottom: var(--spacing-2) !important; 33 | left: var(--spacing-2) !important; 34 | right: var(--spacing-2) !important; 35 | width: auto !important; 36 | top: auto !important; 37 | margin: 0; 38 | 39 | .tagify__dropdown__wrapper { 40 | border: none; 41 | border-radius: var(--radius-small); 42 | background-color: ${({ theme }) => (theme.name === 'light' ? theme.bg.contrast : theme.bg.primary)}; 43 | } 44 | 45 | .tagify__dropdown__item { 46 | color: ${({ theme }) => (theme.name === 'light' ? theme.font.contrastPrimary : theme.font.primary)}; 47 | margin: 0; 48 | border-radius: 0; 49 | padding: var(--spacing-2); 50 | 51 | &:not(:last-child) { 52 | border-bottom: 1px solid ${({ theme }) => theme.border}; 53 | } 54 | } 55 | 56 | .tagify__dropdown__item--active { 57 | background-color: ${({ theme }) => theme.global.accent}; 58 | } 59 | } 60 | ` 61 | -------------------------------------------------------------------------------- /src/tests/fixtures/wallet.json: -------------------------------------------------------------------------------- 1 | { 2 | "mnemonic": "scan pause slender around cube flavor neck shrug gadget ramp rude lend capable tone nose unhappy gift across cluster minor tragic fever detail script", 3 | "seed": "f585d130dd79d3b5bd63aa99d9bc6e6107cfbbe393b86d70e865f6e75c60a37496afc1b25cd4d1ab3b82d9b41f469c6c112a9f310e441814147ff27a5d65882b", 4 | "address": "12kMjpXxCHDebp8ChJYSEyWBgJzmUMSnvgD4EXK6E4kCa", 5 | "publicKey": "033b670c6ee7cb01efa974e9ed2637323a024415a267ff4d43c769e4fb38753628", 6 | "privateKey": "94eccd647bc7b1be87db2187f9c6497561716cf50149e89d7a3f701e2f1b0a86" 7 | } 8 | -------------------------------------------------------------------------------- /src/tests/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { render } from '@testing-library/react' 20 | import { Provider } from 'react-redux' 21 | import { PartialDeep } from 'type-fest' 22 | 23 | import { GlobalContextProps, GlobalContextProvider } from '@/contexts/global' 24 | import { store } from '@/storage/store' 25 | 26 | export const renderWithGlobalContext = (el: JSX.Element, contextObject?: PartialDeep) => 27 | render( 28 | 29 | {el} 30 | 31 | ) 32 | -------------------------------------------------------------------------------- /src/types/assets.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { Asset, AssetAmount } from '@alephium/sdk' 20 | import { FungibleTokenMetaData, NFTMetaData } from '@alephium/web3' 21 | 22 | export type AssetAmountInputType = AssetAmount & { amountInput?: string } 23 | 24 | export type FungibleTokenBasicMetadata = Omit & { id: Asset['id'] } 25 | 26 | export type NFT = { 27 | id: Asset['id'] 28 | collectionAddress: NFTMetaData['collectionAddress'] 29 | name?: string 30 | description?: string 31 | image?: string 32 | } 33 | 34 | export type SyncUnknownTokensInfoResult = { 35 | tokens: FungibleTokenBasicMetadata[] 36 | nfts: NFT[] 37 | } 38 | -------------------------------------------------------------------------------- /src/types/chart.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { AddressHash } from '@/types/addresses' 20 | 21 | export type LatestAmountPerAddress = Record 22 | 23 | export type DataPoint = { 24 | date: string 25 | worth: number 26 | } 27 | 28 | export const chartLengths = ['1d', '1w', '1m', '1y'] as const 29 | 30 | type ChartLengthType = typeof chartLengths 31 | export type ChartLength = ChartLengthType[number] 32 | -------------------------------------------------------------------------------- /src/types/components.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | type LucideIconType = (props: LucideProps) => JSX.Element 20 | 21 | type FC

= React.FC> 22 | -------------------------------------------------------------------------------- /src/types/contacts.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { Optional } from '@alephium/web3' 20 | 21 | import { AddressHash } from '@/types/addresses' 22 | 23 | export type Contact = { 24 | id: string 25 | name: string 26 | address: AddressHash 27 | } 28 | 29 | export type ContactFormData = Optional 30 | -------------------------------------------------------------------------------- /src/types/i18next.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import 'i18next' 20 | 21 | import en from '../../locales/en-US/translation.json' 22 | 23 | type EnglishTranslationKeys = typeof en 24 | 25 | export type TranslationKey = keyof EnglishTranslationKeys 26 | 27 | declare module 'i18next' { 28 | interface CustomTypeOptions { 29 | resources: { 30 | translation: EnglishTranslationKeys 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/types/network.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | export type NetworkStatus = 'offline' | 'connecting' | 'online' | 'uninitialized' 20 | 21 | export enum NetworkNames { 22 | mainnet = 'mainnet', 23 | testnet = 'testnet', 24 | localhost = 'localhost', 25 | custom = 'custom' 26 | } 27 | 28 | export type NetworkName = keyof typeof NetworkNames 29 | 30 | export type NetworkPreset = Exclude 31 | -------------------------------------------------------------------------------- /src/types/numbers.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | export type TimeInMs = number 20 | 21 | export type Coordinates = { x: number; y: number } 22 | -------------------------------------------------------------------------------- /src/types/snackbar.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | export type Message = string 20 | 21 | export type OptionalMessage = Message | undefined 22 | 23 | export interface SnackbarMessage { 24 | text: Message 25 | type?: 'info' | 'alert' | 'success' 26 | duration?: number 27 | } 28 | -------------------------------------------------------------------------------- /src/types/wallet.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { AddressKeyPair, Wallet } from '@alephium/sdk' 20 | 21 | import { AddressBase } from '@/types/addresses' 22 | import { TimeInMs } from '@/types/numbers' 23 | 24 | export type ActiveWallet = { 25 | id: string 26 | name: string 27 | mnemonic: string 28 | passphrase?: string 29 | } 30 | 31 | export type GeneratedWallet = { 32 | wallet: ActiveWallet & StoredWallet 33 | initialAddress: AddressBase 34 | } 35 | 36 | export type UnlockedWallet = { 37 | wallet: ActiveWallet 38 | initialAddress: AddressKeyPair 39 | } 40 | 41 | export type StoredWallet = { 42 | id: ActiveWallet['id'] 43 | name: ActiveWallet['name'] 44 | encrypted: string 45 | lastUsed: TimeInMs 46 | } 47 | 48 | export type UnencryptedWallet = Wallet & { 49 | name: ActiveWallet['name'] 50 | } 51 | -------------------------------------------------------------------------------- /src/types/window.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { Error, ProgressInfo, UpdateDownloadedEvent } from 'electron-updater' 20 | 21 | import { ThemeSettings } from './settings' 22 | 23 | interface NativeTheme { 24 | shouldUseDarkColors: boolean 25 | themeSource: string 26 | } 27 | 28 | export interface AlephiumWindow extends Window { 29 | electron?: { 30 | theme: { 31 | setNativeTheme: (theme: ThemeSettings) => void 32 | getNativeTheme: () => void 33 | onGetNativeTheme: (callback: (nativeTheme: NativeTheme) => void) => () => void 34 | onShouldUseDarkColors: (callback: (useDark: boolean) => void) => () => void 35 | } 36 | updater: { 37 | checkForUpdates: () => Promise 38 | startUpdateDownload: () => void 39 | onUpdateDownloadProgress: (callback: (info: ProgressInfo) => void) => () => void 40 | onUpdateDownloaded: (callback: (updateDownloadedEvent: UpdateDownloadedEvent) => void) => () => void 41 | quitAndInstallUpdate: () => void 42 | onError: (callback: (error: Error) => void) => () => void 43 | } 44 | walletConnect: { 45 | onConnect: (callback: (uri: string) => Promise) => () => void 46 | resetDeepLinkUri: () => void 47 | getDeepLinkUri: () => Promise 48 | } 49 | app: { 50 | hide: () => void 51 | show: () => void 52 | getSystemLanguage: () => Promise 53 | setProxySettings: (proxySettings: ProxySettings) => Promise 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/utils/app-data.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | export const KEY_APPMETADATA = 'alephium/desktop-wallet/appmetadata' 20 | 21 | export interface AppMetaData { 22 | lastVersionCheckedAt: Date 23 | } 24 | 25 | export type TypeConstructors = DateConstructor | StringConstructor | NumberConstructor | BooleanConstructor 26 | 27 | export const APPMETADATA_KEYS: Record = { 28 | lastVersionCheckedAt: Date 29 | } 30 | 31 | export const toAppMetaData = (key: string, value: string): unknown => { 32 | if (key === '') return value 33 | const TypeConstructor = APPMETADATA_KEYS[key] 34 | return (TypeConstructor && new TypeConstructor(value)) || undefined 35 | } 36 | -------------------------------------------------------------------------------- /src/utils/colors.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | export const labelColorPalette = ['#3DD97E', '#FFC400', '#64C9E1', '#9257FF', '#0D92FF', '#EB3BBC', '#EF5959'] 20 | 21 | export const getRandomLabelColor = () => labelColorPalette[Math.floor(Math.random() * labelColorPalette.length)] 22 | 23 | export const stringToColour = (str: string) => { 24 | let hash = 0 25 | for (let i = 0; i < str.length; i++) { 26 | hash = str.charCodeAt(i) + ((hash << 5) - hash) 27 | } 28 | let colour = '#' 29 | for (let i = 0; i < 3; i++) { 30 | const value = (hash >> (i * 8)) & 0xff 31 | colour += ('00' + value.toString(16)).substr(-2) 32 | } 33 | return colour 34 | } 35 | -------------------------------------------------------------------------------- /src/utils/constants.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | export enum WALLETCONNECT_ERRORS { 20 | TRANSACTION_SEND_FAILED = -32000, 21 | PARSING_SESSION_REQUEST_FAILED = -33000, 22 | TRANSACTION_BUILD_FAILED = -34000, 23 | TRANSACTION_SIGN_FAILED = -35000 24 | } 25 | 26 | export const CHART_DATE_FORMAT = 'YYYY-MM-DD' 27 | -------------------------------------------------------------------------------- /src/utils/contacts.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { contactsLoadedFromPersistentStorage } from '@/storage/addresses/addressesActions' 20 | import ContactsStorage from '@/storage/addresses/contactsPersistentStorage' 21 | import { store } from '@/storage/store' 22 | import { Contact } from '@/types/contacts' 23 | 24 | export const filterContacts = (contacts: Contact[], text: string) => 25 | text.length < 2 26 | ? contacts 27 | : contacts.filter( 28 | (contact) => contact.name.toLowerCase().includes(text) || contact.address.toLowerCase().includes(text) 29 | ) 30 | 31 | export const loadContacts = () => { 32 | const contacts: Contact[] = ContactsStorage.load() 33 | 34 | if (contacts.length > 0) store.dispatch(contactsLoadedFromPersistentStorage(contacts)) 35 | } 36 | -------------------------------------------------------------------------------- /src/utils/csvExport.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import dayjs from 'dayjs' 20 | 21 | import { CsvExportTimerangeQueryParams, TransactionTimePeriod } from '@/types/transactions' 22 | 23 | export const getCsvExportTimeRangeQueryParams = ( 24 | selectedTimePeriod: TransactionTimePeriod, 25 | now: dayjs.Dayjs 26 | ): CsvExportTimerangeQueryParams => { 27 | const thisMoment = now.valueOf() 28 | const lastYear = now.subtract(1, 'year') 29 | 30 | return { 31 | '24h': { fromTs: now.subtract(24, 'hour').valueOf(), toTs: thisMoment }, 32 | '1w': { fromTs: now.subtract(7, 'day').valueOf(), toTs: thisMoment }, 33 | '1m': { fromTs: now.subtract(30, 'day').valueOf(), toTs: thisMoment }, 34 | '6m': { fromTs: now.subtract(6, 'month').valueOf(), toTs: thisMoment }, 35 | '12m': { fromTs: now.subtract(12, 'month').valueOf(), toTs: thisMoment }, 36 | previousYear: { 37 | fromTs: lastYear.startOf('year').valueOf(), 38 | toTs: lastYear.endOf('year').valueOf() 39 | }, 40 | thisYear: { fromTs: now.startOf('year').valueOf(), toTs: thisMoment } 41 | }[selectedTimePeriod] 42 | } 43 | 44 | export const generateCsvFile = (csvContent: string, fileName: string) => { 45 | const url = URL.createObjectURL(new Blob([csvContent], { type: 'text/csv' })) 46 | const a = document.createElement('a') 47 | a.style.display = 'none' 48 | a.href = url 49 | a.download = fileName 50 | document.body.appendChild(a) 51 | a.click() 52 | document.body.removeChild(a) 53 | window.URL.revokeObjectURL(url) 54 | } 55 | -------------------------------------------------------------------------------- /src/utils/currencies.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { Currency } from '@/types/settings' 20 | 21 | type CurrencyData = { 22 | name: string 23 | ticker: Currency 24 | symbol: string 25 | } 26 | 27 | export const currencies: Record = { 28 | CHF: { 29 | name: 'Swiss francs', 30 | ticker: 'CHF', 31 | symbol: 'CHF' 32 | }, 33 | EUR: { 34 | name: 'Euro', 35 | ticker: 'EUR', 36 | symbol: '€' 37 | }, 38 | IDR: { 39 | name: 'Rupiah', 40 | ticker: 'IDR', 41 | symbol: 'Rp' 42 | }, 43 | GBP: { 44 | name: 'Great Britain Pound', 45 | ticker: 'GBP', 46 | symbol: '£' 47 | }, 48 | USD: { 49 | name: 'United States Dollar', 50 | ticker: 'USD', 51 | symbol: '$' 52 | }, 53 | TRY: { 54 | name: 'Turkish Lira', 55 | ticker: 'TRY', 56 | symbol: '₺' 57 | }, 58 | VND: { 59 | name: 'Vietnamese Dong', 60 | ticker: 'VND', 61 | symbol: '₫' 62 | }, 63 | RUB: { 64 | name: 'Russian Ruble', 65 | ticker: 'RUB', 66 | symbol: '₽' 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/utils/links.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | export const links = { 20 | passphrase: 21 | 'https://docs.alephium.org/wallet/desktop-wallet/advanced-features#2-passphrase-advanced-security-feature', 22 | latestRelease: 'https://github.com/alephium/desktop-wallet/releases/latest', 23 | latestReleaseApi: 'https://api.github.com/repos/alephium/desktop-wallet/releases/latest', 24 | utxoConsolidation: 'https://docs.alephium.org/wallet/desktop-wallet/advanced-features#1-utxo-consolidation', 25 | miningWallet: 'https://docs.alephium.org/wallet/desktop-wallet/configure-mining-wallet', 26 | discord: 'https://www.alephium.org/discord', 27 | faq: 'https://docs.alephium.org/frequently-asked-questions', 28 | analytics: 'https://docs.alephium.org/frequently-asked-questions#what-analytics-does-the-desktop-wallet-collect', 29 | utxoDust: 30 | 'https://docs.alephium.org/frequently-asked-questions#why-is-there-an-additional-0001-alph-per-token-added-to-my-transaction-when-i-try-to-send-tokens', 31 | github: 'https://github.com/alephium', 32 | twitter: 'https://twitter.com/alephium' 33 | } 34 | -------------------------------------------------------------------------------- /src/utils/pointer.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { PointerEvent } from 'react' 20 | 21 | // TODO: Copied from explorer 22 | 23 | export const getPointerAbsolutePositionInElement = (e: PointerEvent) => { 24 | const bounds = e.currentTarget.getBoundingClientRect() 25 | 26 | return { 27 | x: e.clientX - bounds.x, 28 | y: e.clientY - bounds.y 29 | } 30 | } 31 | 32 | export const getPointerRelativePositionInElement = (e: PointerEvent) => { 33 | const { x: posX, y: posY } = getPointerAbsolutePositionInElement(e) 34 | 35 | return { 36 | x: posX / e.currentTarget.clientWidth, 37 | y: posY / e.currentTarget.clientHeight 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/utils/wallet.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { Wallet } from '@alephium/sdk' 20 | 21 | export const getWalletInitialAddress = (wallet: Wallet) => ({ 22 | index: 0, 23 | hash: wallet.address, 24 | publicKey: wallet.publicKey, 25 | privateKey: wallet.privateKey 26 | }) 27 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | /// 20 | /// 21 | -------------------------------------------------------------------------------- /src/workers/addressDiscovery.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { discoverActiveAddresses, Wallet, walletImport } from '@alephium/sdk' 20 | import { ExplorerProvider } from '@alephium/web3' 21 | 22 | import { exponentialBackoffFetchRetry } from '../api/fetchRetry' 23 | 24 | interface WorkerPayload { 25 | data: { 26 | mnemonic: Wallet['mnemonic'] 27 | clientUrl: string 28 | skipIndexes?: number[] 29 | passphrase?: string 30 | } 31 | } 32 | 33 | self.onmessage = ({ data: { mnemonic, passphrase, clientUrl, skipIndexes } }: WorkerPayload) => { 34 | const { masterKey } = walletImport(mnemonic, passphrase) 35 | const client = new ExplorerProvider(clientUrl, undefined, exponentialBackoffFetchRetry) 36 | 37 | discover(masterKey, client, skipIndexes) 38 | } 39 | 40 | const discover = async (masterKey: Wallet['masterKey'], client: ExplorerProvider, skipIndexes?: number[]) => { 41 | const activeAddresses = await discoverActiveAddresses(masterKey, client, skipIndexes) 42 | self.postMessage(activeAddresses) 43 | } 44 | -------------------------------------------------------------------------------- /src/workers/deriveAddressesFromIndexes.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { deriveNewAddressData, Wallet, walletImport } from '@alephium/sdk' 20 | 21 | interface WorkerPayload { 22 | data: { 23 | mnemonic: Wallet['mnemonic'] 24 | indexesToDerive: number[] 25 | passphrase?: string 26 | } 27 | } 28 | 29 | self.onmessage = ({ data: { mnemonic, passphrase, indexesToDerive } }: WorkerPayload) => { 30 | const { masterKey } = walletImport(mnemonic, passphrase) 31 | 32 | derive(masterKey, indexesToDerive) 33 | } 34 | 35 | const derive = (masterKey: Wallet['masterKey'], indexesToDerive: number[]) => { 36 | self.postMessage(indexesToDerive.map((index) => deriveNewAddressData(masterKey, undefined, index))) 37 | } 38 | -------------------------------------------------------------------------------- /src/workers/deriveAddressesInGroups.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | import { deriveNewAddressData, Wallet, walletImport } from '@alephium/sdk' 20 | 21 | interface WorkerPayload { 22 | data: { 23 | mnemonic: Wallet['mnemonic'] 24 | groups: number[] 25 | skipIndexes?: number[] 26 | passphrase?: string 27 | } 28 | } 29 | 30 | self.onmessage = ({ data: { mnemonic, passphrase, groups, skipIndexes } }: WorkerPayload) => { 31 | const { masterKey } = walletImport(mnemonic, passphrase) 32 | 33 | derive(masterKey, groups, skipIndexes) 34 | } 35 | 36 | const derive = (masterKey: Wallet['masterKey'], groups: number[], skipIndexes?: number[]) => { 37 | self.postMessage( 38 | groups.map((group) => ({ ...deriveNewAddressData(masterKey, group, undefined, skipIndexes), group })) 39 | ) 40 | } 41 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "target": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "types": ["vite/client", "vite-plugin-svgr/client", "vitest/globals"], 7 | "allowJs": true, 8 | "skipLibCheck": true, 9 | "esModuleInterop": true, 10 | "allowSyntheticDefaultImports": true, 11 | "strict": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "module": "esnext", 14 | "moduleResolution": "node", 15 | "resolveJsonModule": true, 16 | "isolatedModules": true, 17 | "noEmit": true, 18 | "jsx": "react-jsx", 19 | "noFallthroughCasesInSwitch": true, 20 | "paths": { 21 | "@/*": ["./src/*"] 22 | } 23 | }, 24 | "include": ["src"] 25 | } 26 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 - 2023 The Alephium Authors 3 | This file is part of the alephium project. 4 | 5 | The library is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | The library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with the library. If not, see . 17 | */ 18 | 19 | /// 20 | 21 | import react from '@vitejs/plugin-react' 22 | import { defineConfig } from 'vite' 23 | import svgrPlugin from 'vite-plugin-svgr' 24 | import viteTsconfigPaths from 'vite-tsconfig-paths' 25 | 26 | // https://vitejs.dev/config/ 27 | export default defineConfig({ 28 | server: { 29 | host: true, 30 | port: 3000 31 | }, 32 | optimizeDeps: { 33 | esbuildOptions: { 34 | target: 'es2020', 35 | // Node.js global to browser globalThis 36 | define: { 37 | global: 'globalThis' 38 | } 39 | }, 40 | include: ['@alephium/sdk'] // To allow for using npm link https://vitejs.dev/guide/dep-pre-bundling.html#monorepos-and-linked-dependencies 41 | }, 42 | plugins: [react(), viteTsconfigPaths(), svgrPlugin()], 43 | test: { 44 | globals: true, 45 | environment: 'jsdom', 46 | setupFiles: ['./src/setupTests.js', '@vitest/web-worker'], 47 | coverage: { 48 | reporter: ['text', 'html'], 49 | exclude: ['node_modules/', 'src/setupTests.js'] 50 | } 51 | }, 52 | build: { 53 | target: 'es2020', 54 | outDir: 'build' 55 | }, 56 | base: '' 57 | }) 58 | --------------------------------------------------------------------------------