├── .babelrc ├── .eslintrc.json ├── .gitattributes ├── .github └── ISSUE_TEMPLATE │ ├── Bug.md │ ├── Feature_Request.md │ └── Proposal.md ├── .gitignore ├── .snyk ├── .solhint.json ├── .soliumignore ├── .soliumrc.json ├── .storybook ├── addons.js └── config.js ├── .travis.yml ├── CONTRIBUTING.md ├── Landing ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── browserconfig.xml ├── css │ ├── 2.a55b1a50.chunk.css │ ├── 2.a55b1a50.chunk.css.map │ ├── main.9b63a9fa.chunk.css │ └── main.9b63a9fa.chunk.css.map ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── images │ ├── beta-tag.svg │ ├── escrowExample.png │ ├── github-icon.png │ ├── logoGroupLeft.png │ ├── logoGroupRight.png │ ├── mostPopularIcon.svg │ ├── peerIcon.svg │ ├── permissionlessIcon.svg │ ├── secureIcon.svg │ ├── status-icon.svg │ ├── statusLogo.svg │ ├── teller-logo-icon.svg │ ├── teller-logo-text.svg │ ├── tradeIcon.svg │ ├── twitter-icon.svg │ └── worldwideIcon.svg ├── index.html ├── manifest.json ├── mstile-144x144.png ├── mstile-150x150.png ├── mstile-310x150.png ├── mstile-310x310.png ├── mstile-70x70.png ├── open-graph.png ├── safari-pinned-tab.svg └── site.webmanifest ├── README.md ├── SWARM.md ├── contracts ├── .gitkeep ├── common │ ├── Controlled.sol │ ├── Medianizer.sol │ ├── MessageSigned.sol │ ├── Ownable.sol │ ├── Pausable.sol │ ├── ReentrancyGuard.sol │ ├── SecuredFunctions.sol │ ├── Stakable.sol │ └── USDStakable.sol ├── fees │ ├── KyberFeeBurner.sol │ └── KyberNetworkProxy.sol ├── misc │ └── GnosisSafe.sol ├── proxy │ ├── Proxiable.sol │ └── Proxy.sol ├── teller-network │ ├── Arbitrable.sol │ ├── ArbitrationLicense.sol │ ├── Escrow.sol │ ├── EscrowRelay.sol │ ├── Fees.sol │ ├── IEscrow.sol │ ├── License.sol │ ├── OfferStore.sol │ └── UserStore.sol ├── test │ ├── StandardToken.sol │ └── TestEscrowUpgrade.sol └── token │ ├── ApproveAndCallFallBack.sol │ ├── ERC20Token.sol │ ├── MiniMeToken.sol │ ├── MiniMeTokenFactory.sol │ ├── MiniMeTokenInterface.sol │ ├── SafeTransfer.sol │ ├── TokenController.sol │ └── TokenFactory.sol ├── cypress.json ├── cypress ├── integration │ └── navigation.spec.js ├── plugins │ └── index.js └── support │ ├── commands.js │ └── index.js ├── embark.json ├── embarkConfig ├── blockchain.js ├── communication.js ├── contracts.js ├── data.js ├── development │ └── password ├── namesystem.js ├── pipeline.js ├── privatenet │ ├── genesis-parity.json │ ├── genesis.json │ └── password ├── storage.js ├── testnet │ └── password └── webserver.js ├── images ├── buyer_take_offer │ ├── Browse offers.png │ ├── Set amount (Active).png │ ├── Set amount (Default).png │ ├── Set amount (Filled).png │ └── Summary.png ├── dispute_resolve │ ├── IMG_2428.png │ ├── IMG_2429.png │ ├── IMG_2430.png │ ├── IMG_2431.png │ └── IMG_2432.png ├── escrow_workflow │ ├── Trade - Step 1 (Buyer).png │ ├── Trade - Step 1 (Seller).png │ ├── Trade - Step 2 (Buyer).png │ ├── Trade - Step 2 (Seller).png │ ├── Trade - Step 3 (Buyer).png │ ├── Trade - Step 3 (Seller).png │ ├── Trade - Step 4 (Seller).png │ └── Trade - Step 4 (Buyer).png ├── seller_create_offer │ ├── Arbitrator.png │ ├── Browse offers.png │ ├── Buy-1.png │ ├── Buy.png │ ├── Contact Details (Status)-1.png │ ├── Contact Details (Status)-2.png │ ├── Contact Details (Status)-3.png │ ├── Contact Details (Status).png │ ├── Crypto select (signature request).png │ ├── Crypto select (wallet not connected).png │ ├── Crypto select.png │ ├── Local Currency.png │ ├── Location (Active).png │ ├── Location (Filled).png │ ├── Location (Typing).png │ ├── Location.png │ ├── Nickname-1.png │ ├── Nickname.png │ ├── No limits.png │ ├── Payment Method.png │ ├── Price.png │ ├── Set amount (Filled).png │ └── Summary.png └── state_diagrams │ └── escrow.png ├── old └── shared.mainnet.json ├── package.json ├── public ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── browserconfig.xml ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── index.html ├── manifest.json ├── mstile-144x144.png ├── mstile-150x150.png ├── mstile-310x150.png ├── mstile-310x310.png ├── mstile-70x70.png ├── open-graph.png ├── safari-pinned-tab.svg └── site.webmanifest ├── shared.rinkeby.json ├── shared.ropsten.chains.json ├── src ├── __mocks__ │ ├── fileMock.js │ └── styleMock.js ├── css │ ├── .gitkeep │ ├── Form.scss │ ├── bootstrap-overrides.scss │ ├── fonts │ │ └── Inter │ │ │ ├── Inter-Black.woff │ │ │ ├── Inter-Black.woff2 │ │ │ ├── Inter-BlackItalic.woff │ │ │ ├── Inter-BlackItalic.woff2 │ │ │ ├── Inter-Bold.woff │ │ │ ├── Inter-Bold.woff2 │ │ │ ├── Inter-BoldItalic.woff │ │ │ ├── Inter-BoldItalic.woff2 │ │ │ ├── Inter-ExtraBold.woff │ │ │ ├── Inter-ExtraBold.woff2 │ │ │ ├── Inter-ExtraBoldItalic.woff │ │ │ ├── Inter-ExtraBoldItalic.woff2 │ │ │ ├── Inter-ExtraLight.woff │ │ │ ├── Inter-ExtraLight.woff2 │ │ │ ├── Inter-ExtraLightItalic.woff │ │ │ ├── Inter-ExtraLightItalic.woff2 │ │ │ ├── Inter-Italic.woff │ │ │ ├── Inter-Italic.woff2 │ │ │ ├── Inter-Light.woff │ │ │ ├── Inter-Light.woff2 │ │ │ ├── Inter-LightItalic.woff │ │ │ ├── Inter-LightItalic.woff2 │ │ │ ├── Inter-Medium.woff │ │ │ ├── Inter-Medium.woff2 │ │ │ ├── Inter-MediumItalic.woff │ │ │ ├── Inter-MediumItalic.woff2 │ │ │ ├── Inter-Regular.woff │ │ │ ├── Inter-Regular.woff2 │ │ │ ├── Inter-SemiBold.woff │ │ │ ├── Inter-SemiBold.woff2 │ │ │ ├── Inter-SemiBoldItalic.woff │ │ │ ├── Inter-SemiBoldItalic.woff2 │ │ │ ├── Inter-Thin.woff │ │ │ ├── Inter-Thin.woff2 │ │ │ ├── Inter-ThinItalic.woff │ │ │ ├── Inter-ThinItalic.woff2 │ │ │ ├── Inter-italic.var.woff2 │ │ │ ├── Inter-upright.var.woff2 │ │ │ ├── Inter.var.woff2 │ │ │ └── inter.css │ └── variable-overrides.scss ├── images │ ├── .gitkeep │ ├── Ellipse.png │ ├── arbitrator.svg │ ├── arrow-disabled.svg │ ├── arrow-down.svg │ ├── arrow.svg │ ├── bank.svg │ ├── becomeArbi.svg │ ├── bell.svg │ ├── beta-tag.svg │ ├── cancel-gray.svg │ ├── cancel.svg │ ├── change.svg │ ├── check-circle.svg │ ├── check.svg │ ├── close.svg │ ├── close_profile.svg │ ├── contact-methods │ │ ├── kakao-talk.svg │ │ ├── line.svg │ │ ├── status.svg │ │ ├── telegram.svg │ │ └── wechat.svg │ ├── cryptoIcons.svg │ ├── delete.svg │ ├── diamond.png │ ├── dispute.svg │ ├── dollar.svg │ ├── dotted-line.svg │ ├── down-arrow.svg │ ├── download.svg │ ├── downvote.svg │ ├── earthIcon.svg │ ├── error.png │ ├── escrow │ │ ├── 01.png │ │ ├── 02.png │ │ ├── 03.png │ │ ├── 04.png │ │ └── 05.png │ ├── exclamation-circle.png │ ├── green-check.svg │ ├── info-red.svg │ ├── info.svg │ ├── landing │ │ ├── escrowExample.png │ │ ├── github-icon.png │ │ ├── logoGroupLeft.png │ │ ├── logoGroupRight.png │ │ ├── mostPopularIcon.svg │ │ ├── peerIcon.svg │ │ ├── permissionlessIcon.svg │ │ ├── secureIcon.svg │ │ ├── status-icon.svg │ │ ├── statusLogo.svg │ │ ├── tradeIcon.svg │ │ ├── twitter-icon.svg │ │ └── worldwideIcon.svg │ ├── lightning.svg │ ├── limits.svg │ ├── list.svg │ ├── location.svg │ ├── make_admin.svg │ ├── money-hand.svg │ ├── no-crypto.png │ ├── pencil.svg │ ├── profile.svg │ ├── profileUser.svg │ ├── question-mark.svg │ ├── read-chat.svg │ ├── settings.svg │ ├── small-info.svg │ ├── success.png │ ├── teller-logo-icon.png │ ├── teller-logo-icon.svg │ ├── teller-logo-text.svg │ ├── teller-logo-white.svg │ ├── transfer.svg │ ├── transparentLogo.png │ ├── unknownIcon.svg │ ├── upvote.svg │ ├── user-check.svg │ └── wallet.svg ├── index.js ├── index.scss └── js │ ├── .gitkeep │ ├── components │ ├── ConfirmDialog │ │ └── index.jsx │ ├── ConnectWallet │ │ └── index.js │ ├── EditContact │ │ ├── ContactList.jsx │ │ ├── __snapshots__ │ │ │ └── index.test.jsx.snap │ │ ├── index.jsx │ │ ├── index.scss │ │ ├── index.test.jsx │ │ └── validators.js │ ├── EditLocation │ │ ├── SellerPosition.jsx │ │ ├── SellerPosition.test.jsx │ │ └── __snapshots__ │ │ │ └── SellerPosition.test.jsx.snap │ ├── ErrorInformation │ │ ├── 404.jsx │ │ ├── index.jsx │ │ └── index.scss │ ├── Loading │ │ ├── __snapshots__ │ │ │ └── index.test.jsx.snap │ │ ├── index.jsx │ │ ├── index.scss │ │ └── index.test.jsx │ ├── Map │ │ ├── CustomInfoWindow.jsx │ │ ├── SearchBar.jsx │ │ ├── index.jsx │ │ └── index.scss │ ├── ModalDialog │ │ └── index.jsx │ ├── NoArbitratorWarning │ │ └── index.jsx │ ├── NoLicense │ │ └── index.jsx │ ├── NoWeb3Dialog │ │ └── index.jsx │ ├── NotificationForm │ │ └── index.jsx │ ├── NotificationManager │ │ ├── index.jsx │ │ ├── index.scss │ │ └── notifications │ │ │ └── EscrowNotifications.jsx │ ├── Offer │ │ ├── index.jsx │ │ └── index.scss │ ├── PriceWarning │ │ └── index.jsx │ ├── Reputation │ │ ├── __snapshots__ │ │ │ └── index.test.jsx.snap │ │ ├── index.jsx │ │ ├── index.scss │ │ └── index.test.jsx │ ├── TransactionWarning │ │ └── index.jsx │ ├── UserInfoRow │ │ └── index.jsx │ └── UserInformation │ │ ├── Address.jsx │ │ ├── Address.scss │ │ ├── Identicon.jsx │ │ └── index.jsx │ ├── constants │ ├── contactMethods.js │ └── currencies.js │ ├── features │ ├── approval │ │ ├── actions.js │ │ ├── constants.js │ │ ├── index.js │ │ ├── reducer.js │ │ ├── saga.js │ │ └── selectors.js │ ├── arbitration │ │ ├── actions.js │ │ ├── constants.js │ │ ├── index.js │ │ ├── reducer.js │ │ ├── saga.js │ │ └── selectors.js │ ├── emailNotifications │ │ ├── actions.js │ │ ├── constants.js │ │ ├── index.js │ │ ├── reducer.js │ │ ├── saga.js │ │ └── selectors.js │ ├── escrow │ │ ├── actions.js │ │ ├── constants.js │ │ ├── helpers.js │ │ ├── index.js │ │ ├── reducer.js │ │ ├── saga.js │ │ └── selectors.js │ ├── events │ │ ├── index.js │ │ ├── reducer.js │ │ └── selectors.js │ ├── license │ │ ├── actions.js │ │ ├── actions.test.js │ │ ├── constants.js │ │ ├── index.js │ │ ├── reducer.js │ │ ├── reducer.test.js │ │ ├── saga.js │ │ └── selectors.js │ ├── metadata │ │ ├── actions.js │ │ ├── constants.js │ │ ├── index.js │ │ ├── reducer.js │ │ ├── saga.js │ │ └── selectors.js │ ├── network │ │ ├── actions.js │ │ ├── constants.js │ │ ├── index.js │ │ ├── reducer.js │ │ ├── saga.js │ │ └── selectors.js │ ├── newBuy │ │ ├── actions.js │ │ ├── constants.js │ │ ├── index.js │ │ ├── reducer.js │ │ └── selectors.js │ ├── newSeller │ │ ├── actions.js │ │ ├── constants.js │ │ ├── index.js │ │ ├── reducer.js │ │ └── selectors.js │ ├── prices │ │ ├── actions.js │ │ ├── constants.js │ │ ├── index.js │ │ ├── reducer.js │ │ ├── saga.js │ │ └── selectors.js │ └── signature │ │ ├── actions.js │ │ ├── constants.js │ │ ├── index.js │ │ ├── reducer.js │ │ ├── saga.js │ │ └── selectors.js │ ├── history.js │ ├── i18n.js │ ├── layout │ ├── App.jsx │ └── Header │ │ ├── index.jsx │ │ └── index.scss │ ├── locales │ └── en.json │ ├── pages │ ├── Arbitration │ │ ├── components │ │ │ ├── ContactUser.jsx │ │ │ ├── EscrowDetail.jsx │ │ │ ├── ReadChatLogs.jsx │ │ │ └── TradeParticipant.jsx │ │ ├── index.jsx │ │ └── index.scss │ ├── ArbitrationLicense │ │ ├── components │ │ │ ├── Info.jsx │ │ │ └── Info.scss │ │ └── index.jsx │ ├── Arbitrators │ │ └── index.jsx │ ├── EditLocation │ │ ├── components │ │ │ ├── UpdateButton.jsx │ │ │ ├── UpdateButton.test.jsx │ │ │ └── __snapshots__ │ │ │ │ └── UpdateButton.test.jsx.snap │ │ └── index.jsx │ ├── EditMyContact │ │ ├── components │ │ │ ├── UpdateButton.jsx │ │ │ ├── UpdateButton.test.jsx │ │ │ └── __snapshots__ │ │ │ │ └── UpdateButton.test.jsx.snap │ │ └── index.jsx │ ├── Escrow │ │ ├── components │ │ │ ├── ApproveTokenFunds.jsx │ │ │ ├── ApproveTokenRow.jsx │ │ │ ├── CancelDispute.jsx │ │ │ ├── CancelEscrow.jsx │ │ │ ├── DisputeWarning.jsx │ │ │ ├── Done.jsx │ │ │ ├── EscrowDetail.jsx │ │ │ ├── FundingEscrow.jsx │ │ │ ├── Mining.jsx │ │ │ ├── OpenDispute.jsx │ │ │ ├── Profile.jsx │ │ │ ├── ReleaseFunds.jsx │ │ │ └── SendMoney.jsx │ │ ├── index.jsx │ │ └── index.scss │ ├── Home │ │ ├── components │ │ │ ├── iconGroup.jsx │ │ │ ├── landingFooter.jsx │ │ │ ├── landingHeader.jsx │ │ │ └── openDappBtn.jsx │ │ ├── index.jsx │ │ └── index.scss │ ├── License │ │ ├── components │ │ │ ├── Balance.jsx │ │ │ ├── Balance.test.jsx │ │ │ ├── BuyButton.jsx │ │ │ ├── BuyButton.test.jsx │ │ │ ├── Info.jsx │ │ │ ├── Info.scss │ │ │ ├── Info.test.jsx │ │ │ └── __snapshots__ │ │ │ │ ├── Balance.test.jsx.snap │ │ │ │ ├── BuyButton.test.jsx.snap │ │ │ │ └── Info.test.jsx.snap │ │ └── index.jsx │ ├── MyDisputes │ │ ├── components │ │ │ ├── Dispute.jsx │ │ │ └── Disputes.jsx │ │ ├── index.jsx │ │ └── index.scss │ ├── MyOffers │ │ ├── components │ │ │ ├── Offers.jsx │ │ │ ├── Offers.test.jsx │ │ │ └── __snapshots__ │ │ │ │ └── Offers.test.jsx.snap │ │ └── index.jsx │ ├── MyProfile │ │ ├── components │ │ │ ├── ProfileButton.jsx │ │ │ ├── ProfileButton.scss │ │ │ └── Separator.jsx │ │ ├── index.jsx │ │ └── index.scss │ ├── MyTrades │ │ ├── components │ │ │ ├── Trades.jsx │ │ │ ├── Trades.scss │ │ │ ├── Trades.test.jsx │ │ │ └── __snapshots__ │ │ │ │ └── Trades.test.jsx.snap │ │ └── index.jsx │ ├── NotificationSettings │ │ └── index.jsx │ ├── OffersList │ │ ├── components │ │ │ ├── ClearButton.jsx │ │ │ ├── Modals │ │ │ │ ├── AmountModal.jsx │ │ │ │ ├── ContactMethodModal.jsx │ │ │ │ ├── CurrencyModal.jsx │ │ │ │ ├── LocationModal.jsx │ │ │ │ ├── PaymentMethodModal.jsx │ │ │ │ └── SortModal.jsx │ │ │ ├── SorterFilter.jsx │ │ │ └── SorterFilter.scss │ │ ├── index.jsx │ │ └── index.scss │ ├── OpenDispute │ │ └── index.jsx │ ├── Profile │ │ ├── components │ │ │ └── Offer.jsx │ │ ├── index.jsx │ │ └── index.scss │ ├── ProfileSettings │ │ └── index.jsx │ ├── SellerApproval │ │ ├── SellerApprovalItem.jsx │ │ ├── index.jsx │ │ └── index.scss │ ├── Settings │ │ └── index.js │ ├── SubscribeToEmails │ │ └── index.jsx │ └── ValidateEmail │ │ └── index.jsx │ ├── provider.js │ ├── reducer.js │ ├── services │ ├── embarkjs.js │ └── googleMap.js │ ├── setupTests.js │ ├── store.js │ ├── ui │ ├── CheckButton │ │ ├── index.jsx │ │ └── index.scss │ ├── LoadingButton │ │ ├── index.jsx │ │ └── index.scss │ ├── LoadingRectangle │ │ ├── index.jsx │ │ └── index.scss │ ├── LogoCircle │ │ ├── index.jsx │ │ └── index.scss │ ├── RatingIcon │ │ └── index.jsx │ ├── RoundedIcon │ │ ├── index.jsx │ │ └── index.scss │ └── TxHash │ │ └── index.js │ ├── utils │ ├── address.js │ ├── images.js │ ├── networks.js │ ├── notifUtils.js │ ├── numbers.js │ ├── saga.js │ ├── sorters.js │ ├── strings.js │ └── transaction.js │ ├── validators.js │ └── wizards │ ├── Buy │ ├── 0_Trade │ │ ├── components │ │ │ ├── OfferTrade.jsx │ │ │ └── index.scss │ │ └── index.jsx │ ├── 1_1_ContactName │ │ └── index.jsx │ ├── 1_2_ContactDetails │ │ └── index.jsx │ └── 2_ConfirmTrade │ │ ├── index.jsx │ │ └── index.scss │ ├── Sell │ ├── 0_Asset │ │ ├── components │ │ │ ├── SellerAssets.jsx │ │ │ └── SellerAssets.scss │ │ └── index.jsx │ ├── 1_PaymentMethods │ │ ├── components │ │ │ ├── SellerPaymentMethod.jsx │ │ │ ├── SellerPaymentMethod.test.jsx │ │ │ └── __snapshots__ │ │ │ │ └── SellerPaymentMethod.test.jsx.snap │ │ └── index.jsx │ ├── 2_Currency │ │ ├── components │ │ │ ├── FiatSelectorForm.jsx │ │ │ ├── FiatSelectorForm.test.jsx │ │ │ └── __snapshots__ │ │ │ │ └── FiatSelectorForm.test.jsx.snap │ │ └── index.jsx │ ├── 3_Location │ │ └── index.jsx │ ├── 4_1_ContactName │ │ └── index.jsx │ ├── 4_2_ContactDetails │ │ └── index.jsx │ ├── 5_SelectArbitrator │ │ ├── components │ │ │ └── ArbitratorSelectorForm.jsx │ │ └── index.jsx │ ├── 6_Margin │ │ ├── components │ │ │ ├── MarginSelectorForm.jsx │ │ │ ├── MarginSelectorForm.scss │ │ │ ├── MarginSelectorForm.test.jsx │ │ │ └── __snapshots__ │ │ │ │ └── MarginSelectorForm.test.jsx.snap │ │ ├── index.jsx │ │ └── index.scss │ ├── 7_Limits │ │ ├── components │ │ │ ├── LimitForm.jsx │ │ │ └── Success.jsx │ │ ├── index.jsx │ │ └── index.scss │ └── 8_Summary │ │ ├── components │ │ ├── FinalModal.jsx │ │ ├── FinalModal.scss │ │ ├── SellSummary.js │ │ └── SellSummary.scss │ │ └── index.jsx │ ├── Wizard.jsx │ └── hoc │ ├── withFooter.jsx │ └── withFooter.scss ├── stories ├── components │ ├── confirmDialog.stories.jsx │ ├── editContact.stories.jsx │ ├── errorInformation.stories.jsx │ ├── loading.stories.jsx │ ├── map.stories.jsx │ ├── mining.stories.jsx │ ├── notFound.stories.jsx │ ├── reputation.stories.jsx │ └── userInformation.stories.jsx ├── pages │ ├── editMyContact.stories.jsx │ ├── license.stories.jsx │ └── myProfile.stories.jsx ├── ui │ └── .gitkeep └── wizards │ └── Sell │ ├── 0_asset.stories.jsx │ ├── 1_location.stories.jsx │ ├── 2_paymentMethods.stories.jsx │ ├── 3_currency.stories.jsx │ └── 4_margin.stories.jsx ├── teller-logo.png ├── test ├── arbitration_spec.js ├── escrow_relay_spec.js ├── escrow_spec.js ├── escrow_upgradability_spec.js ├── funding_escrows_spec.js ├── license_spec.js ├── metadata_store_spec.js └── offer_stake_spec.js ├── utils └── testUtils.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", 4 | "@babel/preset-react" 5 | ], 6 | "plugins": [ 7 | "@babel/plugin-proposal-class-properties" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol diff linguist-language=Solidity 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐞 Bug Report 3 | about: Something is broken? 🔨 4 | --- 5 | 6 | ### Bug Report 7 | 8 | #### Summary 9 | 10 | 11 | 12 | #### Current behavior 13 | 14 | 18 | 19 | #### How to reproduce 20 | 21 | 25 | 26 | #### Expected behavior 27 | 28 | 29 | 30 | #### Please provide additional information about your system 31 | 32 | **OS**: 33 | *Software Version**: 34 | **Node Version**: 35 | **NPM Version**: 36 | 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_Request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🎉 Feature Request 3 | about: You have a neat idea that should be implemented? 🎩 4 | --- 5 | 6 | ### Feature Request 7 | 8 | 9 | 10 | #### Summary 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Proposal.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🤔 Proposal 3 | about: Have a nice proposal? 4 | --- 5 | 6 | ### Proposal description 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /.pnp 5 | .pnp.js 6 | 7 | # testing 8 | /coverage 9 | 10 | # production 11 | /build 12 | 13 | # misc 14 | .DS_Store 15 | .env.local 16 | .env.development.local 17 | .env.test.local 18 | .env.production.local 19 | .idea 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | .embark 26 | chains.json 27 | embarkConfig/production/password 28 | embarkConfig/livenet/password 29 | coverage 30 | dist 31 | node_modules 32 | src/embarkArtifacts 33 | .idea 34 | yarn-error.log 35 | cypress/videos/* 36 | .secret.json 37 | 38 | crytic-export/ -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:default" 3 | } 4 | -------------------------------------------------------------------------------- /.soliumignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.soliumrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solium:all", 3 | "plugins": [ 4 | "security" 5 | ], 6 | "rules": { 7 | "quotes": [ 8 | "error", 9 | "double" 10 | ], 11 | "indentation": [ 12 | "error", 13 | 4 14 | ], 15 | "arg-overflow": [ 16 | "warning", 17 | 3 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /.storybook/addons.js: -------------------------------------------------------------------------------- 1 | import '@storybook/addon-actions/register'; 2 | import '@storybook/addon-knobs/register'; 3 | import '@storybook/addon-links/register'; 4 | -------------------------------------------------------------------------------- /.storybook/config.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { configure, addDecorator } from '@storybook/react'; 3 | import { action } from '@storybook/addon-actions'; 4 | import { Router } from 'react-router'; 5 | const createMemoryHistory = require("history").createMemoryHistory; 6 | 7 | const history = createMemoryHistory(); 8 | 9 | history.push = action('history.push'); 10 | history.replace = action('history.replace'); 11 | history.go = action('history.go'); 12 | history.goBack = action('history.goBack'); 13 | history.goForward = action('history.goForward'); 14 | 15 | addDecorator(story => {story()}); 16 | 17 | const req = require.context("../stories", true, /.stories.jsx$/); 18 | 19 | function loadStories() { 20 | req.keys().forEach(filename => req(filename)); 21 | } 22 | 23 | configure(loadStories, module); 24 | 25 | import '../src/css/fonts/Inter/inter.css'; 26 | import '../src/css/bootstrap-overrides.scss'; 27 | 28 | // TODO: Move to dedicated component 29 | import '../src/index.scss'; 30 | import '../src/css/Form.scss'; 31 | import '../src/js/i18n'; 32 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | os: 3 | - linux 4 | - osx 5 | node_js: 6 | - "10" 7 | before_install: 8 | - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.19.1 9 | - export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" 10 | cache: 11 | yarn: true 12 | env: 13 | - EMBARK_NO_PREPARE=true 14 | install: 15 | - yarn install 16 | script: 17 | - yarn lint 18 | - yarn test:contracts 19 | -------------------------------------------------------------------------------- /Landing/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/android-chrome-192x192.png -------------------------------------------------------------------------------- /Landing/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/android-chrome-512x512.png -------------------------------------------------------------------------------- /Landing/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/apple-touch-icon.png -------------------------------------------------------------------------------- /Landing/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #18B6FF 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Landing/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/favicon-16x16.png -------------------------------------------------------------------------------- /Landing/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/favicon-32x32.png -------------------------------------------------------------------------------- /Landing/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/favicon.ico -------------------------------------------------------------------------------- /Landing/images/beta-tag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Landing/images/escrowExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/images/escrowExample.png -------------------------------------------------------------------------------- /Landing/images/github-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/images/github-icon.png -------------------------------------------------------------------------------- /Landing/images/logoGroupLeft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/images/logoGroupLeft.png -------------------------------------------------------------------------------- /Landing/images/logoGroupRight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/images/logoGroupRight.png -------------------------------------------------------------------------------- /Landing/images/mostPopularIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Landing/images/status-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Landing/images/twitter-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 10 | 11 | 12 | 13 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Landing/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /Landing/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/mstile-144x144.png -------------------------------------------------------------------------------- /Landing/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/mstile-150x150.png -------------------------------------------------------------------------------- /Landing/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/mstile-310x150.png -------------------------------------------------------------------------------- /Landing/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/mstile-310x310.png -------------------------------------------------------------------------------- /Landing/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/mstile-70x70.png -------------------------------------------------------------------------------- /Landing/open-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/Landing/open-graph.png -------------------------------------------------------------------------------- /Landing/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "short_name": "", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /contracts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/contracts/.gitkeep -------------------------------------------------------------------------------- /contracts/common/Controlled.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0 <0.6.0; 2 | 3 | contract Controlled { 4 | /// @notice The address of the controller is the only address that can call 5 | /// a function with this modifier 6 | modifier onlyController { 7 | require(msg.sender == controller, "Unauthorized"); 8 | _; 9 | } 10 | 11 | address payable public controller; 12 | 13 | constructor() internal { 14 | controller = msg.sender; 15 | } 16 | 17 | /// @notice Changes the controller of the contract 18 | /// @param _newController The new controller of the contract 19 | function changeController(address payable _newController) public onlyController { 20 | controller = _newController; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /contracts/common/Medianizer.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0 <0.6.0; 2 | 3 | 4 | /** 5 | * @title Medianizer Mock Contract 6 | */ 7 | contract Medianizer { 8 | function peek() public view returns (bytes32, bool) { 9 | return (bytes32(0x000000000000000000000000000000000000000000000008c233113a8becc000), true); 10 | } 11 | 12 | function read() public view returns (bytes32) { 13 | return bytes32(0x000000000000000000000000000000000000000000000008c233113a8becc000); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /contracts/common/ReentrancyGuard.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0 <0.6.0; 2 | 3 | 4 | contract ReentrancyGuard { 5 | 6 | bool public locked = false; 7 | 8 | /** 9 | * @dev Use this modifier on functions susceptible to reentrancy attacks 10 | */ 11 | modifier reentrancyGuard() { 12 | require(!locked, "Reentrant call detected!"); 13 | locked = true; 14 | _; 15 | locked = false; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /contracts/common/SecuredFunctions.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0 <0.6.0; 2 | 3 | import "../common/Ownable.sol"; 4 | 5 | 6 | contract SecuredFunctions is Ownable { 7 | 8 | mapping(address => bool) public allowedContracts; 9 | 10 | /// @notice Only allowed addresses and the same contract can invoke this function 11 | modifier onlyAllowedContracts { 12 | require(allowedContracts[msg.sender] || msg.sender == address(this), "Only allowed contracts can invoke this function"); 13 | _; 14 | } 15 | 16 | /** 17 | * @dev Set contract addresses with special privileges to execute special functions 18 | * @param _contract Contract address 19 | * @param _allowed Is contract allowed? 20 | */ 21 | function setAllowedContract ( 22 | address _contract, 23 | bool _allowed 24 | ) public onlyOwner 25 | { 26 | allowedContracts[_contract] = _allowed; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/test/TestEscrowUpgrade.sol: -------------------------------------------------------------------------------- 1 | /* solium-disable security/no-block-members */ 2 | /* solium-disable no-empty-blocks */ 3 | 4 | pragma solidity >=0.5.0 <0.6.0; 5 | 6 | import "../teller-network/Escrow.sol"; 7 | 8 | /** 9 | * @title Test Escrow Upgrade contract 10 | */ 11 | contract TestEscrowUpgrade is Escrow { 12 | 13 | constructor ( 14 | address _fallbackArbitrator, 15 | address _relayer, 16 | address _arbitrationLicense, 17 | address _offerStore, 18 | address _userStore, 19 | address payable _feeDestination, 20 | uint _feeMilliPercent 21 | ) 22 | Escrow(_fallbackArbitrator, _relayer, _arbitrationLicense, _offerStore, _userStore, _feeDestination, _feeMilliPercent) 23 | public { 24 | } 25 | 26 | uint private val; 27 | 28 | function getVal() public view returns (uint) { 29 | return val; 30 | } 31 | 32 | function setVal(uint _val) public { 33 | val = _val; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /contracts/token/ApproveAndCallFallBack.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.7; 2 | 3 | contract ApproveAndCallFallBack { 4 | function receiveApproval(address from, uint256 _amount, address _token, bytes memory _data) public; 5 | } 6 | -------------------------------------------------------------------------------- /contracts/token/TokenFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.7; 2 | 3 | contract TokenFactory { 4 | function createCloneToken( 5 | address _parentToken, 6 | uint _snapshotBlock, 7 | string memory _tokenName, 8 | uint8 _decimalUnits, 9 | string memory _tokenSymbol, 10 | bool _transfersEnabled 11 | ) public returns (address payable); 12 | } 13 | -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /cypress/integration/navigation.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | //context('Navigation', () => { 4 | // beforeEach(() => { 5 | // cy.visit('http://localhost:8000'); 6 | // }); 7 | // 8 | // it('allows to go through the different pages', () => { 9 | // cy.get('.navbar-nav').contains('Prices').click(); 10 | // cy.location('hash').should('include', 'price'); 11 | // 12 | // cy.get('.navbar-nav').contains('My Escrows').click(); 13 | // cy.location('hash').should('include', 'escrows'); 14 | // 15 | // cy.get('.navbar-nav').contains('Map').click(); 16 | // cy.location('hash').should('include', 'map'); 17 | // }); 18 | //}); 19 | -------------------------------------------------------------------------------- /cypress/plugins/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example plugins/index.js can be used to load plugins 3 | // 4 | // You can change the location of this file or turn off loading 5 | // the plugins file with the 'pluginsFile' configuration option. 6 | // 7 | // You can read more here: 8 | // https://on.cypress.io/plugins-guide 9 | // *********************************************************** 10 | 11 | // This function is called when a project is opened or re-opened (e.g. due to 12 | // the project's config changing) 13 | 14 | module.exports = (_on, _config) => { 15 | // `on` is used to hook into various events Cypress emits 16 | // `config` is the resolved Cypress config 17 | } 18 | -------------------------------------------------------------------------------- /cypress/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add("login", (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This is will overwrite an existing command -- 25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 26 | -------------------------------------------------------------------------------- /cypress/support/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands'; 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') 21 | -------------------------------------------------------------------------------- /embark.json: -------------------------------------------------------------------------------- 1 | { 2 | "contracts": [ 3 | "contracts/**" 4 | ], 5 | "buildDir": "dist/", 6 | "config": "embarkConfig/", 7 | "versions": { 8 | "solc": "0.5.16" 9 | }, 10 | "plugins": { 11 | "embark-solium": {}, 12 | "@trailofbits/embark-contract-info": { 13 | "flags": "" 14 | }, 15 | "embark-solc": {}, 16 | "embark-geth": {} 17 | }, 18 | "options": { 19 | "solc": { 20 | "optimize": true, 21 | "optimize-runs": 200 22 | } 23 | }, 24 | "generationDir": "src/embarkArtifacts" 25 | } 26 | -------------------------------------------------------------------------------- /embarkConfig/development/password: -------------------------------------------------------------------------------- 1 | dev_password -------------------------------------------------------------------------------- /embarkConfig/namesystem.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | default: { 3 | enabled: true, 4 | available_providers: ["ens"], 5 | provider: "ens" 6 | }, 7 | 8 | development: { 9 | register: { 10 | rootDomain: "embark.eth", 11 | subdomains: { 12 | 'status': '0x1a2f3b98e434c02363f3dac3174af93c1d690914' 13 | } 14 | } 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /embarkConfig/pipeline.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | enabled: false 3 | }; 4 | -------------------------------------------------------------------------------- /embarkConfig/privatenet/genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "homesteadBlock": 0, 4 | "byzantiumBlock": 0, 5 | "daoForkSupport": true 6 | }, 7 | "nonce": "0x0000000000000042", 8 | "difficulty": "0x0", 9 | "alloc": { 10 | "0x3333333333333333333333333333333333333333": {"balance": "15000000000000000000"} 11 | }, 12 | "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", 13 | "coinbase": "0x3333333333333333333333333333333333333333", 14 | "timestamp": "0x00", 15 | "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 16 | "extraData": "0x", 17 | "gasLimit": "0x7a1200" 18 | } 19 | -------------------------------------------------------------------------------- /embarkConfig/privatenet/password: -------------------------------------------------------------------------------- 1 | dev_password 2 | -------------------------------------------------------------------------------- /embarkConfig/storage.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // default applies to all environments 3 | default: { 4 | enabled: false, 5 | ipfs_bin: "ipfs", 6 | available_providers: ["ipfs"], 7 | upload: { 8 | provider: "ipfs", 9 | host: "localhost", 10 | port: 5001 11 | }, 12 | dappConnection: [ 13 | { 14 | provider: "ipfs", 15 | host: "localhost", 16 | port: 5001, 17 | getUrl: "http://localhost:8080/ipfs/" 18 | } 19 | ] 20 | }, 21 | 22 | development: { 23 | upload: { 24 | provider: "ipfs", 25 | host: "localhost", 26 | port: 5001, 27 | getUrl: "http://localhost:8080/ipfs/" 28 | } 29 | }, 30 | 31 | // merges with the settings in default 32 | // used with "embark run privatenet" 33 | privatenet: { 34 | }, 35 | 36 | // merges with the settings in default 37 | // used with "embark run testnet" 38 | testnet: { 39 | enabled: false 40 | }, 41 | 42 | // merges with the settings in default 43 | // used with "embark run livenet" 44 | livenet: { 45 | }, 46 | 47 | // you can name an environment with specific settings and then specify with 48 | // "embark run custom_name" 49 | //custom_name: { 50 | //} 51 | }; 52 | -------------------------------------------------------------------------------- /embarkConfig/testnet/password: -------------------------------------------------------------------------------- 1 | test_password 2 | -------------------------------------------------------------------------------- /embarkConfig/webserver.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | enabled: false 3 | }; 4 | -------------------------------------------------------------------------------- /images/buyer_take_offer/Browse offers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/buyer_take_offer/Browse offers.png -------------------------------------------------------------------------------- /images/buyer_take_offer/Set amount (Active).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/buyer_take_offer/Set amount (Active).png -------------------------------------------------------------------------------- /images/buyer_take_offer/Set amount (Default).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/buyer_take_offer/Set amount (Default).png -------------------------------------------------------------------------------- /images/buyer_take_offer/Set amount (Filled).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/buyer_take_offer/Set amount (Filled).png -------------------------------------------------------------------------------- /images/buyer_take_offer/Summary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/buyer_take_offer/Summary.png -------------------------------------------------------------------------------- /images/dispute_resolve/IMG_2428.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/dispute_resolve/IMG_2428.png -------------------------------------------------------------------------------- /images/dispute_resolve/IMG_2429.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/dispute_resolve/IMG_2429.png -------------------------------------------------------------------------------- /images/dispute_resolve/IMG_2430.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/dispute_resolve/IMG_2430.png -------------------------------------------------------------------------------- /images/dispute_resolve/IMG_2431.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/dispute_resolve/IMG_2431.png -------------------------------------------------------------------------------- /images/dispute_resolve/IMG_2432.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/dispute_resolve/IMG_2432.png -------------------------------------------------------------------------------- /images/escrow_workflow/Trade - Step 1 (Buyer).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/escrow_workflow/Trade - Step 1 (Buyer).png -------------------------------------------------------------------------------- /images/escrow_workflow/Trade - Step 1 (Seller).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/escrow_workflow/Trade - Step 1 (Seller).png -------------------------------------------------------------------------------- /images/escrow_workflow/Trade - Step 2 (Buyer).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/escrow_workflow/Trade - Step 2 (Buyer).png -------------------------------------------------------------------------------- /images/escrow_workflow/Trade - Step 2 (Seller).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/escrow_workflow/Trade - Step 2 (Seller).png -------------------------------------------------------------------------------- /images/escrow_workflow/Trade - Step 3 (Buyer).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/escrow_workflow/Trade - Step 3 (Buyer).png -------------------------------------------------------------------------------- /images/escrow_workflow/Trade - Step 3 (Seller).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/escrow_workflow/Trade - Step 3 (Seller).png -------------------------------------------------------------------------------- /images/escrow_workflow/Trade - Step 4 (Seller).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/escrow_workflow/Trade - Step 4 (Seller).png -------------------------------------------------------------------------------- /images/escrow_workflow/Trade - Step 4 (Buyer).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/escrow_workflow/Trade - Step 4 (Buyer).png -------------------------------------------------------------------------------- /images/seller_create_offer/Arbitrator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Arbitrator.png -------------------------------------------------------------------------------- /images/seller_create_offer/Browse offers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Browse offers.png -------------------------------------------------------------------------------- /images/seller_create_offer/Buy-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Buy-1.png -------------------------------------------------------------------------------- /images/seller_create_offer/Buy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Buy.png -------------------------------------------------------------------------------- /images/seller_create_offer/Contact Details (Status)-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Contact Details (Status)-1.png -------------------------------------------------------------------------------- /images/seller_create_offer/Contact Details (Status)-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Contact Details (Status)-2.png -------------------------------------------------------------------------------- /images/seller_create_offer/Contact Details (Status)-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Contact Details (Status)-3.png -------------------------------------------------------------------------------- /images/seller_create_offer/Contact Details (Status).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Contact Details (Status).png -------------------------------------------------------------------------------- /images/seller_create_offer/Crypto select (signature request).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Crypto select (signature request).png -------------------------------------------------------------------------------- /images/seller_create_offer/Crypto select (wallet not connected).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Crypto select (wallet not connected).png -------------------------------------------------------------------------------- /images/seller_create_offer/Crypto select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Crypto select.png -------------------------------------------------------------------------------- /images/seller_create_offer/Local Currency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Local Currency.png -------------------------------------------------------------------------------- /images/seller_create_offer/Location (Active).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Location (Active).png -------------------------------------------------------------------------------- /images/seller_create_offer/Location (Filled).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Location (Filled).png -------------------------------------------------------------------------------- /images/seller_create_offer/Location (Typing).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Location (Typing).png -------------------------------------------------------------------------------- /images/seller_create_offer/Location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Location.png -------------------------------------------------------------------------------- /images/seller_create_offer/Nickname-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Nickname-1.png -------------------------------------------------------------------------------- /images/seller_create_offer/Nickname.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Nickname.png -------------------------------------------------------------------------------- /images/seller_create_offer/No limits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/No limits.png -------------------------------------------------------------------------------- /images/seller_create_offer/Payment Method.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Payment Method.png -------------------------------------------------------------------------------- /images/seller_create_offer/Price.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Price.png -------------------------------------------------------------------------------- /images/seller_create_offer/Set amount (Filled).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Set amount (Filled).png -------------------------------------------------------------------------------- /images/seller_create_offer/Summary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/seller_create_offer/Summary.png -------------------------------------------------------------------------------- /images/state_diagrams/escrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/images/state_diagrams/escrow.png -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #18B6FF 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/public/favicon.ico -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /public/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/public/mstile-144x144.png -------------------------------------------------------------------------------- /public/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/public/mstile-150x150.png -------------------------------------------------------------------------------- /public/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/public/mstile-310x150.png -------------------------------------------------------------------------------- /public/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/public/mstile-310x310.png -------------------------------------------------------------------------------- /public/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/public/mstile-70x70.png -------------------------------------------------------------------------------- /public/open-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/public/open-graph.png -------------------------------------------------------------------------------- /public/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "short_name": "", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /src/__mocks__/fileMock.js: -------------------------------------------------------------------------------- 1 | module.exports = 'test-file-stub'; 2 | -------------------------------------------------------------------------------- /src/__mocks__/styleMock.js: -------------------------------------------------------------------------------- 1 | module.exports = {}; 2 | -------------------------------------------------------------------------------- /src/css/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/.gitkeep -------------------------------------------------------------------------------- /src/css/Form.scss: -------------------------------------------------------------------------------- 1 | @import "../../node_modules/bootstrap/scss/functions"; 2 | @import "../../node_modules/bootstrap/scss/variables"; 3 | 4 | .is-invalid-input { 5 | border-color: $danger; 6 | } 7 | 8 | .input-group-append { 9 | height: calc(2.25rem + 2px); 10 | } 11 | 12 | .prepend { 13 | border-top-right-radius: 0; 14 | border-bottom-right-radius: 0; 15 | } 16 | 17 | .append { 18 | border-top-left-radius: 0; 19 | border-bottom-left-radius: 0; 20 | } 21 | 22 | .full-width-input.input-group > div:first-child { 23 | flex: 1 1 auto; 24 | width: 1%; 25 | } 26 | 27 | .search-bar { 28 | position: relative; 29 | } 30 | -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Black.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Black.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-BlackItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-BlackItalic.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-BlackItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-BlackItalic.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Bold.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Bold.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-BoldItalic.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-BoldItalic.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-ExtraBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-ExtraBold.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-ExtraBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-ExtraBold.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-ExtraBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-ExtraBoldItalic.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-ExtraBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-ExtraBoldItalic.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-ExtraLight.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-ExtraLight.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-ExtraLight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-ExtraLight.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-ExtraLightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-ExtraLightItalic.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-ExtraLightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-ExtraLightItalic.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Italic.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Italic.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Light.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Light.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-LightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-LightItalic.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-LightItalic.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Medium.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Medium.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-MediumItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-MediumItalic.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-MediumItalic.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Regular.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Regular.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-SemiBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-SemiBold.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-SemiBold.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-SemiBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-SemiBoldItalic.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-SemiBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-SemiBoldItalic.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Thin.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-Thin.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-ThinItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-ThinItalic.woff -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-ThinItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-ThinItalic.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-italic.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-italic.var.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter-upright.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter-upright.var.woff2 -------------------------------------------------------------------------------- /src/css/fonts/Inter/Inter.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/css/fonts/Inter/Inter.var.woff2 -------------------------------------------------------------------------------- /src/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/.gitkeep -------------------------------------------------------------------------------- /src/images/Ellipse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/Ellipse.png -------------------------------------------------------------------------------- /src/images/arbitrator.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/arrow-disabled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/bank.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/becomeArbi.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/beta-tag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/cancel-gray.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/cancel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/change.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/close_profile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/contact-methods/status.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/contact-methods/telegram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/diamond.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/diamond.png -------------------------------------------------------------------------------- /src/images/dollar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/dotted-line.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/down-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/download.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/downvote.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/error.png -------------------------------------------------------------------------------- /src/images/escrow/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/escrow/01.png -------------------------------------------------------------------------------- /src/images/escrow/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/escrow/02.png -------------------------------------------------------------------------------- /src/images/escrow/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/escrow/03.png -------------------------------------------------------------------------------- /src/images/escrow/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/escrow/04.png -------------------------------------------------------------------------------- /src/images/escrow/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/escrow/05.png -------------------------------------------------------------------------------- /src/images/exclamation-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/exclamation-circle.png -------------------------------------------------------------------------------- /src/images/info-red.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/images/info.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/images/landing/escrowExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/landing/escrowExample.png -------------------------------------------------------------------------------- /src/images/landing/github-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/landing/github-icon.png -------------------------------------------------------------------------------- /src/images/landing/logoGroupLeft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/landing/logoGroupLeft.png -------------------------------------------------------------------------------- /src/images/landing/logoGroupRight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/landing/logoGroupRight.png -------------------------------------------------------------------------------- /src/images/landing/mostPopularIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/landing/status-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/landing/twitter-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 10 | 11 | 12 | 13 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/images/lightning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/limits.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/list.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/images/location.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/make_admin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/no-crypto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/no-crypto.png -------------------------------------------------------------------------------- /src/images/pencil.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/profile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/profileUser.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/read-chat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/small-info.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/images/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/success.png -------------------------------------------------------------------------------- /src/images/teller-logo-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/teller-logo-icon.png -------------------------------------------------------------------------------- /src/images/transfer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/transparentLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/images/transparentLogo.png -------------------------------------------------------------------------------- /src/images/unknownIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/images/upvote.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/images/user-check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/wallet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { ConnectedRouter } from "connected-react-router"; 4 | import { Provider } from 'react-redux'; 5 | import { I18nextProvider } from 'react-i18next'; 6 | import { LastLocationProvider } from 'react-router-last-location'; 7 | import i18n from './js/i18n'; 8 | import { PersistGate } from 'redux-persist/integration/react'; 9 | 10 | import './css/fonts/Inter/inter.css'; 11 | import './css/bootstrap-overrides.scss'; 12 | import 'flag-icon-css/css/flag-icon.min.css'; 13 | import './index.scss'; 14 | import './css/Form.scss'; 15 | 16 | import App from './js/layout/App'; 17 | import history from './js/history'; 18 | import {store, persistor} from './js/store'; 19 | 20 | ReactDOM.render( 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | , 32 | document.getElementById('root') 33 | ); 34 | -------------------------------------------------------------------------------- /src/js/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/src/js/.gitkeep -------------------------------------------------------------------------------- /src/js/components/ConfirmDialog/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Modal, ModalHeader, ModalBody, ModalFooter, Button} from 'reactstrap'; 3 | import PropTypes from 'prop-types'; 4 | import {withTranslation} from "react-i18next"; 5 | 6 | const ConfirmDialog = ({t, display, onCancel, title, content, onConfirm, cancelText, confirmText}) => ( 7 | 8 | 9 | {title} 10 | 11 | 12 |

