├── .dockerignore ├── .editorconfig ├── .env.defaults ├── .env.example ├── .env.prod ├── .eslintrc.js ├── .git-blame-ignore-revs ├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── BUG.yml │ ├── FEATURE.yml │ └── config.yml ├── package.json ├── workflows │ ├── build.yml │ ├── builds │ │ ├── detect-env-block.js │ │ └── post-build-link.js │ ├── pledge-signer-sync │ │ ├── package.json │ │ ├── pledge-export.js │ │ ├── pledge-sync.js │ │ └── yarn.lock │ ├── post-build-link.yml │ ├── sync-pledge.yml │ ├── test-list.yml │ └── test-list │ │ └── release-test-list.md └── yarn.lock ├── .gitignore ├── .nvmrc ├── .pre-commit-config.yaml ├── .prettierignore ├── .prettierrc ├── .tsconfig-eslint.json ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── LICENSE-GPLv3.txt ├── LICENSE-additional-terms.txt ├── LICENSE.txt ├── README.md ├── SECURITY.md ├── __mocks__ ├── @ethersproject │ └── web.ts └── uuid.ts ├── babel.config.js ├── background ├── README.md ├── abilities.ts ├── accounts.ts ├── assets.ts ├── constants │ ├── assets.ts │ ├── balances.ts │ ├── base-assets.ts │ ├── coin-types.ts │ ├── currencies.ts │ ├── errors.ts │ ├── index.ts │ ├── network-fees.ts │ ├── networks.ts │ └── website.ts ├── features.ts ├── generate-validators.ts ├── index.ts ├── lib │ ├── alchemy.ts │ ├── approvalTarget.ts │ ├── asset-similarity.ts │ ├── daylight.ts │ ├── enhancers.ts │ ├── erc20.ts │ ├── erc721.ts │ ├── fixed-point.ts │ ├── gas.ts │ ├── logger.ts │ ├── mezo.ts │ ├── multicall.ts │ ├── nfts.ts │ ├── poap.ts │ ├── posthog.ts │ ├── priceOracle.ts │ ├── prices.ts │ ├── simple-hash.ts │ ├── storage-gateway.ts │ ├── tests │ │ ├── daylight.unit.test.ts │ │ └── utils.unit.test.ts │ ├── token-lists.ts │ ├── uniswapPair.ts │ ├── utils │ │ ├── index.ts │ │ └── type-guards.ts │ ├── validate │ │ ├── 0x-swap.ts │ │ ├── alchemy.ts │ │ ├── erc721.ts │ │ ├── index.ts │ │ ├── json-validators.d.ts │ │ ├── json-validators.js │ │ ├── jtd-validators.d.ts │ │ ├── jtd-validators.js │ │ └── prices.ts │ ├── vault.ts │ ├── wrappedAsset.ts │ └── yearnVault.ts ├── networks.ts ├── nfts.ts ├── package.json ├── redux-slices │ ├── 0x-swap.ts │ ├── abilities.ts │ ├── accounts.ts │ ├── activities.ts │ ├── assets.ts │ ├── claim.ts │ ├── contract-abis │ │ └── merkle-distributor.ts │ ├── dapp.ts │ ├── earn-utils │ │ ├── getCurveLPTokenPrice.ts │ │ ├── getDoggoPrice.ts │ │ ├── getLPTokenValue.ts │ │ ├── getPoolAPR.ts │ │ ├── getTokenPrice.ts │ │ ├── getUniswapPairTokenPrice.ts │ │ ├── index.ts │ │ └── tokenIcons.ts │ ├── earn.ts │ ├── index.ts │ ├── internal-signer.ts │ ├── ledger.ts │ ├── migrations │ │ ├── index.ts │ │ ├── to-10.ts │ │ ├── to-11.ts │ │ ├── to-12.ts │ │ ├── to-13.ts │ │ ├── to-14.ts │ │ ├── to-15.ts │ │ ├── to-16.ts │ │ ├── to-17.ts │ │ ├── to-18.ts │ │ ├── to-19.ts │ │ ├── to-2.ts │ │ ├── to-20.ts │ │ ├── to-21.ts │ │ ├── to-22.ts │ │ ├── to-23.ts │ │ ├── to-24.ts │ │ ├── to-25.ts │ │ ├── to-26.ts │ │ ├── to-27.ts │ │ ├── to-28.ts │ │ ├── to-29.ts │ │ ├── to-3.ts │ │ ├── to-30.ts │ │ ├── to-31.ts │ │ ├── to-32.ts │ │ ├── to-33.ts │ │ ├── to-34.ts │ │ ├── to-35.ts │ │ ├── to-4.ts │ │ ├── to-5.ts │ │ ├── to-6.ts │ │ ├── to-7.ts │ │ ├── to-8.ts │ │ └── to-9.ts │ ├── networks.ts │ ├── nfts.ts │ ├── prices.ts │ ├── selectors │ │ ├── 0xSwapSelectors.ts │ │ ├── abilitiesSelectors.ts │ │ ├── accountsSelectors.ts │ │ ├── activitiesSelectors.ts │ │ ├── dappSelectors.ts │ │ ├── index.ts │ │ ├── internalSignerSelectors.ts │ │ ├── ledgerSelectors.ts │ │ ├── networks.ts │ │ ├── nftsSelectors.ts │ │ ├── signingSelectors.ts │ │ ├── transactionConstructionSelectors.ts │ │ └── uiSelectors.ts │ ├── signing.ts │ ├── tests │ │ ├── accounts.unit.test.ts │ │ ├── assets-utils.unit.test.ts │ │ ├── assets.unit.test.ts │ │ ├── nfts.integration.test.ts │ │ ├── nfts.unit.test.ts │ │ ├── nfts.utils.ts │ │ └── transaction-construction.unit.test.ts │ ├── transaction-construction.ts │ ├── ui.ts │ ├── utils.ts │ └── utils │ │ ├── 0x-swap-utils.ts │ │ ├── abilities-utils.ts │ │ ├── activities-utils.ts │ │ ├── asset-utils.ts │ │ ├── constants.ts │ │ ├── contract-utils.ts │ │ ├── nfts-utils.ts │ │ └── tests │ │ ├── abilities-utils.unit.test.ts │ │ ├── asset-utils.unit.test.ts │ │ └── nfts-utils.unit.test.ts ├── services │ ├── README.md │ ├── abilities │ │ ├── db.ts │ │ ├── index.ts │ │ └── tests │ │ │ └── index.integration.test.ts │ ├── analytics │ │ ├── db.ts │ │ ├── index.ts │ │ └── tests │ │ │ └── index.integration.test.ts │ ├── base.ts │ ├── campaign │ │ ├── db.ts │ │ ├── index.ts │ │ ├── matsnet-nft.ts │ │ └── types.ts │ ├── chain │ │ ├── __mocks__ │ │ │ └── serial-fallback-provider.ts │ │ ├── asset-data-helper.ts │ │ ├── db.ts │ │ ├── errors.ts │ │ ├── index.ts │ │ ├── serial-fallback-provider.ts │ │ ├── taho-provider.ts │ │ ├── taho-rpc-provider.ts │ │ ├── tests │ │ │ ├── db.integration.test.ts │ │ │ ├── index.integration.test.ts │ │ │ ├── index.unit.test.ts │ │ │ └── serial-fallback-provider.integration.test.ts │ │ └── utils │ │ │ ├── index.ts │ │ │ └── optimismGasPriceOracle.tsx │ ├── enrichment │ │ ├── addresses.ts │ │ ├── index.ts │ │ ├── tests │ │ │ └── transactions.integration.test.ts │ │ ├── transactions.ts │ │ ├── types.ts │ │ └── utils.ts │ ├── index.ts │ ├── indexing │ │ ├── db.ts │ │ ├── index.ts │ │ ├── tests │ │ │ └── index.integration.test.ts │ │ └── token-list-edit.ts │ ├── internal-ethereum-provider │ │ ├── constants.ts │ │ ├── db.ts │ │ ├── index.ts │ │ └── tests │ │ │ └── index.integration.test.ts │ ├── internal-signer │ │ ├── encryption.ts │ │ ├── index.ts │ │ ├── storage.ts │ │ └── tests │ │ │ ├── encryption.unit.test.ts │ │ │ ├── index.integration.test.ts │ │ │ ├── index.unit.test.ts │ │ │ └── storage.unit.test.ts │ ├── island │ │ ├── contracts.ts │ │ ├── db.ts │ │ ├── defaults.ts │ │ ├── index.ts │ │ ├── types.ts │ │ └── utils.ts │ ├── ledger │ │ ├── db.ts │ │ └── index.ts │ ├── name │ │ ├── index.ts │ │ ├── name-resolver.ts │ │ ├── resolvers │ │ │ ├── address-book.ts │ │ │ ├── ens.ts │ │ │ ├── index.ts │ │ │ ├── known-contracts.ts │ │ │ ├── mezo.ts │ │ │ ├── rns.ts │ │ │ └── uns.ts │ │ └── tests │ │ │ └── index.integration.test.ts │ ├── nfts │ │ ├── db.ts │ │ └── index.ts │ ├── notifications │ │ └── index.ts │ ├── preferences │ │ ├── db.ts │ │ ├── defaults.ts │ │ ├── index.ts │ │ └── tests │ │ │ ├── index.integration.test.ts │ │ │ └── index.unit.test.ts │ ├── provider-bridge │ │ ├── authorization.ts │ │ ├── db.ts │ │ ├── index.ts │ │ ├── show-popup.ts │ │ ├── tests │ │ │ ├── index.unit.test.ts │ │ │ └── utils.unit.test.ts │ │ └── utils.ts │ ├── redux │ │ ├── differ.ts │ │ ├── index.ts │ │ ├── store.ts │ │ └── tests │ │ │ └── differ.test.ts │ ├── signing │ │ ├── index.ts │ │ └── tests │ │ │ └── index.unit.test.ts │ ├── telemetry │ │ └── index.ts │ └── types.ts ├── signing.ts ├── static │ ├── DAOs.json │ ├── delegates.json │ └── eligibles.json ├── tag-types.ts ├── tally-provider.ts ├── tests │ ├── earn │ │ ├── assets.mock.ts │ │ └── earn.test.ts │ ├── factories.ts │ ├── json-serialization.test.ts │ ├── networks.unit.test.ts │ ├── prices.test.ts │ └── utils.ts ├── third-party-data │ └── blocknative │ │ ├── index.ts │ │ └── types.ts ├── types.ts ├── ui.ts └── utils │ ├── fetching.ts │ └── signing.ts ├── build-utils ├── inject-window-provider.ts └── web-extension-archive-webpack-plugin.ts ├── ci ├── README.md ├── hardhat.config.ts ├── package.json └── yarn.lock ├── dev-utils ├── extension-reload.js └── local-chain │ ├── README.md │ ├── contracts │ └── Greeter.sol │ ├── hardhat.config.ts │ ├── package.json │ ├── scripts │ └── sample-script.js │ ├── test │ └── sample-test.js │ └── yarn.lock ├── dist └── .keep ├── e2e-tests ├── fork-based │ └── transactions.spec.ts ├── regular │ ├── accounts.spec.ts │ ├── dapp-connect.spec.ts │ ├── nfts.spec.ts │ ├── onboarding.spec.ts │ ├── signing.spec.ts │ ├── token-trust.spec.ts │ └── transactions.spec.ts ├── utils.ts └── utils │ ├── assets.ts │ ├── connect-popup.ts │ ├── onboarding.ts │ ├── transactions.ts │ └── walletPageHelper.ts ├── env.d.ts ├── firefox-build.sh ├── github_cover@2x.png ├── manifest ├── manifest.brave.json ├── manifest.chrome.json ├── manifest.development.json ├── manifest.firefox.json ├── manifest.json └── manifest.opera.json ├── package.json ├── patches ├── @ethersproject+providers+5.7.2.patch ├── @ledgerhq+hw-app-eth+6.33.4.patch ├── jsan+3.1.14.patch └── webext-redux+4.0.0.patch ├── playwright.config.ts ├── provider-bridge-shared ├── constants.ts ├── eip-1193.ts ├── index.ts ├── package.json ├── runtime-typechecks.ts └── types.ts ├── provider-bridge ├── README.md ├── index.ts └── package.json ├── rfb ├── rfb-1-keyring-design.adoc ├── rfb-2-signers-ui.md ├── rfb-3-multinetwork-dapp-connections.md ├── rfb-4-one-off-keyring-design.adoc ├── rfb-5-control-compatile-addresses.md └── rfb.adoc ├── scripts ├── key-generation │ ├── README.md │ ├── export-key-as-json.js │ ├── package.json │ └── yarn.lock ├── macos-setup.sh ├── unreliable-rpc-provider-utils.ts ├── unreliable-rpc-provider.mjs └── update-version.sh ├── setup-extension-mock.ts ├── setupJest.env.ts ├── setupJest.ts ├── src ├── background-ui.ts ├── background.ts ├── popup.ts ├── provider-bridge.ts ├── tab.ts └── window-provider.ts ├── tsconfig.json ├── ui ├── .babelrc.js ├── README.md ├── __mocks__ │ └── IntersectionObserver.ts ├── _locales │ ├── en │ │ └── messages.json │ ├── es │ │ └── messages.json │ ├── fr │ │ └── messages.json │ ├── i18n.ts │ ├── index.ts │ ├── nb_NO │ │ └── messages.json │ ├── pt_BR │ │ └── messages.json │ ├── ro │ │ └── messages.json │ ├── ru │ │ └── messages.json │ ├── sv │ │ └── messages.json │ ├── zh_Hans │ │ └── messages.json │ └── zh_Hant │ │ └── messages.json ├── components │ ├── AccountItem │ │ ├── AccountItemActionHeader.tsx │ │ ├── AccountItemEditName.tsx │ │ ├── AccountItemOptionLabel.tsx │ │ ├── AccountItemOptionsMenu.tsx │ │ ├── AccountItemRemovalConfirm.tsx │ │ └── RemoveAccountWarning.tsx │ ├── AccountsBackup │ │ ├── ConfirmReveal.tsx │ │ ├── CopyToClipboard.tsx │ │ ├── Explainer.tsx │ │ ├── RevealMnemonic.tsx │ │ ├── RevealPrivateKey.tsx │ │ ├── ShowMnemonic.tsx │ │ └── ShowPrivateKey.tsx │ ├── AccountsNotificationPanel │ │ ├── AccountsNotificationPanel.tsx │ │ ├── AccountsNotificationPanelAccounts.tsx │ │ ├── AccountsNotificationPanelNotificationItem.tsx │ │ ├── AccountsNotificationPanelNotifications.tsx │ │ ├── EditSectionForm.tsx │ │ ├── SigningButton.tsx │ │ └── __tests__ │ │ │ └── SigningButton.test.tsx │ ├── Analytics │ │ └── AnalyticsSlideUpMenu.tsx │ ├── BalanceReloader │ │ └── BalanceReloader.tsx │ ├── BonusProgram │ │ └── BonusProgramModal.tsx │ ├── BrowserTab │ │ └── BrowserTabContainer.tsx │ ├── Claim │ │ ├── ClaimAmountBanner.tsx │ │ ├── ClaimAmountCombinedBanner.tsx │ │ ├── ClaimDelegate.tsx │ │ ├── ClaimDelegateChoiceProfile.tsx │ │ ├── ClaimFooter.tsx │ │ ├── ClaimIntro.tsx │ │ ├── ClaimManifesto.tsx │ │ ├── ClaimReferral.tsx │ │ ├── ClaimReferralBridge.tsx │ │ ├── ClaimReferralByUser.tsx │ │ ├── ClaimReview.tsx │ │ ├── ClaimSuccessModalContent.tsx │ │ └── Success.tsx │ ├── Core │ │ └── CorePage.tsx │ ├── DAppConnection │ │ ├── ActiveDAppConnection.tsx │ │ ├── DAppConnection.tsx │ │ ├── DAppConnectionDefaultToggle.tsx │ │ └── DAppConnectionInfoBar.tsx │ ├── Earn │ │ ├── Clock.tsx │ │ └── EmptyBowl.tsx │ ├── GlobalError │ │ └── GlobalError.tsx │ ├── GlobalModal │ │ └── GlobalModal.tsx │ ├── HiddenDevPanel │ │ ├── FeatureFlagsPanel.tsx │ │ └── HiddenDevPanel.tsx │ ├── InternalSigner │ │ ├── InternalSignerSetPassword.tsx │ │ ├── InternalSignerUnlock.tsx │ │ └── __tests__ │ │ │ └── InternalSignerUnlock.test.tsx │ ├── Ledger │ │ ├── LedgerContinueButton.tsx │ │ ├── LedgerPanelContainer.tsx │ │ └── usb.d.ts │ ├── NFTs │ │ ├── ExploreMarketLink.tsx │ │ ├── Filters │ │ │ ├── FilterList.tsx │ │ │ ├── NFTsFilters.tsx │ │ │ └── __tests__ │ │ │ │ └── FilterList.test.tsx │ │ ├── NFTCollection.tsx │ │ ├── NFTHover.tsx │ │ ├── NFTImage.tsx │ │ ├── NFTItem.tsx │ │ ├── NFTList.tsx │ │ ├── NFTListCurrentWallet.tsx │ │ ├── NFTListPortfolio.tsx │ │ ├── NFTPreview.tsx │ │ ├── NFTsExploreBanner.tsx │ │ ├── NFTsHeader.tsx │ │ ├── NFTsHeaderBase.tsx │ │ ├── NoMatchingNFTs.tsx │ │ └── __tests__ │ │ │ └── NFTItem.test.tsx │ ├── NetworkFees │ │ ├── FeeSettingsButton.tsx │ │ ├── FeeSettingsText.tsx │ │ ├── NetworkSettingsChooser.tsx │ │ ├── NetworkSettingsSelect.tsx │ │ ├── NetworkSettingsSelectArbitrum.tsx │ │ ├── NetworkSettingsSelectBNBChain.tsx │ │ ├── NetworkSettingsSelectOptimism.tsx │ │ ├── NetworkSettingsSelectOptionButtons.tsx │ │ └── NetworkSettingsSelectRSK.tsx │ ├── Onboarding │ │ ├── OnboardingDerivationPathSelect.tsx │ │ ├── OnboardingOpenClaimFlowBanner.tsx │ │ ├── OnboardingStepsIndicator.tsx │ │ ├── RouteBasedContent.tsx │ │ └── WalletShortcut.tsx │ ├── Overview │ │ ├── AbilitiesHeader.tsx │ │ ├── AccountItem.tsx │ │ ├── AccountList.tsx │ │ ├── BalanceHeader.tsx │ │ ├── NFTsPortfolioOverview.tsx │ │ ├── NetworksChart.tsx │ │ └── OverviewAssetsTable.tsx │ ├── Password │ │ └── PasswordStrengthBar.tsx │ ├── Send │ │ ├── NFTCollectionAccordion.tsx │ │ └── NFTCollectionListItem.tsx │ ├── Shared │ │ ├── PasswordInput.tsx │ │ ├── PriceDetails.tsx │ │ ├── ReadOnlyNotice.tsx │ │ ├── SharedAccordion.tsx │ │ ├── SharedAccountItemSummary.tsx │ │ ├── SharedActivityHeader.tsx │ │ ├── SharedActivityIcon.tsx │ │ ├── SharedAddress.tsx │ │ ├── SharedAddressAvatar.tsx │ │ ├── SharedAddressInput.tsx │ │ ├── SharedAssetIcon.tsx │ │ ├── SharedAssetInput.tsx │ │ ├── SharedAssetItem.tsx │ │ ├── SharedAvatar.tsx │ │ ├── SharedBackButton.tsx │ │ ├── SharedBanner.tsx │ │ ├── SharedButton.tsx │ │ ├── SharedButtonUp.tsx │ │ ├── SharedCheckbox.tsx │ │ ├── SharedCurrentAccountInformation.tsx │ │ ├── SharedDropDown.tsx │ │ ├── SharedFileInput.tsx │ │ ├── SharedFilterTooltip.tsx │ │ ├── SharedIcon.tsx │ │ ├── SharedIconRouterLink.tsx │ │ ├── SharedImageWithFallback.tsx │ │ ├── SharedInfoModal.tsx │ │ ├── SharedInput.tsx │ │ ├── SharedLink.tsx │ │ ├── SharedLoadingDoggo.tsx │ │ ├── SharedLoadingSpinner.tsx │ │ ├── SharedModal.tsx │ │ ├── SharedNetworkIcon.tsx │ │ ├── SharedPageHeader.tsx │ │ ├── SharedPanelSwitcher.tsx │ │ ├── SharedProgressIndicator.tsx │ │ ├── SharedRadio.tsx │ │ ├── SharedSecretText.tsx │ │ ├── SharedSeedInput.tsx │ │ ├── SharedSelect.tsx │ │ ├── SharedSkeletonLoader.tsx │ │ ├── SharedSlideUpMenu.tsx │ │ ├── SharedSlideUpMenuPanel.tsx │ │ ├── SharedSquareButton.tsx │ │ ├── SharedToggleButton.tsx │ │ ├── SharedToggleItem.tsx │ │ ├── SharedTooltip.tsx │ │ ├── SharedTwitterButton.tsx │ │ ├── SharedWarningMessage.tsx │ │ ├── __tests__ │ │ │ ├── PasswordInput.test.tsx │ │ │ ├── PriceDetails.test.tsx │ │ │ ├── SharedAssetIcon.test.tsx │ │ │ ├── SharedAssetInput.test.tsx │ │ │ ├── SharedCurrentAccountInformation.test.tsx │ │ │ ├── SharedDropDown.test.tsx │ │ │ ├── SharedInput.test.tsx │ │ │ ├── SharedToggleItem.test.tsx │ │ │ └── SharedTooltip.test.tsx │ │ └── types.ts │ ├── SignData │ │ ├── EIP191Info.tsx │ │ ├── EIP4361Info.tsx │ │ ├── SignDataInfo.tsx │ │ ├── SignTypedDataInfo.tsx │ │ └── index.ts │ ├── Signing │ │ ├── SignatureDetails │ │ │ ├── DataSignatureDetails │ │ │ │ ├── MessageDataSignatureDetails.tsx │ │ │ │ ├── TypedDataSignatureDetails.tsx │ │ │ │ └── index.tsx │ │ │ ├── TransactionSignatureDetails │ │ │ │ ├── DetailsPanel.tsx │ │ │ │ ├── RawDataPanel.tsx │ │ │ │ ├── TransactionAdditionalDetails │ │ │ │ │ ├── SwapAssetDetails.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── TransactionSignatureDetailsPanelCombined.tsx │ │ │ │ ├── TransactionSignatureDetailsPanelSwitcher.tsx │ │ │ │ ├── TransactionSignatureDetailsWarning.tsx │ │ │ │ ├── TransactionSignatureSummary │ │ │ │ │ ├── ContractInteractionSummary.tsx │ │ │ │ │ ├── SpendApprovalSummary.tsx │ │ │ │ │ ├── SwapAssetSummary.tsx │ │ │ │ │ ├── TransactionSignatureSummaryBody.tsx │ │ │ │ │ ├── TransactionSignatureSummaryDefault.tsx │ │ │ │ │ ├── TransactionSignatureSummaryProps.tsx │ │ │ │ │ ├── TransferSummary.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── index.tsx │ │ │ └── index.tsx │ │ ├── Signer │ │ │ ├── SignerBaseFrame.tsx │ │ │ ├── SignerFrame.tsx │ │ │ ├── SignerInternal │ │ │ │ ├── SignerInternalFrame.tsx │ │ │ │ └── SignerInternalSigning.tsx │ │ │ ├── SignerLedger │ │ │ │ ├── LedgerCheckErrorSvg.tsx │ │ │ │ ├── LedgerConnectedSvg.tsx │ │ │ │ ├── LedgerDisconnectedSvg.tsx │ │ │ │ ├── SignerLedgerConnect │ │ │ │ │ ├── ActivateBlindSigning.tsx │ │ │ │ │ ├── LedgerBusy.tsx │ │ │ │ │ ├── LedgerNotConnected.tsx │ │ │ │ │ ├── MultipleLedgersConnected.tsx │ │ │ │ │ ├── SlideUpLayout.tsx │ │ │ │ │ ├── WrongLedgerConnected.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── SignerLedgerConnectionStatus.tsx │ │ │ │ ├── SignerLedgerFrame.tsx │ │ │ │ └── SignerLedgerSigning │ │ │ │ │ └── index.tsx │ │ │ ├── SignerReadOnly │ │ │ │ └── SignerReadOnlyFrame.tsx │ │ │ ├── TransactionButton.tsx │ │ │ └── index.tsx │ │ ├── SigningLoading.tsx │ │ ├── SigningNetworkAccountInfoTopBar.tsx │ │ └── index.tsx │ ├── Snackbar │ │ └── Snackbar.tsx │ ├── Swap │ │ ├── ApproveQuoteButton.tsx │ │ ├── SwapQuoteBalanceChange.tsx │ │ └── SwapRewardsCard.tsx │ ├── TabBar │ │ ├── TabBar.tsx │ │ └── TabBarIconButton.tsx │ ├── TopMenu │ │ ├── TopMenu.tsx │ │ ├── TopMenuConnectedDAppInfo.tsx │ │ ├── TopMenuProfileButton.tsx │ │ ├── TopMenuProfileTooltip.tsx │ │ ├── TopMenuProtocolList.tsx │ │ ├── TopMenuProtocolListFooter.tsx │ │ ├── TopMenuProtocolListItem.tsx │ │ └── TopMenuProtocolSwitcher.tsx │ ├── TransactionDetail │ │ ├── TransactionDetailAddressValue.tsx │ │ ├── TransactionDetailContainer.tsx │ │ └── TransactionDetailItem.tsx │ └── Wallet │ │ ├── AssetListItem │ │ ├── CommonAssetListItem.tsx │ │ ├── DoggoAssetListItem.tsx │ │ └── styles.ts │ │ ├── Banner │ │ ├── PortalBanner.tsx │ │ ├── WalletBanner.tsx │ │ ├── WalletBannerSlideup.tsx │ │ ├── WalletCampaignBanner.tsx │ │ ├── useArbitrumCampaigns.ts │ │ └── useBannerCampaigns.ts │ │ ├── UnverifiedAsset │ │ ├── AssetVerifyToggler.tsx │ │ ├── AssetWarning.tsx │ │ ├── AssetWarningWrapper.tsx │ │ └── UnverifiedAssetBanner.tsx │ │ ├── WalletAccountBalanceControl.tsx │ │ ├── WalletActivityDetails.tsx │ │ ├── WalletActivityList.tsx │ │ ├── WalletActivityListItem.tsx │ │ ├── WalletAnalyticsNotificationBanner.tsx │ │ ├── WalletAssetList.tsx │ │ ├── WalletAssetListItem.tsx │ │ ├── WalletDefaultToggle.tsx │ │ ├── WalletHiddenAssets.tsx │ │ ├── WalletSubscapeLink.tsx │ │ └── __tests__ │ │ └── WalletAnalyticsNotificationBanner.test.tsx ├── hooks │ ├── activity-hooks.ts │ ├── dapp-hooks.ts │ ├── dom-hooks.ts │ ├── earn-hooks.ts │ ├── index.ts │ ├── nft-hooks.ts │ ├── react-hooks.ts │ ├── redux-hooks.ts │ ├── signing-hooks.ts │ └── validation-hooks.ts ├── index.ts ├── package.json ├── pages │ ├── Abilities.tsx │ ├── Abilities │ │ ├── AbilityCard.tsx │ │ ├── AbilityCardHeader.tsx │ │ ├── AbilityFilter.tsx │ │ ├── AbilityFilterCard.tsx │ │ ├── AbilityLabel.tsx │ │ ├── AbilityRemovalConfirm.tsx │ │ └── __tests__ │ │ │ ├── AbilityCard.test.tsx │ │ │ └── AbilityCardHeader.test.tsx │ ├── Claiming │ │ └── Eligible.tsx │ ├── DAppConnect │ │ ├── DAppConnectPage.tsx │ │ └── RequestingDApp.tsx │ ├── DAppConnectRequest.tsx │ ├── Earn.tsx │ ├── Earn │ │ ├── AccordionAPR.tsx │ │ ├── AccordionPoolInfo.tsx │ │ ├── DepositCard.tsx │ │ ├── HeaderComingSoon.tsx │ │ ├── HeaderDeploy.tsx │ │ ├── HeaderTVL.tsx │ │ ├── NotificationVaults.tsx │ │ └── PoolCard.tsx │ ├── EarnDeposit.tsx │ ├── ErrorFallback.tsx │ ├── NFTs.tsx │ ├── NewCustomNetworkRequest.tsx │ ├── Onboarding │ │ ├── Tabbed │ │ │ ├── AddWallet.tsx │ │ │ ├── AddWalletOptions.tsx │ │ │ ├── Done.tsx │ │ │ ├── ImportForm.tsx │ │ │ ├── ImportPrivateKey.tsx │ │ │ ├── ImportPrivateKeyForm.tsx │ │ │ ├── ImportPrivateKeyJSON.tsx │ │ │ ├── ImportSeed.tsx │ │ │ ├── Intro.tsx │ │ │ ├── Ledger │ │ │ │ ├── Ledger.tsx │ │ │ │ ├── LedgerImportAccounts.tsx │ │ │ │ └── LedgerPrepare.tsx │ │ │ ├── NewSeed.tsx │ │ │ ├── NewSeed │ │ │ │ ├── NewSeedIntro.tsx │ │ │ │ ├── NewSeedReview.tsx │ │ │ │ └── NewSeedVerify.tsx │ │ │ ├── OnboardingAdditionalWallet.tsx │ │ │ ├── OnboardingTip.tsx │ │ │ ├── Root.tsx │ │ │ ├── Routes.ts │ │ │ ├── SetPassword.tsx │ │ │ └── ViewOnlyWallet.tsx │ │ ├── VerifySeed │ │ │ ├── SeedVerification.tsx │ │ │ ├── VerifySeedError.tsx │ │ │ └── VerifySeedSuccess.tsx │ │ └── styles.ts │ ├── Overview.tsx │ ├── PersonalSign.tsx │ ├── Popup.tsx │ ├── Receive.tsx │ ├── Send.tsx │ ├── Settings.tsx │ ├── Settings │ │ ├── ConnectedWebsitesListEmpty.tsx │ │ ├── ConnectedWebsitesListItem.tsx │ │ ├── SettingButton.tsx │ │ ├── SettingsAddCustomAsset.tsx │ │ ├── SettingsAnalytics.tsx │ │ ├── SettingsConnectedWebsites.tsx │ │ ├── SettingsCustomNetworks.tsx │ │ └── SettingsExportLogs.tsx │ ├── SignData.tsx │ ├── SignTransaction.tsx │ ├── SingleAsset.tsx │ ├── Swap.tsx │ ├── Tab.tsx │ ├── TabNotFound.tsx │ └── Wallet.tsx ├── public │ ├── fonts.css │ ├── fonts │ │ ├── QuincyCF-Medium.woff │ │ ├── QuincyCF-Medium.woff2 │ │ ├── QuincyCF-Text.woff │ │ ├── QuincyCF-Text.woff2 │ │ ├── segment-medium.woff │ │ ├── segment-medium.woff2 │ │ ├── segment-regular.woff │ │ ├── segment-regular.woff2 │ │ ├── segment-semibold.woff │ │ └── segment-semibold.woff2 │ ├── icon-128.png │ ├── images │ │ ├── abilities │ │ │ ├── airdrop.svg │ │ │ └── mint.svg │ │ ├── activity_approve@2x.png │ │ ├── activity_contract_interaction@2x.png │ │ ├── activity_receive@2x.png │ │ ├── activity_receive_medium@2x.png │ │ ├── activity_send.svg │ │ ├── activity_send@2x.png │ │ ├── activity_send_medium@2x.png │ │ ├── activity_swap@2x.png │ │ ├── activity_swap_medium@2x.png │ │ ├── add_wallet │ │ │ ├── create_tally.svg │ │ │ ├── import.svg │ │ │ ├── ledger.svg │ │ │ └── preview.svg │ │ ├── arbitrum@2x.png │ │ ├── arrow@2x.png │ │ ├── arrow_right@2x.png │ │ ├── assets │ │ │ ├── avax.png │ │ │ ├── bnb.png │ │ │ ├── btc.png │ │ │ ├── doggo.png │ │ │ ├── eth.png │ │ │ ├── matic.png │ │ │ └── rbtc.png │ │ ├── avatar@2x.png │ │ ├── avatars │ │ │ ├── atos@2x.png │ │ │ ├── foz@2x.png │ │ │ ├── lola@2x.png │ │ │ ├── matilda@2x.png │ │ │ ├── phoenix@2x.png │ │ │ ├── sirius@2x.png │ │ │ ├── sport@2x.png │ │ │ └── topa@2x.png │ │ ├── back@2x.png │ │ ├── banner-bg.svg │ │ ├── banner_thumbnail.png │ │ ├── block_icon@2x.png │ │ ├── bolt@2x.png │ │ ├── chain_list.svg │ │ ├── change@2x.png │ │ ├── check.svg │ │ ├── check@2x.png │ │ ├── checkmark@2x.png │ │ ├── chevron@2x.png │ │ ├── chevron_down.svg │ │ ├── chevron_left.svg │ │ ├── chevron_right.svg │ │ ├── claim.svg │ │ ├── claim@2x.png │ │ ├── claim_success.png │ │ ├── close.svg │ │ ├── close@2x.png │ │ ├── cog@2x.png │ │ ├── confetti.svg │ │ ├── congrats_header@2x.png │ │ ├── connect_ledger_indicator_unknown.svg │ │ ├── connect_ledger_popup_underlay_downward_arrow.svg │ │ ├── connect_ledger_popup_underlay_upward_arrow.svg │ │ ├── connected-wc.svg │ │ ├── continue.svg │ │ ├── copy@2x.png │ │ ├── daos │ │ │ ├── aave_logo@2x.png │ │ │ ├── bankless_logo@2x.png │ │ │ ├── dxdao_logo@2x.png │ │ │ ├── ens_logo@2x.png │ │ │ ├── fwb_logo@2x.png │ │ │ ├── gitcoin_logo@2x.png │ │ │ ├── gnosis_logo@2x.png │ │ │ ├── keeper_logo@2x.png │ │ │ ├── pleasr_logo@2x.png │ │ │ ├── radicle_logo@2x.png │ │ │ ├── sushi_logo@2x.png │ │ │ ├── synthetix_logo@2x.png │ │ │ ├── uniswap_logo@2x.png │ │ │ └── yearn_logo@2x.png │ │ ├── dapp_favicon_default@2x.png │ │ ├── dark_forest@2x.png │ │ ├── dark_forest_bg@2x.png │ │ ├── disconnect@2x.png │ │ ├── discord@2x.png │ │ ├── doggo_gold.svg │ │ ├── doggo_gold@2x.png │ │ ├── doggo_grey@2x.png │ │ ├── doggo_import.svg │ │ ├── doggo_intro.svg │ │ ├── doggo_light@2x.png │ │ ├── doggo_onboarding.svg │ │ ├── doggo_private_key.svg │ │ ├── doggo_readonly.svg │ │ ├── doggo_secure.svg │ │ ├── earn.svg │ │ ├── earn_tab@2x.png │ │ ├── edit@2x.png │ │ ├── empty_bowl@2x.png │ │ ├── eth@2x.png │ │ ├── ethereum-background@2x.png │ │ ├── external@2x.png │ │ ├── external_small@2x.png │ │ ├── eye@2x.png │ │ ├── eye_account@2x.png │ │ ├── garbage@2x.png │ │ ├── gas@2x.png │ │ ├── gift@2x.png │ │ ├── github@2x.png │ │ ├── graph@2x.png │ │ ├── icon-34.png │ │ ├── icon-60.png │ │ ├── icons │ │ │ ├── m │ │ │ │ ├── connected.svg │ │ │ │ ├── continue.svg │ │ │ │ ├── copy.svg │ │ │ │ ├── dark.svg │ │ │ │ ├── dashboard.svg │ │ │ │ ├── developer.svg │ │ │ │ ├── disconnect.svg │ │ │ │ ├── discord.svg │ │ │ │ ├── earn.svg │ │ │ │ ├── export.svg │ │ │ │ ├── eye-off.svg │ │ │ │ ├── eye-on.svg │ │ │ │ ├── feedback.svg │ │ │ │ ├── gift.svg │ │ │ │ ├── github.svg │ │ │ │ ├── import.svg │ │ │ │ ├── info.svg │ │ │ │ ├── light.svg │ │ │ │ ├── list.svg │ │ │ │ ├── lock-bold.svg │ │ │ │ ├── lock.svg │ │ │ │ ├── menu.svg │ │ │ │ ├── new-tab.svg │ │ │ │ ├── notif-announcement.svg │ │ │ │ ├── notif-attention.svg │ │ │ │ ├── notif-correct.svg │ │ │ │ ├── notif-wrong.svg │ │ │ │ ├── search.svg │ │ │ │ ├── swap.svg │ │ │ │ ├── switch.svg │ │ │ │ ├── unlock-bold.svg │ │ │ │ ├── unlock.svg │ │ │ │ └── wallet.svg │ │ │ └── s │ │ │ │ ├── add.svg │ │ │ │ ├── arrow-right.svg │ │ │ │ ├── arrow-toggle.svg │ │ │ │ ├── back.svg │ │ │ │ ├── close.svg │ │ │ │ ├── continue.svg │ │ │ │ ├── copy.svg │ │ │ │ ├── discord.svg │ │ │ │ ├── download.svg │ │ │ │ ├── dropdown.svg │ │ │ │ ├── edit.svg │ │ │ │ ├── garbage.svg │ │ │ │ ├── key.svg │ │ │ │ ├── lock-bold.svg │ │ │ │ ├── lock.svg │ │ │ │ ├── mark-read.svg │ │ │ │ ├── new-tab.svg │ │ │ │ ├── notif-announ.svg │ │ │ │ ├── notif-attention.svg │ │ │ │ ├── notif-correct.svg │ │ │ │ ├── notif-wrong.svg │ │ │ │ ├── notification.svg │ │ │ │ ├── receive.svg │ │ │ │ ├── refresh.svg │ │ │ │ ├── send.svg │ │ │ │ ├── settings.svg │ │ │ │ ├── settings2.svg │ │ │ │ ├── swap.svg │ │ │ │ ├── unlock-bold.svg │ │ │ │ └── unlock.svg │ │ ├── illustration_bones@2x.png │ │ ├── illustration_import_seed@2x.png │ │ ├── illustration_unlock@2x.png │ │ ├── imported@2x.png │ │ ├── info@2x.png │ │ ├── island │ │ │ ├── portal-image-title@2x.png │ │ │ └── portal-image@2x.png │ │ ├── json_file.svg │ │ ├── key-light.svg │ │ ├── ledger_icon.svg │ │ ├── loading_doggo.gif │ │ ├── lock@2.png │ │ ├── lock@2x.png │ │ ├── logo.svg │ │ ├── logo_horizontal.svg │ │ ├── logo_onboarding.svg │ │ ├── mac-shortcut-option-t.svg │ │ ├── mac-shortcut-option.svg │ │ ├── mac-shortcut-t.svg │ │ ├── mac-shortcut.svg │ │ ├── mark_read@2x.png │ │ ├── marketplaces │ │ │ ├── galxe.svg │ │ │ ├── looksrare.svg │ │ │ ├── opensea.svg │ │ │ ├── poap.svg │ │ │ ├── poap_color.png │ │ │ ├── poap_white.png │ │ │ └── rarible.svg │ │ ├── mascot.svg │ │ ├── mascot@2x.png │ │ ├── message_correct.png │ │ ├── message_error.png │ │ ├── message_warning.png │ │ ├── mezo-1.png │ │ ├── mezo-2.png │ │ ├── mezo-3.png │ │ ├── more_dots@2x.png │ │ ├── networks │ │ │ ├── arbitrum-square@2x.png │ │ │ ├── arbitrum@2x.png │ │ │ ├── arbitrum_icon_small@2x.png │ │ │ ├── arbitrumnova-square@2x.png │ │ │ ├── arbitrumnova@2x.png │ │ │ ├── arbitrumsepolia-square@2x.png │ │ │ ├── arbitrumsepolia@2x.png │ │ │ ├── avalanche-square@2x.png │ │ │ ├── avalanche@2x.png │ │ │ ├── bnbchain-square@2x.png │ │ │ ├── bnbchain@2x.png │ │ │ ├── celo-square@2x.png │ │ │ ├── celo@2x.png │ │ │ ├── ethereum-square@2x.png │ │ │ ├── ethereum@2x.png │ │ │ ├── ethereumsepolia-square@2x.png │ │ │ ├── ethereumsepolia@2x.png │ │ │ ├── mezomatsnet-square@2x.png │ │ │ ├── mezomatsnet@2x.png │ │ │ ├── optimism-square@2x.png │ │ │ ├── optimism@2x.png │ │ │ ├── polygon-square@2x.png │ │ │ ├── polygon@2x.png │ │ │ ├── rootstock-square@2x.png │ │ │ └── rootstock@2x.png │ │ ├── new_tab@2x.png │ │ ├── new_tab_hover@2x.png │ │ ├── nfts.svg │ │ ├── no_preview.svg │ │ ├── notification_announce.svg │ │ ├── notification_announce@2x.png │ │ ├── notification_error@2x.png │ │ ├── notification_receive@2x.png │ │ ├── onboarding_pin_extension.gif │ │ ├── onboarding_success.svg │ │ ├── optimism@2x.png │ │ ├── other-wallet-connect-icon.svg │ │ ├── overview_tab@2x.png │ │ ├── paste@2x.png │ │ ├── placeholder.svg │ │ ├── plus@2x.png │ │ ├── poap_logo.svg │ │ ├── polygon@2x.png │ │ ├── portfolio.svg │ │ ├── portrait.png │ │ ├── qr_code@2x.png │ │ ├── receive@2x.png │ │ ├── reload@2x.png │ │ ├── reward_locked@2x.png │ │ ├── search_large@2x.png │ │ ├── send@2x.png │ │ ├── send_asset.svg │ │ ├── settings.svg │ │ ├── stars.svg │ │ ├── stars_grey.svg │ │ ├── subscape-logo.svg │ │ ├── swap.svg │ │ ├── swap@2x.png │ │ ├── swap_asset.svg │ │ ├── swap_tab@2x.png │ │ ├── switch@2x.png │ │ ├── tab_background.svg │ │ ├── taho-connect-icon.svg │ │ ├── tahonamechange.gif │ │ ├── tail.svg │ │ ├── tally_reward@2x.png │ │ ├── tally_token.svg │ │ ├── tally_wc.png │ │ ├── time.svg │ │ ├── toggle.svg │ │ ├── transfer@2x.png │ │ ├── trezor_icon@2x.png │ │ ├── twitter.svg │ │ ├── twitter@2x.png │ │ ├── uniswap@2x.png │ │ ├── uniswap_large@2x.png │ │ ├── wallet.svg │ │ ├── wallet_connect_guideline.png │ │ ├── wallet_kind_icon@2x.png │ │ ├── wallet_tab@2x.png │ │ ├── warning@2x.png │ │ ├── windows-shortcut-alt-t.svg │ │ ├── windows-shortcut-alt.svg │ │ ├── windows-shortcut-t.svg │ │ ├── windows-shortcut.svg │ │ └── wordmark.svg │ ├── index.css │ ├── popup.html │ └── tab.html ├── routes │ └── routes.tsx ├── setupJest.env.ts ├── tests │ ├── factories.ts │ ├── store.ts │ └── test-utils.tsx └── utils │ ├── accounts.ts │ ├── constants.ts │ ├── lists.ts │ ├── networks.ts │ ├── noop.ts │ ├── pageTransition.ts │ ├── swap.ts │ ├── tabs.ts │ └── textUtils.ts ├── webpack.config.ts ├── window-provider ├── index.ts └── package.json └── yarn.lock /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | ui/node_modules 4 | background/node_modules 5 | provider-bridge/node_modules 6 | dist/* 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | 7 | [*.yml] 8 | indent_style = space 9 | indent_size = 2 10 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_KEY= 2 | BLOCKNATIVE_API_KEY= 3 | -------------------------------------------------------------------------------- /.env.prod: -------------------------------------------------------------------------------- 1 | ALCHEMY_KEY="..." 2 | BLOCKNATIVE_API_KEY="..." 3 | ZEROX_API_KEY="..." 4 | COMMIT_SHA="..." 5 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Impose prettier formatting on JS and TS, with some smaller eslint fixes. 2 | 23545c8ed87d8e9b1661ab02dfaefddaf3725f3e 3 | # Impose prettier formatting on JSON and Markdown. 4 | 8a90e88658795d569ca525ecb7bced875922c59c 5 | # Impose prettier formatting on .github YAML files. 6 | 4851e7989a3473c64b03adb4fbef16b3957ac2ab 7 | # Shift to @thesis-co/eslint-config. 8 | fd45e9ffe8405e00ed34ca500bbf8f88d06de20f 9 | # Bump to @thesis-co/eslint-config@0.6.0 with prettier 3.x. 10 | 9c4488cebd14d578dcd2cf9d3d3b26934b5262df 11 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | *.ai binary 3 | *.png binary 4 | *.woff binary 5 | *.woff2 binary -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Any changes to internal-signer service code deserve extra scrutiny to prevent key 2 | # exfiltration and general "roll your own crypto" mistakes. Newer 3 | # contributions to internal-signer code should be assumed insecure, requiring 4 | # agreement across the team to merge. 5 | /background/services/internal-signer/* @tahowallet/extension-security-auditors 6 | # Any changes to dependencies deserve extra scrutiny to help prevent supply 7 | # chain attacks 8 | yarn.lock @tahowallet/extension-dependency-auditors 9 | # Any changes to code owners deserve extra scrutiny 10 | .github/CODEOWNERS @tahowallet/extension-security-auditors 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: "Discord #feature-requests" 4 | url: https://discord.gg/hxeQC5wxzf 5 | about: Please discuss feature requests here before filing an issue. 6 | - name: "Discord #bug-reports for bugs" 7 | url: https://discord.gg/cw84Ae5UQt 8 | about: Please discuss bugs here before filing an issue. 9 | -------------------------------------------------------------------------------- /.github/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tallyho/tally-extension-workflows", 3 | "version": "1.0.0", 4 | "private": true, 5 | "devDependencies": { 6 | "@actions/github": "^5.1.1" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.github/workflows/pledge-signer-sync/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tallyho/pledge-signer-sync", 3 | "type": "module", 4 | "version": "1.0.0", 5 | "private": true, 6 | "dependencies": { 7 | "firebase": "^9.9.0", 8 | "node-fetch": "3.3.1" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.github/workflows/post-build-link.yml: -------------------------------------------------------------------------------- 1 | name: Post build link 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | workflow_run_id: 7 | type: string 8 | description: "The id of a workflow run to dispatch off of." 9 | required: true 10 | workflow_run: 11 | workflows: 12 | - Build 13 | types: 14 | - completed 15 | 16 | jobs: 17 | post-link: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Post artifact link to PR if available 22 | uses: actions/github-script@v6 23 | with: 24 | script: | 25 | const postBuildLink = require("./.github/workflows/builds/post-build-link.js") 26 | await postBuildLink({ github, context }) 27 | -------------------------------------------------------------------------------- /.github/workflows/sync-pledge.yml: -------------------------------------------------------------------------------- 1 | name: Sync pledge 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | workflow_dispatch: 7 | 8 | jobs: 9 | cron: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | with: 14 | fetch-depth: 0 15 | - name: Read .nvmrc 16 | run: echo "NVMRC=$(cat ./.nvmrc)" >> $GITHUB_OUTPUT 17 | id: nvm 18 | - name: Use Node + Yarn 19 | uses: actions/setup-node@v3 20 | with: 21 | node-version: "${{ steps.nvm.outputs.NVMRC }}" 22 | cache: "yarn" 23 | - run: yarn install --frozen-lockfile 24 | working-directory: .github/workflows/pledge-signer-sync 25 | - name: Sync pledge addresses 26 | run: node pledge-sync.js 27 | working-directory: .github/workflows/pledge-signer-sync 28 | env: 29 | GALXE_ACCESS_TOKEN: ${{ secrets.GALXE_ACCESS_TOKEN }} 30 | FIRESTORE_USER: ${{ vars.FIRESTORE_USER }} 31 | FIRESTORE_PASSWORD: ${{ secrets.FIRESTORE_PASSWORD }} 32 | -------------------------------------------------------------------------------- /.github/workflows/test-list.yml: -------------------------------------------------------------------------------- 1 | # This workflow adds a comment with tests list to the PRs with the release 2 | # candidates (PRs that want to merge `release-*` branches to `main`). The test 3 | # list is specified in the `./.github/workflows/test-list/release-test-list.md` 4 | # file. The comment is added only once, right after the PR gets created. 5 | 6 | name: Add test list to release PRs 7 | 8 | on: 9 | pull_request: 10 | types: 11 | - opened 12 | branches: 13 | - main 14 | 15 | jobs: 16 | add-release-test-list: 17 | runs-on: ubuntu-latest 18 | if: startsWith(github.head_ref, 'release-') 19 | permissions: 20 | pull-requests: write 21 | steps: 22 | - uses: actions/checkout@v3 23 | - uses: mshick/add-pr-comment@v2 24 | with: 25 | message-path: ./.github/workflows/test-list/release-test-list.md 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | yarn-error.log 3 | node_modules 4 | dist/ 5 | size-plugin.json 6 | app/extension-scripts/api/playground/ 7 | .env 8 | *.rest 9 | .DS_Store 10 | .vscode 11 | playwright-report 12 | test-results/ 13 | ci/cache/ 14 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/hydrogen 2 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: local 3 | hooks: 4 | - id: lint-js 5 | name: "lint typescript and javascript" 6 | entry: /usr/bin/env npx eslint 7 | files: '\.jsx?$|\.tsx?$' 8 | language: script 9 | description: "Checks JS/TS code according to the package's linter configuration" 10 | - repo: local 11 | hooks: 12 | - id: lint-config 13 | name: "lint config files" 14 | entry: /usr/bin/env npx prettier -c 15 | files: '\.json$|\.yaml$|\.toml$|\.yml$' 16 | language: script 17 | description: "Checks config files according to the package's linter configuration" 18 | - repo: local 19 | hooks: 20 | - id: lint-docs 21 | name: "lint documentation files" 22 | entry: /usr/bin/env npx prettier -c 23 | files: '\.md$' 24 | language: script 25 | description: "Checks documentation files according to the package's linter configuration" 26 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | # Ignore weblate json translation formatting 3 | ui/_locales/**/*.json 4 | !.github 5 | ci/cache 6 | .vscode 7 | size-plugin.json -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false 3 | } 4 | -------------------------------------------------------------------------------- /.tsconfig-eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": [ 4 | ".eslintrc.js", 5 | "**/*.js", 6 | "**/*.ts", 7 | "**/*.tsx", 8 | ".github/**/*.js" 9 | ], 10 | "exclude": [ 11 | "node_modules", 12 | "dist", 13 | "**/validate/*.js", 14 | "**/local-chain/**", 15 | "ci/cache" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16-alpine AS build 2 | 3 | WORKDIR /tally-ho 4 | 5 | COPY . . 6 | 7 | RUN mv .env.prod .env 8 | RUN apk add --no-cache python3 py3-pip git make bash && ln -sf python3 /usr/bin/python 9 | # sqlite compile throws an error during install, but it does not cause any problem so we are ignoring it 10 | RUN yarn install --frozen-lockfile || true 11 | ENV SUPPORT_BROWSER="firefox" 12 | RUN yarn build 13 | 14 | FROM scratch AS dist 15 | 16 | COPY --from=build /tally-ho/dist . 17 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2021 A community of like-minded individuals, shadowy super-doggos, 2 | and very good pups including YLVIS, LLC. 3 | 4 | This program is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | this program. If not, see https://www.gnu.org/licenses/. 15 | 16 | Additional permission under GNU GPL version 3 section 7 are specified in the 17 | file LICENSE-additional-terms.txt in this directory. 18 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | The Taho security policy is maintained at https://taho.xyz/SECURITY.md . 4 | 5 | Security contact info is maintained at the RFC8615-recommended 6 | https://taho.xyz/.well-known/security.txt, and is also available from 7 | https://taho.xyz/security.txt . 8 | -------------------------------------------------------------------------------- /__mocks__/@ethersproject/web.ts: -------------------------------------------------------------------------------- 1 | // Fixing this here requires digging into Jest a bit, kicking for now. 2 | // eslint-disable-next-line import/no-import-module-exports 3 | import sinon from "sinon" 4 | 5 | const mock = 6 | jest.createMockFromModule( 7 | "@ethersproject/web", 8 | ) 9 | 10 | const actual = 11 | jest.requireActual("@ethersproject/web") 12 | 13 | const fetchJson = sinon.stub() 14 | 15 | module.exports = { 16 | ...mock, 17 | ...actual, 18 | fetchJson, 19 | } 20 | -------------------------------------------------------------------------------- /__mocks__/uuid.ts: -------------------------------------------------------------------------------- 1 | const uuidMock = jest.createMockFromModule("uuid") 2 | const v4Mock = jest 3 | .fn() 4 | .mockImplementation(() => jest.requireActual("uuid").v4()) 5 | 6 | module.exports = { 7 | ...uuidMock, 8 | v4: v4Mock, 9 | } 10 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | // Global config for all babel-affected Taho packages. 2 | module.exports = { 3 | plugins: ["styled-jsx/babel"], 4 | presets: [ 5 | [ 6 | "@babel/env", 7 | { 8 | targets: { 9 | browsers: ["chrome >= 107", "firefox >= 107"], 10 | }, 11 | }, 12 | ], 13 | // Because babel is used by Webpack to load the Webpack config, which is 14 | // TS. 15 | "@babel/typescript", 16 | ], 17 | babelrcRoots: [".", "ui/*", "background/*", "provider-bridge/*"], 18 | } 19 | -------------------------------------------------------------------------------- /background/constants/assets.ts: -------------------------------------------------------------------------------- 1 | import { SmartContractFungibleAsset } from "../assets" 2 | import { ETHEREUM } from "./networks" 3 | import { WEBSITE_ORIGIN } from "./website" 4 | 5 | /** 6 | * The primary token for the wallet's DAO. 7 | */ 8 | // We expect more assets later. 9 | // eslint-disable-next-line import/prefer-default-export 10 | export const DOGGO: SmartContractFungibleAsset = { 11 | name: "Doggo", 12 | symbol: "DOGGO", 13 | decimals: 18, 14 | contractAddress: "0xdce3d2c2186e3E92af121F477dE76cBED2fc979F", 15 | homeNetwork: ETHEREUM, 16 | metadata: { 17 | tokenLists: [], 18 | websiteURL: WEBSITE_ORIGIN, 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /background/constants/balances.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers" 2 | 3 | const balances = [ 4 | { account: "0x1234", amount: ethers.BigNumber.from(100) }, 5 | { account: "0x1234", amount: ethers.BigNumber.from(101) }, 6 | { account: "0x1245", amount: ethers.BigNumber.from(102) }, 7 | { account: "0x123456", amount: ethers.BigNumber.from(103) }, 8 | ] 9 | export default balances 10 | -------------------------------------------------------------------------------- /background/constants/coin-types.ts: -------------------------------------------------------------------------------- 1 | // This file includes SLIP-0044 data used by the extension. Because this is raw 2 | // data but is important, it SHOULD NOT be imported from an external package. 3 | 4 | /** 5 | * Limited extension-specific list of coin types by asset symbol. 6 | */ 7 | export const coinTypesByAssetSymbol = { 8 | BTC: 0, 9 | ETH: 60, 10 | RBTC: 137, 11 | MATIC: 966, 12 | AVAX: 9005, 13 | BNB: 714, 14 | } as const 15 | 16 | /** 17 | * All coin types known to the extension. 18 | */ 19 | export type Slip44CoinType = 20 | (typeof coinTypesByAssetSymbol)[keyof typeof coinTypesByAssetSymbol] 21 | -------------------------------------------------------------------------------- /background/constants/errors.ts: -------------------------------------------------------------------------------- 1 | // // Disabled while we decide how we want to move here. 2 | // eslint-disable-next-line import/prefer-default-export 3 | export const NETWORK_ERRORS = { 4 | // 405: 'RPC response not ok: 405 method not found', 5 | // 429: 'Request is being rate limited.', 6 | // 503: 7 | // 504: 8 | // 504: 9 | // internal: 10 | UNSUPORTED_NETWORK: "Currently Taho does not support this network", 11 | UNSUPORTED_TRANSPORT: "Currently Taho does not support this transport type", 12 | CONNECT_NOT_SUPPORTED: 13 | "The provided endpoint does not support socket connections", 14 | SOCKET_CLOSED: "Connection with node is no longer open", 15 | } 16 | -------------------------------------------------------------------------------- /background/constants/network-fees.ts: -------------------------------------------------------------------------------- 1 | export const ESTIMATED_FEE_MULTIPLIERS: { [confidence: number]: bigint } = { 2 | 70: 11n, 3 | 95: 13n, 4 | 99: 18n, 5 | 0: 20n, 6 | } 7 | 8 | export const ESTIMATED_FEE_MULTIPLIERS_BY_TYPE: { 9 | [feeType: string]: bigint 10 | } = { 11 | regular: 11n, 12 | express: 13n, 13 | instant: 18n, 14 | } 15 | 16 | export const MAX_FEE_MULTIPLIER: { [confidence: number]: bigint } = { 17 | 70: 13n, 18 | 95: 15n, 19 | 99: 20n, 20 | 0: 20n, 21 | } 22 | 23 | export const INSTANT = 99 24 | export const EXPRESS = 95 25 | export const REGULAR = 70 26 | export const CUSTOM = 0 27 | -------------------------------------------------------------------------------- /background/constants/website.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/prefer-default-export */ 2 | export const WEBSITE_ORIGIN = process.env.WEBSITE_ORIGIN ?? "" 3 | -------------------------------------------------------------------------------- /background/lib/enhancers.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/background/lib/enhancers.ts -------------------------------------------------------------------------------- /background/lib/tests/daylight.unit.test.ts: -------------------------------------------------------------------------------- 1 | // It's necessary to have an object w/ the function on it so we can use spyOn 2 | import * as ethers from "@ethersproject/web" // << THIS IS THE IMPORTANT TRICK 3 | import * as daylight from "../daylight" 4 | 5 | describe("Daylight", () => { 6 | describe("getDaylightAbilities", () => { 7 | it("Should retry the correct number of times if response status is 'pending' ", async () => { 8 | const fetchJsonResponse = { 9 | abilities: [], 10 | status: "pending", 11 | } 12 | 13 | const spy = jest 14 | .spyOn(ethers, "fetchJson") 15 | .mockResolvedValue(fetchJsonResponse) 16 | 17 | await daylight.getDaylightAbilities( 18 | "0x208e94d5661a73360d9387d3ca169e5c130090cd", 19 | 5, 20 | ) 21 | 22 | expect(spy).toHaveBeenCalledTimes(6) 23 | }) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /background/lib/validate/erc721.ts: -------------------------------------------------------------------------------- 1 | export const metadataJTD = { 2 | optionalProperties: { 3 | name: { type: "string" }, 4 | description: { type: "string" }, 5 | image: { type: "string" }, 6 | title: { type: "string" }, // not found in 721, but seen in the wild 7 | external_url: { type: "string" }, // not found in 721, but seen in the wild 8 | }, 9 | additionalProperties: true, 10 | } as const 11 | 12 | export default metadataJTD 13 | -------------------------------------------------------------------------------- /background/lib/validate/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./jtd-validators" 2 | export * from "./json-validators" 3 | -------------------------------------------------------------------------------- /background/lib/validate/json-validators.d.ts: -------------------------------------------------------------------------------- 1 | import { JSONSchemaType, ValidateFunction } from "ajv" 2 | import { coingeckoPriceSchema } from "./prices" 3 | 4 | export const isValidCoinGeckoPriceResponse: ValidateFunction< 5 | JSONSchemaType 6 | > 7 | 8 | export const isValidUniswapTokenListResponse: (arg: unknown) => boolean 9 | -------------------------------------------------------------------------------- /background/redux-slices/earn-utils/index.ts: -------------------------------------------------------------------------------- 1 | export { default as getCurveLPTokenPrice } from "./getCurveLPTokenPrice" 2 | export { default as getDoggoPrice } from "./getDoggoPrice" 3 | export { default as getLPTokenValue } from "./getLPTokenValue" 4 | export { default as getPoolAPR } from "./getPoolAPR" 5 | export { default as getTokenPrice } from "./getTokenPrice" 6 | export { default as getUniswapPairTokenPrice } from "./getUniswapPairTokenPrice" 7 | export { default as tokenIcons } from "./tokenIcons" 8 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-11.ts: -------------------------------------------------------------------------------- 1 | type OldState = { 2 | ui: { 3 | [sliceKey: string]: unknown 4 | } 5 | [otherSlice: string]: unknown 6 | } 7 | 8 | type NewState = { 9 | ui: { 10 | slippageTolerance: number 11 | [sliceKey: string]: unknown 12 | } 13 | [otherSlice: string]: unknown 14 | } 15 | 16 | export default (prevState: Record): NewState => { 17 | const typedPrevState = prevState as OldState 18 | 19 | return { 20 | ...prevState, 21 | ui: { 22 | ...typedPrevState.ui, 23 | slippageTolerance: 0.01, 24 | }, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-14.ts: -------------------------------------------------------------------------------- 1 | // This migration ensures the assets collection is cleared due to a change in 2 | // assets slice shape; the assets list should be repopulated during startup by 3 | // the IndexingService. 4 | 5 | export default ( 6 | prevState: Record, 7 | ): Record => { 8 | const { assets: _, ...newState } = prevState 9 | 10 | // Clear assets collection; these should be immediately repopulated by the 11 | // IndexingService in startService. 12 | newState.assets = [] 13 | 14 | return newState 15 | } 16 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-15.ts: -------------------------------------------------------------------------------- 1 | type OldState = { 2 | ui: { 3 | settings: { 4 | hideDust: boolean 5 | defaultWallet: boolean 6 | } 7 | [sliceKey: string]: unknown 8 | } 9 | [otherSlice: string]: unknown 10 | } 11 | 12 | type NewState = { 13 | ui: { 14 | settings: { 15 | hideDust: boolean 16 | defaultWallet: boolean 17 | showTestNetworks: boolean 18 | } 19 | [sliceKey: string]: unknown 20 | } 21 | [otherSlice: string]: unknown 22 | } 23 | 24 | export default (prevState: Record): NewState => { 25 | const typedPrevState = prevState as OldState 26 | 27 | return { 28 | ...prevState, 29 | ui: { 30 | ...typedPrevState.ui, 31 | settings: { 32 | ...typedPrevState.ui.settings, 33 | showTestNetworks: false, 34 | }, 35 | }, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-17.ts: -------------------------------------------------------------------------------- 1 | type OldState = { 2 | ui: { 3 | settings: { 4 | hideDust: boolean 5 | defaultWallet: boolean 6 | showTestNetworks: boolean 7 | } 8 | [sliceKey: string]: unknown 9 | } 10 | [otherSlice: string]: unknown 11 | } 12 | 13 | type NewState = { 14 | ui: { 15 | settings: { 16 | hideDust: boolean 17 | defaultWallet: boolean 18 | showTestNetworks: boolean 19 | collectAnalytics: boolean 20 | } 21 | [sliceKey: string]: unknown 22 | } 23 | [otherSlice: string]: unknown 24 | } 25 | 26 | export default (prevState: Record): NewState => { 27 | const typedPrevState = prevState as OldState 28 | 29 | return { 30 | ...prevState, 31 | ui: { 32 | ...typedPrevState.ui, 33 | settings: { 34 | ...typedPrevState.ui.settings, 35 | collectAnalytics: false, 36 | }, 37 | }, 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-18.ts: -------------------------------------------------------------------------------- 1 | import { ZrxQuote } from "../0x-swap" 2 | import { PriceDetails, SwapQuoteRequest } from "../utils/0x-swap-utils" 3 | 4 | type OldState = { 5 | swap: { 6 | latestQuoteRequest?: SwapQuoteRequest | undefined 7 | finalQuote?: ZrxQuote | undefined 8 | inProgressApprovalContract?: string 9 | [sliceKey: string]: unknown 10 | } 11 | [otherSlice: string]: unknown 12 | } 13 | 14 | type NewState = { 15 | swap: { 16 | latestQuoteRequest?: SwapQuoteRequest | undefined 17 | finalQuote?: ZrxQuote | undefined 18 | inProgressApprovalContract?: string 19 | priceDetails?: PriceDetails | undefined 20 | [sliceKey: string]: unknown 21 | } 22 | [otherSlice: string]: unknown 23 | } 24 | 25 | export default (prevState: Record): NewState => { 26 | const typedPrevState = prevState as OldState 27 | 28 | return { 29 | ...prevState, 30 | swap: { 31 | ...typedPrevState.swap, 32 | priceDetails: undefined, 33 | }, 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-19.ts: -------------------------------------------------------------------------------- 1 | export default ( 2 | prevState: Record, 3 | ): Record => { 4 | const { activities: _, ...newState } = prevState 5 | 6 | // Clear activities slice as we now have new activities slice instead 7 | newState.activities = {} 8 | 9 | return newState 10 | } 11 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-2.ts: -------------------------------------------------------------------------------- 1 | // This migration moves from the old currentAccount SelectedAccount type to a 2 | // bare selectedAccount AddressNetwork type. Note the avoidance of imported 3 | // types so this migration will work in the future, regardless of other code 4 | // changes 5 | 6 | type BroadAddressNetwork = { 7 | address: string 8 | network: Record 9 | } 10 | type OldState = { 11 | ui: { 12 | currentAccount?: { 13 | addressNetwork: BroadAddressNetwork 14 | truncatedAddress: string 15 | } 16 | } 17 | } 18 | 19 | export default ( 20 | prevState: Record, 21 | ): Record => { 22 | const newState = { ...prevState } 23 | const addressNetwork = (prevState as OldState)?.ui?.currentAccount 24 | ?.addressNetwork 25 | delete (newState as OldState)?.ui?.currentAccount 26 | newState.selectedAccount = addressNetwork as BroadAddressNetwork 27 | return newState 28 | } 29 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-20.ts: -------------------------------------------------------------------------------- 1 | type OldState = { 2 | ui: { 3 | [sliceKey: string]: unknown 4 | } 5 | [otherSlice: string]: unknown 6 | } 7 | 8 | type NewState = { 9 | ui: { 10 | accountSignerSettings: Array<{ 11 | signer: unknown 12 | title?: string 13 | }> 14 | [sliceKey: string]: unknown 15 | } 16 | [otherSlice: string]: unknown 17 | } 18 | 19 | export default (oldState: Record): NewState => { 20 | const prevState = oldState as OldState 21 | 22 | const { ui } = prevState 23 | 24 | return { ...prevState, ui: { ...ui, accountSignerSettings: [] } } 25 | } 26 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-21.ts: -------------------------------------------------------------------------------- 1 | type OldState = { 2 | ui: { 3 | settings: { 4 | [settingsKey: string]: unknown 5 | } 6 | [sliceKey: string]: unknown 7 | } 8 | [otherSlice: string]: unknown 9 | } 10 | 11 | type NewState = { 12 | ui: { 13 | settings: { 14 | [settingsKey: string]: unknown 15 | hideBanners: boolean 16 | } 17 | [sliceKey: string]: unknown 18 | } 19 | [otherSlice: string]: unknown 20 | } 21 | 22 | export default (prevState: Record): NewState => { 23 | const typedPrevState = prevState as OldState 24 | 25 | return { 26 | ...prevState, 27 | ui: { 28 | ...typedPrevState.ui, 29 | settings: { 30 | ...typedPrevState.ui.settings, 31 | hideBanners: false, 32 | }, 33 | }, 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-22.ts: -------------------------------------------------------------------------------- 1 | // This migration ensures the assets collection is cleared due to a change in 2 | // assets slice shape; the assets list should be repopulated during startup by 3 | // the IndexingService. 4 | 5 | export default ( 6 | prevState: Record, 7 | ): Record => { 8 | const { assets: _, ...newState } = prevState 9 | 10 | // Clear assets collection; these should be immediately repopulated by the 11 | // IndexingService in startService. 12 | newState.assets = [] 13 | 14 | return newState 15 | } 16 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-24.ts: -------------------------------------------------------------------------------- 1 | type OldState = { 2 | networks: { 3 | evm: unknown 4 | } 5 | } 6 | 7 | type NewState = { 8 | networks: { 9 | blockInfo: unknown 10 | evmNetworks: Record 11 | } 12 | } 13 | 14 | export default ( 15 | prevState: Record, 16 | ): Record => { 17 | const { networks, ...newState } = prevState as OldState 18 | 19 | ;(newState as NewState).networks = { 20 | blockInfo: networks.evm, 21 | evmNetworks: {}, 22 | } 23 | 24 | return newState as NewState 25 | } 26 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-25.ts: -------------------------------------------------------------------------------- 1 | // Missing migration due to incorrect version update from 23 to 25. 2 | export default (prevState: Record): Record => 3 | prevState 4 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-26.ts: -------------------------------------------------------------------------------- 1 | type State = { 2 | abilities: { 3 | filter: { state: string; types: string[]; accounts: string[] } 4 | abilities: { 5 | [address: string]: { 6 | [uuid: string]: unknown 7 | } 8 | } 9 | hideDescription: boolean 10 | } 11 | } 12 | 13 | export default ( 14 | prevState: Record, 15 | ): Record => { 16 | const typedPrevState = prevState as State 17 | 18 | const { abilities } = typedPrevState 19 | 20 | if (!abilities) { 21 | return prevState 22 | } 23 | 24 | const { filter } = abilities 25 | 26 | const types = filter.types.includes("claim") 27 | ? filter.types 28 | : [...filter.types, "claim"] 29 | 30 | return { 31 | ...prevState, 32 | abilities: { 33 | ...abilities, 34 | filter: { 35 | ...filter, 36 | types, 37 | }, 38 | }, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-27.ts: -------------------------------------------------------------------------------- 1 | type OldState = { 2 | ui: { 3 | settings: { 4 | [settingsKey: string]: unknown 5 | } 6 | [sliceKey: string]: unknown 7 | } 8 | [otherSlice: string]: unknown 9 | } 10 | 11 | type NewState = { 12 | ui: { 13 | settings: { 14 | [settingsKey: string]: unknown 15 | showHiddenAssets: boolean 16 | } 17 | [sliceKey: string]: unknown 18 | } 19 | [otherSlice: string]: unknown 20 | } 21 | 22 | export default (prevState: Record): NewState => { 23 | const typedPrevState = prevState as OldState 24 | 25 | return { 26 | ...prevState, 27 | ui: { 28 | ...typedPrevState.ui, 29 | settings: { 30 | ...typedPrevState.ui.settings, 31 | showHiddenAssets: false, 32 | }, 33 | }, 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-28.ts: -------------------------------------------------------------------------------- 1 | type OldState = { 2 | ui: { 3 | settings: { 4 | [settingsKey: string]: unknown 5 | } 6 | [sliceKey: string]: unknown 7 | } 8 | [otherSlice: string]: unknown 9 | } 10 | 11 | type NewState = { 12 | ui: { 13 | settings: { 14 | [settingsKey: string]: unknown 15 | showUnverifiedAssets: boolean 16 | } 17 | [sliceKey: string]: unknown 18 | } 19 | [otherSlice: string]: unknown 20 | } 21 | 22 | export default (prevState: Record): NewState => { 23 | const typedPrevState = prevState as OldState 24 | delete typedPrevState.ui.settings.showHiddenAssets 25 | 26 | return { 27 | ...prevState, 28 | ui: { 29 | ...typedPrevState.ui, 30 | settings: { 31 | ...typedPrevState.ui.settings, 32 | showUnverifiedAssets: false, 33 | }, 34 | }, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-29.ts: -------------------------------------------------------------------------------- 1 | // This migration ensures the assets collection is cleared of duplicated 2 | // base assets https://github.com/tahowallet/extension/issues/3445 3 | 4 | export default ( 5 | prevState: Record, 6 | ): Record => { 7 | const { assets: _, ...newState } = prevState 8 | 9 | // Clear assets collection; these should be immediately repopulated by the 10 | // IndexingService in startService. 11 | newState.assets = [] 12 | 13 | return newState 14 | } 15 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-3.ts: -------------------------------------------------------------------------------- 1 | // This migration ensures the assets collection is cleared due to a change in 2 | // assets slice shape; the assets list should be repopulated during startup by 3 | // the IndexingService. 4 | 5 | export default ( 6 | prevState: Record, 7 | ): Record => { 8 | const { assets: _, ...newState } = prevState 9 | 10 | // Clear assets collection; these should be immediately repopulated by the 11 | // IndexingService in startService. 12 | newState.assets = [] 13 | 14 | return newState 15 | } 16 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-30.ts: -------------------------------------------------------------------------------- 1 | type OldState = { 2 | nfts: unknown 3 | nftsUpdate: unknown 4 | [otherSlice: string]: unknown 5 | } 6 | 7 | type NewState = { 8 | nfts: unknown 9 | [otherSlice: string]: unknown 10 | } 11 | 12 | // Remove old nfts slice and rename updated nfts slice 13 | export default (prevState: Record): NewState => { 14 | const { nfts: _, nftsUpdate, ...otherState } = prevState as OldState 15 | 16 | return { 17 | ...otherState, 18 | nfts: nftsUpdate, 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-32.ts: -------------------------------------------------------------------------------- 1 | type OldState = { 2 | keyrings: { 3 | keyringMetadata: { 4 | [keyringId: string]: { 5 | source: "import" | "internal" 6 | } 7 | } 8 | importing: false | "pending" | "done" | "failed" 9 | [sliceKey: string]: unknown 10 | } 11 | } 12 | 13 | type NewState = { 14 | internalSigner: { 15 | metadata: { 16 | [keyringId: string]: { 17 | source: "import" | "internal" 18 | } 19 | } 20 | privateKeys: { type: "single#secp256k1"; path: null; addresses: [string] }[] 21 | [sliceKey: string]: unknown 22 | } 23 | } 24 | 25 | export default (prevState: Record): NewState => { 26 | const oldState = prevState as OldState 27 | const { 28 | keyrings: { keyringMetadata, importing: _, ...keyringsState }, 29 | ...stateWithoutKeyrings 30 | } = oldState 31 | 32 | return { 33 | ...stateWithoutKeyrings, 34 | internalSigner: { 35 | ...keyringsState, 36 | metadata: keyringMetadata, 37 | privateKeys: [], 38 | }, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-33.ts: -------------------------------------------------------------------------------- 1 | import { MINUTE } from "../../constants" 2 | 3 | const DEFAULT_AUTOLOCK_INTERVAL = 60 * MINUTE 4 | 5 | type OldState = { 6 | ui: { 7 | settings: { 8 | [settingsKey: string]: unknown 9 | } 10 | [sliceKey: string]: unknown 11 | } 12 | [otherSlice: string]: unknown 13 | } 14 | 15 | type NewState = { 16 | ui: { 17 | settings: { 18 | [settingsKey: string]: unknown 19 | autoLockInterval: number 20 | } 21 | [sliceKey: string]: unknown 22 | } 23 | [otherSlice: string]: unknown 24 | } 25 | 26 | export default (prevState: Record): NewState => { 27 | const typedPrevState = prevState as OldState 28 | 29 | return { 30 | ...prevState, 31 | ui: { 32 | ...typedPrevState.ui, 33 | settings: { 34 | ...typedPrevState.ui.settings, 35 | autoLockInterval: DEFAULT_AUTOLOCK_INTERVAL, 36 | }, 37 | }, 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-34.ts: -------------------------------------------------------------------------------- 1 | type OldState = { 2 | ui: { 3 | settings: { 4 | [settingsKey: string]: unknown 5 | } 6 | [sliceKey: string]: unknown 7 | } 8 | [otherSlice: string]: unknown 9 | } 10 | 11 | type NewState = { 12 | ui: { 13 | settings: { 14 | [settingsKey: string]: unknown 15 | useFlashbots: boolean 16 | } 17 | [sliceKey: string]: unknown 18 | } 19 | [otherSlice: string]: unknown 20 | } 21 | 22 | export default (prevState: Record): NewState => { 23 | const typedPrevState = prevState as OldState 24 | 25 | return { 26 | ...prevState, 27 | ui: { 28 | ...typedPrevState.ui, 29 | settings: { 30 | ...typedPrevState.ui.settings, 31 | useFlashbots: false, 32 | }, 33 | }, 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /background/redux-slices/migrations/to-5.ts: -------------------------------------------------------------------------------- 1 | // This migration ensures the keyrings slice with no keyringMetadata key has a 2 | // keyringMetadata key whose default value is an empty object. 3 | 4 | type OldState = { 5 | keyrings: { 6 | [sliceKey: string]: unknown 7 | } 8 | [otherSlice: string]: unknown 9 | } 10 | 11 | type NewState = { 12 | keyrings: { 13 | keyringMetadata?: unknown 14 | [otherKey: string]: unknown 15 | } 16 | [otherSlice: string]: unknown 17 | } 18 | 19 | export default (prevState: Record): NewState => { 20 | const typedPrevState = prevState as OldState 21 | 22 | const newState: NewState = { 23 | ...typedPrevState, 24 | keyrings: { 25 | ...typedPrevState.keyrings, 26 | keyringMetadata: {}, 27 | }, 28 | } 29 | 30 | newState.keyrings.keyringMetadata = {} 31 | 32 | return newState 33 | } 34 | -------------------------------------------------------------------------------- /background/redux-slices/selectors/activitiesSelectors.ts: -------------------------------------------------------------------------------- 1 | import { createSelector } from "@reduxjs/toolkit" 2 | import { selectCurrentAccount, selectCurrentNetwork } from "./uiSelectors" 3 | import { RootState } from ".." 4 | 5 | export const selectCurrentAccountActivities = createSelector( 6 | (state: RootState) => state.activities.activities, 7 | selectCurrentAccount, 8 | selectCurrentNetwork, 9 | (activities, account, network) => 10 | activities?.[account.address]?.[network.chainID] ?? [], 11 | ) 12 | 13 | export const selectActivitesHashesForEnrichment = createSelector( 14 | selectCurrentAccountActivities, 15 | (currentActivities) => 16 | currentActivities.flatMap((activity) => 17 | "type" in activity ? [] : activity.hash, 18 | ), 19 | ) 20 | -------------------------------------------------------------------------------- /background/redux-slices/selectors/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./activitiesSelectors" 2 | export * from "./accountsSelectors" 3 | export * from "./internalSignerSelectors" 4 | export * from "./signingSelectors" 5 | export * from "./dappSelectors" 6 | export * from "./uiSelectors" 7 | export * from "./nftsSelectors" 8 | export * from "./abilitiesSelectors" 9 | -------------------------------------------------------------------------------- /background/redux-slices/selectors/ledgerSelectors.ts: -------------------------------------------------------------------------------- 1 | import { createSelector } from "@reduxjs/toolkit" 2 | import { RootState } from ".." 3 | import { HexString } from "../../types" 4 | import { LedgerDeviceState } from "../ledger" 5 | 6 | export const selectLedgerDeviceByAddresses = createSelector( 7 | (state: RootState) => state.ledger.devices, 8 | (ledgerDevices) => { 9 | const ledgerEntries = Object.values(ledgerDevices).flatMap((device) => 10 | Object.values(device.accounts).flatMap( 11 | (account): [[HexString, LedgerDeviceState]] | [] => { 12 | if (account.address === null) return [] 13 | 14 | return [[account.address, device]] 15 | }, 16 | ), 17 | ) 18 | 19 | return Object.fromEntries(ledgerEntries) 20 | }, 21 | ) 22 | 23 | export default {} 24 | -------------------------------------------------------------------------------- /background/redux-slices/tests/transaction-construction.unit.test.ts: -------------------------------------------------------------------------------- 1 | import reducer, { 2 | clearCustomGas, 3 | initialState, 4 | NetworkFeeTypeChosen, 5 | } from "../transaction-construction" 6 | 7 | describe("Transaction Construction Redux Slice", () => { 8 | describe("Actions", () => { 9 | describe("clearCustomGas", () => { 10 | it("Should reset selected fee type to Regular", () => { 11 | const mockState = { 12 | ...initialState, 13 | feeTypeSeected: NetworkFeeTypeChosen.Custom, 14 | } 15 | 16 | const newState = reducer(mockState, clearCustomGas()) 17 | expect(newState.feeTypeSelected).toBe(NetworkFeeTypeChosen.Regular) 18 | }) 19 | }) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /background/redux-slices/utils/constants.ts: -------------------------------------------------------------------------------- 1 | // FIXME Make this configurable. 2 | export const hardcodedMainCurrencySymbol = "USD" 3 | 4 | export const hardcodedMainCurrencySign = "$" 5 | -------------------------------------------------------------------------------- /background/services/campaign/types.ts: -------------------------------------------------------------------------------- 1 | import { MezoCampaign } from "./matsnet-nft" 2 | 3 | type FilterValidCampaigns = T extends { 4 | id: string 5 | data: unknown 6 | /** 7 | * The campaign is disabled if the user is e.g. not eligible 8 | */ 9 | enabled: boolean 10 | } 11 | ? T 12 | : never 13 | 14 | /** 15 | * Campaigns must use the following format 16 | * ```ts 17 | * { 18 | * id: "some-campaign-id" 19 | * data: {...} 20 | * disabled: boolean 21 | * } 22 | * ``` 23 | */ 24 | export type Campaigns = FilterValidCampaigns 25 | 26 | export type CampaignIds = Campaigns["id"] 27 | 28 | export type FilterCampaignsById = T extends { id: K } ? T : never 29 | -------------------------------------------------------------------------------- /background/services/chain/__mocks__/serial-fallback-provider.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable class-methods-use-this */ 2 | import { BigNumber } from "ethers" 3 | import { Block, FeeData } from "@ethersproject/abstract-provider" 4 | import { makeEthersBlock, makeEthersFeeData } from "../../../tests/factories" 5 | import type SerialFallbackProvider from "../serial-fallback-provider" 6 | 7 | export default class MockSerialFallbackProvider 8 | implements Partial 9 | { 10 | async getBlock(): Promise { 11 | return makeEthersBlock() 12 | } 13 | 14 | async getBlockNumber(): Promise { 15 | return 1 16 | } 17 | 18 | async getBalance(): Promise { 19 | return BigNumber.from(100) 20 | } 21 | 22 | async getFeeData(): Promise { 23 | return makeEthersFeeData() 24 | } 25 | 26 | async getCode(): Promise { 27 | return "false" 28 | } 29 | 30 | async subscribeFullPendingTransactions(): Promise { 31 | return Promise.resolve() 32 | } 33 | } 34 | 35 | export const makeSerialFallbackProvider = (): Partial => 36 | new MockSerialFallbackProvider() 37 | -------------------------------------------------------------------------------- /background/services/internal-ethereum-provider/constants.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/prefer-default-export 2 | export const TAHO_INTERNAL_ORIGIN = "@tally-internal" 3 | -------------------------------------------------------------------------------- /background/services/island/defaults.ts: -------------------------------------------------------------------------------- 1 | import eligibles from "../../static/eligibles.json" 2 | import { Claim, Eligible } from "./types" 3 | 4 | const defaultClaim: Claim = { 5 | eligibles: eligibles.map( 6 | (item): Eligible => ({ ...item, amount: BigInt(item.amount) }), 7 | ), 8 | } 9 | 10 | export default defaultClaim 11 | -------------------------------------------------------------------------------- /background/services/island/types.ts: -------------------------------------------------------------------------------- 1 | import { HexString } from "../../types" 2 | 3 | export type ReferrerStats = { 4 | bonusTotal: bigint 5 | referredUsers: number 6 | } 7 | 8 | export interface Eligible { 9 | index: HexString 10 | account: HexString 11 | amount: bigint 12 | proof: HexString[] 13 | } 14 | 15 | export interface Claim { 16 | eligibles: Eligible[] 17 | } 18 | 19 | export interface IPFSLinkItem { 20 | Hash: { "/": string } 21 | Name: string 22 | Tsize: number 23 | } 24 | -------------------------------------------------------------------------------- /background/services/name/resolvers/address-book.ts: -------------------------------------------------------------------------------- 1 | import { AddressOnNetwork, NameOnNetwork } from "../../../accounts" 2 | import PreferenceService from "../../preferences" 3 | import { NameResolver } from "../name-resolver" 4 | 5 | export default function addressBookResolverFor( 6 | preferenceService: PreferenceService, 7 | ): NameResolver<"tally-address-book"> { 8 | return { 9 | type: "tally-address-book", 10 | 11 | canAttemptNameResolution(): boolean { 12 | return true 13 | }, 14 | canAttemptAvatarResolution(): boolean { 15 | return false 16 | }, 17 | canAttemptAddressResolution(): boolean { 18 | return true 19 | }, 20 | 21 | async lookUpAddressForName(nameOnNetwork: NameOnNetwork) { 22 | return preferenceService.lookUpAddressForName(nameOnNetwork) 23 | }, 24 | async lookUpAvatar() { 25 | throw new Error("Avatar resolution not supported in address book.") 26 | }, 27 | async lookUpNameForAddress(addressOnNetwork: AddressOnNetwork) { 28 | return preferenceService.lookUpNameForAddress(addressOnNetwork) 29 | }, 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /background/services/name/resolvers/index.ts: -------------------------------------------------------------------------------- 1 | import ensResolverFor from "./ens" 2 | import addressBookResolverFor from "./address-book" 3 | import knownContractResolverFor from "./known-contracts" 4 | import unsResolver from "./uns" 5 | import rnsResolver from "./rns" 6 | import mezoResolver from "./mezo" 7 | 8 | const resolvers = { 9 | ensResolverFor, 10 | addressBookResolverFor, 11 | knownContractResolverFor, 12 | unsResolver, 13 | rnsResolver, 14 | mezoResolver, 15 | } 16 | 17 | type ResolverConstructors = ReturnType< 18 | (typeof resolvers)[keyof typeof resolvers] 19 | > 20 | 21 | export type NameResolverSystem = ResolverConstructors["type"] 22 | 23 | export { 24 | ensResolverFor, 25 | addressBookResolverFor, 26 | knownContractResolverFor, 27 | unsResolver, 28 | rnsResolver, 29 | mezoResolver, 30 | } 31 | -------------------------------------------------------------------------------- /background/services/name/resolvers/known-contracts.ts: -------------------------------------------------------------------------------- 1 | import PreferenceService from "../../preferences" 2 | import { NameResolver } from "../name-resolver" 3 | 4 | export default function knownContractResolverFor( 5 | preferenceService: PreferenceService, 6 | ): NameResolver<"tally-known-contracts"> { 7 | return { 8 | type: "tally-known-contracts", 9 | canAttemptNameResolution(): boolean { 10 | return true 11 | }, 12 | canAttemptAvatarResolution(): boolean { 13 | return false 14 | }, 15 | canAttemptAddressResolution(): boolean { 16 | return true 17 | }, 18 | 19 | lookUpAddressForName: 20 | preferenceService.lookUpAddressForContractName.bind(preferenceService), 21 | async lookUpAvatar() { 22 | throw new Error( 23 | "Avatar resolution not supported in known contracts resolver.", 24 | ) 25 | }, 26 | lookUpNameForAddress: 27 | preferenceService.lookUpNameForContractAddress.bind(preferenceService), 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /background/services/redux/differ.ts: -------------------------------------------------------------------------------- 1 | import { DiffContext, Filter, create } from "jsondiffpatch" 2 | 3 | const differ = create() 4 | 5 | const bigintDiffFilter: Filter = (context) => { 6 | if (typeof context.left === "bigint" && typeof context.right === "bigint") { 7 | if (context.left !== context.right) { 8 | context.setResult([context.left, context.right]) 9 | } 10 | } 11 | } 12 | bigintDiffFilter.filterName = "bigint" 13 | 14 | differ.processor.pipes.diff.before("objects", bigintDiffFilter) 15 | 16 | export const diff = differ.diff.bind(differ) 17 | export const patch = differ.patch.bind(differ) 18 | export type { Delta } from "jsondiffpatch" 19 | -------------------------------------------------------------------------------- /background/signing.ts: -------------------------------------------------------------------------------- 1 | import type { AccountSigner, ReadOnlyAccountSigner } from "./services/signing" 2 | 3 | export type AccountSignerWithId = Exclude< 4 | AccountSigner, 5 | typeof ReadOnlyAccountSigner 6 | > 7 | -------------------------------------------------------------------------------- /background/tag-types.ts: -------------------------------------------------------------------------------- 1 | declare const OpaqueTagSymbol: unique symbol 2 | declare class OpaqueTag { 3 | readonly [OpaqueTagSymbol]: S 4 | } 5 | 6 | export type Opaque = T & OpaqueTag 7 | 8 | export type UnwrapOpaque> = 9 | OpaqueType extends Opaque 10 | ? Type 11 | : OpaqueType 12 | -------------------------------------------------------------------------------- /background/tests/networks.unit.test.ts: -------------------------------------------------------------------------------- 1 | import { toHexChainID } from "../networks" 2 | 3 | describe("Networks", () => { 4 | describe("toHexchainID", () => { 5 | it("should be case-insensitive", async () => { 6 | expect(toHexChainID("0xA")).toEqual(toHexChainID("0xa")) 7 | expect(toHexChainID("0xA")).toEqual(toHexChainID(10)) 8 | expect(toHexChainID("0xa")).toEqual(toHexChainID(10)) 9 | }) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /background/third-party-data/blocknative/types.ts: -------------------------------------------------------------------------------- 1 | import { EthereumTransactionData as BlocknativeEthereumTransactionData } from "bnc-sdk/dist/types/src/interfaces" 2 | 3 | // Some remedial typing for BlockNative; see blocknative/sdk#138 . 4 | type EthereumNetBalanceChanges = { 5 | address: string 6 | balanceChanges: EthereumAssetBalanceChanges[] 7 | } 8 | 9 | type EthereumAssetBalanceChanges = { 10 | delta: string 11 | asset: AssetDetails 12 | breakdown: TransferDetails[] 13 | } 14 | 15 | type AssetDetails = { 16 | type: AssetType 17 | symbol: string 18 | } 19 | 20 | type AssetType = "ether" | "ERC20" 21 | 22 | type TransferDetails = { 23 | counterparty: string 24 | amount: string 25 | } 26 | 27 | export type EthereumTransactionData = BlocknativeEthereumTransactionData & { 28 | netBalanceChanges?: EthereumNetBalanceChanges[] 29 | } 30 | -------------------------------------------------------------------------------- /background/ui.ts: -------------------------------------------------------------------------------- 1 | import { AccountSignerWithId } from "./signing" 2 | 3 | export type AccountSignerSettings = { 4 | signer: AccountSignerWithId 5 | title?: string 6 | } 7 | -------------------------------------------------------------------------------- /background/utils/fetching.ts: -------------------------------------------------------------------------------- 1 | import { logger } from "ethers" 2 | 3 | const DEFAULT_TIMEOUT = 10000 4 | 5 | export const makeFetchWithTimeout = (timeoutMs: number) => 6 | // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types 7 | async function fetchWithTimeout( 8 | requestInfo: RequestInfo, 9 | options?: RequestInit | undefined, 10 | ) { 11 | const controller = new AbortController() 12 | const id = setTimeout(() => { 13 | logger.warn("Request to ", requestInfo, " timed out") 14 | return controller.abort() 15 | }, timeoutMs) 16 | const response = await fetch(requestInfo, { 17 | ...options, 18 | signal: controller.signal, 19 | }) 20 | clearTimeout(id) 21 | return response 22 | } 23 | 24 | export const fetchWithTimeout = makeFetchWithTimeout(DEFAULT_TIMEOUT) 25 | -------------------------------------------------------------------------------- /ci/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import { HardhatUserConfig } from "hardhat/config" 2 | import "dotenv-defaults/config" 3 | 4 | /* eslint-disable @typescript-eslint/no-var-requires */ 5 | require("dotenv-defaults").config({ 6 | path: "../.env", 7 | defaults: "../.env.defaults", 8 | }) 9 | 10 | const config: HardhatUserConfig = { 11 | networks: { 12 | hardhat: { 13 | forking: { 14 | enabled: true, 15 | url: process.env.CHAIN_API_URL || "", 16 | blockNumber: parseInt(process.env.FORKING_BLOCK ?? "", 10), 17 | }, 18 | chainId: parseInt(process.env.MAINNET_FORK_CHAIN_ID ?? "1337", 10), 19 | }, 20 | }, 21 | } 22 | 23 | export default config 24 | -------------------------------------------------------------------------------- /ci/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tallyho/ci", 3 | "version": "0.0.1", 4 | "description": "Taho, the community owned and operated Web3 wallet: window provider is responsible for creating the in-page object for communication.", 5 | "repository": "git@github.com:thesis/tally-extension.git", 6 | "author": "Michalina Cienciala", 7 | "license": "GPL-3.0", 8 | "keywords": [ 9 | "ethereum", 10 | "bitcoin", 11 | "cryptocurrency", 12 | "wallet", 13 | "web3", 14 | "dapp" 15 | ], 16 | "devDependencies": { 17 | "dotenv-defaults": "^5.0.2", 18 | "hardhat": "^2.14.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /dev-utils/local-chain/contracts/Greeter.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.8.0; 3 | 4 | import "hardhat/console.sol"; 5 | 6 | contract Greeter { 7 | string private greeting; 8 | 9 | constructor(string memory _greeting) { 10 | console.log("Deploying a Greeter with greeting:", _greeting); 11 | greeting = _greeting; 12 | } 13 | 14 | function greet() public view returns (string memory) { 15 | return greeting; 16 | } 17 | 18 | function setGreeting(string memory _greeting) public { 19 | console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); 20 | greeting = _greeting; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /dev-utils/local-chain/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "local-chain", 3 | "description": "Local chain setup to support Taho extension development.", 4 | "license": "GPL-3.0", 5 | "private": true, 6 | "repository": "https://github.com/tallycash/extension", 7 | "author": "Gergo Nagy", 8 | "scripts": { 9 | "start": "hardhat node" 10 | }, 11 | "devDependencies": { 12 | "@nomiclabs/hardhat-ethers": "^2.0.5", 13 | "@nomiclabs/hardhat-waffle": "^2.0.3", 14 | "@typechain/hardhat": "^5.0.0", 15 | "chai": "^4.3.6", 16 | "ethereum-waffle": "^3.4.0", 17 | "ethers": "^5.7.2", 18 | "hardhat": "^2.14.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /dev-utils/local-chain/test/sample-test.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai") 2 | const { ethers } = require("hardhat") 3 | 4 | describe("Greeter", function () { 5 | it("Should return the new greeting once it's changed", async function () { 6 | const Greeter = await ethers.getContractFactory("Greeter") 7 | const greeter = await Greeter.deploy("Hello, world!") 8 | await greeter.deployed() 9 | 10 | expect(await greeter.greet()).to.equal("Hello, world!") 11 | 12 | const setGreetingTx = await greeter.setGreeting("Hola, mundo!") 13 | 14 | // wait until the transaction is mined 15 | await setGreetingTx.wait() 16 | 17 | expect(await greeter.greet()).to.equal("Hola, mundo!") 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /dist/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/dist/.keep -------------------------------------------------------------------------------- /e2e-tests/regular/accounts.spec.ts: -------------------------------------------------------------------------------- 1 | import { test } from "../utils" 2 | 3 | test("Remove wallet", async ({ page, walletPageHelper }) => { 4 | await walletPageHelper.onboarding.addNewWallet() 5 | await walletPageHelper.goToStartPage() 6 | 7 | await page.locator(".profile_button").click() 8 | await page.locator(".icon_settings").click() 9 | await page.locator("text=Remove address").click() 10 | await page.locator("text=Yes, I want to remove it").click() 11 | }) 12 | -------------------------------------------------------------------------------- /firefox-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/env sh 2 | 3 | if command -v nerdctl &> /dev/null; then 4 | ctrmanager=nerdctl 5 | elif command -v docker &> /dev/null; then 6 | ctrmanager=docker 7 | elif command -v podman &> /dev/null; then 8 | ctrmanager=podman 9 | else 10 | echo "Installing a container manager" >&2 11 | exit 12 | fi 13 | 14 | echo "--- Let's clean up from earlier ---" 15 | rm firefox.zip 16 | rm -rf dist 17 | $ctrmanager image rm --force tally-ho-image:latest || true 18 | 19 | echo "--- Build extension ---" 20 | $ctrmanager build -t tally-ho-image:latest --output=dist --target=dist . 21 | 22 | echo "--- Let's clean up ---" 23 | 24 | $ctrmanager image rm --force tally-ho-image:latest || true 25 | -------------------------------------------------------------------------------- /github_cover@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/github_cover@2x.png -------------------------------------------------------------------------------- /manifest/manifest.brave.json: -------------------------------------------------------------------------------- 1 | { 2 | "externally_connectable": { 3 | "ids": [] 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /manifest/manifest.chrome.json: -------------------------------------------------------------------------------- 1 | { 2 | "minimum_chrome_version": "107", 3 | "externally_connectable": { 4 | "ids": [] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /manifest/manifest.development.json: -------------------------------------------------------------------------------- 1 | { 2 | "content_security_policy": { 3 | "extension_pages": "object-src 'self'; script-src 'self' 'wasm-unsafe-eval' http://localhost:*;" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /manifest/manifest.firefox.json: -------------------------------------------------------------------------------- 1 | { 2 | "browser_specific_settings": { 3 | "gecko": { 4 | "id": "webextension@tally.cash", 5 | "strict_min_version": "68.0" 6 | } 7 | }, 8 | "permissions": ["https://*/*"] 9 | } 10 | -------------------------------------------------------------------------------- /manifest/manifest.opera.json: -------------------------------------------------------------------------------- 1 | { 2 | "externally_connectable": { 3 | "ids": [] 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /patches/jsan+3.1.14.patch: -------------------------------------------------------------------------------- 1 | diff --git a/node_modules/jsan/lib/index.js b/node_modules/jsan/lib/index.js 2 | index c32b85b..dcdde87 100644 3 | --- a/node_modules/jsan/lib/index.js 4 | +++ b/node_modules/jsan/lib/index.js 5 | @@ -30,7 +30,12 @@ exports.stringify = function stringify(value, replacer, space, _options) { 6 | 7 | var decycled = cycle.decycle(value, options, replacer); 8 | if (arguments.length === 1) { 9 | - return JSON.stringify(decycled); 10 | + return JSON.stringify(decycled, (_, value) => { 11 | + if (typeof value === "bigint") { 12 | + return { B_I_G_I_N_T: value.toString() } 13 | + } 14 | + return value 15 | + }) 16 | } else { 17 | // decycle already handles when replacer is a function. 18 | return JSON.stringify(decycled, Array.isArray(replacer) ? replacer : null, space); 19 | -------------------------------------------------------------------------------- /provider-bridge-shared/constants.ts: -------------------------------------------------------------------------------- 1 | export const WINDOW_PROVIDER_TARGET = "tally-window-provider" 2 | export const PROVIDER_BRIDGE_TARGET = "tally-provider-bridge" 3 | 4 | export const EXTERNAL_PORT_NAME = "tally-external" 5 | export const INTERNAL_PORT_NAME = "tally-internal" 6 | -------------------------------------------------------------------------------- /provider-bridge-shared/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./constants" 2 | export * from "./eip-1193" 3 | export * from "./runtime-typechecks" 4 | export * from "./types" 5 | -------------------------------------------------------------------------------- /provider-bridge-shared/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tallyho/provider-bridge-shared", 3 | "version": "0.0.1", 4 | "description": "Taho, the community owned and operated Web3 wallet: provider bridge to connect the in-page provider with the background script.", 5 | "main": "index.ts", 6 | "repository": "git@github.com:thesis/tally-extension.git", 7 | "author": "Greg Nagy ", 8 | "license": "GPL-3.0", 9 | "keywords": [ 10 | "ethereum", 11 | "bitcoin", 12 | "cryptocurrency", 13 | "wallet", 14 | "web3", 15 | "dapp" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /provider-bridge/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tallyho/provider-bridge", 3 | "version": "0.0.1", 4 | "description": "Taho, the community owned and operated Web3 wallet: provider bridge to connect the in-page provider with the background script.", 5 | "main": "index.ts", 6 | "repository": "git@github.com:thesis/tally-extension.git", 7 | "author": "Greg Nagy ", 8 | "license": "GPL-3.0", 9 | "keywords": [ 10 | "ethereum", 11 | "bitcoin", 12 | "cryptocurrency", 13 | "wallet", 14 | "web3", 15 | "dapp" 16 | ], 17 | "scripts": { 18 | "build": "webpack --mode=production", 19 | "lint": "run-p lint:*", 20 | "lint-fix": "run-p 'lint:* -- --fix'", 21 | "lint:js": "eslint .", 22 | "test": "run-p lint:* build", 23 | "test:unit": "node tests/index.js", 24 | "watch": "webpack --mode=development --watch" 25 | }, 26 | "dependencies": { 27 | "webextension-polyfill": "^0.12.0", 28 | "@tallyho/provider-bridge-shared": "0.0.1" 29 | }, 30 | "devDependencies": { 31 | "@types/webextension-polyfill": "^0.12.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /scripts/key-generation/export-key-as-json.js: -------------------------------------------------------------------------------- 1 | // Since this is a script we can’t use import yet. 2 | /* eslint-disable @typescript-eslint/no-var-requires */ 3 | const fs = require("fs") 4 | const wallet = require("ethereumjs-wallet").default 5 | 6 | const pk = Buffer.from( 7 | process.env.PRIVATE_KEY, // should not contrain `0x` prefix 8 | "hex", 9 | ) 10 | const account = wallet.fromPrivateKey(pk) 11 | const password = process.env.PASSWORD 12 | account.toV3(password).then((value) => { 13 | const address = account.getAddress().toString("hex") 14 | const file = `UTC--${new Date() 15 | .toISOString() 16 | .replace(/[:]/g, "-")}--${address}.json` 17 | fs.writeFileSync(file, JSON.stringify(value)) 18 | }) 19 | -------------------------------------------------------------------------------- /scripts/key-generation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tallyho/key-generation", 3 | "version": "0.0.1", 4 | "description": "Taho, the community owned and operated Web3 wallet: a script generating JSON keystore file encoding given private key.", 5 | "main": "export-key-as-json.js", 6 | "repository": "git@github.com:tahowallet/extension.git", 7 | "author": "Michalina Cienciała", 8 | "license": "GPL-3.0", 9 | "private": true, 10 | "scripts": { 11 | "generate": "node export-key-as-json.js" 12 | }, 13 | "dependencies": { 14 | "ethereumjs-wallet": "^1.0.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scripts/macos-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | echo "Installing jq..." 5 | brew list jq &>/dev/null || brew install jq 6 | 7 | echo "Installing yq..." 8 | brew list yq &>/dev/null || brew install yq 9 | 10 | echo "Installing pre-commit and specified hooks..." 11 | brew list pre-commit &>/dev/null || brew install pre-commit 12 | pre-commit install --install-hooks 13 | 14 | echo "Installing nvm..." 15 | brew list nvm &>/dev/null || brew install nvm 16 | 17 | echo "Setting up nvm, yarn, and dependencies..." 18 | nvm use 19 | if ! [ -x "$(command -v yarn)" ]; then 20 | npm install -g yarn 21 | fi 22 | yarn install 23 | 24 | echo "Ready to rock! See above for any extra environment-related instructions." 25 | -------------------------------------------------------------------------------- /scripts/unreliable-rpc-provider-utils.ts: -------------------------------------------------------------------------------- 1 | export const patchRPCURL = (url: string): string => 2 | `http://localhost:9000?rpc=${url}` 3 | 4 | export const patchRPCURLS = ( 5 | chainIDToRPCMap: Record, 6 | ): typeof chainIDToRPCMap => 7 | Object.fromEntries( 8 | Object.entries(chainIDToRPCMap).map(([_, urls]) => [ 9 | _, 10 | urls.map(patchRPCURL), 11 | ]), 12 | ) 13 | -------------------------------------------------------------------------------- /setup-extension-mock.ts: -------------------------------------------------------------------------------- 1 | import "jest-webextension-mock" 2 | 3 | global.chrome.runtime.id = "mocked-extension-runtime-id" 4 | 5 | Object.assign(global.chrome, { 6 | ...global.chrome, 7 | runtime: { 8 | ...global.chrome.runtime, 9 | setUninstallURL: jest.fn(), 10 | }, 11 | windows: { 12 | ...global.chrome.windows, 13 | getCurrent: jest.fn(), 14 | create: jest.fn(), 15 | onRemoved: { 16 | ...(global.chrome.windows?.onRemoved ?? {}), 17 | addListener: jest.fn(), 18 | }, 19 | }, 20 | alarms: { 21 | ...global.chrome.alarms, 22 | create: jest.fn(), 23 | clear: jest.fn(), 24 | onAlarm: { 25 | ...(global.chrome.alarms?.onAlarm ?? {}), 26 | addListener: jest.fn(), 27 | removeListener: jest.fn(), 28 | }, 29 | }, 30 | }) 31 | -------------------------------------------------------------------------------- /setupJest.env.ts: -------------------------------------------------------------------------------- 1 | /* Reset IndexedDB between tests */ 2 | beforeEach(() => { 3 | global.indexedDB = new IDBFactory() 4 | }) 5 | 6 | /* Reset IndexedDB between tests */ 7 | afterEach(() => { 8 | global.indexedDB = new IDBFactory() 9 | }) 10 | 11 | it.flaky = function checkFlaky(label: string, testCase: () => unknown): void { 12 | // eslint-disable-next-line no-only-tests/no-only-tests 13 | it.only(label, () => { 14 | const results = [] 15 | for (let i = 0; i < 2000; i += 1) { 16 | results.push(testCase()) 17 | } 18 | return Promise.all(results) 19 | }) 20 | } 21 | 22 | // eslint-disable-next-line @typescript-eslint/no-namespace, @typescript-eslint/no-unused-vars 23 | declare namespace jest { 24 | interface It { 25 | /** 26 | * Used for debugging flaky tests 27 | */ 28 | flaky: (label: string, testCase: () => unknown) => void 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/provider-bridge.ts: -------------------------------------------------------------------------------- 1 | import connectProviderBridge from "@tallyho/provider-bridge" 2 | 3 | connectProviderBridge() 4 | -------------------------------------------------------------------------------- /src/tab.ts: -------------------------------------------------------------------------------- 1 | import { attachTabUIToRootElement } from "@tallyho/tally-ui" 2 | 3 | attachTabUIToRootElement() 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "declaration": false, 5 | "moduleResolution": "node", 6 | "esModuleInterop": true, 7 | "allowSyntheticDefaultImports": true, 8 | "jsx": "react-jsx", 9 | "strict": true, 10 | "resolveJsonModule": true, 11 | "noEmit": true, 12 | "noImplicitOverride": true 13 | }, 14 | "exclude": ["dev-utils", "ci"] 15 | } 16 | -------------------------------------------------------------------------------- /ui/.babelrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // Add styled-jsx and @babel/react for UI code specifically. 3 | plugins: ["styled-jsx/babel"], 4 | presets: ["@babel/preset-typescript", "@babel/react"], 5 | } 6 | -------------------------------------------------------------------------------- /ui/__mocks__/IntersectionObserver.ts: -------------------------------------------------------------------------------- 1 | export default class IntersectionObserverMock { 2 | callbackMap: Map void> = new Map() 3 | 4 | constructor( 5 | protected callback: (entry: [Partial]) => void, 6 | ) {} 7 | 8 | observe(element: HTMLElement): void { 9 | const observerCallback = () => 10 | this.callback([{ isIntersecting: true, target: element }]) 11 | 12 | this.callbackMap.set(element, observerCallback) 13 | element.addEventListener("custom_intersect", observerCallback) 14 | 15 | // Intersect immediately 16 | observerCallback() 17 | } 18 | 19 | unobserve(element: HTMLElement): void { 20 | this.callbackMap.delete(element) 21 | } 22 | } 23 | 24 | Object.defineProperty(window, "IntersectionObserver", { 25 | value: IntersectionObserverMock, 26 | }) 27 | -------------------------------------------------------------------------------- /ui/_locales/fr/messages.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /ui/_locales/nb_NO/messages.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /ui/_locales/ro/messages.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /ui/_locales/ru/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "overview": { 3 | "assets": "Активы", 4 | "tableHeader": { 5 | "asset": "Актив", 6 | "balance": "Баланс" 7 | } 8 | }, 9 | "passwordStrength": { 10 | "average": "Средний" 11 | }, 12 | "popupEdition": "Community Edition", 13 | "settings": { 14 | "bugReport": "Сообщить об ошибке", 15 | "exportLogs": { 16 | "title": "Сообщить об ошибке" 17 | }, 18 | "hideSmallAssetBalance": "" 19 | }, 20 | "swap": { 21 | "transactionSettings": { 22 | "estimatedFee": "Примерная комиссия сети" 23 | } 24 | }, 25 | "wallet": { 26 | "assetAmount": "Актив / Количество" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ui/_locales/sv/messages.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /ui/components/AccountsNotificationPanel/AccountsNotificationPanel.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import { useTranslation } from "react-i18next" 3 | import SharedSlideUpMenuPanel from "../Shared/SharedSlideUpMenuPanel" 4 | import AccountsNotificationPanelAccounts from "./AccountsNotificationPanelAccounts" 5 | 6 | type Props = { 7 | onCurrentAddressChange: (address: string) => void 8 | } 9 | 10 | export default function AccountsNotificationPanel({ 11 | onCurrentAddressChange, 12 | }: Props): ReactElement { 13 | const { t } = useTranslation() 14 | 15 | return ( 16 | 19 | 22 | 23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /ui/components/Claim/ClaimReferralBridge.tsx: -------------------------------------------------------------------------------- 1 | import { WEBSITE_ORIGIN } from "@tallyho/tally-background/constants/website" 2 | import { useEffect } from "react" 3 | 4 | /** 5 | * By mounting this component, the claim referrer is pulled from the website local storage. 6 | * This implemented by loading a hidden iframe which points to `/_referral-bridge.html`, 7 | * which in turn invokes `tally_setClaimReferrer` with the data from the local storage. 8 | */ 9 | export default function ClaimReferralBridge(): null { 10 | useEffect(() => { 11 | if (WEBSITE_ORIGIN === null) { 12 | throw new Error("Missing env variable 'WEBSITE_ORIGIN'") 13 | } 14 | 15 | const iframe = document.createElement("iframe") 16 | iframe.src = `${WEBSITE_ORIGIN}/_referral-bridge.html` 17 | iframe.style.display = "none" 18 | 19 | document.body.append(iframe) 20 | 21 | return () => { 22 | iframe.remove() 23 | } 24 | }, []) 25 | 26 | return null 27 | } 28 | -------------------------------------------------------------------------------- /ui/components/Claim/Success.tsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/components/Claim/Success.tsx -------------------------------------------------------------------------------- /ui/components/DAppConnection/DAppConnection.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import ActiveDAppConnection from "./ActiveDAppConnection" 3 | import DAppConnectionDefaultToggle from "./DAppConnectionDefaultToggle" 4 | import { useDappPermission } from "../../hooks/dapp-hooks" 5 | 6 | export default function DAppConnection(): ReactElement { 7 | const { isConnected, currentPermission, allowedPages } = useDappPermission() 8 | 9 | return ( 10 |
11 | 16 | 17 | 18 | 29 |
30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /ui/components/Earn/EmptyBowl.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | 3 | export default function EmptyBowl(): ReactElement { 4 | return ( 5 |
6 | 7 |
Just an empty bowl
8 |
You don't have an active deposit.
9 | 32 |
33 | ) 34 | } 35 | -------------------------------------------------------------------------------- /ui/components/Ledger/usb.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Temporary, partial typing used to test `navigator.usb.requestDevice()` popup. 3 | * TODO: remove this file when using real implementation. 4 | */ 5 | 6 | interface Navigator { 7 | readonly usb: USB 8 | } 9 | 10 | declare class USB extends EventTarget { 11 | requestDevice(options?: USBDeviceRequestOptions): Promise 12 | } 13 | 14 | interface USBDeviceRequestOptions { 15 | filters: unknown[] 16 | } 17 | -------------------------------------------------------------------------------- /ui/components/NFTs/NFTListCurrentWallet.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import { 3 | selectCurrentAccountNFTs, 4 | selectCurrentAccountNFTsCount, 5 | selectIsReloadingNFTs, 6 | } from "@tallyho/tally-background/redux-slices/selectors" 7 | import NFTList from "./NFTList" 8 | import { useBackgroundSelector, useNFTsReload } from "../../hooks" 9 | import NFTsExploreBanner from "./NFTsExploreBanner" 10 | 11 | export default function NFTListCurrentWallet(): ReactElement { 12 | const collections = useBackgroundSelector(selectCurrentAccountNFTs) 13 | const nftCount = useBackgroundSelector(selectCurrentAccountNFTsCount) 14 | const isLoading = useBackgroundSelector(selectIsReloadingNFTs) 15 | 16 | useNFTsReload() 17 | 18 | if (!nftCount && !isLoading) return 19 | 20 | return 21 | } 22 | -------------------------------------------------------------------------------- /ui/components/NFTs/NoMatchingNFTs.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import { useTranslation } from "react-i18next" 3 | import NFTsExploreBanner from "./NFTsExploreBanner" 4 | 5 | export default function NoMatchingNFTs(props: { 6 | type: "badge" | "nfts" 7 | }): ReactElement { 8 | const { type } = props 9 | const { t } = useTranslation("translation", { 10 | keyPrefix: "nfts", 11 | }) 12 | 13 | return ( 14 |
15 |

16 | {t("noMatchingNFTs", { 17 | type: type === "nfts" ? t("type1") : t("type2"), 18 | })} 19 |

20 | 21 | 36 |
37 | ) 38 | } 39 | -------------------------------------------------------------------------------- /ui/components/NetworkFees/NetworkSettingsSelectBNBChain.tsx: -------------------------------------------------------------------------------- 1 | import { useTranslation } from "react-i18next" 2 | import React, { ReactElement } from "react" 3 | 4 | export default function NetworkSettingsSelectBNBChain(): ReactElement { 5 | const { t } = useTranslation("translation", { 6 | keyPrefix: "networkFees.bsc", 7 | }) 8 | return ( 9 |
10 | {t("title")} 11 | {t("description")} 12 | 32 |
33 | ) 34 | } 35 | -------------------------------------------------------------------------------- /ui/components/Shared/SharedActivityHeader.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | 3 | interface Props { 4 | label: string 5 | activity: string 6 | } 7 | 8 | export default function SharedActivityHeader(props: Props): ReactElement { 9 | const { label, activity } = props 10 | 11 | return ( 12 |

13 | 14 | {label} 15 | 37 |

38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /ui/components/Shared/SharedAddressAvatar.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import SharedAvatar from "./SharedAvatar" 3 | 4 | type SharedAddressAvatarProps = { 5 | address: string 6 | url?: string 7 | } 8 | 9 | /* 10 | @TODO Switch to using our own resolution service, especially 11 | once we upgrade our service to support whatever else Effigy can do. 12 | */ 13 | export default function SharedAddressAvatar({ 14 | address, 15 | url, 16 | }: SharedAddressAvatarProps): ReactElement { 17 | return ( 18 | 25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /ui/components/Shared/SharedPageHeader.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import SharedBackButton from "./SharedBackButton" 3 | 4 | export default function SharedPageHeader({ 5 | children, 6 | withoutBackText, 7 | backPath, 8 | }: { 9 | children: React.ReactNode 10 | withoutBackText?: boolean 11 | backPath?: string 12 | }): ReactElement { 13 | return ( 14 |
15 | 16 |

{children}

17 | 33 |
34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /ui/components/Shared/SharedTwitterButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import SharedButton from "./SharedButton" 3 | 4 | export default function SharedTwitterButton({ 5 | link, 6 | text, 7 | buttonLabel = "Share", 8 | onClick, 9 | }: { 10 | link: string 11 | text: string 12 | buttonLabel?: string 13 | onClick?: () => void 14 | }): ReactElement { 15 | return ( 16 | 23 | 29 | {buttonLabel} 30 | 31 | 32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /ui/components/Shared/__tests__/SharedAssetIcon.test.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { render } from "@testing-library/react" 3 | import SharedAssetIcon from "../SharedAssetIcon" 4 | 5 | describe("SharedAssetIcon", () => { 6 | test("should render asset icon ", () => { 7 | const ui = render( 8 | , 13 | ) 14 | 15 | expect(ui.getByRole("img")).toBeInTheDocument() 16 | expect(ui.getByRole("img")).toBeVisible() 17 | }) 18 | 19 | test("should handle assets with invalid symbols", () => { 20 | const ui = render( 21 | , 26 | ) 27 | 28 | expect(ui.getByRole("img")).toBeInTheDocument() 29 | expect(ui.getByRole("img")).toBeVisible() 30 | expect(ui.getByText("?")).toBeVisible() 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /ui/components/Shared/__tests__/SharedTooltip.test.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { render, waitFor } from "@testing-library/react" 3 | import userEvent from "@testing-library/user-event" 4 | import SharedTooltip from "../SharedTooltip" 5 | 6 | const text = "Text text" 7 | const id = "tooltip_wrap" 8 | 9 | describe("SharedTooltip", () => { 10 | test("should display a tooltip", async () => { 11 | const ui = render( 12 | 13 |

{text}

14 |
, 15 | ) 16 | const tooltipElement = ui.getByTestId(id) 17 | 18 | expect(tooltipElement).toBeInTheDocument() 19 | expect(ui.queryByText(text)).not.toBeInTheDocument() 20 | await userEvent.hover(tooltipElement) 21 | await waitFor(() => expect(ui.getByText(text)).toBeInTheDocument()) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /ui/components/SignData/SignDataInfo.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | type Props = { 4 | label: string 5 | content: string 6 | } 7 | 8 | export default function SignDataInfo({ label, content }: Props): JSX.Element { 9 | return ( 10 | <> 11 |
12 |
{label}:
13 |
{content}
14 |
15 | 32 | 33 | ) 34 | } 35 | -------------------------------------------------------------------------------- /ui/components/SignData/index.ts: -------------------------------------------------------------------------------- 1 | export { default as EIP191Info } from "./EIP191Info" 2 | export { default as EIP4361Info } from "./EIP4361Info" 3 | export { default as SignDataInfo } from "./SignDataInfo" 4 | -------------------------------------------------------------------------------- /ui/components/Signing/SignatureDetails/TransactionSignatureDetails/TransactionAdditionalDetails/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import { TransactionSignatureSummaryProps } from "../TransactionSignatureSummary/TransactionSignatureSummaryProps" 3 | import SwapAssetDetails from "./SwapAssetDetails" 4 | 5 | export default function TransactionAdditionalDetails({ 6 | transactionRequest, 7 | annotation, 8 | }: TransactionSignatureSummaryProps): ReactElement | null { 9 | switch (annotation?.type) { 10 | case "asset-swap": 11 | return ( 12 | 16 | ) 17 | default: 18 | return null 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ui/components/Signing/SignatureDetails/TransactionSignatureDetails/TransactionSignatureDetailsPanelCombined.tsx: -------------------------------------------------------------------------------- 1 | import { EnrichedEVMTransactionRequest } from "@tallyho/tally-background/services/enrichment" 2 | import React, { ReactElement } from "react" 3 | import DetailsPanel from "./DetailsPanel" 4 | import RawDataPanel from "./RawDataPanel" 5 | 6 | export default function TransactionSignatureDetailsPanelCombined({ 7 | transactionRequest, 8 | }: { 9 | transactionRequest: EnrichedEVMTransactionRequest 10 | }): ReactElement { 11 | return ( 12 | <> 13 | 14 | 15 | 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /ui/components/Signing/SignatureDetails/TransactionSignatureDetails/TransactionSignatureDetailsPanelSwitcher.tsx: -------------------------------------------------------------------------------- 1 | import { EnrichedEVMTransactionRequest } from "@tallyho/tally-background/services/enrichment" 2 | import React, { ReactElement } from "react" 3 | import { useSwitchablePanels } from "../../../../hooks" 4 | import DetailsPanel from "./DetailsPanel" 5 | import RawDataPanel from "./RawDataPanel" 6 | 7 | export default function TransactionDataPanelSwitcher({ 8 | transactionRequest, 9 | }: { 10 | transactionRequest: EnrichedEVMTransactionRequest 11 | }): ReactElement | null { 12 | const switchablePanels = useSwitchablePanels([ 13 | { 14 | name: "Details", 15 | panelElement: () => ( 16 | 17 | ), 18 | }, 19 | { 20 | name: "Raw data", 21 | panelElement: () => ( 22 | 23 | ), 24 | }, 25 | ]) 26 | 27 | return switchablePanels 28 | } 29 | -------------------------------------------------------------------------------- /ui/components/Signing/SignatureDetails/TransactionSignatureDetails/TransactionSignatureSummary/TransactionSignatureSummaryBody.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement, ReactNode } from "react" 2 | 3 | export default function TransactionSignatureSummaryBody({ 4 | children, 5 | }: { 6 | children: ReactNode 7 | }): ReactElement { 8 | return ( 9 |
10 | {children} 11 | 24 |
25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /ui/components/Signing/SignatureDetails/TransactionSignatureDetails/TransactionSignatureSummary/TransactionSignatureSummaryProps.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | EnrichedEVMTransactionRequest, 3 | TransactionAnnotation, 4 | } from "@tallyho/tally-background/services/enrichment" 5 | 6 | export type TransactionSignatureSummaryProps< 7 | T extends TransactionAnnotation | undefined = 8 | | TransactionAnnotation 9 | | undefined, 10 | > = { 11 | transactionRequest: EnrichedEVMTransactionRequest 12 | annotation: T 13 | } 14 | -------------------------------------------------------------------------------- /ui/components/Signing/Signer/SignerLedger/SignerLedgerConnect/ActivateBlindSigning.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import { useTranslation } from "react-i18next" 3 | import SlideUpContentLayout from "./SlideUpLayout" 4 | 5 | export default function LedgerActivateBlindSigning(): ReactElement { 6 | const { t } = useTranslation("translation", { 7 | keyPrefix: "ledger.activation", 8 | }) 9 | return ( 10 | {t("step1")}, <>{t("step2")}, <>{t("step3")}]} 14 | onHelpClick={() => 15 | window.open( 16 | "https://support.ledger.com/hc/en-us/articles/4405481324433-Enable-blind-signing-in-the-Ethereum-ETH-app?docs=true", 17 | ) 18 | } 19 | /> 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /ui/components/Signing/Signer/SignerLedger/SignerLedgerConnect/LedgerBusy.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import { useTranslation } from "react-i18next" 3 | import SlideUpContentLayout from "./SlideUpLayout" 4 | 5 | export default function LedgerBusy(): ReactElement { 6 | const { t } = useTranslation("translation", { keyPrefix: "ledger.busy" }) 7 | return ( 8 | {t("step1")}, <>{t("step2")}]} 12 | /> 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /ui/components/Signing/Signer/SignerLedger/SignerLedgerConnect/LedgerNotConnected.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import { useTranslation } from "react-i18next" 3 | import SlideUpContentLayout from "./SlideUpLayout" 4 | 5 | export default function LedgerNotConnected(): ReactElement { 6 | const { t } = useTranslation("translation", { 7 | keyPrefix: "ledger.notConnected", 8 | }) 9 | return ( 10 | {t("step1")}, <>{t("step2")}, <>{t("step3")}]} 14 | /> 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /ui/components/Signing/Signer/SignerLedger/SignerLedgerConnect/MultipleLedgersConnected.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import { useTranslation } from "react-i18next" 3 | import SlideUpContentLayout from "./SlideUpLayout" 4 | 5 | export default function MultipleLedgersConnected(): ReactElement { 6 | const { t } = useTranslation("translation", { 7 | keyPrefix: "ledger.multipleLedgersConnected", 8 | }) 9 | return ( 10 | {t("step1")}, <>{t("step2")}, <>{t("step3")}]} 14 | /> 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /ui/components/Signing/Signer/SignerReadOnly/SignerReadOnlyFrame.tsx: -------------------------------------------------------------------------------- 1 | import { SignOperationType } from "@tallyho/tally-background/redux-slices/signing" 2 | import React, { ReactElement } from "react" 3 | import { SignerFrameProps } from ".." 4 | import { useBackgroundDispatch } from "../../../../hooks" 5 | import SharedButton from "../../../Shared/SharedButton" 6 | 7 | export default function SignerReadOnlyFrame({ 8 | children, 9 | rejectActionCreator, 10 | }: SignerFrameProps): ReactElement { 11 | const dispatch = useBackgroundDispatch() 12 | 13 | return ( 14 | <> 15 |
{children}
16 |
17 | dispatch(rejectActionCreator())} 21 | > 22 | Reject 23 | 24 | 25 | Read-only accounts cannot sign 26 |
27 | 32 | 33 | ) 34 | } 35 | -------------------------------------------------------------------------------- /ui/components/Signing/Signer/index.tsx: -------------------------------------------------------------------------------- 1 | import { SignOperationType } from "@tallyho/tally-background/redux-slices/signing" 2 | import { AccountSigner } from "@tallyho/tally-background/services/signing" 3 | import { ReactElement } from "react" 4 | import { ResolvedSignatureDetails } from "../SignatureDetails" 5 | 6 | /** 7 | * The props passed to a signer-specific frame, as well as to the dispatcher 8 | * component SignerFrame. 9 | */ 10 | export type SignerFrameProps< 11 | T extends SignOperationType, 12 | S extends AccountSigner = AccountSigner, 13 | > = ResolvedSignatureDetails & { 14 | request: T 15 | signer: S 16 | /** 17 | * The children a signer frame should render to present the user with 18 | * additional information about the data being signed. 19 | */ 20 | children: ReactElement 21 | } 22 | -------------------------------------------------------------------------------- /ui/components/Swap/ApproveQuoteButton.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { useTranslation } from "react-i18next" 3 | import SharedButton from "../Shared/SharedButton" 4 | 5 | export default function ApproveQuoteButton({ 6 | isApprovalInProgress, 7 | isDisabled, 8 | onApproveClick, 9 | isLoading, 10 | }: { 11 | isApprovalInProgress: boolean 12 | onApproveClick(): void 13 | isLoading: boolean 14 | isDisabled: boolean 15 | }): React.ReactElement { 16 | const { t } = useTranslation("translation", { keyPrefix: "swap" }) 17 | 18 | return isApprovalInProgress ? ( 19 | 20 | {t("waitingForApproval")} 21 | 22 | ) : ( 23 | 30 | {t("approveAsset")} 31 | 32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /ui/components/TopMenu/TopMenuProfileTooltip.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import { useTranslation } from "react-i18next" 3 | import SharedAddress from "../Shared/SharedAddress" 4 | 5 | export default function TopMenuProfileTooltip(props: { 6 | address: string 7 | }): ReactElement { 8 | const { t } = useTranslation() 9 | const { address } = props 10 | 11 | return ( 12 |
13 | 18 | 33 |
34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /ui/components/TransactionDetail/TransactionDetailAddressValue.tsx: -------------------------------------------------------------------------------- 1 | import { truncateAddress } from "@tallyho/tally-background/lib/utils" 2 | import React, { ReactElement } from "react" 3 | import SharedButton from "../Shared/SharedButton" 4 | 5 | export default function TransactionDetailAddressValue({ 6 | address, 7 | }: { 8 | address: string 9 | }): ReactElement { 10 | return ( 11 |
12 | { 18 | window 19 | .open(`https://etherscan.io/address/${address}`, "_blank") 20 | ?.focus() 21 | }} 22 | > 23 | {truncateAddress(address)} 24 | 25 | 30 |
31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /ui/components/TransactionDetail/TransactionDetailContainer.tsx: -------------------------------------------------------------------------------- 1 | import classNames from "classnames" 2 | import React, { ReactElement, ReactNode } from "react" 3 | 4 | export default function TransactionDetailContainer({ 5 | children, 6 | footer, 7 | }: { 8 | children: ReactNode 9 | footer?: ReactNode 10 | }): ReactElement { 11 | return ( 12 |
13 | {children} 14 | {footer &&
} 15 | {footer} 16 | 34 |
35 | ) 36 | } 37 | -------------------------------------------------------------------------------- /ui/hooks/redux-hooks.ts: -------------------------------------------------------------------------------- 1 | import { BackgroundDispatch, RootState } from "@tallyho/tally-background" 2 | import { noopAction } from "@tallyho/tally-background/redux-slices/utils" 3 | import { useEffect, useState } from "react" 4 | import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux" 5 | 6 | export const useBackgroundDispatch = (): BackgroundDispatch => 7 | useDispatch() 8 | 9 | export const useBackgroundSelector: TypedUseSelectorHook = 10 | useSelector 11 | 12 | /** 13 | * Returns true once all pending redux updates scheduled before the first render 14 | * (if any) have been applied, and false otherwise. 15 | */ 16 | export function useIsBackgroundSettled(): boolean { 17 | const [settled, setSettled] = useState(false) 18 | const dispatch = useBackgroundDispatch() 19 | useEffect(() => { 20 | Promise.resolve(dispatch(noopAction())).then(() => { 21 | setSettled(true) 22 | }) 23 | }) 24 | return settled 25 | } 26 | -------------------------------------------------------------------------------- /ui/pages/Onboarding/Tabbed/Routes.ts: -------------------------------------------------------------------------------- 1 | export const ONBOARDING_ROOT = "/tab.html#onboarding" 2 | 3 | const OnboardingRoutes = { 4 | ONBOARDING_START: "/onboarding", 5 | ADD_WALLET: "/onboarding/add-wallet", 6 | LEDGER: "/onboarding/ledger", 7 | SET_PASSWORD: "/onboarding/set-password", 8 | IMPORT_SEED: "/onboarding/import-seed", 9 | IMPORT_PRIVATE_KEY: "/onboarding/import-private-key", 10 | NEW_SEED: "/onboarding/new-seed", 11 | VIEW_ONLY_WALLET: "/onboarding/view-only-wallet", 12 | ONBOARDING_COMPLETE: "/onboarding/done", 13 | } as const 14 | 15 | export default OnboardingRoutes 16 | -------------------------------------------------------------------------------- /ui/pages/Onboarding/styles.ts: -------------------------------------------------------------------------------- 1 | export const OnboardingBox = ` 2 | border: 1px solid var(--green-60); 3 | border-radius: 8px; 4 | font-weight: 600; 5 | color: var(--green-20); 6 | padding: 24px; 7 | margin: 15px 0 24px; 8 | display: flex; 9 | flex-direction: column; 10 | width: 280px; 11 | ` 12 | export const OnboardingContainer = ` 13 | display: flex; 14 | flex-direction: column; 15 | justify-content: center; 16 | align-items: center; 17 | padding: 24px; 18 | ` 19 | export const OnboardingHeader = ` 20 | font-size: 36px; 21 | margin-top: 24px; 22 | margin-bottom: 8px; 23 | ` 24 | 25 | export const OnboardingSubheader = ` 26 | font-size: 16px; 27 | font-weight: 500; 28 | text-align: center; 29 | color: var(--green-60); 30 | margin: 0; 31 | ` 32 | 33 | export const OnboardingMessageHeader = ` 34 | display: flex; 35 | align-items: center; 36 | font-weight: 600; 37 | font-size: 18px; 38 | ` 39 | -------------------------------------------------------------------------------- /ui/pages/PersonalSign.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import { selectSigningData } from "@tallyho/tally-background/redux-slices/signing" 3 | import { useBackgroundSelector } from "../hooks" 4 | import Signing from "../components/Signing" 5 | 6 | export default function PersonalSignData(): ReactElement { 7 | const signingDataRequest = useBackgroundSelector(selectSigningData) 8 | 9 | return 10 | } 11 | -------------------------------------------------------------------------------- /ui/pages/Settings/ConnectedWebsitesListEmpty.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { useTranslation } from "react-i18next" 3 | 4 | export default function ConnectedWebsitesListEmpty(): React.ReactElement { 5 | const { t } = useTranslation("translation", { keyPrefix: "settings" }) 6 | 7 | return ( 8 |
9 | 10 |

{t("connectedWebsitesSettings.emptyList")}

11 | 34 |
35 | ) 36 | } 37 | -------------------------------------------------------------------------------- /ui/pages/SignData.tsx: -------------------------------------------------------------------------------- 1 | import { selectTypedData } from "@tallyho/tally-background/redux-slices/signing" 2 | import React, { ReactElement } from "react" 3 | import Signing from "../components/Signing" 4 | import { useBackgroundSelector } from "../hooks" 5 | 6 | export default function SignData(): ReactElement { 7 | const typedDataRequest = useBackgroundSelector(selectTypedData) 8 | 9 | return 10 | } 11 | -------------------------------------------------------------------------------- /ui/pages/SignTransaction.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import { selectTransactionData } from "@tallyho/tally-background/redux-slices/selectors/transactionConstructionSelectors" 3 | import { useBackgroundSelector } from "../hooks" 4 | import Signing from "../components/Signing" 5 | 6 | export default function SignTransaction(): ReactElement { 7 | const transactionDetails = useBackgroundSelector(selectTransactionData) 8 | 9 | return 10 | } 11 | -------------------------------------------------------------------------------- /ui/pages/TabNotFound.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement } from "react" 2 | import { useTranslation } from "react-i18next" 3 | 4 | export default function TabNotFound(): ReactElement { 5 | const { t } = useTranslation() 6 | return ( 7 | <> 8 |
9 |

{t("genericPages.pageDoesNotExist")}

10 |
11 | 20 | 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /ui/public/fonts/QuincyCF-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/fonts/QuincyCF-Medium.woff -------------------------------------------------------------------------------- /ui/public/fonts/QuincyCF-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/fonts/QuincyCF-Medium.woff2 -------------------------------------------------------------------------------- /ui/public/fonts/QuincyCF-Text.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/fonts/QuincyCF-Text.woff -------------------------------------------------------------------------------- /ui/public/fonts/QuincyCF-Text.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/fonts/QuincyCF-Text.woff2 -------------------------------------------------------------------------------- /ui/public/fonts/segment-medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/fonts/segment-medium.woff -------------------------------------------------------------------------------- /ui/public/fonts/segment-medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/fonts/segment-medium.woff2 -------------------------------------------------------------------------------- /ui/public/fonts/segment-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/fonts/segment-regular.woff -------------------------------------------------------------------------------- /ui/public/fonts/segment-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/fonts/segment-regular.woff2 -------------------------------------------------------------------------------- /ui/public/fonts/segment-semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/fonts/segment-semibold.woff -------------------------------------------------------------------------------- /ui/public/fonts/segment-semibold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/fonts/segment-semibold.woff2 -------------------------------------------------------------------------------- /ui/public/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/icon-128.png -------------------------------------------------------------------------------- /ui/public/images/abilities/mint.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ui/public/images/activity_approve@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/activity_approve@2x.png -------------------------------------------------------------------------------- /ui/public/images/activity_contract_interaction@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/activity_contract_interaction@2x.png -------------------------------------------------------------------------------- /ui/public/images/activity_receive@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/activity_receive@2x.png -------------------------------------------------------------------------------- /ui/public/images/activity_receive_medium@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/activity_receive_medium@2x.png -------------------------------------------------------------------------------- /ui/public/images/activity_send.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/activity_send@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/activity_send@2x.png -------------------------------------------------------------------------------- /ui/public/images/activity_send_medium@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/activity_send_medium@2x.png -------------------------------------------------------------------------------- /ui/public/images/activity_swap@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/activity_swap@2x.png -------------------------------------------------------------------------------- /ui/public/images/activity_swap_medium@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/activity_swap_medium@2x.png -------------------------------------------------------------------------------- /ui/public/images/add_wallet/import.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ui/public/images/add_wallet/ledger.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ui/public/images/arbitrum@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/arbitrum@2x.png -------------------------------------------------------------------------------- /ui/public/images/arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/arrow@2x.png -------------------------------------------------------------------------------- /ui/public/images/arrow_right@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/arrow_right@2x.png -------------------------------------------------------------------------------- /ui/public/images/assets/avax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/assets/avax.png -------------------------------------------------------------------------------- /ui/public/images/assets/bnb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/assets/bnb.png -------------------------------------------------------------------------------- /ui/public/images/assets/btc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/assets/btc.png -------------------------------------------------------------------------------- /ui/public/images/assets/doggo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/assets/doggo.png -------------------------------------------------------------------------------- /ui/public/images/assets/eth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/assets/eth.png -------------------------------------------------------------------------------- /ui/public/images/assets/matic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/assets/matic.png -------------------------------------------------------------------------------- /ui/public/images/assets/rbtc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/assets/rbtc.png -------------------------------------------------------------------------------- /ui/public/images/avatar@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/avatar@2x.png -------------------------------------------------------------------------------- /ui/public/images/avatars/atos@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/avatars/atos@2x.png -------------------------------------------------------------------------------- /ui/public/images/avatars/foz@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/avatars/foz@2x.png -------------------------------------------------------------------------------- /ui/public/images/avatars/lola@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/avatars/lola@2x.png -------------------------------------------------------------------------------- /ui/public/images/avatars/matilda@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/avatars/matilda@2x.png -------------------------------------------------------------------------------- /ui/public/images/avatars/phoenix@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/avatars/phoenix@2x.png -------------------------------------------------------------------------------- /ui/public/images/avatars/sirius@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/avatars/sirius@2x.png -------------------------------------------------------------------------------- /ui/public/images/avatars/sport@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/avatars/sport@2x.png -------------------------------------------------------------------------------- /ui/public/images/avatars/topa@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/avatars/topa@2x.png -------------------------------------------------------------------------------- /ui/public/images/back@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/back@2x.png -------------------------------------------------------------------------------- /ui/public/images/banner-bg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ui/public/images/banner_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/banner_thumbnail.png -------------------------------------------------------------------------------- /ui/public/images/block_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/block_icon@2x.png -------------------------------------------------------------------------------- /ui/public/images/bolt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/bolt@2x.png -------------------------------------------------------------------------------- /ui/public/images/change@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/change@2x.png -------------------------------------------------------------------------------- /ui/public/images/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/check@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/check@2x.png -------------------------------------------------------------------------------- /ui/public/images/checkmark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/checkmark@2x.png -------------------------------------------------------------------------------- /ui/public/images/chevron@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/chevron@2x.png -------------------------------------------------------------------------------- /ui/public/images/chevron_down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/chevron_left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/chevron_right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/claim@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/claim@2x.png -------------------------------------------------------------------------------- /ui/public/images/claim_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/claim_success.png -------------------------------------------------------------------------------- /ui/public/images/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/close@2x.png -------------------------------------------------------------------------------- /ui/public/images/cog@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/cog@2x.png -------------------------------------------------------------------------------- /ui/public/images/congrats_header@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/congrats_header@2x.png -------------------------------------------------------------------------------- /ui/public/images/connect_ledger_popup_underlay_downward_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /ui/public/images/connect_ledger_popup_underlay_upward_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /ui/public/images/continue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/copy@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/copy@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/aave_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/aave_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/bankless_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/bankless_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/dxdao_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/dxdao_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/ens_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/ens_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/fwb_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/fwb_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/gitcoin_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/gitcoin_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/gnosis_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/gnosis_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/keeper_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/keeper_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/pleasr_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/pleasr_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/radicle_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/radicle_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/sushi_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/sushi_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/synthetix_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/synthetix_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/uniswap_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/uniswap_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/daos/yearn_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/daos/yearn_logo@2x.png -------------------------------------------------------------------------------- /ui/public/images/dapp_favicon_default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/dapp_favicon_default@2x.png -------------------------------------------------------------------------------- /ui/public/images/dark_forest@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/dark_forest@2x.png -------------------------------------------------------------------------------- /ui/public/images/dark_forest_bg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/dark_forest_bg@2x.png -------------------------------------------------------------------------------- /ui/public/images/disconnect@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/disconnect@2x.png -------------------------------------------------------------------------------- /ui/public/images/discord@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/discord@2x.png -------------------------------------------------------------------------------- /ui/public/images/doggo_gold@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/doggo_gold@2x.png -------------------------------------------------------------------------------- /ui/public/images/doggo_grey@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/doggo_grey@2x.png -------------------------------------------------------------------------------- /ui/public/images/doggo_light@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/doggo_light@2x.png -------------------------------------------------------------------------------- /ui/public/images/earn_tab@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/earn_tab@2x.png -------------------------------------------------------------------------------- /ui/public/images/edit@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/edit@2x.png -------------------------------------------------------------------------------- /ui/public/images/empty_bowl@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/empty_bowl@2x.png -------------------------------------------------------------------------------- /ui/public/images/eth@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/eth@2x.png -------------------------------------------------------------------------------- /ui/public/images/ethereum-background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/ethereum-background@2x.png -------------------------------------------------------------------------------- /ui/public/images/external@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/external@2x.png -------------------------------------------------------------------------------- /ui/public/images/external_small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/external_small@2x.png -------------------------------------------------------------------------------- /ui/public/images/eye@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/eye@2x.png -------------------------------------------------------------------------------- /ui/public/images/eye_account@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/eye_account@2x.png -------------------------------------------------------------------------------- /ui/public/images/garbage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/garbage@2x.png -------------------------------------------------------------------------------- /ui/public/images/gas@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/gas@2x.png -------------------------------------------------------------------------------- /ui/public/images/gift@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/gift@2x.png -------------------------------------------------------------------------------- /ui/public/images/github@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/github@2x.png -------------------------------------------------------------------------------- /ui/public/images/graph@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/graph@2x.png -------------------------------------------------------------------------------- /ui/public/images/icon-34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/icon-34.png -------------------------------------------------------------------------------- /ui/public/images/icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/icon-60.png -------------------------------------------------------------------------------- /ui/public/images/icons/m/connected.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/continue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/copy.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/dashboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/developer.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/export.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/eye-on.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/feedback.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/import.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/info.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/list.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/lock-bold.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/menu.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/new-tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/notif-announcement.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/notif-attention.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/notif-correct.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/notif-wrong.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/swap.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/switch.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/unlock-bold.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/unlock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/icons/m/wallet.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/add.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/arrow-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/arrow-toggle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/back.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/continue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/copy.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/download.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/dropdown.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/edit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/garbage.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/key.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/lock-bold.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/mark-read.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/new-tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/notif-announ.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/notif-attention.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/notif-correct.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/notif-wrong.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/notification.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/receive.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/send.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/settings2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/swap.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/unlock-bold.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /ui/public/images/icons/s/unlock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/illustration_bones@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/illustration_bones@2x.png -------------------------------------------------------------------------------- /ui/public/images/illustration_import_seed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/illustration_import_seed@2x.png -------------------------------------------------------------------------------- /ui/public/images/illustration_unlock@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/illustration_unlock@2x.png -------------------------------------------------------------------------------- /ui/public/images/imported@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/imported@2x.png -------------------------------------------------------------------------------- /ui/public/images/info@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/info@2x.png -------------------------------------------------------------------------------- /ui/public/images/island/portal-image-title@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/island/portal-image-title@2x.png -------------------------------------------------------------------------------- /ui/public/images/island/portal-image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/island/portal-image@2x.png -------------------------------------------------------------------------------- /ui/public/images/key-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ui/public/images/ledger_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/loading_doggo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/loading_doggo.gif -------------------------------------------------------------------------------- /ui/public/images/lock@2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/lock@2.png -------------------------------------------------------------------------------- /ui/public/images/lock@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/lock@2x.png -------------------------------------------------------------------------------- /ui/public/images/mark_read@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/mark_read@2x.png -------------------------------------------------------------------------------- /ui/public/images/marketplaces/poap_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/marketplaces/poap_color.png -------------------------------------------------------------------------------- /ui/public/images/marketplaces/poap_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/marketplaces/poap_white.png -------------------------------------------------------------------------------- /ui/public/images/marketplaces/rarible.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ui/public/images/mascot@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/mascot@2x.png -------------------------------------------------------------------------------- /ui/public/images/message_correct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/message_correct.png -------------------------------------------------------------------------------- /ui/public/images/message_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/message_error.png -------------------------------------------------------------------------------- /ui/public/images/message_warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/message_warning.png -------------------------------------------------------------------------------- /ui/public/images/mezo-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/mezo-1.png -------------------------------------------------------------------------------- /ui/public/images/mezo-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/mezo-2.png -------------------------------------------------------------------------------- /ui/public/images/mezo-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/mezo-3.png -------------------------------------------------------------------------------- /ui/public/images/more_dots@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/more_dots@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/arbitrum-square@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/arbitrum-square@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/arbitrum@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/arbitrum@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/arbitrum_icon_small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/arbitrum_icon_small@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/arbitrumnova-square@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/arbitrumnova-square@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/arbitrumnova@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/arbitrumnova@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/arbitrumsepolia-square@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/arbitrumsepolia-square@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/arbitrumsepolia@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/arbitrumsepolia@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/avalanche-square@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/avalanche-square@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/avalanche@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/avalanche@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/bnbchain-square@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/bnbchain-square@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/bnbchain@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/bnbchain@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/celo-square@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/celo-square@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/celo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/celo@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/ethereum-square@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/ethereum-square@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/ethereum@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/ethereum@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/ethereumsepolia-square@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/ethereumsepolia-square@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/ethereumsepolia@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/ethereumsepolia@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/mezomatsnet-square@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/mezomatsnet-square@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/mezomatsnet@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/mezomatsnet@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/optimism-square@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/optimism-square@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/optimism@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/optimism@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/polygon-square@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/polygon-square@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/polygon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/polygon@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/rootstock-square@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/rootstock-square@2x.png -------------------------------------------------------------------------------- /ui/public/images/networks/rootstock@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/networks/rootstock@2x.png -------------------------------------------------------------------------------- /ui/public/images/new_tab@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/new_tab@2x.png -------------------------------------------------------------------------------- /ui/public/images/new_tab_hover@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/new_tab_hover@2x.png -------------------------------------------------------------------------------- /ui/public/images/notification_announce.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/notification_announce@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/notification_announce@2x.png -------------------------------------------------------------------------------- /ui/public/images/notification_error@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/notification_error@2x.png -------------------------------------------------------------------------------- /ui/public/images/notification_receive@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/notification_receive@2x.png -------------------------------------------------------------------------------- /ui/public/images/onboarding_pin_extension.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/onboarding_pin_extension.gif -------------------------------------------------------------------------------- /ui/public/images/optimism@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/optimism@2x.png -------------------------------------------------------------------------------- /ui/public/images/other-wallet-connect-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/overview_tab@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/overview_tab@2x.png -------------------------------------------------------------------------------- /ui/public/images/paste@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/paste@2x.png -------------------------------------------------------------------------------- /ui/public/images/placeholder.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /ui/public/images/plus@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/plus@2x.png -------------------------------------------------------------------------------- /ui/public/images/polygon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/polygon@2x.png -------------------------------------------------------------------------------- /ui/public/images/portfolio.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/portrait.png -------------------------------------------------------------------------------- /ui/public/images/qr_code@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/qr_code@2x.png -------------------------------------------------------------------------------- /ui/public/images/receive@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/receive@2x.png -------------------------------------------------------------------------------- /ui/public/images/reload@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/reload@2x.png -------------------------------------------------------------------------------- /ui/public/images/reward_locked@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/reward_locked@2x.png -------------------------------------------------------------------------------- /ui/public/images/search_large@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/search_large@2x.png -------------------------------------------------------------------------------- /ui/public/images/send@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/send@2x.png -------------------------------------------------------------------------------- /ui/public/images/send_asset.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ui/public/images/subscape-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/swap.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/swap@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/swap@2x.png -------------------------------------------------------------------------------- /ui/public/images/swap_asset.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ui/public/images/swap_tab@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/swap_tab@2x.png -------------------------------------------------------------------------------- /ui/public/images/switch@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/switch@2x.png -------------------------------------------------------------------------------- /ui/public/images/tahonamechange.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/tahonamechange.gif -------------------------------------------------------------------------------- /ui/public/images/tally_reward@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/tally_reward@2x.png -------------------------------------------------------------------------------- /ui/public/images/tally_wc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/tally_wc.png -------------------------------------------------------------------------------- /ui/public/images/time.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ui/public/images/transfer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/transfer@2x.png -------------------------------------------------------------------------------- /ui/public/images/trezor_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/trezor_icon@2x.png -------------------------------------------------------------------------------- /ui/public/images/twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ui/public/images/twitter@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/twitter@2x.png -------------------------------------------------------------------------------- /ui/public/images/uniswap@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/uniswap@2x.png -------------------------------------------------------------------------------- /ui/public/images/uniswap_large@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/uniswap_large@2x.png -------------------------------------------------------------------------------- /ui/public/images/wallet.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/public/images/wallet_connect_guideline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/wallet_connect_guideline.png -------------------------------------------------------------------------------- /ui/public/images/wallet_kind_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/wallet_kind_icon@2x.png -------------------------------------------------------------------------------- /ui/public/images/wallet_tab@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/wallet_tab@2x.png -------------------------------------------------------------------------------- /ui/public/images/warning@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tahowallet/extension/312fc28b4569f689edd5e65ebe49f54cf21bad25/ui/public/images/warning@2x.png -------------------------------------------------------------------------------- /ui/public/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Taho 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ui/public/tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Taho 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ui/setupJest.env.ts: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom" 2 | import "./_locales/i18n" 3 | import "./__mocks__/IntersectionObserver" 4 | -------------------------------------------------------------------------------- /ui/tests/store.ts: -------------------------------------------------------------------------------- 1 | import { CombinedState, configureStore, EnhancedStore } from "@reduxjs/toolkit" 2 | import rootReducer, { RootState } from "@tallyho/tally-background/redux-slices" 3 | 4 | export const initializeStoreForTest = ( 5 | preloadedState = {}, 6 | ): EnhancedStore> => 7 | configureStore({ 8 | reducer: rootReducer, 9 | preloadedState, 10 | middleware: (getDefaultMiddleware) => 11 | getDefaultMiddleware({ 12 | serializableCheck: false, 13 | }), 14 | }) 15 | 16 | export type ReduxStoreTypeForTest = ReturnType 17 | -------------------------------------------------------------------------------- /ui/utils/accounts.ts: -------------------------------------------------------------------------------- 1 | import { AccountType } from "@tallyho/tally-background/redux-slices/accounts" 2 | import { AccountSigner } from "@tallyho/tally-background/services/signing" 3 | 4 | export const isAccountWithSecrets = (accountType: AccountType): boolean => 5 | accountType === AccountType.Imported || 6 | accountType === AccountType.Internal || 7 | accountType === AccountType.PrivateKey 8 | 9 | export const isAccountWithMnemonic = (accountType: AccountType): boolean => 10 | accountType === AccountType.Imported || accountType === AccountType.Internal 11 | 12 | export const isAccountSingular = (accountType: AccountType): boolean => 13 | accountType === AccountType.PrivateKey || accountType === AccountType.ReadOnly 14 | 15 | export const isSignerWithSecrets = (accountSigner: AccountSigner): boolean => 16 | accountSigner.type === "keyring" || accountSigner.type === "private-key" 17 | -------------------------------------------------------------------------------- /ui/utils/lists.ts: -------------------------------------------------------------------------------- 1 | export const intersperseWith = ( 2 | items: T[], 3 | getItem: (index: number) => K, 4 | ): (T | K)[] => { 5 | const result: (T | K)[] = [] 6 | 7 | for (let i = 0; i < items.length; i += 1) { 8 | const element = items[i] 9 | 10 | result.push(element) 11 | 12 | if (i < items.length - 1) { 13 | result.push(getItem(i)) 14 | } 15 | } 16 | return result 17 | } 18 | 19 | export default {} 20 | -------------------------------------------------------------------------------- /ui/utils/noop.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Stable function that can be set as default value 3 | * for optional callbacks 4 | */ 5 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 6 | export default function noop(): any {} 7 | -------------------------------------------------------------------------------- /ui/utils/tabs.ts: -------------------------------------------------------------------------------- 1 | import { FeatureFlags, isEnabled } from "@tallyho/tally-background/features" 2 | import { I18nKey } from "../_locales/i18n" 3 | 4 | export type TabInfo = { 5 | /** 6 | * i18n key with the title for this tab 7 | */ 8 | title: I18nKey 9 | path: string 10 | icon: string 11 | } 12 | 13 | const allTabs: (TabInfo & { visible?: boolean })[] = [ 14 | { 15 | path: "/wallet", 16 | title: "tabs.wallet", 17 | icon: "wallet", 18 | }, 19 | { 20 | path: "/nfts", 21 | title: "tabs.nfts", 22 | icon: "nfts", 23 | }, 24 | { 25 | path: "/portfolio", 26 | title: "tabs.portfolio", 27 | icon: "portfolio", 28 | }, 29 | { 30 | path: "/earn", 31 | title: "tabs.earn", 32 | icon: "earn", 33 | visible: isEnabled(FeatureFlags.SHOW_TOKEN_FEATURES), 34 | }, 35 | { 36 | path: "/settings", 37 | title: "tabs.settings", 38 | icon: "settings", 39 | }, 40 | ] 41 | 42 | const tabs = allTabs 43 | .map(({ visible = true, ...tab }) => (visible ? tab : null)) 44 | .filter((tab): tab is TabInfo => tab !== null) 45 | 46 | export const defaultTab = tabs[0] 47 | 48 | export default tabs 49 | -------------------------------------------------------------------------------- /ui/utils/textUtils.ts: -------------------------------------------------------------------------------- 1 | export function capitalize(s: string): string { 2 | return s[0].toUpperCase() + s.slice(1) 3 | } 4 | 5 | export function trimWithEllipsis(text: string, maxLength: number): string { 6 | return text && text.length > maxLength 7 | ? `${text.slice(0, maxLength).trim()}...` 8 | : text 9 | } 10 | -------------------------------------------------------------------------------- /window-provider/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tallyho/window-provider", 3 | "version": "0.0.1", 4 | "description": "Taho, the community owned and operated Web3 wallet: window provider is responsible for creating the in-page object for communication.", 5 | "main": "index.ts", 6 | "repository": "git@github.com:thesis/tally-extension.git", 7 | "author": "Greg Nagy ", 8 | "license": "GPL-3.0", 9 | "keywords": [ 10 | "ethereum", 11 | "bitcoin", 12 | "cryptocurrency", 13 | "wallet", 14 | "web3", 15 | "dapp" 16 | ], 17 | "dependencies": { 18 | "@tallyho/provider-bridge-shared": "0.0.1" 19 | } 20 | } 21 | --------------------------------------------------------------------------------