{content}

13 |
14 | 15 | 16 | 17 | 18 |
19 | ); 20 | 21 | ConfirmDialog.defaultProps = { 22 | display: false 23 | }; 24 | 25 | ConfirmDialog.propTypes = { 26 | t: PropTypes.func, 27 | onCancel: PropTypes.func, 28 | onConfirm: PropTypes.func, 29 | title: PropTypes.string, 30 | content: PropTypes.string, 31 | display: PropTypes.bool, 32 | cancelText: PropTypes.string, 33 | confirmText: PropTypes.string 34 | }; 35 | 36 | export default withTranslation()(ConfirmDialog); 37 | -------------------------------------------------------------------------------- /src/js/components/ConnectWallet/index.js: -------------------------------------------------------------------------------- 1 | import React, {Fragment} from "react"; 2 | import WalletIcon from "../../../images/wallet.svg"; 3 | import RoundedIcon from "../../ui/RoundedIcon"; 4 | import PropTypes from 'prop-types'; 5 | import { Button } from "reactstrap"; 6 | import {withTranslation} from "react-i18next"; 7 | import NoWeb3Dialog from '../NoWeb3Dialog'; 8 | 9 | const ConnectWallet = ({t, enableEthereum}) => ( 10 | 11 | 12 |
13 | 14 |

{t('connectWallet.title')}

15 | 18 |
19 |
20 | ); 21 | 22 | ConnectWallet.propTypes = { 23 | t: PropTypes.func, 24 | enableEthereum: PropTypes.func 25 | }; 26 | 27 | export default withTranslation()(ConnectWallet); 28 | -------------------------------------------------------------------------------- /src/js/components/EditContact/__snapshots__/index.test.jsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`EditContact should render correctly 1`] = ` 4 | 5 |

8 | 11 | 14 | 41 | 42 | 43 | `; 44 | -------------------------------------------------------------------------------- /src/js/components/EditContact/index.scss: -------------------------------------------------------------------------------- 1 | .infos-and-warnings { 2 | .info { 3 | font-size: 12px; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/js/components/EditContact/index.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import EditContact from "./index"; 5 | 6 | describe('EditContact', () => { 7 | it('should render correctly', () => { 8 | const component = shallow( undefined} changeContactCode={() => undefined} 9 | resolveENSName={() => undefined} ensError="" nickname={"nickname"} statusContactCode={"contractCode"} />); 10 | 11 | expect(component).toMatchSnapshot(); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /src/js/components/EditLocation/SellerPosition.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import SellerPosition from "./SellerPosition"; 5 | 6 | describe('SellerPosition', () => { 7 | it('should render correctly', () => { 8 | const component = shallow( undefined} locatinon={""}/>); 9 | 10 | expect(component).toMatchSnapshot(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/js/components/ErrorInformation/404.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import {withRouter, Link} from "react-router-dom"; 4 | import {withTranslation} from "react-i18next"; 5 | import {Button} from 'reactstrap'; 6 | 7 | import errorImage from '../../../images/error.png'; 8 | import './index.scss'; 9 | 10 | const fourOFour = ({t, history}) => ( 11 |
12 | error 13 |

14 | {t('errorInformation.404.title')} 15 |

16 |

17 | {t('errorInformation.404.tip')} 18 |

19 |

20 | 21 | 22 |

23 |
24 | ); 25 | 26 | fourOFour.propTypes = { 27 | t: PropTypes.func, 28 | history: PropTypes.object 29 | }; 30 | 31 | export default withRouter(withTranslation()(fourOFour)); 32 | -------------------------------------------------------------------------------- /src/js/components/ErrorInformation/index.scss: -------------------------------------------------------------------------------- 1 | .error-information { 2 | width: 100%; 3 | text-align: center; 4 | padding: 0 35px; 5 | } 6 | -------------------------------------------------------------------------------- /src/js/components/Loading/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; 4 | import {faCircleNotch} from "@fortawesome/free-solid-svg-icons"; 5 | import {withTranslation} from "react-i18next"; 6 | import TxHash from '../../ui/TxHash'; 7 | 8 | import "./index.scss"; 9 | 10 | const Loading = ({t, mining, initial, page, value, txHash}) => ( 11 |
12 |

13 | {value} 14 | {mining && t('loading.mining')} 15 | {initial && t('loading.initial')} 16 | {page && t('loading.page')} 17 |

18 | 19 | {txHash &&

{t('transaction.hash')}:

} 20 |
21 | ); 22 | 23 | Loading.propTypes = { 24 | t: PropTypes.func, 25 | mining: PropTypes.bool, 26 | initial: PropTypes.bool, 27 | page: PropTypes.bool, 28 | value: PropTypes.string, 29 | txHash: PropTypes.string 30 | }; 31 | 32 | export default withTranslation()(Loading); 33 | -------------------------------------------------------------------------------- /src/js/components/Loading/index.scss: -------------------------------------------------------------------------------- 1 | .loading { 2 | margin-top: 174px; 3 | } -------------------------------------------------------------------------------- /src/js/components/Loading/index.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import Loading from "."; 5 | 6 | describe('Loading', () => { 7 | it('should render correctly when mining', () => { 8 | const component = shallow(); 9 | 10 | expect(component).toMatchSnapshot(); 11 | }); 12 | 13 | it('should render correctly when initial', () => { 14 | const component = shallow(); 15 | 16 | expect(component).toMatchSnapshot(); 17 | }); 18 | 19 | it('should render correctly when page', () => { 20 | const component = shallow(); 21 | 22 | expect(component).toMatchSnapshot(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/js/components/Map/CustomInfoWindow.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {InfoWindow} from "react-google-maps"; 3 | import PropTypes from 'prop-types'; 4 | import {Button} from 'reactstrap'; 5 | 6 | const CustomInfoWindow = ({name, address: _address, onClose, onClick, assets}) => ( 7 | 8 |
9 |

{name}

10 |

{assets.join(', ')}

11 | 12 |
13 |
14 | ); 15 | 16 | CustomInfoWindow.propTypes = { 17 | name: PropTypes.string, 18 | address: PropTypes.string, 19 | assets: PropTypes.array, 20 | onClose: PropTypes.func, 21 | onClick: PropTypes.func 22 | }; 23 | 24 | export default CustomInfoWindow; 25 | -------------------------------------------------------------------------------- /src/js/components/Map/SearchBar.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import {FormGroup, Input, Form} from 'reactstrap'; 4 | import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; 5 | import {faSearch} from "@fortawesome/free-solid-svg-icons"; 6 | 7 | const SearchBar = (props) => ( 8 |
9 | 10 | e.key === 'Enter' && e.preventDefault()} 12 | onChange={(e) => props.onChange && props.onChange(e.target.value)}/> 13 | 14 | 15 |
16 | ); 17 | 18 | SearchBar.propTypes = { 19 | className: PropTypes.string, 20 | placeholder: PropTypes.string, 21 | onChange: PropTypes.func 22 | }; 23 | 24 | export default SearchBar; 25 | -------------------------------------------------------------------------------- /src/js/components/Map/index.scss: -------------------------------------------------------------------------------- 1 | $search-field-height: 52px; 2 | $autocomplete-height: 157px; 3 | 4 | .map-error { 5 | position: absolute; 6 | z-index: 990; 7 | left: 0; 8 | right: 0; 9 | } 10 | 11 | .map-component { 12 | height: 88%; 13 | position: absolute; 14 | left: 0; 15 | right: 0; 16 | bottom: 0; 17 | 18 | .map-search-form { 19 | position: absolute; 20 | bottom: 7px !important; 21 | left: 10px !important; 22 | right: 60px !important; 23 | top: auto !important; 24 | 25 | .form-control { 26 | height: $search-field-height; 27 | background: white; 28 | } 29 | } 30 | 31 | .gm-style-iw { 32 | text-align: center; 33 | 34 | .btn { 35 | width: 100%; 36 | } 37 | } 38 | } 39 | 40 | .pac-container { 41 | height: $autocomplete-height; 42 | margin-top: - ($autocomplete-height + $search-field-height); 43 | } 44 | -------------------------------------------------------------------------------- /src/js/components/ModalDialog/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Modal, ModalBody, Button} from 'reactstrap'; 3 | import PropTypes from 'prop-types'; 4 | 5 | const ModalDialog = ({display, onClose, onClick, children, buttonText, hideButton}) => ( 6 | 7 | 8 |
9 | {children} 10 |
11 | {!hideButton && } 12 |
13 |
14 | ); 15 | 16 | ModalDialog.defaultProps = { 17 | display: false, 18 | hideButton: false, 19 | onClose: () => {} 20 | }; 21 | 22 | ModalDialog.propTypes = { 23 | onClose: PropTypes.func, 24 | onClick: PropTypes.func, 25 | content: PropTypes.string, 26 | display: PropTypes.bool, 27 | buttonText: PropTypes.string, 28 | children: PropTypes.node, 29 | hideButton: PropTypes.bool 30 | }; 31 | 32 | export default ModalDialog; 33 | -------------------------------------------------------------------------------- /src/js/components/NoArbitratorWarning/index.jsx: -------------------------------------------------------------------------------- 1 | import React, {Fragment} from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import {zeroAddress} from '../../utils/address'; 4 | import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; 5 | import {faExclamationTriangle} from "@fortawesome/free-solid-svg-icons"; 6 | import {withTranslation} from "react-i18next"; 7 | 8 | const NoArbitratorWarning = ({t, arbitrator, label}) => 9 | {arbitrator === zeroAddress && 10 | 11 | {label || t('arbitration.noArbitrationLabel')} 12 | } 13 | ; 14 | 15 | NoArbitratorWarning.propTypes = { 16 | t: PropTypes.func, 17 | arbitrator: PropTypes.string, 18 | label: PropTypes.string 19 | }; 20 | 21 | export default withTranslation()(NoArbitratorWarning); 22 | -------------------------------------------------------------------------------- /src/js/components/NoLicense/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Button} from 'reactstrap'; 3 | import {Link} from "react-router-dom"; 4 | import PropTypes from 'prop-types'; 5 | import {withTranslation} from "react-i18next"; 6 | 7 | const NoLicense = ({t, arbitratorPage}) => ( 8 |
9 |

10 | {arbitratorPage && t('license.noArbiLicense')} 11 | {!arbitratorPage && t('license.noSellerLicense')} 12 |

13 | {arbitratorPage && 14 |

{t('license.onceArbi')}

} 15 | {!arbitratorPage &&

{t('license.onceSeller')}

} 16 |

17 | {arbitratorPage && } 18 | {!arbitratorPage && } 19 |

20 |
21 | ); 22 | 23 | NoLicense.defaultProps = { 24 | arbitratorPage: false 25 | }; 26 | 27 | NoLicense.propTypes = { 28 | t: PropTypes.func, 29 | arbitratorPage: PropTypes.bool 30 | }; 31 | 32 | export default withTranslation()(NoLicense); 33 | -------------------------------------------------------------------------------- /src/js/components/NotificationManager/index.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import EscrowNotifications from './notifications/EscrowNotifications'; 3 | 4 | import 'react-notifications/lib/notifications.css'; 5 | import './index.scss'; 6 | 7 | class NotificationManager extends Component { 8 | render() { 9 | return ( 10 | 11 | ); 12 | } 13 | } 14 | 15 | NotificationManager.propTypes = {}; 16 | 17 | export default NotificationManager; 18 | -------------------------------------------------------------------------------- /src/js/components/NotificationManager/index.scss: -------------------------------------------------------------------------------- 1 | @import "../../../css/variable-overrides"; 2 | 3 | .notification-container { 4 | .notification-info { 5 | background-color: $info; 6 | } 7 | 8 | .notification-success { 9 | background-color: $success; 10 | } 11 | 12 | .notification-warning { 13 | background-color: $warning; 14 | } 15 | 16 | .notification-error { 17 | background-color: $danger; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/js/components/Offer/index.scss: -------------------------------------------------------------------------------- 1 | .offer-reputation { 2 | position: absolute; 3 | top: 14px; 4 | right: 10px; 5 | font-size: 14px; 6 | } 7 | 8 | .offer-card { 9 | border-radius: 8px; 10 | padding: 16px; 11 | 12 | .card-body { 13 | padding: 0; 14 | } 15 | 16 | .seller-name { 17 | font-weight: 500; 18 | font-size: 15px; 19 | } 20 | 21 | .data-item { 22 | font-size: 14px; 23 | font-weight: normal; 24 | } 25 | 26 | .card-footer { 27 | padding: 0; 28 | 29 | p { 30 | font-size: 13px; 31 | font-weight: normal; 32 | 33 | span { 34 | font-size: 16px; 35 | margin: 0 3px; 36 | } 37 | } 38 | } 39 | } 40 | 41 | .flag-icon { 42 | border-radius: 2px; 43 | background-repeat: initial; 44 | height: 15px; 45 | width: 20px; 46 | } 47 | -------------------------------------------------------------------------------- /src/js/components/Reputation/__snapshots__/index.test.jsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Reputation should render correctly 1`] = ` 4 | 7 | 10 | 1 11 |   12 | 17 | 18 | 21 | 2 22 |   23 | 28 | 29 | 30 | `; 31 | -------------------------------------------------------------------------------- /src/js/components/Reputation/index.scss: -------------------------------------------------------------------------------- 1 | @import "../../../css/variable-overrides"; 2 | 3 | .reputation-container { 4 | .left-rating, .right-rating { 5 | font-size: 15px; 6 | margin: 0 1px; 7 | display: inline-block; 8 | text-align: center; 9 | } 10 | 11 | .left-rating { 12 | margin-right: 20px; 13 | } 14 | 15 | .rating-with-action { 16 | width: 40px; 17 | height: 40px; 18 | } 19 | 20 | &.small { 21 | .left-rating, .right-rating { 22 | font-size: 13px; 23 | width: 55px; 24 | height: 24px; 25 | line-height: 22px; 26 | } 27 | } 28 | } 29 | 30 | .average-rating, .rating-with-action { 31 | $rating-opacity-bg: 38%; 32 | 33 | &.bg-dark { 34 | background-color: lighten($dark, $rating-opacity-bg) !important; 35 | } 36 | 37 | &.bg-success { 38 | background-color: lighten($success, $rating-opacity-bg) !important; 39 | } 40 | 41 | &.bg-warning { 42 | background-color: lighten($warning, $rating-opacity-bg) !important; 43 | } 44 | 45 | &.bg-danger { 46 | background-color: lighten($danger, $rating-opacity-bg) !important; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/js/components/Reputation/index.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import Reputation from "./index"; 5 | 6 | describe('Reputation', () => { 7 | it('should render correctly', () => { 8 | const component = shallow(); 9 | 10 | expect(component).toMatchSnapshot(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/js/components/UserInformation/Address.scss: -------------------------------------------------------------------------------- 1 | .addr { 2 | word-wrap: break-word; 3 | } -------------------------------------------------------------------------------- /src/js/components/UserInformation/Identicon.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import IdenticonJS from 'identicon.js'; 4 | import {zeroAddress} from '../../utils/address'; 5 | 6 | class Identicon extends Component { 7 | render() { 8 | let {className, seed, scale} = this.props; 9 | if (!seed) { 10 | seed = zeroAddress; 11 | } 12 | const size = 8 * (scale || 4); 13 | const options = { 14 | background: [255, 255, 255, 255], 15 | margin: 0.24, 16 | size: size, 17 | format: 'svg' 18 | }; 19 | 20 | const data = new IdenticonJS(seed, options).toString(); 21 | return identicon; 22 | } 23 | } 24 | 25 | Identicon.propTypes = { 26 | className: PropTypes.string, 27 | seed: PropTypes.string, 28 | scale: PropTypes.number 29 | }; 30 | 31 | export default Identicon; 32 | -------------------------------------------------------------------------------- /src/js/constants/contactMethods.js: -------------------------------------------------------------------------------- 1 | import statusIcon from '../../images/contact-methods/status.svg'; 2 | import telegramIcon from '../../images/contact-methods/telegram.svg'; 3 | import lineIcon from '../../images/contact-methods/line.svg'; 4 | import kakaoIcon from '../../images/contact-methods/kakao-talk.svg'; 5 | import wechatIcon from '../../images/contact-methods/wechat.svg'; 6 | 7 | export const DialogOptions = { 8 | 'Status': 'Status chat key', 9 | 'Telegram': 'Telegram ID', 10 | 'Line': 'Line ID', 11 | 'KakaoTalk': 'KakaoTalk ID', 12 | 'WeChat': 'WeChat ID' 13 | }; 14 | 15 | export const DialogOptionsIcons = { 16 | 'Status': statusIcon, 17 | 'Telegram': telegramIcon, 18 | 'Line': lineIcon, 19 | 'KakaoTalk': kakaoIcon, 20 | 'WeChat': wechatIcon 21 | }; 22 | 23 | export const STATUS = 'Status'; 24 | -------------------------------------------------------------------------------- /src/js/features/approval/actions.js: -------------------------------------------------------------------------------- 1 | import { APPROVE_TOKEN, GET_SNT_ALLOWANCE, GET_TOKEN_ALLOWANCE, CANCEL_APPROVE_TOKEN } from './constants'; 2 | import ERC20Token from '../../../embarkArtifacts/contracts/ERC20Token'; 3 | import EscrowInstance from '../../../embarkArtifacts/contracts/EscrowInstance'; 4 | 5 | export const approve = (tokenAddress, amount, tokenDecimals) => { 6 | ERC20Token.options.address = tokenAddress; 7 | return { 8 | type: APPROVE_TOKEN, 9 | toSend: ERC20Token.methods.approve(EscrowInstance.options.address, amount), 10 | amount, 11 | tokenDecimals 12 | }; 13 | }; 14 | 15 | export const cancelApproval = () => ({ type: CANCEL_APPROVE_TOKEN}); 16 | 17 | export const getSNTAllowance = () => ({ type: GET_SNT_ALLOWANCE}); 18 | 19 | export const getTokenAllowance = (token) => ({ type: GET_TOKEN_ALLOWANCE, token}); 20 | 21 | -------------------------------------------------------------------------------- /src/js/features/approval/constants.js: -------------------------------------------------------------------------------- 1 | export const APPROVE_TOKEN = 'APPROVAL/APPROVE_TOKEN'; 2 | export const CANCEL_APPROVE_TOKEN = 'APPROVAL/CANCEL_APPROVE_TOKEN'; 3 | 4 | export const GET_SNT_ALLOWANCE = 'APPROVAL/GET_SNT_ALLOWANCE'; 5 | export const GET_SNT_ALLOWANCE_SUCCEEDED = 'APPROVAL/GET_SNT_ALLOWANCE_SUCCEEDED'; 6 | export const GET_SNT_ALLOWANCE_FAILED = 'APPROVAL/GET_SNT_ALLOWANCE_FAILED'; 7 | 8 | export const GET_TOKEN_ALLOWANCE = 'APPROVAL/GET_TOKEN_ALLOWANCE'; 9 | export const GET_TOKEN_ALLOWANCE_SUCCEEDED = 'APPROVAL/GET_TOKEN_ALLOWANCE_SUCCEEDED'; 10 | export const GET_TOKEN_ALLOWANCE_FAILED = 'APPROVAL/GET_TOKEN_ALLOWANCE_FAILED'; 11 | 12 | export const APPROVE_PRE_SUCCEEDED = 'APPROVAL/APPROVE_PRE_SUCCEEDED'; 13 | export const APPROVE_SUCCEEDED = 'APPROVAL/APPROVE_SUCCEEDED'; 14 | export const APPROVE_FAILED = 'APPROVAL/APPROVE_FAILED'; 15 | -------------------------------------------------------------------------------- /src/js/features/approval/index.js: -------------------------------------------------------------------------------- 1 | import saga from './saga'; 2 | import reducer from './reducer'; 3 | import * as actions from './actions'; 4 | import * as selectors from './selectors'; 5 | 6 | export default {saga, reducer, actions, selectors}; 7 | -------------------------------------------------------------------------------- /src/js/features/approval/selectors.js: -------------------------------------------------------------------------------- 1 | export const receipt = state => state.approval.receipt; 2 | export const error = state => state.approval.error; 3 | export const isLoading = state => state.approval.loading; 4 | export const txHash = state => state.approval.txHash; 5 | export const getSNTAllowance = state => state.approval.sntAllowance; 6 | export const getTokenAllowance = state => state.approval.tokenAllowance; 7 | -------------------------------------------------------------------------------- /src/js/features/arbitration/index.js: -------------------------------------------------------------------------------- 1 | import saga from './saga'; 2 | import reducer from './reducer'; 3 | import * as actions from './actions'; 4 | import * as selectors from './selectors'; 5 | import * as constants from './constants'; 6 | 7 | export default {saga, reducer, actions, selectors, constants}; 8 | -------------------------------------------------------------------------------- /src/js/features/emailNotifications/actions.js: -------------------------------------------------------------------------------- 1 | import {CHECK_EMAIL_SUBSCRIPTION, SUBSCRIBE_EMAIL, UNSUBSCRIBE_EMAIL, 2 | HIDE_ERROR, VERIFY_EMAIL, HIDE_SUCCESS, SET_REDIRECT_TARGET, 3 | REFUSE_EMAIL_NOTIFICATIONS, RESET_NOTIFICATION_WARNINGS} from './constants'; 4 | 5 | export const checkEmailSubscription = () => { 6 | return {type: CHECK_EMAIL_SUBSCRIPTION}; 7 | }; 8 | 9 | export const setRedirectTarget = (redirectTarget) => { 10 | return {type: SET_REDIRECT_TARGET, redirectTarget}; 11 | }; 12 | 13 | export const subscribeToEmail = (email) => { 14 | return {type: SUBSCRIBE_EMAIL, email}; 15 | }; 16 | 17 | export const unsubscribeToEmail = () => { 18 | return {type: UNSUBSCRIBE_EMAIL}; 19 | }; 20 | 21 | export const hideError = () => { 22 | return {type: HIDE_ERROR}; 23 | }; 24 | 25 | export const hideSuccess = () => { 26 | return {type: HIDE_SUCCESS}; 27 | }; 28 | 29 | export const verifyEmail = (token) => { 30 | return {type: VERIFY_EMAIL, token}; 31 | }; 32 | 33 | export const refuseEmailNotifications = () => { 34 | return {type: REFUSE_EMAIL_NOTIFICATIONS}; 35 | }; 36 | 37 | export const resetNotificationWarnings = () => ({type: RESET_NOTIFICATION_WARNINGS}); 38 | -------------------------------------------------------------------------------- /src/js/features/emailNotifications/index.js: -------------------------------------------------------------------------------- 1 | import saga from './saga'; 2 | import reducer from './reducer'; 3 | import * as actions from './actions'; 4 | import * as selectors from './selectors'; 5 | 6 | export default {saga, reducer, actions, selectors}; 7 | -------------------------------------------------------------------------------- /src/js/features/emailNotifications/selectors.js: -------------------------------------------------------------------------------- 1 | export const isSubscribed = state => state.emailNotifications.isSubscribed; 2 | 3 | export const email = state => state.emailNotifications.email; 4 | 5 | export const redirectTarget = state => state.emailNotifications.redirectTarget; 6 | 7 | export const error = state => state.emailNotifications.error; 8 | 9 | export const working = state => state.emailNotifications.working; 10 | 11 | export const subscribeSuccess = state => state.emailNotifications.subscribeSuccess; 12 | 13 | export const verifySuccess = state => state.emailNotifications.verifySuccess; 14 | 15 | export const refusedEmailNotifications = state => state.emailNotifications.refusedEmailNotifications; 16 | 17 | export const hideSignatureWarning = state => state.emailNotifications.hideSignatureWarning; 18 | -------------------------------------------------------------------------------- /src/js/features/escrow/index.js: -------------------------------------------------------------------------------- 1 | import saga from './saga'; 2 | import reducer from './reducer'; 3 | import * as actions from './actions'; 4 | import * as selectors from './selectors'; 5 | import * as helpers from './helpers'; 6 | 7 | export default {saga, reducer, actions, selectors, helpers}; 8 | -------------------------------------------------------------------------------- /src/js/features/events/index.js: -------------------------------------------------------------------------------- 1 | import reducer from './reducer'; 2 | import * as selectors from './selectors'; 3 | 4 | export default {reducer, selectors}; 5 | -------------------------------------------------------------------------------- /src/js/features/events/reducer.js: -------------------------------------------------------------------------------- 1 | import {RESET_STATE, PURGE_STATE} from "../network/constants"; 2 | import {WATCH_ESCROW} from "../escrow/constants"; 3 | 4 | const DEFAULT_STATE = { 5 | escrows: {} 6 | }; 7 | 8 | function reducer(state = DEFAULT_STATE, action) { 9 | switch (action.type) { 10 | case WATCH_ESCROW: 11 | return { 12 | ...state, 13 | escrows: { 14 | ...state.escrows, 15 | [action.escrowId]: true 16 | } 17 | }; 18 | case PURGE_STATE: 19 | case RESET_STATE: { 20 | return DEFAULT_STATE; 21 | } 22 | default: 23 | return state; 24 | } 25 | } 26 | 27 | export default reducer; 28 | -------------------------------------------------------------------------------- /src/js/features/events/selectors.js: -------------------------------------------------------------------------------- 1 | export const getEscrowEvents = state => state.events.escrows; 2 | -------------------------------------------------------------------------------- /src/js/features/license/actions.js: -------------------------------------------------------------------------------- 1 | import { BUY_LICENSE, CHECK_LICENSE_OWNER, GET_LICENSE_OWNERS, LOAD_PRICE, BUY_LICENSE_CANCEL } from './constants'; 2 | 3 | export const buyLicense = () => ({ type: BUY_LICENSE }); 4 | export const cancelBuyLicense = () => ({ type: BUY_LICENSE_CANCEL }); 5 | 6 | export const loadPrice = () => ({ type: LOAD_PRICE }); 7 | 8 | export const checkLicenseOwner = () => ({ type: CHECK_LICENSE_OWNER }); 9 | 10 | export const getLicenseOwners = () => ({ type: GET_LICENSE_OWNERS }); 11 | -------------------------------------------------------------------------------- /src/js/features/license/actions.test.js: -------------------------------------------------------------------------------- 1 | import * as actions from './actions'; 2 | import * as constants from './constants'; 3 | 4 | describe('actions', () => { 5 | it('should create an action to buy a license', () => { 6 | const expectedAction = { 7 | type: constants.BUY_LICENSE 8 | }; 9 | expect(actions.buyLicense()).toEqual(expectedAction); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /src/js/features/license/constants.js: -------------------------------------------------------------------------------- 1 | export const BUY_LICENSE = 'BUY_LICENSE'; 2 | export const BUY_LICENSE_PRE_SUCCESS = 'BUY_LICENSE_PRE_SUCCESS'; 3 | export const BUY_LICENSE_SUCCEEDED = 'BUY_LICENSE_SUCCEEDED'; 4 | export const BUY_LICENSE_FAILED = 'BUY_LICENSE_FAILED'; 5 | export const BUY_LICENSE_CANCEL = 'BUY_LICENSE_CANCEL'; 6 | 7 | export const LOAD_PRICE = 'LICENSE/LOAD_PRICE'; 8 | export const LOAD_PRICE_SUCCEEDED = 'LICENSE/LOAD_PRICE/SUCCEEDED'; 9 | export const LOAD_PRICE_FAILED = 'LICENSE/LOAD_PRICE/FAILED'; 10 | 11 | export const CHECK_LICENSE_OWNER = 'CHECK_LICENSE_OWNER'; 12 | export const CHECK_LICENSE_OWNER_SUCCEEDED = 'CHECK_LICENSE_OWNER_SUCCEEDED'; 13 | export const CHECK_LICENSE_OWNER_FAILED = 'CHECK_LICENSE_OWNER_FAILED'; 14 | 15 | export const GET_LICENSE_OWNERS = 'GET_LICENSE_OWNERS'; 16 | export const GET_LICENSE_OWNERS_SUCCCEDED = 'GET_LICENSE_OWNERS_SUCCCEDED'; 17 | export const GET_LICENSE_OWNERS_FAILED = 'GET_LICENSE_OWNERS_FAILED'; 18 | -------------------------------------------------------------------------------- /src/js/features/license/index.js: -------------------------------------------------------------------------------- 1 | import saga from './saga'; 2 | import reducer from './reducer'; 3 | import * as actions from './actions'; 4 | import * as selectors from './selectors'; 5 | 6 | export default {saga, reducer, actions, selectors}; 7 | -------------------------------------------------------------------------------- /src/js/features/license/reducer.test.js: -------------------------------------------------------------------------------- 1 | import reducer from './reducer'; 2 | import * as constants from './constants'; 3 | 4 | describe('reducer', () => { 5 | it('should return the initial state', () => { 6 | expect(reducer(undefined, {})).toEqual( 7 | { 8 | licenseOwner: false, 9 | userRating: 0, 10 | loading: false, 11 | price: Number.MAX_SAFE_INTEGER, 12 | error: '' 13 | } 14 | ); 15 | }); 16 | 17 | it('should handle BUY_LICENSE_SUCCEEDED', () => { 18 | expect( 19 | reducer({}, { 20 | type: constants.BUY_LICENSE_SUCCEEDED 21 | }) 22 | ).toEqual( 23 | { 24 | licenseOwner: true, 25 | loading: false, 26 | error: '' 27 | } 28 | ); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /src/js/features/license/selectors.js: -------------------------------------------------------------------------------- 1 | export const isLicenseOwner = state => state.license.licenseOwner; 2 | export const isLoading = state => state.license.loading; 3 | export const userRating = state => parseInt(state.license.userRating, 10); 4 | export const error = state => state.license.error; 5 | export const txHash = state => state.license.txHash; 6 | export const licenseOwners = state => state.license.licenseOwners; 7 | export const licenseOwnersError = state => state.license.licenseOwnersError; 8 | export const getLicensePrice = state => { 9 | if (state.license.price === Number.MAX_SAFE_INTEGER) { 10 | return "price_error"; 11 | } 12 | return parseInt(state.license.price, 10); 13 | }; 14 | -------------------------------------------------------------------------------- /src/js/features/metadata/index.js: -------------------------------------------------------------------------------- 1 | import saga from './saga'; 2 | import reducer from './reducer'; 3 | import * as actions from './actions'; 4 | import * as selectors from './selectors'; 5 | 6 | export default {saga, reducer, actions, selectors}; 7 | -------------------------------------------------------------------------------- /src/js/features/network/actions.js: -------------------------------------------------------------------------------- 1 | import { INIT, UPDATE_BALANCES, UPDATE_BALANCE, GET_CONTACT_CODE, 2 | RESET_STATE, RESOLVE_ENS_NAME, PURGE_STATE, GET_GAS_PRICE, SET_TRANSACTION_WARNING_STATE } from './constants'; 3 | 4 | export const init = () => ({ type: INIT }); 5 | export const resetState = () => ({ type: RESET_STATE }); 6 | export const updateBalances = (address) => ({ type: UPDATE_BALANCES, address }); 7 | export const updateBalance = (symbol, address) => ({ type: UPDATE_BALANCE, symbol, address }); 8 | export const getContactCode = () => ({type: GET_CONTACT_CODE}); 9 | export const resolveENSName = (ens) => ({type: RESOLVE_ENS_NAME, ens}); 10 | export const getGasPrice = () => ({type: GET_GAS_PRICE}); 11 | 12 | export const setTransactionWarningState = (acceptation, neverShowAgain) => ({type: SET_TRANSACTION_WARNING_STATE, acceptation, neverShowAgain}); 13 | 14 | export const clearCache = (cb) => { 15 | return {type: PURGE_STATE, result: cb}; 16 | }; 17 | -------------------------------------------------------------------------------- /src/js/features/network/index.js: -------------------------------------------------------------------------------- 1 | import saga from './saga'; 2 | import reducer from './reducer'; 3 | import * as actions from './actions'; 4 | import * as selectors from './selectors'; 5 | 6 | export default {saga, reducer, actions, selectors}; 7 | -------------------------------------------------------------------------------- /src/js/features/newBuy/actions.js: -------------------------------------------------------------------------------- 1 | import {SET_CONTACT_INFO, SET_TRADE, SET_OFFER_ID, RESET_NEW_BUY} from './constants'; 2 | 3 | export const setOfferId = (offerId) => ({type: SET_OFFER_ID, offerId}); 4 | export const setContactInfo = ({username, contactMethod, contactUsername}) => ({type: SET_CONTACT_INFO, username, contactMethod, contactUsername}); 5 | export const setTrade = (currencyQuantity, assetQuantity, price) => ({type: SET_TRADE, currencyQuantity, assetQuantity, price}); 6 | export const resetNewBuy = () => ({type: RESET_NEW_BUY}); 7 | -------------------------------------------------------------------------------- /src/js/features/newBuy/constants.js: -------------------------------------------------------------------------------- 1 | export const SET_CONTACT_INFO = 'SET_CONTACT'; 2 | export const SET_TRADE = 'SET_TRADE'; 3 | export const SET_OFFER_ID = 'SET_OFFER_ID'; 4 | export const RESET_NEW_BUY = 'RESET_NEW_BUY'; 5 | -------------------------------------------------------------------------------- /src/js/features/newBuy/index.js: -------------------------------------------------------------------------------- 1 | import reducer from './reducer'; 2 | import * as actions from './actions'; 3 | import * as selectors from './selectors'; 4 | 5 | export default {reducer, actions, selectors}; 6 | -------------------------------------------------------------------------------- /src/js/features/newBuy/reducer.js: -------------------------------------------------------------------------------- 1 | import {SET_CONTACT_INFO, SET_TRADE, SET_OFFER_ID, RESET_NEW_BUY} from './constants'; 2 | import {RESET_STATE, PURGE_STATE} from "../network/constants"; 3 | import {getContactData} from "../../utils/strings"; 4 | 5 | const DEFAULT_STATE = { 6 | currencyQuantity: 0, 7 | assetQuantity: 0 8 | }; 9 | 10 | function reducer(state = DEFAULT_STATE, action) { 11 | switch (action.type) { 12 | case SET_OFFER_ID: 13 | return { 14 | ...state, offerId: parseInt(action.offerId, 10) 15 | }; 16 | case SET_CONTACT_INFO: 17 | return { 18 | ...state, 19 | username: action.username, 20 | contactData: action.contactMethod && action.contactUsername ? getContactData(action.contactMethod, action.contactUsername) : state.contactData 21 | }; 22 | case SET_TRADE: 23 | return { 24 | ...state, 25 | currencyQuantity: action.currencyQuantity, 26 | assetQuantity: action.assetQuantity, 27 | price: action.price 28 | }; 29 | case RESET_NEW_BUY: 30 | case PURGE_STATE: 31 | case RESET_STATE: { 32 | return DEFAULT_STATE; 33 | } 34 | default: 35 | return state; 36 | } 37 | } 38 | 39 | export default reducer; 40 | -------------------------------------------------------------------------------- /src/js/features/newBuy/selectors.js: -------------------------------------------------------------------------------- 1 | export const statusContactCode = state => state.newBuy.statusContactCode || ''; 2 | export const contactData = state => state.newBuy.contactData || ''; 3 | export const username = state => state.newBuy.username || ''; 4 | export const assetQuantity = state => state.newBuy.assetQuantity; 5 | export const currencyQuantity = state => state.newBuy.currencyQuantity; 6 | export const offerId= state => state.newBuy.offerId; 7 | export const price = state => state.newBuy.price; 8 | -------------------------------------------------------------------------------- /src/js/features/newSeller/actions.js: -------------------------------------------------------------------------------- 1 | import {SET_CURENCY, SET_MARGIN, SET_ASSET, SET_LOCATION, SET_PAYMENT_METHODS, SET_CONTACT_INFO, SET_ARBITRATOR, SET_LIMITS} from './constants'; 2 | import {RESET_NEW_OFFER} from "../metadata/constants"; 3 | 4 | export const setAsset = (asset) => ({type: SET_ASSET, asset}); 5 | export const setLocation = (location) => ({type: SET_LOCATION, location}); 6 | export const setPaymentMethods = (paymentMethods) => ({type: SET_PAYMENT_METHODS, paymentMethods}); 7 | export const setCurrency = (currency) => ({type: SET_CURENCY, currency}); 8 | export const setMargin = (margin) => ({type: SET_MARGIN, margin}); 9 | export const setContactInfo = ({username, contactMethod, contactUsername}) => ({type: SET_CONTACT_INFO, username, contactMethod, contactUsername}); 10 | export const setArbitrator = (arbitrator) => ({type: SET_ARBITRATOR, arbitrator}); 11 | export const setLimits = (useCustomLimits, limitL, limitU) => ({type: SET_LIMITS, limitL, limitU, useCustomLimits}); 12 | export const resetNewOfferData = () => ({type: RESET_NEW_OFFER}); 13 | -------------------------------------------------------------------------------- /src/js/features/newSeller/constants.js: -------------------------------------------------------------------------------- 1 | export const SET_CURENCY = 'NEW_SELLER/SET_CURRENCY'; 2 | export const SET_MARGIN = 'NEW_SELLER/SET_MARGIN'; 3 | export const SET_ASSET = 'NEW_SELLER/SET_ASSET'; 4 | export const SET_LOCATION = 'NEW_SELLER/SET_LOCATION'; 5 | export const SET_PAYMENT_METHODS = 'NEW_SELLER/SET_PAYMENT_METHODS'; 6 | export const SET_CONTACT_INFO = 'NEW_SELLER/SET_CONTACT_INFO'; 7 | export const SET_ARBITRATOR = 'NEW_SELLER/SET_ARBITRATOR'; 8 | export const SET_LIMITS = 'NEW_SELLER/SET_LIMITS'; 9 | -------------------------------------------------------------------------------- /src/js/features/newSeller/index.js: -------------------------------------------------------------------------------- 1 | import reducer from './reducer'; 2 | import * as actions from './actions'; 3 | import * as selectors from './selectors'; 4 | 5 | export default {reducer, actions, selectors}; 6 | -------------------------------------------------------------------------------- /src/js/features/newSeller/selectors.js: -------------------------------------------------------------------------------- 1 | export const getNewSeller = state => { 2 | return state.newSeller; 3 | }; 4 | -------------------------------------------------------------------------------- /src/js/features/prices/actions.js: -------------------------------------------------------------------------------- 1 | import { FETCH_EXCHANGE_RATE, LOAD_PRICE_FOR_ASSET_AND_CURRENCY } from './constants'; 2 | 3 | export const fetchExchangeRates = () => ({type: FETCH_EXCHANGE_RATE}); 4 | 5 | export const loadPriceForAssetAndCurrency = (asset, currency) => ({type: LOAD_PRICE_FOR_ASSET_AND_CURRENCY, asset, currency}); 6 | -------------------------------------------------------------------------------- /src/js/features/prices/constants.js: -------------------------------------------------------------------------------- 1 | export const FETCH_PRICES_SUCCEEDED = 'FETCH_PRICES_SUCCEEDED'; 2 | export const FETCH_EXCHANGE_RATE_FALLBACK = 'FETCH_EXCHANGE_RATE_FALLBACK'; 3 | export const FETCH_PRICES_FAILED = 'FETCH_PRICES_FAILED'; 4 | export const FETCH_EXCHANGE_RATE = 'FETCH_EXCHANGE_RATE'; 5 | 6 | 7 | export const LOAD_PRICE_FOR_ASSET_AND_CURRENCY = 'LOAD_PRICE_FOR_ASSET_AND_CURRENCY'; 8 | 9 | export const SAVE_COIN_GECKO_IDS = 'SAVE_COIN_GECKO_IDS'; 10 | -------------------------------------------------------------------------------- /src/js/features/prices/index.js: -------------------------------------------------------------------------------- 1 | import saga from './saga'; 2 | import reducer from './reducer'; 3 | import * as actions from './actions'; 4 | import * as selectors from './selectors'; 5 | 6 | export default {saga, reducer, actions, selectors}; 7 | -------------------------------------------------------------------------------- /src/js/features/prices/reducer.js: -------------------------------------------------------------------------------- 1 | import { FETCH_PRICES_SUCCEEDED, FETCH_PRICES_FAILED, SAVE_COIN_GECKO_IDS } from './constants'; 2 | import {PURGE_STATE} from '../network/constants'; 3 | import merge from "merge"; 4 | 5 | function reducer(state = {}, action) { 6 | switch (action.type) { 7 | case FETCH_PRICES_SUCCEEDED: 8 | return { 9 | ...merge.recursive(true, state, action.data), 10 | error: null 11 | }; 12 | case FETCH_PRICES_FAILED: 13 | return { 14 | ...state, 15 | ...{error: action.error} 16 | }; 17 | case SAVE_COIN_GECKO_IDS: 18 | return { 19 | ...state, 20 | coinGeckoIds: action.coinGeckoIds 21 | }; 22 | case PURGE_STATE: 23 | return {}; 24 | default: 25 | return state; 26 | } 27 | } 28 | 29 | export default reducer; 30 | -------------------------------------------------------------------------------- /src/js/features/prices/selectors.js: -------------------------------------------------------------------------------- 1 | export const getPrices = state => state.prices; 2 | 3 | export const getAssetPrice = (state, assetSymbol) => { 4 | if (!assetSymbol) { 5 | return null; 6 | } 7 | return state.prices[assetSymbol]; 8 | }; 9 | 10 | export const hasPrices = state => { 11 | return state.prices !== undefined; 12 | }; 13 | 14 | export const getGeckoIds = state => state.prices.coinGeckoIds; 15 | 16 | export const error = state => state.prices.error; 17 | -------------------------------------------------------------------------------- /src/js/features/signature/actions.js: -------------------------------------------------------------------------------- 1 | import {INCLUDE_SIGNATURE, SIGNATURE_OPEN_CASE, SIGNATURE_PAYMENT} from './constants'; 2 | import EscrowInstance from '../../../embarkArtifacts/contracts/EscrowInstance'; 3 | 4 | export const includeSignature = ({type, escrowId, message}) => { 5 | let method; 6 | switch(type){ 7 | case SIGNATURE_PAYMENT: 8 | method = 'pay(uint256,bytes)'; 9 | break; 10 | case SIGNATURE_OPEN_CASE: 11 | method = 'openCase(uint256,bytes)'; 12 | break; 13 | default: 14 | throw new Error("Invalid signature type"); 15 | } 16 | return { type: INCLUDE_SIGNATURE, toSend: EscrowInstance.methods[method](escrowId, message) }; 17 | }; 18 | -------------------------------------------------------------------------------- /src/js/features/signature/constants.js: -------------------------------------------------------------------------------- 1 | export const INCLUDE_SIGNATURE = 'INCLUDE_SIGNATURE'; 2 | export const INCLUDE_SIGNATURE_PRE_SUCCESS = 'INCLUDE_SIGNATURE_PRE_SUCCESS'; 3 | export const INCLUDE_SIGNATURE_SUCCEEDED = 'INCLUDE_SIGNATURE_SUCCEEDED'; 4 | export const INCLUDE_SIGNATURE_FAILED = 'INCLUDE_SIGNATURE_FAILED'; 5 | 6 | export const SIGNATURE_PAYMENT = 'payment'; 7 | export const SIGNATURE_OPEN_CASE = 'open-case'; 8 | -------------------------------------------------------------------------------- /src/js/features/signature/index.js: -------------------------------------------------------------------------------- 1 | import saga from './saga'; 2 | import reducer from './reducer'; 3 | import * as actions from './actions'; 4 | import * as selectors from './selectors'; 5 | 6 | export default {saga, reducer, actions, selectors}; 7 | -------------------------------------------------------------------------------- /src/js/features/signature/saga.js: -------------------------------------------------------------------------------- 1 | import {fork, takeEvery} from 'redux-saga/effects'; 2 | import {INCLUDE_SIGNATURE, INCLUDE_SIGNATURE_FAILED, INCLUDE_SIGNATURE_SUCCEEDED, INCLUDE_SIGNATURE_PRE_SUCCESS} from './constants'; 3 | import {doTransaction} from "../../utils/saga"; 4 | 5 | export function *onIncludeSignature() { 6 | yield takeEvery(INCLUDE_SIGNATURE, doTransaction.bind(null, INCLUDE_SIGNATURE_PRE_SUCCESS, INCLUDE_SIGNATURE_SUCCEEDED, INCLUDE_SIGNATURE_FAILED)); 7 | } 8 | 9 | export default [fork(onIncludeSignature)]; 10 | -------------------------------------------------------------------------------- /src/js/features/signature/selectors.js: -------------------------------------------------------------------------------- 1 | export const loading = state => state.signature.loading; 2 | export const receipt = state => state.signature.receipt; 3 | export const txHash = state => state.signature.txHash; 4 | export const error = state => state.signature.error; 5 | -------------------------------------------------------------------------------- /src/js/history.js: -------------------------------------------------------------------------------- 1 | const createHistory = require("history").createBrowserHistory; 2 | 3 | export default createHistory(); 4 | -------------------------------------------------------------------------------- /src/js/i18n.js: -------------------------------------------------------------------------------- 1 | import i18n from "i18next"; 2 | import { initReactI18next } from "react-i18next"; 3 | import LngDetector from "i18next-browser-languagedetector"; 4 | 5 | import translationEn from './locales/en.json'; 6 | 7 | i18n 8 | .use(initReactI18next) 9 | .use(LngDetector) 10 | .init({ 11 | resources: { 12 | en: { 13 | translation: translationEn 14 | } 15 | }, 16 | debug: true, 17 | fallbackLng: "en", 18 | interpolation: { 19 | escapeValue: false 20 | } 21 | }); 22 | 23 | export default i18n; 24 | -------------------------------------------------------------------------------- /src/js/pages/Arbitration/components/EscrowDetail.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Row, Col} from 'reactstrap'; 3 | import PropTypes from 'prop-types'; 4 | 5 | const EscrowDetail = ({escrow}) => 6 | 7 |

Trade details

8 |

{(escrow.fiatAmount / 100).toFixed(2)} {escrow.offer.currency} for {escrow.tokenAmount} {escrow.token.symbol}

9 |

{escrow.token.symbol} Price = {((escrow.fiatAmount / 100) / escrow.tokenAmount).toFixed(4)} {escrow.offer.currency}

10 |

Took place on {escrow.createDate}

11 | 12 |
; 13 | 14 | 15 | EscrowDetail.propTypes = { 16 | escrow: PropTypes.object 17 | }; 18 | 19 | export default EscrowDetail; 20 | -------------------------------------------------------------------------------- /src/js/pages/Arbitration/components/ReadChatLogs.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Row, Col} from 'reactstrap'; 3 | import ChatIcon from "../../../../images/read-chat.svg"; 4 | 5 | const ReadChatLogs = () => ( 6 | 7 | 8 |
9 | read chat 10 |
11 | 12 | 13 |
Read chat logs of this trade
14 | 15 |
16 | ); 17 | 18 | export default ReadChatLogs; 19 | -------------------------------------------------------------------------------- /src/js/pages/Arbitration/index.scss: -------------------------------------------------------------------------------- 1 | @import "../../../css/variable-overrides"; 2 | 3 | .arbitrationStatus { 4 | border-radius: 4px; 5 | background: $black; 6 | text-transform: uppercase; 7 | color: $white; 8 | font-weight: bold; 9 | font-size: 11px; 10 | letter-spacing: 1px; 11 | padding: 3px 10px; 12 | position: relative; 13 | top: -3px; 14 | } 15 | 16 | .arbitrationDialog button svg { 17 | margin-top: 10px !important; 18 | } 19 | 20 | .arbitrationStatus.open { 21 | background: $success; 22 | } 23 | 24 | .arbitrationStatus.resolved { 25 | background: $primary; 26 | } 27 | 28 | .arbitrationMotive { 29 | background: $secondary; 30 | border-radius: 8px; 31 | padding: 10px; 32 | } 33 | 34 | .triangle { 35 | display: block; 36 | position: relative; 37 | top: -15px; 38 | left: 18px; 39 | margin-bottom: -8px; 40 | } 41 | 42 | body .seller-text { 43 | background-color: $gray-300; 44 | } 45 | body .buyer-text { 46 | background-color: $gray-100; 47 | } 48 | -------------------------------------------------------------------------------- /src/js/pages/ArbitrationLicense/components/Info.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {Row, Col} from 'reactstrap'; 3 | import PropTypes from 'prop-types'; 4 | import {withTranslation} from 'react-i18next'; 5 | 6 | import "./Info.scss"; 7 | 8 | class LicenseInfo extends Component { 9 | render() { 10 | const t = this.props.t; 11 | return ( 12 |
13 | 14 | 15 |

{t('arbitration.title')}

16 | 17 |
18 | 19 |
20 | {t('arbitration.stake1', {price: this.props.price})}
21 | {t('arbitration.stake2', {price: this.props.price})} 22 |
23 |
24 | ); 25 | } 26 | } 27 | 28 | LicenseInfo.propTypes = { 29 | t: PropTypes.func, 30 | price: PropTypes.oneOfType([ 31 | PropTypes.string, 32 | PropTypes.number 33 | ]) 34 | }; 35 | 36 | export default withTranslation()(LicenseInfo); 37 | -------------------------------------------------------------------------------- /src/js/pages/ArbitrationLicense/components/Info.scss: -------------------------------------------------------------------------------- 1 | @import "../../../../css/variable-overrides.scss"; 2 | 3 | .fee-card, .stake-card { 4 | font-size: 17px; 5 | } 6 | 7 | .fee-card { 8 | background-color: lighten($purple, 25%); 9 | color: $purple; 10 | } 11 | 12 | .stake-card { 13 | background-color: lighten($orange, 25%); 14 | color: $orange; 15 | } 16 | -------------------------------------------------------------------------------- /src/js/pages/EditLocation/components/UpdateButton.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {Row, Col, Button} from 'reactstrap'; 3 | import PropTypes from 'prop-types'; 4 | import {withTranslation} from 'react-i18next'; 5 | 6 | class UpdateButton extends Component { 7 | render() { 8 | const t = this.props.t; 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | } 17 | } 18 | 19 | UpdateButton.propTypes = { 20 | t: PropTypes.func, 21 | onClick: PropTypes.func, 22 | disabled: PropTypes.bool 23 | }; 24 | 25 | export default withTranslation()(UpdateButton); 26 | -------------------------------------------------------------------------------- /src/js/pages/EditLocation/components/UpdateButton.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import UpdateButton from "./UpdateButton"; 5 | 6 | describe('UpdateButton', () => { 7 | it('should render correctly when disabled', () => { 8 | const component = shallow( undefined}/>); 9 | 10 | expect(component).toMatchSnapshot(); 11 | }); 12 | 13 | it('should render correctly when enabled', () => { 14 | const component = shallow( undefined}/>); 15 | 16 | expect(component).toMatchSnapshot(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /src/js/pages/EditMyContact/components/UpdateButton.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {Row, Col, Button} from 'reactstrap'; 3 | import PropTypes from 'prop-types'; 4 | import {withTranslation} from 'react-i18next'; 5 | 6 | class UpdateButton extends Component { 7 | render() { 8 | const t = this.props.t; 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | } 17 | } 18 | 19 | UpdateButton.propTypes = { 20 | t: PropTypes.func, 21 | onClick: PropTypes.func, 22 | disabled: PropTypes.bool 23 | }; 24 | 25 | export default withTranslation()(UpdateButton); 26 | -------------------------------------------------------------------------------- /src/js/pages/EditMyContact/components/UpdateButton.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import UpdateButton from "./UpdateButton"; 5 | 6 | describe('UpdateButton', () => { 7 | it('should render correctly when disabled', () => { 8 | const component = shallow( undefined}/>); 9 | 10 | expect(component).toMatchSnapshot(); 11 | }); 12 | 13 | it('should render correctly when enabled', () => { 14 | const component = shallow( undefined}/>); 15 | 16 | expect(component).toMatchSnapshot(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /src/js/pages/Escrow/components/OpenDispute.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Row, Col} from 'reactstrap'; 3 | import PropTypes from 'prop-types'; 4 | import exclamationCircle from "../../../../images/exclamation-circle.png"; 5 | import RoundedIcon from "../../../ui/RoundedIcon"; 6 | import escrow from '../../../features/escrow'; 7 | import {Link} from "react-router-dom"; 8 | import {zeroAddress} from '../../../utils/address'; 9 | import {withTranslation} from "react-i18next"; 10 | 11 | const OpenDispute = ({t, trade}) => { 12 | const shouldDisplay = trade.status === escrow.helpers.tradeStates.paid && trade.arbitrator !== zeroAddress; 13 | return shouldDisplay && ( 14 | 15 | 16 | 17 |

{t('escrow.openDispute.open')}

18 |

{t('escrow.openDispute.havingProblem')}

19 | 20 |
21 | ); 22 | }; 23 | 24 | OpenDispute.propTypes = { 25 | t: PropTypes.func, 26 | trade: PropTypes.object 27 | }; 28 | 29 | export default withTranslation()(OpenDispute); 30 | -------------------------------------------------------------------------------- /src/js/pages/Escrow/components/Profile.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Row, Col} from 'reactstrap'; 3 | import RoundedIcon from "../../../ui/RoundedIcon"; 4 | import PropTypes from 'prop-types'; 5 | import ProfileIcon from "../../../../images/profileUser.svg"; 6 | import {withRouter, Link} from "react-router-dom"; 7 | import {withTranslation} from "react-i18next"; 8 | 9 | const Profile = ({t, address, withBuyer}) => ( 10 | 11 | 12 | 13 |
{t('escrow.profile.title', {person: withBuyer ? t('general.buyer') : t('general.seller')})}
14 | 15 |
16 | ); 17 | 18 | Profile.defaultProps = { 19 | withBuyer: false 20 | }; 21 | 22 | Profile.propTypes = { 23 | t: PropTypes.func, 24 | address: PropTypes.string, 25 | withBuyer: PropTypes.bool 26 | }; 27 | 28 | export default withRouter(withTranslation()(Profile)); 29 | -------------------------------------------------------------------------------- /src/js/pages/Home/components/iconGroup.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Col} from 'reactstrap'; 3 | import PropTypes from "prop-types"; 4 | 5 | import {withTranslation} from "react-i18next"; 6 | 7 | const IconGroup = ({src, title, children, fullSize, className, aos}) => ( 8 | 9 | icon 10 |

{title}

11 |
12 | {children} 13 |
14 | 15 | ); 16 | 17 | IconGroup.propTypes = { 18 | t: PropTypes.func, 19 | src: PropTypes.string, 20 | title: PropTypes.string, 21 | fullSize: PropTypes.bool, 22 | children: PropTypes.node, 23 | className: PropTypes.string, 24 | aos: PropTypes.string 25 | }; 26 | 27 | export default withTranslation()(IconGroup); 28 | -------------------------------------------------------------------------------- /src/js/pages/Home/components/landingHeader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from "react-router-dom"; 3 | import {Navbar, Nav, NavItem} from 'reactstrap'; 4 | import PropTypes from "prop-types"; 5 | 6 | import logo from "../../../../images/teller-logo-icon.svg"; 7 | import logoText from "../../../../images/teller-logo-text.svg"; 8 | import OpenDappBtn from "./openDappBtn"; 9 | 10 | const LandingHeader = ({loading}) => ( 11 |
12 | 13 | 14 | LogoLogo text 15 | 16 | 21 | 22 |
23 | ); 24 | 25 | LandingHeader.propTypes = { 26 | loading: PropTypes.bool 27 | }; 28 | 29 | export default LandingHeader; 30 | -------------------------------------------------------------------------------- /src/js/pages/Home/components/openDappBtn.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Button} from 'reactstrap'; 3 | import PropTypes from "prop-types"; 4 | 5 | import {withTranslation} from "react-i18next"; 6 | import {Link} from "react-router-dom"; 7 | 8 | const OpenDappBtn = ({t, loading, size, text, aos}) => ( 9 | 12 | ); 13 | 14 | OpenDappBtn.propTypes = { 15 | t: PropTypes.func, 16 | loading: PropTypes.bool, 17 | size: PropTypes.string, 18 | text: PropTypes.string, 19 | aos: PropTypes.string 20 | }; 21 | 22 | export default withTranslation()(OpenDappBtn); 23 | -------------------------------------------------------------------------------- /src/js/pages/License/components/Balance.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component, Fragment} from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import {withTranslation} from 'react-i18next'; 4 | import classnames from 'classnames'; 5 | 6 | import SNTIcon from '../../../../../node_modules/cryptocurrency-icons/svg/color/snt.svg'; 7 | 8 | class YourSNTBalance extends Component { 9 | render() { 10 | const t = this.props.t; 11 | return ( 12 | 13 |

{t('yourSNTBalance.label')}

14 |

15 | 16 | SNT icon 17 | {(this.props.value || this.props.value === 0) && {this.props.value} SNT} 18 | {!this.props.value && this.props.value !== 0 && t('general.loading')} 19 | 20 |

21 |
22 | ); 23 | } 24 | } 25 | 26 | YourSNTBalance.propTypes = { 27 | t: PropTypes.func, 28 | value: PropTypes.string, 29 | disabled: PropTypes.bool 30 | }; 31 | 32 | export default withTranslation()(YourSNTBalance); 33 | -------------------------------------------------------------------------------- /src/js/pages/License/components/Balance.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import YourSNTBalance from "./Balance"; 5 | 6 | describe('YourSNTBalance', () => { 7 | it('should render correctly', () => { 8 | const component = shallow(); 9 | 10 | expect(component).toMatchSnapshot(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/js/pages/License/components/BuyButton.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {Row, Col, Button} from 'reactstrap'; 3 | import PropTypes from 'prop-types'; 4 | import {withTranslation} from 'react-i18next'; 5 | 6 | class LicenseBuy extends Component { 7 | render() { 8 | const t = this.props.t; 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | } 17 | } 18 | 19 | LicenseBuy.propTypes = { 20 | t: PropTypes.func, 21 | onClick: PropTypes.func, 22 | disabled: PropTypes.bool 23 | }; 24 | 25 | export default withTranslation()(LicenseBuy); 26 | -------------------------------------------------------------------------------- /src/js/pages/License/components/BuyButton.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import LicenseBuy from "./BuyButton"; 5 | 6 | describe('LicenseBuy', () => { 7 | it('should render correctly when disabled', () => { 8 | const component = shallow( undefined}/>); 9 | 10 | expect(component).toMatchSnapshot(); 11 | }); 12 | 13 | it('should render correctly when enabled', () => { 14 | const component = shallow( undefined}/>); 15 | 16 | expect(component).toMatchSnapshot(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /src/js/pages/License/components/Info.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {Row, Col} from 'reactstrap'; 3 | import PropTypes from 'prop-types'; 4 | import {withTranslation} from 'react-i18next'; 5 | 6 | import "./Info.scss"; 7 | 8 | class LicenseInfo extends Component { 9 | render() { 10 | const t = this.props.t; 11 | return ( 12 |
13 | 14 | 15 |

{t('sellerLicenseInfo.title')}

16 | 17 |
18 | 19 |
20 | {t('sellerLicenseInfo.fee')}
{t('sellerLicenseInfo.fee2')} 21 |
22 | 23 |
24 | {t('sellerLicenseInfo.stake', {price: this.props.price})}
{t('sellerLicenseInfo.stake2')} 25 |
26 |
27 | ); 28 | } 29 | } 30 | 31 | LicenseInfo.propTypes = { 32 | t: PropTypes.func, 33 | price: PropTypes.oneOfType([ 34 | PropTypes.string, 35 | PropTypes.number 36 | ]) 37 | }; 38 | 39 | export default withTranslation()(LicenseInfo); 40 | -------------------------------------------------------------------------------- /src/js/pages/License/components/Info.scss: -------------------------------------------------------------------------------- 1 | @import "../../../../css/variable-overrides.scss"; 2 | 3 | .fee-card, .stake-card { 4 | font-size: 17px; 5 | } 6 | 7 | .fee-card { 8 | background-color: lighten($purple, 25%); 9 | color: $purple; 10 | } 11 | 12 | .stake-card { 13 | background-color: lighten($orange, 25%); 14 | color: $orange; 15 | } 16 | -------------------------------------------------------------------------------- /src/js/pages/License/components/Info.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import LicenseInfo from "./Info"; 5 | 6 | describe('LicenseInfo', () => { 7 | it('should render correctly', () => { 8 | const component = shallow(); 9 | 10 | expect(component).toMatchSnapshot(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/js/pages/License/components/__snapshots__/Balance.test.jsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`YourSNTBalance should render correctly 1`] = ` 4 | 5 |

6 |

9 | 12 | SNT icon 17 | 10 18 | SNT 19 | 20 |

21 | 22 | `; 23 | -------------------------------------------------------------------------------- /src/js/pages/License/components/__snapshots__/Info.test.jsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`LicenseInfo should render correctly 1`] = ` 4 |
7 | 19 | 32 |

35 | 36 | 37 |
40 |
41 |
42 |
45 |
46 |
47 |

48 | `; 49 | -------------------------------------------------------------------------------- /src/js/pages/MyDisputes/index.scss: -------------------------------------------------------------------------------- 1 | .topCircle { 2 | z-index: 90; 3 | position: relative; 4 | } 5 | 6 | .bottomCircle { 7 | z-index: 80; 8 | position: relative; 9 | left: -10px; 10 | } 11 | 12 | .profile-button span, 13 | .profile-button h6 { 14 | font-size: 15px; 15 | } 16 | -------------------------------------------------------------------------------- /src/js/pages/MyOffers/components/Offers.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import Offers from "./Offers"; 5 | 6 | describe('Offers', () => { 7 | it('should render correctly', () => { 8 | const component = shallow(); 23 | 24 | expect(component).toMatchSnapshot(); 25 | }); 26 | 27 | it('should render when empty', () => { 28 | const component = shallow(); 29 | 30 | expect(component).toMatchSnapshot(); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /src/js/pages/MyProfile/components/ProfileButton.scss: -------------------------------------------------------------------------------- 1 | @import "../../../../css/variable-overrides.scss"; 2 | 3 | .profile-button { 4 | .action-needed-badge { 5 | background-color: $warning; 6 | display: inline-block; 7 | width: 18px; 8 | height: 18px; 9 | line-height: 18px; 10 | text-align: center; 11 | border-radius: 10px; 12 | font-weight: 500; 13 | font-size: 10px; 14 | color: $white; 15 | position: relative; 16 | top: -1.2px; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/js/pages/MyProfile/components/Separator.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import classnames from 'classnames'; 4 | 5 | const Separator = ({className}) => ( 6 |
7 | 8 |
9 | ); 10 | 11 | Separator.propTypes = { 12 | className: PropTypes.string 13 | }; 14 | 15 | export default Separator; 16 | -------------------------------------------------------------------------------- /src/js/pages/MyProfile/index.scss: -------------------------------------------------------------------------------- 1 | @import "../../../css/variable-overrides"; 2 | 3 | .topCircle { 4 | z-index: 90; 5 | position: relative; 6 | } 7 | 8 | .bottomCircle { 9 | z-index: 80; 10 | position: relative; 11 | left: -10px; 12 | } 13 | 14 | .profile-button { 15 | &:hover { 16 | text-decoration: none; 17 | } 18 | 19 | .profile-button-icon, 20 | .profile-button-title { 21 | font-size: 15px; 22 | 23 | &.line-height-40 { 24 | line-height: 40px; 25 | } 26 | } 27 | } 28 | 29 | .separator { 30 | display: block; 31 | width: 300px; 32 | border: 1px solid $secondary; 33 | margin: 15px auto; 34 | } 35 | -------------------------------------------------------------------------------- /src/js/pages/MyTrades/components/Trades.scss: -------------------------------------------------------------------------------- 1 | @import "../../../../css/variable-overrides"; 2 | 3 | .state-filters { 4 | .form-control { 5 | height: 40px; 6 | } 7 | } 8 | 9 | .offer-card { 10 | position: relative; 11 | @media screen and (min-width: 500px) and (max-width: 765px) { 12 | .col-md-1:first-child { 13 | max-width: 65px; 14 | } 15 | } 16 | } 17 | 18 | .offer-card .label { 19 | position: absolute; 20 | top: 0; 21 | right: 10px; 22 | } 23 | -------------------------------------------------------------------------------- /src/js/pages/MyTrades/components/Trades.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import Trades from "./Trades"; 5 | 6 | /* eslint-disable-next-line no-unused-vars*/ 7 | global.web3 = { 8 | utils: { 9 | toChecksumAddress: () => true 10 | } 11 | }; 12 | 13 | describe('Trades', () => { 14 | it('should render correctly', () => { 15 | const component = shallow(); 16 | 17 | expect(component).toMatchSnapshot(); 18 | }); 19 | 20 | it('should render when empty', () => { 21 | const component = shallow(); 22 | 23 | expect(component).toMatchSnapshot(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/js/pages/MyTrades/components/__snapshots__/Trades.test.jsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Trades should render correctly 1`] = ` 4 |
7 |
10 | 23 | 36 | 37 |
38 |
39 | `; 40 | 41 | exports[`Trades should render when empty 1`] = ` 42 |
45 | 50 |
51 | `; 52 | -------------------------------------------------------------------------------- /src/js/pages/OffersList/components/ClearButton.jsx: -------------------------------------------------------------------------------- 1 | import {Button} from "reactstrap"; 2 | import PropTypes from "prop-types"; 3 | import React from "react"; 4 | import {withTranslation} from "react-i18next"; 5 | 6 | const ClearButton = ({t, onClear, close}) => ( 7 | 13 | ); 14 | 15 | ClearButton.propTypes = { 16 | t: PropTypes.func, 17 | onClear: PropTypes.func, 18 | close: PropTypes.func 19 | }; 20 | 21 | export default withTranslation()(ClearButton); 22 | -------------------------------------------------------------------------------- /src/js/pages/OffersList/components/Modals/SortModal.jsx: -------------------------------------------------------------------------------- 1 | import {ButtonGroup, Modal, ModalBody} from "reactstrap"; 2 | import React, {Fragment} from "react"; 3 | import CheckButton from "../../../../ui/CheckButton"; 4 | import Separator from "../../../MyProfile/components/Separator"; 5 | import PropTypes from "prop-types"; 6 | 7 | const SorterModal = ({onClose, sortTypes, setSortType, sortType}) => ( 8 | 9 | 10 | 11 | {sortTypes.map((_sortType, index) => ( 12 | 13 | { 14 | setSortType(index); 15 | onClose(); 16 | }} active={index === sortType}> 17 | {_sortType} 18 | 19 | {index !== sortTypes.length - 1 && } 20 | 21 | ))} 22 | 23 | 24 | 25 | ); 26 | 27 | SorterModal.propTypes = { 28 | onClose: PropTypes.func, 29 | setSortType: PropTypes.func, 30 | sortTypes: PropTypes.array, 31 | sortType: PropTypes.number 32 | }; 33 | 34 | export default SorterModal; 35 | -------------------------------------------------------------------------------- /src/js/pages/OffersList/index.scss: -------------------------------------------------------------------------------- 1 | @import "../../../../node_modules/bootstrap/scss/functions"; 2 | @import "../../../../node_modules/bootstrap/scss/variables"; 3 | 4 | .offer-listing { 5 | color: $yiq-text-dark; 6 | 7 | .rating-col { 8 | font-size: 13px; 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/js/pages/Profile/index.scss: -------------------------------------------------------------------------------- 1 | .seller-profile-container { 2 | 3 | .map-component { 4 | position: relative; 5 | height: 130px; 6 | margin-top: 16px; 7 | overflow: hidden; 8 | border-radius: 10px; 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/js/pages/ProfileSettings/index.jsx: -------------------------------------------------------------------------------- 1 | import React, {Fragment} from "react"; 2 | import {withTranslation} from "react-i18next"; 3 | import PropTypes from "prop-types"; 4 | import ProfileButton from "../MyProfile/components/ProfileButton"; 5 | import iconChat from "../../../images/read-chat.svg"; 6 | import iconBell from "../../../images/bell.svg"; 7 | import iconSettings from "../../../images/settings.svg"; 8 | import { ReactComponent as iconLocation } from "../../../images/location.svg"; 9 | 10 | const ProfileSettings = ({t}) => ( 11 |

{t('profileSettings.title')}

12 | 13 | 14 | 15 | 16 |
); 17 | 18 | 19 | ProfileSettings.propTypes = { 20 | t: PropTypes.func 21 | }; 22 | 23 | export default withTranslation()(ProfileSettings); 24 | -------------------------------------------------------------------------------- /src/js/pages/SellerApproval/index.scss: -------------------------------------------------------------------------------- 1 | .accept-all-switch { 2 | top: 6px; 3 | margin: 0 7px; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /src/js/reducer.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import { connectRouter } from 'connected-react-router'; 3 | 4 | import history from './history'; 5 | 6 | import prices from './features/prices'; 7 | import license from './features/license'; 8 | import escrow from './features/escrow'; 9 | import network from './features/network'; 10 | import signature from './features/signature'; 11 | import arbitration from './features/arbitration'; 12 | import newSeller from './features/newSeller'; 13 | import newBuy from './features/newBuy'; 14 | import metadata from './features/metadata'; 15 | import approval from './features/approval'; 16 | import events from './features/events'; 17 | import emailNotifications from './features/emailNotifications'; 18 | 19 | const rootReducer = combineReducers({ 20 | router: connectRouter(history), 21 | prices: prices.reducer, 22 | license: license.reducer, 23 | network: network.reducer, 24 | escrow: escrow.reducer, 25 | signature: signature.reducer, 26 | arbitration: arbitration.reducer, 27 | newSeller: newSeller.reducer, 28 | newBuy: newBuy.reducer, 29 | metadata: metadata.reducer, 30 | approval: approval.reducer, 31 | events: events.reducer, 32 | emailNotifications: emailNotifications.reducer 33 | }); 34 | 35 | export default rootReducer; 36 | -------------------------------------------------------------------------------- /src/js/setupTests.js: -------------------------------------------------------------------------------- 1 | import {configure} from "enzyme"; 2 | import Adapter from "enzyme-adapter-react-16"; 3 | import * as jest from "jest"; 4 | 5 | configure({adapter: new Adapter()}); 6 | 7 | jest.mock('react-i18next', () => ({ 8 | // this mock makes sure any components using the translate HoC receive the t function as a prop 9 | withTranslation: () => Component => { 10 | Component.defaultProps = { ...Component.defaultProps, t: () => "" }; 11 | return Component; 12 | } 13 | })); 14 | -------------------------------------------------------------------------------- /src/js/ui/CheckButton/index.scss: -------------------------------------------------------------------------------- 1 | @import "../../../css/variable-overrides"; 2 | 3 | .check-button { 4 | text-decoration: none !important; 5 | font-size: 15px; 6 | 7 | .large { 8 | font-size: 17px; 9 | } 10 | .small { 11 | font-size: 13px; 12 | } 13 | 14 | .fa-circle { 15 | position: relative; 16 | top: 2px; 17 | } 18 | 19 | .float-left { 20 | margin-right: 10px; 21 | } 22 | 23 | .radio-box, .check-box { 24 | width: 20px; 25 | height: 20px; 26 | } 27 | 28 | .check-box { 29 | border-radius: 2px; 30 | } 31 | 32 | &.active .fa-circle path { 33 | stroke: $blue !important; 34 | stroke-width: 50px; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/js/ui/LoadingButton/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Button} from 'reactstrap'; 3 | 4 | import './index.scss'; 5 | import {withTranslation} from "react-i18next"; 6 | import PropTypes from "prop-types"; 7 | 8 | const LoadingButton = ({t}) => ( 9 | 14 | ); 15 | 16 | LoadingButton.propTypes = { 17 | t: PropTypes.func 18 | }; 19 | 20 | export default withTranslation()(LoadingButton); 21 | -------------------------------------------------------------------------------- /src/js/ui/LoadingButton/index.scss: -------------------------------------------------------------------------------- 1 | .loading-button-spinner { 2 | width: 150px; 3 | height: 48px; 4 | 5 | .spinner-border { 6 | width: 22px; 7 | height: 22px; 8 | border-width: 0.2rem; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/js/ui/LoadingRectangle/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from "prop-types"; 3 | 4 | import './index.scss'; 5 | 6 | const LoadingRectangle = ({className}) => ( 7 | 8 | ); 9 | 10 | LoadingRectangle.propTypes = { 11 | className: PropTypes.string 12 | }; 13 | 14 | export default LoadingRectangle; 15 | -------------------------------------------------------------------------------- /src/js/ui/LoadingRectangle/index.scss: -------------------------------------------------------------------------------- 1 | .loading-gradient { 2 | display: inline-block; 3 | height: 22px; 4 | width: 95px; 5 | border-radius: 11px; 6 | animation-duration: 1.5s; 7 | animation-fill-mode: forwards; 8 | animation-iteration-count: infinite; 9 | animation-name: placeHolderShimmer; 10 | animation-timing-function: linear; 11 | background: #f6f7f8; 12 | background: linear-gradient(to right, #EDEDED 8%, #DFE0DF 38%, #EDEDED 54%); 13 | background-size: 1000px 640px; 14 | position: relative; 15 | } 16 | 17 | @keyframes placeHolderShimmer{ 18 | 0%{ 19 | background-position: -468px 0 20 | } 21 | 100%{ 22 | background-position: 468px 0 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/js/ui/LogoCircle/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import './index.scss'; 5 | 6 | const LogoCircle = ({children}) => ( 7 |

{children}

8 | ); 9 | 10 | LogoCircle.propTypes = { 11 | children: PropTypes.string 12 | }; 13 | 14 | export default LogoCircle; 15 | -------------------------------------------------------------------------------- /src/js/ui/LogoCircle/index.scss: -------------------------------------------------------------------------------- 1 | $logo-size: 64px; 2 | .logo-circle { 3 | width: $logo-size; 4 | height: $logo-size; 5 | line-height: $logo-size; 6 | font-size: 28px; 7 | color: white; 8 | font-weight: bold; 9 | } 10 | -------------------------------------------------------------------------------- /src/js/ui/RatingIcon/index.jsx: -------------------------------------------------------------------------------- 1 | import React, {Fragment} from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; 4 | import {faThumbsDown, faThumbsUp} from "@fortawesome/free-solid-svg-icons"; 5 | import classnames from 'classnames'; 6 | 7 | const RatingIcon = ({isPositiveRating, onClick, isRated, size, className}) => ( 8 | 9 | {isPositiveRating && } 13 | 14 | {!isPositiveRating && } 18 | 19 | ); 20 | 21 | RatingIcon.propTypes = { 22 | isPositiveRating: PropTypes.bool, 23 | isRated: PropTypes.bool, 24 | onClick: PropTypes.func, 25 | size: PropTypes.string, 26 | className: PropTypes.string 27 | }; 28 | 29 | export default RatingIcon; 30 | -------------------------------------------------------------------------------- /src/js/ui/TxHash/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from 'prop-types'; 3 | import {getNetwork} from "../../features/network/selectors"; 4 | import {connect} from "react-redux"; 5 | 6 | const etherScanUrls = { 7 | 1: 'https://etherscan.io/tx/', 8 | 3: 'https://ropsten.etherscan.io/tx/', 9 | 4: 'https://rinkeby.etherscan.io/tx/', 10 | 5: 'https://goerli.etherscan.io/tx/', 11 | 42: 'https://kovan.etherscan.io/tx/', 12 | 401697: 'https://tobalaba.etherscan.com/tx/' 13 | }; 14 | 15 | const TxHash = ({value, network}) => { 16 | if (!network || (!network.id && network.id !== 0) || !etherScanUrls[network.id]) { 17 | return value; 18 | } 19 | 20 | return ({value}); 21 | }; 22 | 23 | TxHash.propTypes = { 24 | value: PropTypes.string, 25 | network: PropTypes.object 26 | }; 27 | 28 | const mapStateToProps = state => ({ 29 | network: getNetwork(state) 30 | }); 31 | 32 | export default connect( 33 | mapStateToProps 34 | )(TxHash); 35 | -------------------------------------------------------------------------------- /src/js/utils/address.js: -------------------------------------------------------------------------------- 1 | /* global web3 */ 2 | 3 | export function compactAddress(addr, numberOfChars) { 4 | 5 | if(addr.length <= 5 + (numberOfChars * 2)){ // 5 represents these chars 0x... 6 | return addr; 7 | } 8 | 9 | return addr.substring(0, 2 + numberOfChars) + "..." + addr.substring(addr.length - numberOfChars); 10 | } 11 | 12 | export const zeroAddress = '0x0000000000000000000000000000000000000000'; 13 | 14 | export const zeroBytes = zeroAddress + '000000000000000000000000'; 15 | 16 | export const contactCodeRegExp = /^0x[0-9a-fA-F]{130}$/; 17 | 18 | export const toChecksumAddress = (address) => { 19 | return web3.utils.toChecksumAddress(address); 20 | }; 21 | 22 | export const addressCompare = (address1, address2) => { 23 | if(!address1 || !address2) return false; 24 | return toChecksumAddress(address1) === toChecksumAddress(address2); 25 | }; 26 | -------------------------------------------------------------------------------- /src/js/utils/images.js: -------------------------------------------------------------------------------- 1 | const genericImage = require(`./../../../node_modules/cryptocurrency-icons/svg/color/generic.svg`); 2 | 3 | export function getTokenImage(token) { 4 | if (!token) { 5 | return genericImage; 6 | } 7 | try { 8 | return require(`./../../../node_modules/cryptocurrency-icons/svg/color/${token.toLowerCase()}.svg`); 9 | } catch (_e) { 10 | return genericImage; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/js/utils/transaction.js: -------------------------------------------------------------------------------- 1 | /* global web3 */ 2 | 3 | export const States = { 4 | none: 'none', 5 | pending: 'pending', 6 | success: 'success', 7 | failed: 'failed' 8 | }; 9 | 10 | export const calculateEscrowPrice = (escrow, prices) => { 11 | if (!prices || prices.error || !prices[escrow.token.symbol]) { 12 | return -1; 13 | } 14 | return prices[escrow.token.symbol][escrow.currency] * ((100 + (parseFloat(escrow.margin))) / 100); 15 | }; 16 | 17 | export const checkNotEnoughETH = (gasPrice, ethBalance) => { 18 | const toBN = web3.utils.toBN; 19 | const relayGasPrice = toBN(gasPrice || '0').mul(toBN(120)).div(toBN(100)); // 120%. toBN doesnt like decimals? 20 | return toBN(web3.utils.toWei(ethBalance || '0', 'ether')).lt(toBN(600000).mul(relayGasPrice)); // only allow ETH if less than 500000*gasPrice 21 | }; 22 | 23 | export const filterValidGaslessOffers = (offers, noBalance) => { 24 | return noBalance ? offers.filter(x => ['ETH', 'SNT'].indexOf(x.token.symbol) > -1) : offers; 25 | }; 26 | -------------------------------------------------------------------------------- /src/js/wizards/Buy/0_Trade/components/index.scss: -------------------------------------------------------------------------------- 1 | .offerTrade { 2 | h3 { 3 | font-size: 15px; 4 | font-weight: normal; 5 | } 6 | 7 | .name { 8 | font-size: 17px; 9 | font-weight: 500; 10 | } 11 | 12 | .limits { 13 | font-size: 12px; 14 | } 15 | 16 | .seller-info, .reputation { 17 | font-size: 15px; 18 | } 19 | 20 | .reputation { 21 | font-weight: 500; 22 | } 23 | 24 | .info-btn { 25 | padding: 0 3px 2px 3px; 26 | } 27 | 28 | .arbitrator-info { 29 | font-size: 12px; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/js/wizards/Buy/2_ConfirmTrade/index.scss: -------------------------------------------------------------------------------- 1 | .confirmTrade { 2 | h3 { 3 | font-size: 15px; 4 | } 5 | 6 | .addr { 7 | font-size: 12px; 8 | } 9 | } -------------------------------------------------------------------------------- /src/js/wizards/Sell/0_Asset/components/SellerAssets.scss: -------------------------------------------------------------------------------- 1 | .asset-list { 2 | .asset-image { 3 | width: 40px; 4 | height: 40px; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/js/wizards/Sell/1_PaymentMethods/components/SellerPaymentMethod.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import SellerPaymentMethod from "./SellerPaymentMethod"; 5 | 6 | describe('SellerPaymentMethod', () => { 7 | it('should render correctly', () => { 8 | const component = shallow( undefined} selectedMethods={[]}/>); 9 | 10 | expect(component).toMatchSnapshot(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/js/wizards/Sell/2_Currency/components/FiatSelectorForm.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import FiatSelectorForm from "./FiatSelectorForm"; 5 | 6 | describe('FiatSelectorForm', () => { 7 | it('should render correctly', () => { 8 | const component = shallow( undefined}/>); 11 | 12 | expect(component).toMatchSnapshot(); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /src/js/wizards/Sell/6_Margin/components/MarginSelectorForm.scss: -------------------------------------------------------------------------------- 1 | @import "../../../../../css/variable-overrides"; 2 | $slider-height: 10px; 3 | 4 | .rc-slider { 5 | .rc-slider-rail { 6 | height: $slider-height; 7 | background-color: $secondary; 8 | } 9 | 10 | .rc-slider-track { 11 | height: $slider-height; 12 | background-color: $primary; 13 | } 14 | 15 | .rc-slider-handle{ 16 | height: 30px; 17 | width: 30px; 18 | margin-top: -11px; 19 | border-color: $primary; 20 | } 21 | } 22 | 23 | .margin-input { 24 | .input-group-append { 25 | width: 52px; 26 | } 27 | } 28 | @media screen and (max-width: 450px) { 29 | .margin-input { 30 | .form-control { 31 | padding: 0.375rem 0.75rem; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/js/wizards/Sell/6_Margin/components/MarginSelectorForm.test.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { shallow } from "enzyme"; 3 | 4 | import MarginSelectorForm from "./MarginSelectorForm"; 5 | 6 | describe('MarginSelectorForm', () => { 7 | it('should render correctly', () => { 8 | const component = shallow( undefined} 15 | onMarginChange={() => undefined}/>); 16 | 17 | expect(component).toMatchSnapshot(); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/js/wizards/Sell/6_Margin/index.scss: -------------------------------------------------------------------------------- 1 | .marginSelector button { 2 | font-size: 16px; 3 | } 4 | -------------------------------------------------------------------------------- /src/js/wizards/Sell/7_Limits/components/Success.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import successImage from '../../../../../images/success.png'; 3 | import {Button} from 'reactstrap'; 4 | import PropTypes from 'prop-types'; 5 | 6 | const Success = ({onClick}) => ( 7 |
8 | Success 9 |

Your offer has been successfully published

10 |

11 | 12 |

13 |
14 | ); 15 | 16 | Success.propTypes = { 17 | onClick: PropTypes.func 18 | }; 19 | 20 | export default Success; 21 | -------------------------------------------------------------------------------- /src/js/wizards/Sell/7_Limits/index.scss: -------------------------------------------------------------------------------- 1 | .disabled-limits { 2 | opacity: 0.4; 3 | } 4 | -------------------------------------------------------------------------------- /src/js/wizards/Sell/8_Summary/components/FinalModal.scss: -------------------------------------------------------------------------------- 1 | .final-step-modal { 2 | .modal-content { 3 | padding-top: 25px; 4 | padding-bottom: 25px; 5 | 6 | .bottom-details { 7 | .row { 8 | line-height: 33px; 9 | margin-top: 20px; 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/js/wizards/Sell/8_Summary/components/SellSummary.scss: -------------------------------------------------------------------------------- 1 | .offer-summary { 2 | .line-title { 3 | font-size: 15px; 4 | } 5 | 6 | .line-text { 7 | font-weight: 500; 8 | } 9 | 10 | .token-img { 11 | width: 24px; 12 | height: 24px; 13 | } 14 | 15 | .line-text-asset { 16 | position: relative; 17 | top: 2px; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/js/wizards/hoc/withFooter.scss: -------------------------------------------------------------------------------- 1 | @import "../../../css/variable-overrides"; 2 | 3 | $footer-btn-height: 44px; 4 | $footer-padding: 16px; 5 | $footer-height: $footer-btn-height + $footer-padding * 2; 6 | 7 | .container { 8 | position: relative; 9 | padding-bottom: $footer-height + 10px !important; 10 | min-height: 100%; 11 | 12 | .wizard-container { 13 | align-items: flex-start; 14 | 15 | .footer { 16 | right: 0; 17 | bottom: 0; 18 | left: 0; 19 | height: $footer-height; 20 | max-width: $content-width; 21 | margin: 0 auto; 22 | position: fixed; 23 | z-index: 1000; 24 | padding: $footer-padding; 25 | 26 | @media screen and (min-width: map-get($grid-breakpoints, "md")) { 27 | position: sticky; 28 | width: 100%; 29 | padding: $footer-padding 0; 30 | z-index: auto; 31 | } 32 | 33 | .btn { 34 | width: 100%; 35 | height: $footer-btn-height; 36 | } 37 | 38 | .footer-arrow { 39 | position: relative; 40 | bottom: 1px; 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /stories/components/confirmDialog.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | import { withKnobs, text, boolean } from '@storybook/addon-knobs'; 6 | import {action} from "@storybook/addon-actions"; 7 | 8 | import ConfirmDialog from '../../src/js/components/ConfirmDialog'; 9 | 10 | storiesOf('Components/ConfirmDialog', module) 11 | .addDecorator(withKnobs) 12 | .add( 13 | "Default", 14 | withInfo({inline: true})(() => ( 15 | 21 | )) 22 | ); 23 | -------------------------------------------------------------------------------- /stories/components/errorInformation.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | import {withKnobs} from '@storybook/addon-knobs'; 6 | import {action} from '@storybook/addon-actions'; 7 | 8 | import ErrorInformation from '../../src/js/components/ErrorInformation'; 9 | 10 | storiesOf('Components/ErrorInformation', module) 11 | .addDecorator(withKnobs) 12 | .add( 13 | "provider", 14 | withInfo({inline: true})(() => ( 15 | 16 | )) 17 | ) 18 | .add( 19 | "network", 20 | withInfo({inline: true})(() => ( 21 | 22 | )) 23 | ) 24 | .add( 25 | "transaction", 26 | withInfo({inline: true})(() => ( 27 | 28 | )) 29 | ); 30 | 31 | -------------------------------------------------------------------------------- /stories/components/loading.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | 6 | import Loading from '../../src/js/components/Loading'; 7 | 8 | storiesOf('Components/Loading', module) 9 | .add( 10 | "Mining", 11 | withInfo({inline: true})(() => ( 12 | 13 | )) 14 | ) 15 | .add( 16 | "Mining + Hash", 17 | withInfo({inline: true})(() => ( 18 | 19 | )) 20 | ) 21 | .add( 22 | "Page", 23 | withInfo({inline: true})(() => ( 24 | 25 | )) 26 | ) 27 | .add( 28 | "Initial", 29 | withInfo({inline: true})(() => ( 30 | 31 | )) 32 | ); 33 | -------------------------------------------------------------------------------- /stories/components/map.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { storiesOf } from '@storybook/react'; 4 | import { withInfo } from "@storybook/addon-info"; 5 | 6 | import Map, { Map as MapWrapped } from '../../src/js/components/Map'; 7 | 8 | const info = {inline: true, propTables: [MapWrapped]}; 9 | 10 | const defaultCoords = { 11 | latitude: 45.492611, 12 | longitude: -73.617959 13 | }; 14 | 15 | storiesOf('Components/Map', module) 16 | .add( 17 | "With Coords", 18 | withInfo(info)(() => ( 19 | 20 | )) 21 | ).add( 22 | "When access denied", 23 | withInfo(info)(() => ( 24 | 25 | )) 26 | ).add( 27 | "With errors", 28 | withInfo(info)(() => ( 29 | 30 | )) 31 | ); 32 | -------------------------------------------------------------------------------- /stories/components/mining.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | 6 | import Mining from '../../src/js/pages/Escrow/components/Mining'; 7 | 8 | storiesOf('Components/Mining', module) 9 | .add( 10 | "Mining", 11 | withInfo({inline: true})(() => ( 12 | 13 | )) 14 | ) 15 | .add( 16 | "Mining + Hash", 17 | withInfo({inline: true})(() => ( 18 | 19 | )) 20 | ); 21 | -------------------------------------------------------------------------------- /stories/components/notFound.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | import {withKnobs} from '@storybook/addon-knobs'; 6 | import {action} from '@storybook/addon-actions'; 7 | 8 | import FourOrFour from '../../src/js/components/ErrorInformation/404'; 9 | 10 | storiesOf('Components/ErrorInformation', module) 11 | .addDecorator(withKnobs) 12 | .add( 13 | "404", 14 | withInfo({inline: true})(() => ( 15 |
16 | 17 |
18 | )) 19 | ); 20 | 21 | -------------------------------------------------------------------------------- /stories/components/reputation.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | import {action} from "@storybook/addon-actions"; 6 | 7 | import Reputation from '../../src/js/components/Reputation'; 8 | 9 | storiesOf('Components/Reputation', module) 10 | .add( 11 | "Default", 12 | withInfo({inline: true})(() => ( 13 | 14 | )) 15 | ) 16 | .add( 17 | "Small", 18 | withInfo({inline: true})(() => ( 19 | 20 | )) 21 | ) 22 | .add( 23 | "After trade", 24 | withInfo({inline: true})(() => ( 25 | 26 | )) 27 | ) 28 | .add( 29 | "After trade rated", 30 | withInfo({inline: true})(() => ( 31 | 32 | )) 33 | ); 34 | 35 | -------------------------------------------------------------------------------- /stories/components/userInformation.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | import { withKnobs, text, boolean } from '@storybook/addon-knobs'; 6 | 7 | import UserInformation from '../../src/js/components/UserInformation'; 8 | import Address from '../../src/js/components/UserInformation/Address'; 9 | 10 | storiesOf('Components/UserInformation', module) 11 | .addDecorator(withKnobs) 12 | .add( 13 | "Default", 14 | withInfo({inline: true})(() => ( 15 | 16 | )) 17 | ) 18 | .add( 19 | "Address", 20 | withInfo({inline: true})(() => ( 21 |
22 | )) 23 | ) 24 | .add( 25 | "Address Compact", 26 | withInfo({inline: true})(() => ( 27 |
28 | )) 29 | ); 30 | -------------------------------------------------------------------------------- /stories/pages/editMyContact.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | import {withKnobs, boolean} from '@storybook/addon-knobs'; 6 | import {action} from "@storybook/addon-actions"; 7 | 8 | import UpdateButton from '../../src/js/pages/EditMyContact/components/UpdateButton'; 9 | 10 | storiesOf('Pages/EditMyContact', module) 11 | .addDecorator(withKnobs) 12 | .add( 13 | "Update Button", 14 | withInfo({inline: true})(() => ( 15 | 16 | )) 17 | ); 18 | -------------------------------------------------------------------------------- /stories/pages/license.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | import {withKnobs, boolean, text} from '@storybook/addon-knobs'; 6 | import {action} from "@storybook/addon-actions"; 7 | 8 | import BuyButton from '../../src/js/pages/License/components/BuyButton'; 9 | import Info from '../../src/js/pages/License/components/Info'; 10 | import Balance from '../../src/js/pages/License/components/Balance'; 11 | 12 | storiesOf('Pages/License', module) 13 | .addDecorator(withKnobs) 14 | .add( 15 | "Buy Button", 16 | withInfo({inline: true})(() => ( 17 | 18 | )) 19 | ) 20 | .add( 21 | "Info", 22 | withInfo({inline: true})(() => ( 23 | 24 | )) 25 | ) 26 | .add( 27 | "Balance", 28 | withInfo({inline: true})(() => ( 29 | 30 | )) 31 | ); 32 | -------------------------------------------------------------------------------- /stories/ui/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/stories/ui/.gitkeep -------------------------------------------------------------------------------- /stories/wizards/Sell/0_asset.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | import {action} from "@storybook/addon-actions"; 6 | 7 | import SellerAssets from '../../../src/js/wizards/Sell/0_Asset/components/SellerAssets'; 8 | 9 | storiesOf('Wizards/Sell/0_Asset', module) 10 | .add( 11 | "No Asset Selected", 12 | withInfo({inline: true})(() => ( 13 | 14 | )) 15 | ) 16 | .add( 17 | "Asset Selected", 18 | withInfo({inline: true})(() => ( 19 | 20 | )) 21 | ); 22 | -------------------------------------------------------------------------------- /stories/wizards/Sell/1_location.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | import {action} from "@storybook/addon-actions"; 6 | 7 | import SellerPosition from '../../../src/js/components/EditLocation/SellerPosition'; 8 | 9 | storiesOf('Wizards/Sell/3_Location', module) 10 | .add( 11 | "Without default location", 12 | withInfo({inline: true})(() => ( 13 | 14 | )) 15 | ) 16 | .add( 17 | "With default location", 18 | withInfo({inline: true})(() => ( 19 | 20 | )) 21 | ); 22 | -------------------------------------------------------------------------------- /stories/wizards/Sell/2_paymentMethods.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | import {action} from "@storybook/addon-actions"; 6 | 7 | import SellerPaymentMethod from '../../../src/js/wizards/Sell/1_PaymentMethods/components/SellerPaymentMethod'; 8 | 9 | const methods = ['Cash (In person)', 'Bank Transfer', 'International wire']; 10 | 11 | storiesOf('Wizards/Sell/1_PaymentMethods', module) 12 | .add( 13 | "Not Selected", 14 | withInfo({inline: true})(() => ( 15 | 16 | )) 17 | ) 18 | .add( 19 | "Selected", 20 | withInfo({inline: true})(() => ( 21 | 22 | )) 23 | ); 24 | -------------------------------------------------------------------------------- /stories/wizards/Sell/3_currency.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | import {action} from "@storybook/addon-actions"; 6 | 7 | import FiatSelectorForm from '../../../src/js/wizards/Sell/2_Currency/components/FiatSelectorForm'; 8 | 9 | const CURRENCY_DATA = [ 10 | {id: 'USD', label: 'United States Dollar - USD'}, 11 | {id: 'EUR', label: 'Euro - EUR'}, 12 | {id: 'GBP', label: 'Pound sterling - GBP'}, 13 | {id: 'JPY', label: 'Japanese Yen - JPY'}, 14 | {id: 'CNY', label: 'Chinese Yuan - CNY'}, 15 | {id: 'KRW', label: 'South Korean Won - KRW'} 16 | ]; 17 | 18 | storiesOf('Wizards/Sell/4_Currency', module) 19 | .add( 20 | "Not Selected", 21 | withInfo({inline: true})(() => ( 22 | 23 | )) 24 | ) 25 | .add( 26 | "Selected", 27 | withInfo({inline: true})(() => ( 28 | 29 | )) 30 | ); 31 | -------------------------------------------------------------------------------- /stories/wizards/Sell/4_margin.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {storiesOf} from '@storybook/react'; 4 | import {withInfo} from "@storybook/addon-info"; 5 | import {action} from "@storybook/addon-actions"; 6 | 7 | import MarginSelectorForm from '../../../src/js/wizards/Sell/6_Margin/components/MarginSelectorForm'; 8 | 9 | storiesOf('Wizards/Sell/6_Margin', module) 10 | .add( 11 | "Default", 12 | withInfo({inline: true})(() => ( 13 | 18 | )) 19 | ); 20 | -------------------------------------------------------------------------------- /teller-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/status-im/status-teller-network/b72ed063404da276db24a180ad47d2f4bb917438/teller-logo.png --------------------------------------------------------------------------------