├── .watchmanconfig
├── .gitattributes
├── ios
├── .bundle
│ └── config
├── mobidex
│ ├── Images.xcassets
│ │ ├── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── mobidex-120.png
│ │ │ ├── mobidex-121.png
│ │ │ ├── mobidex-180.png
│ │ │ ├── mobidex-40.png
│ │ │ ├── mobidex-58.png
│ │ │ ├── mobidex-60.png
│ │ │ ├── mobidex-80.png
│ │ │ ├── mobidex-87.png
│ │ │ ├── logo-with-text-1024.png
│ │ │ └── Contents.json
│ │ ├── logo-with-text-300x115.imageset
│ │ │ ├── logo-with-text-300x115.png
│ │ │ └── Contents.json
│ │ ├── logo-with-text-beta-green.imageset
│ │ │ ├── logo-with-text-beta-green.png
│ │ │ └── Contents.json
│ │ └── logo-with-alpha-red-bold-300.imageset
│ │ │ ├── logo-with-alpha-red-bold-300.png
│ │ │ └── Contents.json
│ ├── Entitlements.pinfo
│ ├── main.m
│ ├── AppDelegate.h
│ └── AppDelegate.m
├── mobidex-Bridging-Header.h
├── Gemfile
├── mobidex.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
├── mobidexTests
│ └── Info.plist
├── Web3+Sign.swift
├── BitskiManagerBridge.m
├── Bitski.podspec.json
├── WalletManagerBridge.m
├── Device.swift
└── Web3.podspec.json
├── app.json
├── lib
├── decorators
│ └── cls
│ │ ├── index.js
│ │ └── timing.js
├── utils
│ ├── index.js
│ ├── token.js
│ ├── ethereum.js
│ └── cache.js
├── middleware
│ └── app.js
└── stores
│ └── app.js
├── images
├── tokens
│ ├── AE.png
│ ├── CL.png
│ ├── ABT.png
│ ├── AGI.png
│ ├── AION.png
│ ├── AIR.png
│ ├── AIX.png
│ ├── ANT.png
│ ├── ARN.png
│ ├── ART.png
│ ├── AST.png
│ ├── AUC.png
│ ├── BAT.png
│ ├── BAX.png
│ ├── BCDT.png
│ ├── BEE.png
│ ├── BLT.png
│ ├── BLZ.png
│ ├── BNT.png
│ ├── BNTY.png
│ ├── CAG.png
│ ├── CAN.png
│ ├── CAT.png
│ ├── CBT.png
│ ├── CDT.png
│ ├── CFI.png
│ ├── CND.png
│ ├── CRED.png
│ ├── CVC.png
│ ├── CVT.png
│ ├── DAI.png
│ ├── DALA.png
│ ├── DATA.png
│ ├── DCL.png
│ ├── DENT.png
│ ├── DFS.png
│ ├── DGD.png
│ ├── DGPT.png
│ ├── DNT.png
│ ├── DOV.png
│ ├── DPP.png
│ ├── DRT.png
│ ├── DXT.png
│ ├── EBTC.png
│ ├── ELF.png
│ ├── ENO.png
│ ├── ETH.png
│ ├── EUSD.png
│ ├── EVC.png
│ ├── EVE.png
│ ├── FDX.png
│ ├── FLIP.png
│ ├── FLLW.png
│ ├── FND.png
│ ├── FUEL.png
│ ├── FUN.png
│ ├── FYN.png
│ ├── GET.png
│ ├── GNO.png
│ ├── GNT.png
│ ├── GOAL.png
│ ├── GRID.png
│ ├── GUP.png
│ ├── HAV.png
│ ├── HGT.png
│ ├── HIRE.png
│ ├── HST.png
│ ├── ICX.png
│ ├── IFT.png
│ ├── INS.png
│ ├── INXT.png
│ ├── IOST.png
│ ├── JNT.png
│ ├── KICK.png
│ ├── KNC.png
│ ├── LEND.png
│ ├── LINK.png
│ ├── LNK.png
│ ├── LOC.png
│ ├── LOOM.png
│ ├── MANA.png
│ ├── MBRS.png
│ ├── MKR.png
│ ├── MLN.png
│ ├── MTL.png
│ ├── MWAT.png
│ ├── NEWB.png
│ ├── NMR.png
│ ├── NVT.png
│ ├── OMG.png
│ ├── PAX.png
│ ├── PCL.png
│ ├── PLU.png
│ ├── POE.png
│ ├── POLY.png
│ ├── POW.png
│ ├── POWR.png
│ ├── PTOY.png
│ ├── QSP.png
│ ├── QVT.png
│ ├── RCN.png
│ ├── RDN.png
│ ├── REAL.png
│ ├── REN.png
│ ├── REP.png
│ ├── REQ.png
│ ├── RHOC.png
│ ├── RKT.png
│ ├── RLC.png
│ ├── RVT.png
│ ├── SALT.png
│ ├── SHP.png
│ ├── SNIP.png
│ ├── SNM.png
│ ├── SNOV.png
│ ├── SNT.png
│ ├── STAC.png
│ ├── STU.png
│ ├── SUB.png
│ ├── TAU.png
│ ├── TIX.png
│ ├── TUSD.png
│ ├── UFR.png
│ ├── UKG.png
│ ├── USDC.png
│ ├── VEE.png
│ ├── VIT.png
│ ├── WAND.png
│ ├── WAX.png
│ ├── WBTC.png
│ ├── WETH.png
│ ├── WLK.png
│ ├── WYS.png
│ ├── XAUR.png
│ ├── XGM.png
│ ├── XRL.png
│ ├── XSC.png
│ ├── ZAP.png
│ ├── ZIL.png
│ ├── ZRX.png
│ ├── BERRY.png
│ ├── EMONT.png
│ ├── ENTRP.png
│ ├── ETHOS.png
│ ├── GOLDX.png
│ ├── SPANK.png
│ ├── STORJ.png
│ ├── STORM.png
│ ├── THETA.png
│ └── ZAPIT.png
├── previews
│ ├── android
│ │ ├── send.png
│ │ ├── history.png
│ │ ├── receive.png
│ │ ├── trade.png
│ │ ├── wallet.png
│ │ ├── my-orders.png
│ │ ├── fill-orders.png
│ │ ├── limit-order.png
│ │ └── product-details.png
│ ├── ios
│ │ ├── product-5.5.png
│ │ ├── product-5.8.png
│ │ ├── product-12.9.png
│ │ ├── products-12.9.png
│ │ ├── products-5.5.png
│ │ ├── products-5.8.png
│ │ ├── limit-order-12.9.png
│ │ ├── limit-order-5.5.png
│ │ ├── limit-order-5.8.png
│ │ └── multiple-large.png
│ └── animated
│ │ └── 10-06-2018T13-57-49.gif
├── logo-circle
│ ├── mobidex-144.png
│ ├── mobidex-48.png
│ ├── mobidex-72.png
│ └── mobidex-96.png
├── logo-without-text
│ ├── mobidex-120.png
│ ├── mobidex-144.png
│ ├── mobidex-148.png
│ ├── mobidex-152.png
│ ├── mobidex-167.png
│ ├── mobidex-180.png
│ ├── mobidex-192.png
│ ├── mobidex-20.png
│ ├── mobidex-29.png
│ ├── mobidex-36.png
│ ├── mobidex-40.png
│ ├── mobidex-48.png
│ ├── mobidex-512.png
│ ├── mobidex-58.png
│ ├── mobidex-60.png
│ ├── mobidex-72.png
│ ├── mobidex-76.png
│ ├── mobidex-80.png
│ ├── mobidex-87.png
│ ├── mobidex-96.png
│ └── mobidex-83.5.png
└── logo-with-text
│ ├── logo-with-text-1024.png
│ ├── logo-with-text-1024x500.png
│ ├── logo-with-text-300x115.png
│ ├── logo-with-text-beta-green.png
│ ├── logo-with-text-transparent.png
│ ├── logo-with-alpha-red-bold-300.png
│ └── logo-with-text-alpha-red-bold2.png
├── FAQ.md
├── thunks
├── index.js
└── settings.js
├── navigation
├── index.js
├── headers.js
├── context.js
└── permissions.js
├── android
├── app
│ ├── src
│ │ └── main
│ │ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── colors.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── drawable
│ │ │ │ ├── logo.png
│ │ │ │ └── launch_screen.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── mobidex.png
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── mobidex.png
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── mobidex.png
│ │ │ │ └── ic_launcher.png
│ │ │ └── mipmap-xxhdpi
│ │ │ │ ├── mobidex.png
│ │ │ │ └── ic_launcher.png
│ │ │ ├── assets
│ │ │ └── fonts
│ │ │ │ ├── Entypo.ttf
│ │ │ │ ├── Feather.ttf
│ │ │ │ ├── Zocial.ttf
│ │ │ │ ├── AntDesign.ttf
│ │ │ │ ├── EvilIcons.ttf
│ │ │ │ ├── Fontisto.ttf
│ │ │ │ ├── Ionicons.ttf
│ │ │ │ ├── Octicons.ttf
│ │ │ │ ├── FontAwesome.ttf
│ │ │ │ ├── Foundation.ttf
│ │ │ │ ├── MaterialIcons.ttf
│ │ │ │ ├── SimpleLineIcons.ttf
│ │ │ │ ├── FontAwesome5_Brands.ttf
│ │ │ │ ├── FontAwesome5_Solid.ttf
│ │ │ │ ├── FontAwesome5_Regular.ttf
│ │ │ │ └── MaterialCommunityIcons.ttf
│ │ │ ├── java
│ │ │ └── io
│ │ │ │ └── mobidex
│ │ │ │ ├── WalletManagerPackage.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── WalletManager.kt
│ │ │ │ └── MainApplication.java
│ │ │ └── AndroidManifest.xml
│ ├── proguard-rules.pro
│ ├── build_defs.bzl
│ └── BUCK
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradle.properties
└── settings.gradle
├── constants
├── uniswap.js
├── actions.js
└── index.js
├── patches
├── whatwg-fetch.sh
├── isomorphic-fetch.sh
├── ethers.sh
├── web3.sh
├── whatwg-fetch.js
├── isomorphic-fetch.js
├── web3.js
├── ethers.js
├── zeroex-exchange-bug.sh
└── zeroex-exchange-bug.js
├── .buckconfig
├── .prettierrc.js
├── rn-cli.config.js
├── types
└── props
│ ├── bignumber.js
│ ├── token.js
│ ├── index.js
│ ├── navigation.js
│ ├── asset.js
│ ├── product.js
│ ├── styles.js
│ ├── asset-data.js
│ ├── address.js
│ └── transaction.js
├── App
├── components
│ ├── MaxButton.js
│ ├── Row.js
│ ├── MutedText.js
│ ├── Divider.js
│ ├── Text.js
│ ├── HorizontalPadding.js
│ ├── VerticalPadding.js
│ ├── MajorText.js
│ ├── BigCenter.js
│ ├── FormattedPercent.js
│ ├── AssetIcon.js
│ ├── FormattedSymbol.js
│ ├── EmptyList.js
│ ├── TouchableInputTokenAmount.js
│ ├── TokenAmount.js
│ ├── MajorTextWithVectorIcon.js
│ ├── Col.js
│ ├── AddressText.js
│ ├── Button.js
│ ├── TouchableListItem.js
│ ├── EthereumAmount.js
│ ├── RotatingView.js
│ ├── ReferralCodeInput.js
│ ├── SmallClearButton.js
│ ├── UserIcon.js
│ ├── Tabs.js
│ ├── MnemonicWordInput.js
│ ├── BlinkingCursor.js
│ └── AddressInput.js
├── modals
│ ├── SendModal
│ │ └── index.js
│ ├── ActionModal
│ │ ├── index.js
│ │ └── base.js
│ ├── SelectModal
│ │ ├── index.js
│ │ └── Option.js
│ ├── ErrorModal
│ │ ├── index.js
│ │ ├── AssetBuyerError.js
│ │ ├── InsufficientFundsError.js
│ │ └── TokenError.js
│ ├── ReceiveModal
│ │ └── index.js
│ ├── ConfirmationModal
│ │ └── index.js
│ ├── NotificationModal
│ │ ├── index.js
│ │ └── base.js
│ ├── UnlockAndSignModal
│ │ ├── index.js
│ │ └── UnlockWithPin.js
│ └── LoadingModal.js
├── screens
│ ├── onboarding
│ │ ├── PinScreen
│ │ │ └── index.js
│ │ ├── IntroScreen
│ │ │ └── index.js
│ │ ├── BitskiLogin
│ │ │ └── index.js
│ │ ├── ImportMnemonicScreen
│ │ │ └── index.js
│ │ └── PreviewMnemonicScreen
│ │ │ └── index.js
│ └── trade
│ │ ├── DetailsScreen
│ │ ├── EmptyWallet.js
│ │ ├── base.js
│ │ ├── UnwrapConfirmation.js
│ │ ├── UnlockTokenNotice.js
│ │ ├── UnlockConfirmation.js
│ │ ├── index.js
│ │ └── EthereumDetails.js
│ │ └── ProductScreen
│ │ ├── base.js
│ │ └── index.js
├── views
│ ├── Loading.js
│ └── NotificationView.js
├── hoc
│ ├── uniswap
│ │ ├── FactoryContract.js
│ │ └── TradeDetails.js
│ └── ethereum
│ │ └── Balance.js
├── layouts
│ └── ConfirmationLayout.js
└── NavigationProvider.js
├── reducers
├── error.js
├── device.js
├── index.js
├── bitski.js
└── wallet.js
├── services
├── BaseService.js
├── NavigationService.js
├── GasService.js
├── AssetService.js
├── UniswapService.js
└── TransactionService.js
├── babel.config.js
├── .github
└── ISSUE_TEMPLATE
│ ├── bug.md
│ └── feature_request.md
├── metro.config.js
├── .eslintrc.js
├── actions
└── index.js
├── clients
├── EtherChainGasPriceOracle.js
├── Uniswap.js
├── EthGasStationInfo.js
└── EtherToken.js
├── store.js
├── .gitignore
├── error-handlers.js
└── cli
└── build-android.sh
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
2 |
--------------------------------------------------------------------------------
/ios/.bundle/config:
--------------------------------------------------------------------------------
1 | ---
2 | BUNDLE_PATH: ".gems"
3 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mobidex",
3 | "displayName": "mobidex"
4 | }
--------------------------------------------------------------------------------
/lib/decorators/cls/index.js:
--------------------------------------------------------------------------------
1 | export * from './cache';
2 | export * from './timing';
3 |
--------------------------------------------------------------------------------
/images/tokens/AE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/AE.png
--------------------------------------------------------------------------------
/images/tokens/CL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/CL.png
--------------------------------------------------------------------------------
/images/tokens/ABT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ABT.png
--------------------------------------------------------------------------------
/images/tokens/AGI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/AGI.png
--------------------------------------------------------------------------------
/images/tokens/AION.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/AION.png
--------------------------------------------------------------------------------
/images/tokens/AIR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/AIR.png
--------------------------------------------------------------------------------
/images/tokens/AIX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/AIX.png
--------------------------------------------------------------------------------
/images/tokens/ANT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ANT.png
--------------------------------------------------------------------------------
/images/tokens/ARN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ARN.png
--------------------------------------------------------------------------------
/images/tokens/ART.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ART.png
--------------------------------------------------------------------------------
/images/tokens/AST.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/AST.png
--------------------------------------------------------------------------------
/images/tokens/AUC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/AUC.png
--------------------------------------------------------------------------------
/images/tokens/BAT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/BAT.png
--------------------------------------------------------------------------------
/images/tokens/BAX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/BAX.png
--------------------------------------------------------------------------------
/images/tokens/BCDT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/BCDT.png
--------------------------------------------------------------------------------
/images/tokens/BEE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/BEE.png
--------------------------------------------------------------------------------
/images/tokens/BLT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/BLT.png
--------------------------------------------------------------------------------
/images/tokens/BLZ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/BLZ.png
--------------------------------------------------------------------------------
/images/tokens/BNT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/BNT.png
--------------------------------------------------------------------------------
/images/tokens/BNTY.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/BNTY.png
--------------------------------------------------------------------------------
/images/tokens/CAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/CAG.png
--------------------------------------------------------------------------------
/images/tokens/CAN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/CAN.png
--------------------------------------------------------------------------------
/images/tokens/CAT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/CAT.png
--------------------------------------------------------------------------------
/images/tokens/CBT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/CBT.png
--------------------------------------------------------------------------------
/images/tokens/CDT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/CDT.png
--------------------------------------------------------------------------------
/images/tokens/CFI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/CFI.png
--------------------------------------------------------------------------------
/images/tokens/CND.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/CND.png
--------------------------------------------------------------------------------
/images/tokens/CRED.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/CRED.png
--------------------------------------------------------------------------------
/images/tokens/CVC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/CVC.png
--------------------------------------------------------------------------------
/images/tokens/CVT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/CVT.png
--------------------------------------------------------------------------------
/images/tokens/DAI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/DAI.png
--------------------------------------------------------------------------------
/images/tokens/DALA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/DALA.png
--------------------------------------------------------------------------------
/images/tokens/DATA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/DATA.png
--------------------------------------------------------------------------------
/images/tokens/DCL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/DCL.png
--------------------------------------------------------------------------------
/images/tokens/DENT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/DENT.png
--------------------------------------------------------------------------------
/images/tokens/DFS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/DFS.png
--------------------------------------------------------------------------------
/images/tokens/DGD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/DGD.png
--------------------------------------------------------------------------------
/images/tokens/DGPT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/DGPT.png
--------------------------------------------------------------------------------
/images/tokens/DNT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/DNT.png
--------------------------------------------------------------------------------
/images/tokens/DOV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/DOV.png
--------------------------------------------------------------------------------
/images/tokens/DPP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/DPP.png
--------------------------------------------------------------------------------
/images/tokens/DRT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/DRT.png
--------------------------------------------------------------------------------
/images/tokens/DXT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/DXT.png
--------------------------------------------------------------------------------
/images/tokens/EBTC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/EBTC.png
--------------------------------------------------------------------------------
/images/tokens/ELF.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ELF.png
--------------------------------------------------------------------------------
/images/tokens/ENO.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ENO.png
--------------------------------------------------------------------------------
/images/tokens/ETH.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ETH.png
--------------------------------------------------------------------------------
/images/tokens/EUSD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/EUSD.png
--------------------------------------------------------------------------------
/images/tokens/EVC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/EVC.png
--------------------------------------------------------------------------------
/images/tokens/EVE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/EVE.png
--------------------------------------------------------------------------------
/images/tokens/FDX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/FDX.png
--------------------------------------------------------------------------------
/images/tokens/FLIP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/FLIP.png
--------------------------------------------------------------------------------
/images/tokens/FLLW.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/FLLW.png
--------------------------------------------------------------------------------
/images/tokens/FND.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/FND.png
--------------------------------------------------------------------------------
/images/tokens/FUEL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/FUEL.png
--------------------------------------------------------------------------------
/images/tokens/FUN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/FUN.png
--------------------------------------------------------------------------------
/images/tokens/FYN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/FYN.png
--------------------------------------------------------------------------------
/images/tokens/GET.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/GET.png
--------------------------------------------------------------------------------
/images/tokens/GNO.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/GNO.png
--------------------------------------------------------------------------------
/images/tokens/GNT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/GNT.png
--------------------------------------------------------------------------------
/images/tokens/GOAL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/GOAL.png
--------------------------------------------------------------------------------
/images/tokens/GRID.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/GRID.png
--------------------------------------------------------------------------------
/images/tokens/GUP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/GUP.png
--------------------------------------------------------------------------------
/images/tokens/HAV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/HAV.png
--------------------------------------------------------------------------------
/images/tokens/HGT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/HGT.png
--------------------------------------------------------------------------------
/images/tokens/HIRE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/HIRE.png
--------------------------------------------------------------------------------
/images/tokens/HST.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/HST.png
--------------------------------------------------------------------------------
/images/tokens/ICX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ICX.png
--------------------------------------------------------------------------------
/images/tokens/IFT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/IFT.png
--------------------------------------------------------------------------------
/images/tokens/INS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/INS.png
--------------------------------------------------------------------------------
/images/tokens/INXT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/INXT.png
--------------------------------------------------------------------------------
/images/tokens/IOST.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/IOST.png
--------------------------------------------------------------------------------
/images/tokens/JNT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/JNT.png
--------------------------------------------------------------------------------
/images/tokens/KICK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/KICK.png
--------------------------------------------------------------------------------
/images/tokens/KNC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/KNC.png
--------------------------------------------------------------------------------
/images/tokens/LEND.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/LEND.png
--------------------------------------------------------------------------------
/images/tokens/LINK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/LINK.png
--------------------------------------------------------------------------------
/images/tokens/LNK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/LNK.png
--------------------------------------------------------------------------------
/images/tokens/LOC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/LOC.png
--------------------------------------------------------------------------------
/images/tokens/LOOM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/LOOM.png
--------------------------------------------------------------------------------
/images/tokens/MANA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/MANA.png
--------------------------------------------------------------------------------
/images/tokens/MBRS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/MBRS.png
--------------------------------------------------------------------------------
/images/tokens/MKR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/MKR.png
--------------------------------------------------------------------------------
/images/tokens/MLN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/MLN.png
--------------------------------------------------------------------------------
/images/tokens/MTL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/MTL.png
--------------------------------------------------------------------------------
/images/tokens/MWAT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/MWAT.png
--------------------------------------------------------------------------------
/images/tokens/NEWB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/NEWB.png
--------------------------------------------------------------------------------
/images/tokens/NMR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/NMR.png
--------------------------------------------------------------------------------
/images/tokens/NVT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/NVT.png
--------------------------------------------------------------------------------
/images/tokens/OMG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/OMG.png
--------------------------------------------------------------------------------
/images/tokens/PAX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/PAX.png
--------------------------------------------------------------------------------
/images/tokens/PCL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/PCL.png
--------------------------------------------------------------------------------
/images/tokens/PLU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/PLU.png
--------------------------------------------------------------------------------
/images/tokens/POE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/POE.png
--------------------------------------------------------------------------------
/images/tokens/POLY.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/POLY.png
--------------------------------------------------------------------------------
/images/tokens/POW.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/POW.png
--------------------------------------------------------------------------------
/images/tokens/POWR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/POWR.png
--------------------------------------------------------------------------------
/images/tokens/PTOY.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/PTOY.png
--------------------------------------------------------------------------------
/images/tokens/QSP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/QSP.png
--------------------------------------------------------------------------------
/images/tokens/QVT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/QVT.png
--------------------------------------------------------------------------------
/images/tokens/RCN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/RCN.png
--------------------------------------------------------------------------------
/images/tokens/RDN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/RDN.png
--------------------------------------------------------------------------------
/images/tokens/REAL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/REAL.png
--------------------------------------------------------------------------------
/images/tokens/REN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/REN.png
--------------------------------------------------------------------------------
/images/tokens/REP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/REP.png
--------------------------------------------------------------------------------
/images/tokens/REQ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/REQ.png
--------------------------------------------------------------------------------
/images/tokens/RHOC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/RHOC.png
--------------------------------------------------------------------------------
/images/tokens/RKT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/RKT.png
--------------------------------------------------------------------------------
/images/tokens/RLC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/RLC.png
--------------------------------------------------------------------------------
/images/tokens/RVT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/RVT.png
--------------------------------------------------------------------------------
/images/tokens/SALT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/SALT.png
--------------------------------------------------------------------------------
/images/tokens/SHP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/SHP.png
--------------------------------------------------------------------------------
/images/tokens/SNIP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/SNIP.png
--------------------------------------------------------------------------------
/images/tokens/SNM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/SNM.png
--------------------------------------------------------------------------------
/images/tokens/SNOV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/SNOV.png
--------------------------------------------------------------------------------
/images/tokens/SNT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/SNT.png
--------------------------------------------------------------------------------
/images/tokens/STAC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/STAC.png
--------------------------------------------------------------------------------
/images/tokens/STU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/STU.png
--------------------------------------------------------------------------------
/images/tokens/SUB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/SUB.png
--------------------------------------------------------------------------------
/images/tokens/TAU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/TAU.png
--------------------------------------------------------------------------------
/images/tokens/TIX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/TIX.png
--------------------------------------------------------------------------------
/images/tokens/TUSD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/TUSD.png
--------------------------------------------------------------------------------
/images/tokens/UFR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/UFR.png
--------------------------------------------------------------------------------
/images/tokens/UKG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/UKG.png
--------------------------------------------------------------------------------
/images/tokens/USDC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/USDC.png
--------------------------------------------------------------------------------
/images/tokens/VEE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/VEE.png
--------------------------------------------------------------------------------
/images/tokens/VIT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/VIT.png
--------------------------------------------------------------------------------
/images/tokens/WAND.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/WAND.png
--------------------------------------------------------------------------------
/images/tokens/WAX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/WAX.png
--------------------------------------------------------------------------------
/images/tokens/WBTC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/WBTC.png
--------------------------------------------------------------------------------
/images/tokens/WETH.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/WETH.png
--------------------------------------------------------------------------------
/images/tokens/WLK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/WLK.png
--------------------------------------------------------------------------------
/images/tokens/WYS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/WYS.png
--------------------------------------------------------------------------------
/images/tokens/XAUR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/XAUR.png
--------------------------------------------------------------------------------
/images/tokens/XGM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/XGM.png
--------------------------------------------------------------------------------
/images/tokens/XRL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/XRL.png
--------------------------------------------------------------------------------
/images/tokens/XSC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/XSC.png
--------------------------------------------------------------------------------
/images/tokens/ZAP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ZAP.png
--------------------------------------------------------------------------------
/images/tokens/ZIL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ZIL.png
--------------------------------------------------------------------------------
/images/tokens/ZRX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ZRX.png
--------------------------------------------------------------------------------
/images/tokens/BERRY.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/BERRY.png
--------------------------------------------------------------------------------
/images/tokens/EMONT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/EMONT.png
--------------------------------------------------------------------------------
/images/tokens/ENTRP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ENTRP.png
--------------------------------------------------------------------------------
/images/tokens/ETHOS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ETHOS.png
--------------------------------------------------------------------------------
/images/tokens/GOLDX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/GOLDX.png
--------------------------------------------------------------------------------
/images/tokens/SPANK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/SPANK.png
--------------------------------------------------------------------------------
/images/tokens/STORJ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/STORJ.png
--------------------------------------------------------------------------------
/images/tokens/STORM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/STORM.png
--------------------------------------------------------------------------------
/images/tokens/THETA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/THETA.png
--------------------------------------------------------------------------------
/images/tokens/ZAPIT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/tokens/ZAPIT.png
--------------------------------------------------------------------------------
/FAQ.md:
--------------------------------------------------------------------------------
1 | # Frequently Asked Questions
2 |
3 | ### How Do Trades Work?
4 |
5 | ### Is my trade stuck?
6 |
--------------------------------------------------------------------------------
/thunks/index.js:
--------------------------------------------------------------------------------
1 | export * from './navigation';
2 | export * from './settings';
3 | export * from './wallet';
4 |
--------------------------------------------------------------------------------
/images/previews/android/send.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/android/send.png
--------------------------------------------------------------------------------
/navigation/index.js:
--------------------------------------------------------------------------------
1 | export * from './context';
2 | export * from './methods';
3 | export * from './permissions';
4 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 | #FFFFFF
3 |
--------------------------------------------------------------------------------
/images/logo-circle/mobidex-144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-circle/mobidex-144.png
--------------------------------------------------------------------------------
/images/logo-circle/mobidex-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-circle/mobidex-48.png
--------------------------------------------------------------------------------
/images/logo-circle/mobidex-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-circle/mobidex-72.png
--------------------------------------------------------------------------------
/images/logo-circle/mobidex-96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-circle/mobidex-96.png
--------------------------------------------------------------------------------
/images/previews/android/history.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/android/history.png
--------------------------------------------------------------------------------
/images/previews/android/receive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/android/receive.png
--------------------------------------------------------------------------------
/images/previews/android/trade.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/android/trade.png
--------------------------------------------------------------------------------
/images/previews/android/wallet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/android/wallet.png
--------------------------------------------------------------------------------
/images/previews/ios/product-5.5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/ios/product-5.5.png
--------------------------------------------------------------------------------
/images/previews/ios/product-5.8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/ios/product-5.8.png
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | mobidex
3 |
4 |
--------------------------------------------------------------------------------
/constants/uniswap.js:
--------------------------------------------------------------------------------
1 | export const ETH_TO_TOKEN_SWAP_INPUT_GAS = 12757;
2 | export const TOKEN_TO_ETH_SWAP_INPUT_GAS = 47503;
3 |
--------------------------------------------------------------------------------
/images/previews/android/my-orders.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/android/my-orders.png
--------------------------------------------------------------------------------
/images/previews/ios/product-12.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/ios/product-12.9.png
--------------------------------------------------------------------------------
/images/previews/ios/products-12.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/ios/products-12.9.png
--------------------------------------------------------------------------------
/images/previews/ios/products-5.5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/ios/products-5.5.png
--------------------------------------------------------------------------------
/images/previews/ios/products-5.8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/ios/products-5.8.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-120.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-144.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-148.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-148.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-152.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-167.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-180.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-192.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-20.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-29.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-36.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-40.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-48.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-512.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-58.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-60.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-72.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-76.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-80.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-87.png
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-96.png
--------------------------------------------------------------------------------
/images/previews/android/fill-orders.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/android/fill-orders.png
--------------------------------------------------------------------------------
/images/previews/android/limit-order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/android/limit-order.png
--------------------------------------------------------------------------------
/images/previews/ios/limit-order-12.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/ios/limit-order-12.9.png
--------------------------------------------------------------------------------
/images/previews/ios/limit-order-5.5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/ios/limit-order-5.5.png
--------------------------------------------------------------------------------
/images/previews/ios/limit-order-5.8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/ios/limit-order-5.8.png
--------------------------------------------------------------------------------
/images/previews/ios/multiple-large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/ios/multiple-large.png
--------------------------------------------------------------------------------
/patches/whatwg-fetch.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | find ./node_modules -name fetch.umd.js -print -exec sed -i.bk 's/self/global/g' {} \;
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/res/drawable/logo.png
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/images/logo-without-text/mobidex-83.5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-without-text/mobidex-83.5.png
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Entypo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/Entypo.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Feather.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/Feather.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Zocial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/Zocial.ttf
--------------------------------------------------------------------------------
/images/logo-with-text/logo-with-text-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-with-text/logo-with-text-1024.png
--------------------------------------------------------------------------------
/images/previews/android/product-details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/android/product-details.png
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/AntDesign.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/AntDesign.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/EvilIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/EvilIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Fontisto.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/Fontisto.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/Ionicons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Octicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/Octicons.ttf
--------------------------------------------------------------------------------
/patches/isomorphic-fetch.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | find ./node_modules -name fetch-npm-browserify.js -print -exec sed -i.bk 's/self/global/g' {} \;
--------------------------------------------------------------------------------
/.buckconfig:
--------------------------------------------------------------------------------
1 |
2 | [android]
3 | target = Google Inc.:Google APIs:23
4 |
5 | [maven_repositories]
6 | central = https://repo1.maven.org/maven2
7 |
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/FontAwesome.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Foundation.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/Foundation.ttf
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/mobidex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/res/mipmap-hdpi/mobidex.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/mobidex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/res/mipmap-mdpi/mobidex.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/mobidex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/res/mipmap-xhdpi/mobidex.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/mobidex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/res/mipmap-xxhdpi/mobidex.png
--------------------------------------------------------------------------------
/images/logo-with-text/logo-with-text-1024x500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-with-text/logo-with-text-1024x500.png
--------------------------------------------------------------------------------
/images/logo-with-text/logo-with-text-300x115.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-with-text/logo-with-text-300x115.png
--------------------------------------------------------------------------------
/images/previews/animated/10-06-2018T13-57-49.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/previews/animated/10-06-2018T13-57-49.gif
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | bracketSpacing: false,
3 | jsxBracketSameLine: true,
4 | singleQuote: true,
5 | trailingComma: 'all',
6 | };
7 |
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/MaterialIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/MaterialIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/images/logo-with-text/logo-with-text-beta-green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-with-text/logo-with-text-beta-green.png
--------------------------------------------------------------------------------
/images/logo-with-text/logo-with-text-transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-with-text/logo-with-text-transparent.png
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/SimpleLineIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/SimpleLineIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/images/logo-with-text/logo-with-alpha-red-bold-300.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-with-text/logo-with-alpha-red-bold-300.png
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome5_Brands.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/FontAwesome5_Brands.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome5_Solid.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/FontAwesome5_Solid.ttf
--------------------------------------------------------------------------------
/images/logo-with-text/logo-with-text-alpha-red-bold2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/images/logo-with-text/logo-with-text-alpha-red-bold2.png
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome5_Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/FontAwesome5_Regular.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf
--------------------------------------------------------------------------------
/lib/utils/index.js:
--------------------------------------------------------------------------------
1 | export * from './cache';
2 | export * from './crypto';
3 | export * from './display';
4 | export * from './ethereum';
5 | export * from './token';
6 |
--------------------------------------------------------------------------------
/navigation/headers.js:
--------------------------------------------------------------------------------
1 | import {Navigation} from 'react-native-navigation';
2 | import {Provider} from 'react-redux';
3 |
4 | export function registerHeaders(store) {}
5 |
--------------------------------------------------------------------------------
/patches/ethers.sh:
--------------------------------------------------------------------------------
1 | find ./node_modules -name ethers -type d -print -exec sed -i.bk 's|"browser": "./dist/ethers.js"|"browser": "./dist/ethers.min.js"|g' {}/package.json \;
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-120.png
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-121.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-121.png
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-180.png
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-40.png
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-58.png
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-60.png
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-80.png
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/ios/mobidex/Images.xcassets/AppIcon.appiconset/mobidex-87.png
--------------------------------------------------------------------------------
/rn-cli.config.js:
--------------------------------------------------------------------------------
1 | const blacklist = require('metro-config/src/defaults/blacklist');
2 |
3 | module.exports = {
4 | resolver: {
5 | blacklistRE: blacklist
6 | }
7 | };
8 |
--------------------------------------------------------------------------------
/ios/mobidex-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 | #import
6 |
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/AppIcon.appiconset/logo-with-text-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/ios/mobidex/Images.xcassets/AppIcon.appiconset/logo-with-text-1024.png
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/logo-with-text-300x115.imageset/logo-with-text-300x115.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/ios/mobidex/Images.xcassets/logo-with-text-300x115.imageset/logo-with-text-300x115.png
--------------------------------------------------------------------------------
/ios/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source "https://rubygems.org"
4 |
5 | git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
6 |
7 | # gem "rails"
8 | gem "cocoapods"
9 | gem "cocoapods-fix-react-native"
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/logo-with-text-beta-green.imageset/logo-with-text-beta-green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/ios/mobidex/Images.xcassets/logo-with-text-beta-green.imageset/logo-with-text-beta-green.png
--------------------------------------------------------------------------------
/ios/mobidex/Entitlements.pinfo:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/logo-with-alpha-red-bold-300.imageset/logo-with-alpha-red-bold-300.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigillabs/mobidex/HEAD/ios/mobidex/Images.xcassets/logo-with-alpha-red-bold-300.imageset/logo-with-alpha-red-bold-300.png
--------------------------------------------------------------------------------
/lib/middleware/app.js:
--------------------------------------------------------------------------------
1 | import { saveState } from '../stores/app';
2 |
3 | export const saveStateMiddleware = store => next => action => {
4 | try {
5 | return next(action);
6 | } finally {
7 | saveState(store.getState());
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/types/props/bignumber.js:
--------------------------------------------------------------------------------
1 | import {BigNumber} from '@uniswap/sdk';
2 | import PropTypes from 'prop-types';
3 |
4 | export const BigNumberProp = PropTypes.oneOfType([
5 | PropTypes.instanceOf(BigNumber),
6 | PropTypes.number,
7 | PropTypes.string,
8 | ]);
9 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/App/components/MaxButton.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import SmallClearButton from './SmallClearButton';
3 |
4 | export default class MaxButton extends Component {
5 | render() {
6 | return ;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/lib/utils/token.js:
--------------------------------------------------------------------------------
1 | import { BigNumber } from '@uniswap/sdk';
2 |
3 | export function toUnitAmount(amount, decimals = 18) {
4 | return new BigNumber(amount);
5 | }
6 |
7 | export function toBaseUnitAmount(amount, decimals = 18) {
8 | return new BigNumber(amount);
9 | }
10 |
--------------------------------------------------------------------------------
/reducers/error.js:
--------------------------------------------------------------------------------
1 | import * as Actions from '../constants/actions';
2 |
3 | export default function error(state = null, action) {
4 | switch (action.type) {
5 | case Actions.SET_ERROR:
6 | return action.payload;
7 | default:
8 | return state;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/patches/web3.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | utils=$( find ./node_modules -name utils.js | grep "web3/lib/utils" )
4 | for f in ${utils}; do
5 | sed -i.bk -E "s|object.constructor.name === 'BigNumber'|object.s !== undefined \&\& object.e !== undefined \&\& object.c !== undefined|" ${f};
6 | done;
7 |
--------------------------------------------------------------------------------
/services/BaseService.js:
--------------------------------------------------------------------------------
1 | const SERVICES = {};
2 |
3 | export default class BaseService {
4 | constructor(store) {
5 | this.store = store;
6 | SERVICES[this.constructor.name] = this;
7 | }
8 |
9 | static get instance() {
10 | return SERVICES[this.name];
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/patches/whatwg-fetch.js:
--------------------------------------------------------------------------------
1 | const shell = require('shelljs');
2 |
3 | const paths = shell
4 | .find('./node_modules')
5 | .filter(file => file.match('fetch.umd.js'));
6 |
7 | for (const _path of paths) {
8 | console.log(`Patching path: ${_path}`);
9 | shell.sed('-i', /self/g, 'global', _path);
10 | }
11 |
--------------------------------------------------------------------------------
/ios/mobidex.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/mobidex.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/types/props/token.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import {addressProp} from './address';
3 |
4 | export const tokenProp = PropTypes.shape({
5 | address: addressProp,
6 | name: PropTypes.string.isRequired,
7 | symbol: PropTypes.string.isRequired,
8 | decimals: PropTypes.number.isRequired,
9 | });
10 |
--------------------------------------------------------------------------------
/patches/isomorphic-fetch.js:
--------------------------------------------------------------------------------
1 | const shell = require('shelljs');
2 |
3 | const paths = shell
4 | .find('./node_modules')
5 | .filter(file => file.match('fetch-npm-browserify.js'));
6 |
7 | for (const _path of paths) {
8 | console.log(`Patching path: ${_path}`);
9 | shell.sed('-i', /self/g, 'global', _path);
10 | }
11 |
--------------------------------------------------------------------------------
/ios/mobidex.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildSystemType
6 | Original
7 |
8 |
9 |
--------------------------------------------------------------------------------
/reducers/device.js:
--------------------------------------------------------------------------------
1 | import { Dimensions } from 'react-native';
2 | import { handleActions } from 'redux-actions';
3 |
4 | const initialState = {
5 | layout: {
6 | width: Dimensions.get('window').width,
7 | height: Dimensions.get('window').height
8 | }
9 | };
10 |
11 | export default handleActions({}, initialState);
12 |
--------------------------------------------------------------------------------
/types/props/index.js:
--------------------------------------------------------------------------------
1 | export * from './address';
2 | export * from './asset';
3 | export * from './asset-data';
4 | export * from './bignumber';
5 | export * from './navigation';
6 | export * from './styles';
7 | export * from './token';
8 | export * from './transaction';
9 | export * from './product';
10 | export * from './uniswap';
11 |
--------------------------------------------------------------------------------
/types/props/navigation.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | export const navigationProp = PropTypes.shape({
4 | push: PropTypes.func.isRequired,
5 | pop: PropTypes.func.isRequired,
6 | dismissModal: PropTypes.func.isRequired,
7 | showModal: PropTypes.func.isRequired,
8 | showErrorModal: PropTypes.func.isRequired
9 | });
10 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:metro-react-native-babel-preset'],
3 | plugins: [
4 | ['@babel/plugin-proposal-decorators', { legacy: true }],
5 | ['@babel/plugin-syntax-decorators', { legacy: true }]
6 | ],
7 | env: {
8 | production: {
9 | plugins: ['transform-remove-console']
10 | }
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/types/props/asset.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import { addressProp } from './address';
3 | import { assetDataProp } from './asset-data';
4 |
5 | export const assetProp = PropTypes.shape({
6 | address: addressProp,
7 | assetData: assetDataProp,
8 | decimals: PropTypes.number,
9 | name: PropTypes.string.isRequired,
10 | symbol: PropTypes.string.isRequired
11 | });
12 |
--------------------------------------------------------------------------------
/App/components/Row.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { View } from 'react-native';
3 | import { styles } from '../../styles';
4 |
5 | export default class Row extends Component {
6 | render() {
7 | let { style, ...rest } = this.props;
8 | return (
9 |
10 | {this.props.children}
11 |
12 | );
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug
3 | about: General purpose bug template
4 | title: ''
5 | labels: help wanted
6 | assignees: ''
7 |
8 | ---
9 |
10 | # Description
11 |
12 | A description of the issue including any relevant context.
13 |
14 | ## Platform
15 |
16 | iOS/Android/Mac OS X/Windows/Linux.
17 |
18 | Please include the version number.
19 |
20 | # Reproduce (Optional)
21 |
22 | Steps to reproduce the issue if it's a bug.
23 |
--------------------------------------------------------------------------------
/App/components/MutedText.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Text } from 'react-native-elements';
3 | import { colors, fonts } from '../../styles';
4 |
5 | export default class MutedText extends Component {
6 | render() {
7 | let { style } = this.props;
8 |
9 | return (
10 |
11 | {this.props.children}
12 |
13 | );
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/patches/web3.js:
--------------------------------------------------------------------------------
1 | const shell = require('shelljs');
2 |
3 | const paths = shell
4 | .find('./node_modules')
5 | .filter(file => file.match('web3/lib/utils') && file.match('utils.js'));
6 |
7 | for (const _path of paths) {
8 | console.log(`Patching path: ${_path}`);
9 | shell.sed(
10 | '-i',
11 | /object.constructor.name === 'BigNumber'/,
12 | 'object.s !== undefined && object.e !== undefined && object.c !== undefined',
13 | _path
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_screen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/logo-with-text-300x115.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "logo-with-text-300x115.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/mobidex/main.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | #import
9 |
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/App/components/Divider.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Divider as RNEDivider } from 'react-native-elements';
3 | import { colors } from '../../styles';
4 |
5 | export default class Divider extends Component {
6 | render() {
7 | return (
8 |
14 | );
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/logo-with-text-beta-green.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "logo-with-text-beta-green.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/patches/ethers.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const shell = require('shelljs');
3 |
4 | const paths = shell
5 | .find('./node_modules')
6 | .filter(file => file.match(/ethers$/));
7 |
8 | for (const _path of paths) {
9 | console.log(`Patching path: ${path.join(_path, '/package.json')}`);
10 | shell.sed(
11 | '-i',
12 | /"browser": ".\/dist\/ethers.js"/g,
13 | '"browser": "./dist/ethers.min.js"',
14 | path.join(_path, '/package.json')
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/logo-with-alpha-red-bold-300.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "logo-with-alpha-red-bold-300.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/reducers/index.js:
--------------------------------------------------------------------------------
1 | import { reducer as network } from 'react-native-offline';
2 | import { combineReducers } from 'redux';
3 | import bitski from './bitski';
4 | import device from './device';
5 | import error from './error';
6 | import settings from './settings';
7 | import tokens from './tokens';
8 | import wallet from './wallet';
9 |
10 | export default combineReducers({
11 | bitski,
12 | device,
13 | error,
14 | network,
15 | settings,
16 | tokens,
17 | wallet
18 | });
19 |
--------------------------------------------------------------------------------
/reducers/bitski.js:
--------------------------------------------------------------------------------
1 | import { handleActions } from 'redux-actions';
2 | import * as Actions from '../constants/actions';
3 |
4 | const initialState = {
5 | accessToken: null,
6 | accessTokenExpirationDate: null,
7 | refreshToken: null
8 | };
9 |
10 | export default handleActions(
11 | {
12 | [Actions.SET_BITSKI_CREDENTIALS]: (state, action) => {
13 | return {
14 | ...state,
15 | ...action.payload
16 | };
17 | }
18 | },
19 | initialState
20 | );
21 |
--------------------------------------------------------------------------------
/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
--------------------------------------------------------------------------------
/types/props/product.js:
--------------------------------------------------------------------------------
1 | import { BigNumber } from '@uniswap/sdk';
2 | import PropTypes from 'prop-types';
3 | import { addressProp } from './address';
4 |
5 | export const productProp = PropTypes.shape({
6 | address: addressProp.isRequired,
7 | maxAmount: PropTypes.oneOf([PropTypes.string, PropTypes.number, BigNumber])
8 | .isRequired,
9 | minAmount: PropTypes.oneOf([PropTypes.string, PropTypes.number, BigNumber])
10 | .isRequired,
11 | precision: PropTypes.number.isRequired
12 | });
13 |
--------------------------------------------------------------------------------
/App/components/Text.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Text as RNEText } from 'react-native-elements';
3 |
4 | export default class Text extends Component {
5 | render() {
6 | let { children, ...rest } = this.props;
7 | let _children = ['\u2066'];
8 | if (Array.isArray(children)) {
9 | _children = _children.concat(children);
10 | } else {
11 | _children.push(children);
12 | }
13 | return {_children};
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/App/components/HorizontalPadding.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { View } from 'react-native';
4 |
5 | export default class VerticalPadding extends Component {
6 | static get propTypes() {
7 | return { size: PropTypes.number.isRequired };
8 | }
9 |
10 | render() {
11 | return (
12 |
18 | );
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/App/components/VerticalPadding.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { View } from 'react-native';
4 |
5 | export default class VerticalPadding extends Component {
6 | static get propTypes() {
7 | return { size: PropTypes.number.isRequired };
8 | }
9 |
10 | render() {
11 | return (
12 |
18 | );
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/constants/actions.js:
--------------------------------------------------------------------------------
1 | export const SET_ALLOWANCE = 'SET_ALLOWANCE';
2 | export const SET_BALANCE = 'SET_BALANCE';
3 | export const SET_BITSKI_CREDENTIALS = 'SET_BITSKI_CREDENTIALS';
4 | export const SET_ERROR = 'SET_ERROR';
5 | export const SET_GAS_LEVEL = 'SET_GAS_LEVEL';
6 | export const SET_GAS_LIMIT = 'SET_GAS_LIMIT';
7 | export const SET_GAS_PRICE = 'SET_GAS_PRICE';
8 | export const SET_GAS_STATION = 'SET_GAS_STATION';
9 | export const SET_NETWORK = 'SET_NETWORK';
10 | export const SET_WALLET_ADDRESS = 'SET_WALLET_ADDRESS';
11 |
--------------------------------------------------------------------------------
/types/props/styles.js:
--------------------------------------------------------------------------------
1 | const styleValidator = (
2 | propValue,
3 | key,
4 | componentName,
5 | location,
6 | propFullName
7 | ) => {
8 | if (Array.isArray(propValue)) {
9 | propValue.map((value, index) =>
10 | styleValidator(value, index, componentName, location, propFullName)
11 | );
12 | }
13 |
14 | if (propValue !== null && typeof propValue !== 'object') {
15 | throw new Error(`${componentName}: incorrect prop ${propFullName}`);
16 | }
17 | };
18 |
19 | export const styleProp = styleValidator;
20 |
--------------------------------------------------------------------------------
/constants/index.js:
--------------------------------------------------------------------------------
1 | import {BigNumber} from '@uniswap/sdk';
2 |
3 | export const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
4 | export const ZERO = new BigNumber(0);
5 | export const ONE = new BigNumber(1);
6 | export const TEN = new BigNumber(10);
7 | export const MAX_UINT256_HEX =
8 | '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff';
9 | export const UNLOCKED_AMOUNT = new BigNumber(2).pow(128).minus(1);
10 | export const MAX_UINT256 = new BigNumber(2).pow(256).minus(1);
11 |
12 | export * from './uniswap';
13 |
--------------------------------------------------------------------------------
/navigation/context.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const NavigationContext = React.createContext();
4 |
5 | export function connect(WrappedComponent) {
6 | class ConnectedNavigation extends React.Component {
7 | render() {
8 | return (
9 |
10 | {navigation => (
11 |
12 | )}
13 |
14 | );
15 | }
16 | }
17 |
18 | return ConnectedNavigation;
19 | }
20 |
--------------------------------------------------------------------------------
/App/modals/SendModal/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import NavigationProvider from '../../NavigationProvider';
3 | import BaseSendScreen from './base';
4 |
5 | export default class SendScreen extends React.Component {
6 | static options() {
7 | return {
8 | topBar: {
9 | visible: false,
10 | drawBehind: true
11 | }
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/App/modals/ActionModal/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import NavigationProvider from '../../NavigationProvider';
3 | import BaseActionModal from './base';
4 |
5 | export default class ActionModal extends React.Component {
6 | static options() {
7 | return {
8 | topBar: {
9 | visible: false,
10 | drawBehind: true
11 | }
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/App/modals/SelectModal/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import NavigationProvider from '../../NavigationProvider';
3 | import BaseSelectModal from './base';
4 |
5 | export default class SelectModal extends React.Component {
6 | static options() {
7 | return {
8 | topBar: {
9 | visible: false,
10 | drawBehind: true
11 | }
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ios/mobidex/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | #import
9 | #import "RNAppAuthAuthorizationFlowManager.h"
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property(nonatomic, weak)idauthorizationFlowManagerDelegate;
14 | @property (nonatomic, strong) UIWindow *window;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/App/modals/ErrorModal/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import NavigationProvider from '../../NavigationProvider';
3 | import BaseErrorModal from './base';
4 |
5 | export default class ErrorModal extends Component {
6 | static options() {
7 | return {
8 | topBar: {
9 | visible: false,
10 | drawBehind: true
11 | }
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/App/modals/ReceiveModal/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import NavigationProvider from '../../NavigationProvider';
3 | import BaseReceiveScreen from './base';
4 |
5 | export default class ReceiveModal extends React.Component {
6 | static options() {
7 | return {
8 | topBar: {
9 | visible: false,
10 | drawBehind: true
11 | }
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/App/screens/onboarding/PinScreen/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import NavigationProvider from '../../../NavigationProvider';
3 | import BasePinScreen from './base';
4 |
5 | export default class PinScreen extends React.Component {
6 | static options() {
7 | return {
8 | topBar: {
9 | visible: false,
10 | drawBehind: true
11 | }
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/App/components/MajorText.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { Text } from 'react-native-elements';
4 | import { fonts, styles } from '../../styles';
5 |
6 | export default class MajorText extends Component {
7 | static get propTypes() {
8 | return {
9 | children: PropTypes.node.isRequired
10 | };
11 | }
12 |
13 | render() {
14 | return (
15 |
18 | {this.props.children}
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/App/screens/onboarding/IntroScreen/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import NavigationProvider from '../../../NavigationProvider';
3 | import BaseIntroScreen from './base';
4 |
5 | export default class IntroScreen extends React.Component {
6 | static options() {
7 | return {
8 | topBar: {
9 | visible: false,
10 | drawBehind: true
11 | }
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/App/modals/ConfirmationModal/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import NavigationProvider from '../../NavigationProvider';
3 | import BaseConfirmationModal from './base';
4 |
5 | export default class ConfirmationModal extends React.Component {
6 | static options() {
7 | return {
8 | topBar: {
9 | visible: false,
10 | drawBehind: true
11 | }
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/App/modals/NotificationModal/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import NavigationProvider from '../../NavigationProvider';
3 | import BaseNotificationModal from './base';
4 |
5 | export default class ConfirmationModal extends React.Component {
6 | static options() {
7 | return {
8 | topBar: {
9 | visible: false,
10 | drawBehind: true
11 | }
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/App/screens/onboarding/BitskiLogin/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import NavigationProvider from '../../../NavigationProvider';
3 | import BaseBitskiLoginScreen from './base';
4 |
5 | export default class BitskiLoginScreen extends React.Component {
6 | static options() {
7 | return {
8 | topBar: {
9 | visible: false,
10 | drawBehind: true
11 | }
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/services/NavigationService.js:
--------------------------------------------------------------------------------
1 | import { Linking } from 'react-native';
2 | import EthereumClient from '../clients/ethereum';
3 | import { WalletService } from './WalletService';
4 |
5 | export async function gotoEtherScan(txaddr) {
6 | const web3 = WalletService.instance.web3;
7 |
8 | const ethereumClient = new EthereumClient(web3);
9 | const networkId = await ethereumClient.getNetworkId();
10 | switch (networkId) {
11 | case 42:
12 | return await Linking.openURL(`https://kovan.etherscan.io/tx/${txaddr}`);
13 |
14 | default:
15 | return await Linking.openURL(`https://etherscan.io/tx/${txaddr}`);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
--------------------------------------------------------------------------------
/metro.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Metro configuration for React Native
3 | * https://github.com/facebook/react-native
4 | *
5 | * @format
6 | */
7 |
8 | // const path = require('path');
9 | const blacklist = require('metro-config/src/defaults/blacklist');
10 | const extraNodeModules = require('node-libs-react-native');
11 |
12 | module.exports = {
13 | resolver: {
14 | extraNodeModules,
15 | blacklistRE: blacklist()
16 | },
17 | transformer: {
18 | getTransformOptions: async () => ({
19 | transform: {
20 | experimentalImportSupport: false,
21 | inlineRequires: false
22 | }
23 | })
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/App/screens/onboarding/ImportMnemonicScreen/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import NavigationProvider from '../../../NavigationProvider';
3 | import BaseImportMnemonicScreen from './base';
4 |
5 | export default class ImportMnemonicScreen extends React.Component {
6 | static options() {
7 | return {
8 | topBar: {
9 | visible: false,
10 | drawBehind: true
11 | }
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/App/screens/trade/DetailsScreen/EmptyWallet.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import {Text, View} from 'react-native';
3 | import Entypo from 'react-native-vector-icons/Entypo';
4 | import {styles} from '../../../../styles';
5 | import BigCenter from '../../../components/BigCenter';
6 |
7 | export default class EmptyWallet extends Component {
8 | render() {
9 | return (
10 |
11 |
12 |
13 | You have an empty wallet. Transfer some ether to start using wallet.
14 |
15 |
16 | );
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/lib/stores/app.js:
--------------------------------------------------------------------------------
1 | import {AsyncStorage} from 'react-native';
2 |
3 | const KEY = 'app-state';
4 |
5 | export async function getState(transform = obj => obj) {
6 | try {
7 | const json = await AsyncStorage.getItem(KEY);
8 | if (!json) {
9 | return undefined;
10 | }
11 | const object = JSON.parse(json);
12 |
13 | return transform(object);
14 | } catch (err) {
15 | console.warn(err);
16 | }
17 | }
18 |
19 | export async function clearState() {
20 | return AsyncStorage.removeItem(KEY);
21 | }
22 |
23 | export async function saveState(state) {
24 | await AsyncStorage.setItem(KEY, JSON.stringify(state));
25 | }
26 |
--------------------------------------------------------------------------------
/App/screens/onboarding/PreviewMnemonicScreen/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import NavigationProvider from '../../../NavigationProvider';
3 | import BasePreviewMnemonicScreen from './base';
4 |
5 | export default class PreviewMnemonicScreen extends React.Component {
6 | static options() {
7 | return {
8 | topBar: {
9 | visible: false,
10 | drawBehind: true
11 | }
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/android/app/build_defs.bzl:
--------------------------------------------------------------------------------
1 | """Helper definitions to glob .aar and .jar targets"""
2 |
3 | def create_aar_targets(aarfiles):
4 | for aarfile in aarfiles:
5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")]
6 | lib_deps.append(":" + name)
7 | android_prebuilt_aar(
8 | name = name,
9 | aar = aarfile,
10 | )
11 |
12 | def create_jar_targets(jarfiles):
13 | for jarfile in jarfiles:
14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")]
15 | lib_deps.append(":" + name)
16 | prebuilt_jar(
17 | name = name,
18 | binary_jar = jarfile,
19 | )
--------------------------------------------------------------------------------
/App/components/BigCenter.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { View } from 'react-native';
3 |
4 | export default class BigCenter extends Component {
5 | render() {
6 | let { style, ...rest } = this.props;
7 | return (
8 |
23 | {this.props.children}
24 |
25 | );
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: generalpiston
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/App/components/FormattedPercent.js:
--------------------------------------------------------------------------------
1 | import { BigNumber } from '@uniswap/sdk';
2 | import PropTypes from 'prop-types';
3 | import React, { Component } from 'react';
4 | import { Text } from 'react-native-elements';
5 | import { formatPercent } from '../../lib/utils';
6 |
7 | export default class FormattedPercent extends Component {
8 | static get propTypes() {
9 | return {
10 | percent: PropTypes.oneOfType([
11 | PropTypes.instanceOf(BigNumber),
12 | PropTypes.number,
13 | PropTypes.string
14 | ]).isRequired
15 | };
16 | }
17 |
18 | render() {
19 | const { percent, ...rest } = this.props;
20 | return {formatPercent(percent)};
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es6: true,
5 | commonjs: true,
6 | amd: true
7 | },
8 | extends: [
9 | 'eslint:recommended',
10 | 'plugin:react/recommended',
11 | '@react-native-community'
12 | ],
13 | parser: 'babel-eslint',
14 | parserOptions: {
15 | ecmaVersion: 8,
16 | ecmaFeatures: {
17 | experimentalObjectRestSpread: true,
18 | jsx: true
19 | },
20 | sourceType: 'module'
21 | },
22 | plugins: ['react'],
23 | rules: {
24 | indent: ['error', 2, { SwitchCase: 1 }],
25 | 'linebreak-style': ['error', 'unix'],
26 | quotes: ['error', 'single'],
27 | semi: ['error', 'always'],
28 | 'no-console': [1]
29 | },
30 | root: true
31 | };
32 |
--------------------------------------------------------------------------------
/App/components/AssetIcon.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import * as AssetService from '../../services/AssetService';
3 | import {addressProp} from '../../types/props';
4 | import EthereumIcon from './EthereumIcon';
5 | import TokenIcon from './TokenIcon';
6 |
7 | export default class AssetIcon extends Component {
8 | static get propTypes() {
9 | return {
10 | address: addressProp,
11 | };
12 | }
13 |
14 | static get defaultProps() {
15 | return {
16 | address: null,
17 | };
18 | }
19 |
20 | render() {
21 | if (AssetService.isEthereum(this.props.address)) {
22 | return ;
23 | } else {
24 | return ;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/App/modals/UnlockAndSignModal/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { checkOrRequestExternalStorageRead } from '../../../navigation';
3 | import NavigationProvider from '../../NavigationProvider';
4 | import BaseUnlockAndSignModal from './base';
5 |
6 | export default class UnlockAndSignModal extends Component {
7 | static options() {
8 | return {
9 | topBar: {
10 | visible: false,
11 | drawBehind: true
12 | }
13 | };
14 | }
15 |
16 | componentDidMount() {
17 | checkOrRequestExternalStorageRead();
18 | }
19 |
20 | render() {
21 | return (
22 |
23 |
24 |
25 | );
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/App/components/FormattedSymbol.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, {Component} from 'react';
3 | import {Text} from 'react-native-elements';
4 | import {formatSymbol} from '../../lib/utils';
5 | import * as AssetService from '../../services/AssetService';
6 |
7 | export default class FormattedSymbol extends Component {
8 | static get propTypes() {
9 | return {
10 | address: PropTypes.string,
11 | symbol: PropTypes.string,
12 | };
13 | }
14 |
15 | render() {
16 | const {address, symbol, ...rest} = this.props;
17 | if (symbol) {
18 | return {formatSymbol(symbol)};
19 | } else {
20 | const token = AssetService.findAssetByAddress(address);
21 | return {formatSymbol(token.symbol)};
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/actions/index.js:
--------------------------------------------------------------------------------
1 | import {createAction} from 'redux-actions';
2 | import * as Actions from '../constants/actions';
3 |
4 | export const setAllowance = createAction(Actions.SET_ALLOWANCE);
5 | export const setBalance = createAction(Actions.SET_BALANCE);
6 | export const setBitskiCredentials = createAction(
7 | Actions.SET_BITSKI_CREDENTIALS,
8 | );
9 | export const setError = createAction(Actions.SET_ERROR);
10 | export const setGasLevel = createAction(Actions.SET_GAS_LEVEL);
11 | export const setGasLimit = createAction(Actions.SET_GAS_LIMIT);
12 | export const setGasPrice = createAction(Actions.SET_GAS_PRICE);
13 | export const setGasStation = createAction(Actions.SET_GAS_STATION);
14 | export const setNetwork = createAction(Actions.SET_NETWORK);
15 | export const setWalletAddress = createAction(Actions.SET_WALLET_ADDRESS);
16 |
--------------------------------------------------------------------------------
/App/screens/trade/ProductScreen/base.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, {Component} from 'react';
3 | import {connect} from 'react-redux';
4 | import * as AssetService from '../../../../services/AssetService';
5 | import {tokenProp} from '../../../../types/props';
6 | import TokenList from './TokenList';
7 |
8 | class BaseProductScreen extends Component {
9 | static get propTypes() {
10 | return {
11 | tokens: PropTypes.arrayOf(tokenProp).isRequired,
12 | };
13 | }
14 |
15 | render() {
16 | const tokens = this.props.tokens.slice();
17 | tokens.unshift(AssetService.getETHAsset());
18 | return ;
19 | }
20 | }
21 |
22 | const ProductScreen = connect(state => ({
23 | tokens: state.tokens,
24 | }))(BaseProductScreen);
25 |
26 | export default ProductScreen;
27 |
--------------------------------------------------------------------------------
/App/screens/trade/DetailsScreen/base.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, {Component} from 'react';
3 | import * as AssetService from '../../../../services/AssetService';
4 | import {addressProp} from '../../../../types/props';
5 | import EthereumDetails from './EthereumDetails';
6 | import TokenDetails from './TokenDetails';
7 |
8 | export default class DetailsScreen extends Component {
9 | static get propTypes() {
10 | return {
11 | tokenAddress: PropTypes.oneOfType([
12 | addressProp,
13 | PropTypes.instanceOf(null),
14 | ]).isRequired,
15 | };
16 | }
17 |
18 | render() {
19 | if (AssetService.isEthereum(this.props.tokenAddress)) {
20 | return ;
21 | } else {
22 | return ;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/App/components/EmptyList.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import {TouchableOpacity} from 'react-native';
3 | import BigCenter from '../components/BigCenter';
4 |
5 | export default class EmptyList extends Component {
6 | render() {
7 | let {containerStyle, wrapperStyle} = this.props;
8 | return (
9 |
10 |
22 | {this.props.children}
23 |
24 |
25 | );
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/App/components/TouchableInputTokenAmount.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { TouchableOpacity } from 'react-native';
4 | import { styles } from '../../styles';
5 | import { styleProp } from '../../types/props';
6 | import InputTokenAmount from './InputTokenAmount';
7 |
8 | export default class TouchableInputTokenAmount extends Component {
9 | static get propTypes() {
10 | return {
11 | wrapperStyle: styleProp,
12 | onPress: PropTypes.func
13 | };
14 | }
15 |
16 | render() {
17 | const { onPress, wrapperStyle } = this.props;
18 |
19 | return (
20 |
24 |
25 |
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ios/mobidexTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | io.mobidex.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 0.6
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSApplicationCategoryType
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/types/props/asset-data.js:
--------------------------------------------------------------------------------
1 | const assetDataValidator = (
2 | propValue,
3 | key,
4 | componentName,
5 | location,
6 | propFullName
7 | ) => {
8 | const value = key !== null ? propValue[key] : propValue;
9 |
10 | if (typeof value !== 'string') {
11 | throw new Error(`${componentName}: incorrect prop ${propFullName}`);
12 | }
13 |
14 | if (!/^(0x)?[a-fA-F0-9]{40,}$/.test(value)) {
15 | throw new Error(`${componentName}: incorrect prop ${propFullName}`);
16 | }
17 | };
18 |
19 | export const assetDataProp = (
20 | propValue,
21 | key,
22 | componentName,
23 | location,
24 | propFullName
25 | ) => {
26 | const value = key !== null ? propValue[key] : propValue;
27 |
28 | if (value !== null && value !== undefined) {
29 | assetDataValidator(propValue, key, componentName, location, propFullName);
30 | }
31 | };
32 |
33 | assetDataProp.isRequired = assetDataValidator;
34 |
--------------------------------------------------------------------------------
/App/views/Loading.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component, Fragment } from 'react';
3 | import { ActivityIndicator } from 'react-native';
4 | import { Text } from 'react-native-elements';
5 | import BigCenter from '../components/BigCenter';
6 | import VerticalPadding from '../components/VerticalPadding';
7 |
8 | export default class Loading extends Component {
9 | static get propTypes() {
10 | return {
11 | label: PropTypes.string
12 | };
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 | {this.renderLabelFragment()}
20 |
21 | );
22 | }
23 |
24 | renderLabelFragment() {
25 | if (!this.props.label) return null;
26 |
27 | return (
28 |
29 |
30 | {this.props.label}
31 |
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/android/app/src/main/java/io/mobidex/WalletManagerPackage.java:
--------------------------------------------------------------------------------
1 | package io.mobidex;
2 |
3 | import com.facebook.react.ReactPackage;
4 | import com.facebook.react.bridge.NativeModule;
5 | import com.facebook.react.bridge.ReactApplicationContext;
6 | import com.facebook.react.uimanager.ViewManager;
7 |
8 | import java.util.ArrayList;
9 | import java.util.Collections;
10 | import java.util.List;
11 |
12 | public class WalletManagerPackage implements ReactPackage {
13 |
14 | @Override
15 | public List createViewManagers(ReactApplicationContext reactContext) {
16 | return Collections.emptyList();
17 | }
18 |
19 | @Override
20 | public List createNativeModules(ReactApplicationContext reactContext) {
21 | List modules = new ArrayList<>();
22 |
23 | modules.add(new WalletManagerModule(reactContext));
24 |
25 | return modules;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/App/screens/trade/DetailsScreen/UnwrapConfirmation.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, {Component} from 'react';
3 | import {Text} from 'react-native';
4 | import FA from 'react-native-vector-icons/FontAwesome';
5 | import {fonts, styles} from '../../../../styles';
6 | import {BigNumberProp} from '../../../../types/props';
7 | import BigCenter from '../../../components/BigCenter';
8 | import EthereumAmount from '../../../components/EthereumAmount';
9 |
10 | export default class UnwrapConfirmation extends Component {
11 | static get propTypes() {
12 | return {
13 | amount: BigNumberProp.isRequired,
14 | direction: PropTypes.oneOf(['wrap', 'unwrap']),
15 | };
16 | }
17 |
18 | render() {
19 | return (
20 |
21 |
22 | Unwrapping all Ethereum.
23 |
24 | );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/App/components/TokenAmount.js:
--------------------------------------------------------------------------------
1 | import {BigNumber, formatFixedDecimals} from '@uniswap/sdk';
2 | import PropTypes from 'prop-types';
3 | import React from 'react';
4 | import {Text} from 'react-native-elements';
5 | import {ZERO} from '../../constants';
6 | import * as AssetService from '../../services/AssetService';
7 | import {addressProp, BigNumberProp} from '../../types/props';
8 |
9 | export default class TokenAmount extends React.PureComponent {
10 | static get propTypes() {
11 | return {
12 | address: addressProp,
13 | amount: BigNumberProp,
14 | };
15 | }
16 |
17 | render() {
18 | const {address, amount, ...rest} = this.props;
19 | const {decimals} = AssetService.findAssetByAddress(address);
20 | const formattedAmount = formatFixedDecimals(amount || ZERO, decimals, {
21 | decimalPlaces: Math.floor(decimals / 3),
22 | });
23 |
24 | return {formattedAmount};
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/App/screens/trade/DetailsScreen/UnlockTokenNotice.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, {Component} from 'react';
3 | import {Text} from 'react-native';
4 | import Entypo from 'react-native-vector-icons/Entypo';
5 | import * as AssetService from '../../../../services/AssetService';
6 | import {styles} from '../../../../styles';
7 | import BigCenter from '../../../components/BigCenter';
8 |
9 | export default class UnlockToken extends Component {
10 | static get propTypes() {
11 | return {
12 | tokenAddress: PropTypes.string.isRequired,
13 | };
14 | }
15 |
16 | render() {
17 | const {name} = AssetService.findAssetByAddress(this.props.tokenAddress);
18 |
19 | return (
20 |
21 |
22 | {name} must be unlocked to see more.
23 |
24 | );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ios/Web3+Sign.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Web3+Sign.swift
3 | // mobidex
4 | //
5 | // Created by Abraham Elmahrek on 6/6/19.
6 | // Copyright © 2019 Facebook. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Web3
11 |
12 | extension Web3.Eth {
13 | public func sign(
14 | address: EthereumAddress,
15 | data: EthereumData,
16 | response: @escaping Web3.Web3ResponseCompletion
17 | ) {
18 | let req = BasicRPCRequest(
19 | id: properties.rpcId,
20 | jsonrpc: Web3.jsonrpc,
21 | method: "eth_sign",
22 | params: [address, data]
23 | )
24 | properties.provider.send(request: req, response: response)
25 | }
26 |
27 | public func sign(address: EthereumAddress, data: EthereumData) -> Promise {
28 | return Promise { seal in
29 | self.sign(address: address, data: data) { response in
30 | seal.resolve(response.result, response.error)
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/ios/BitskiManagerBridge.m:
--------------------------------------------------------------------------------
1 | //
2 | // WalletManagerBridge.m
3 | // mobidex
4 | //
5 | // Created by Abraham Elmahrek on 6/21/18.
6 | // Copyright © 2018 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import
12 |
13 | @interface RCT_EXTERN_MODULE(BitskiManager, NSObject)
14 |
15 | RCT_EXTERN_METHOD(initialize:(NSString *)network clientID:(NSString *)clientID redirectURL:(NSString *)redirectURL callback:(RCTResponseSenderBlock)callback)
16 | RCT_EXTERN_METHOD(isWalletAvailable:(RCTResponseSenderBlock)callback)
17 | RCT_EXTERN_METHOD(loadWalletAddress:(RCTResponseSenderBlock)callback)
18 | RCT_EXTERN_METHOD(sendTransaction:(NSDictionary *)tx callback:(RCTResponseSenderBlock)callback)
19 | RCT_EXTERN_METHOD(signMessage:(NSString *)message callback:(RCTResponseSenderBlock)callback)
20 | RCT_EXTERN_METHOD(login:(RCTResponseSenderBlock)callback)
21 | RCT_EXTERN_METHOD(logout:(RCTResponseSenderBlock)callback)
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/services/GasService.js:
--------------------------------------------------------------------------------
1 | import EthereumClient from '../clients/ethereum';
2 | import {bigIntToEthHex, formatHexString} from '../lib/utils';
3 | import TokenClient from '../clients/token';
4 | import BaseService from './BaseService';
5 | import {WalletService} from './WalletService';
6 |
7 | export class GasService extends BaseService {
8 | async EthereumSend() {
9 | return 21000;
10 | }
11 |
12 | async TokenTransfer(tokenAddress, to, amount) {
13 | // const {
14 | // settings: {
15 | // uniswap: {factoryAddress},
16 | // },
17 | // } = this.store.getState();
18 |
19 | const ethereumClient = new EthereumClient(WalletService.instance.web3);
20 | const tokenClient = new TokenClient(ethereumClient, tokenAddress);
21 | const contract = await tokenClient.getContract();
22 | const result = await contract.methods
23 | .transfer(formatHexString(to), bigIntToEthHex(amount))
24 | .estimateGas();
25 | return result;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/utils/ethereum.js:
--------------------------------------------------------------------------------
1 | import {BigNumber} from '@uniswap/sdk';
2 | import ethUtil from 'ethereumjs-util';
3 | import * as _ from 'lodash';
4 | import {formatHexString} from './display';
5 |
6 | export function bigIntToEthHex(arg) {
7 | return formatHexString(new BigNumber(arg).toString(16));
8 | }
9 |
10 | export function getURLFromNetwork(network) {
11 | switch (network) {
12 | case 'mainnet':
13 | case 1:
14 | return 'https://mainnet.infura.io/';
15 |
16 | default:
17 | return 'https://kovan.infura.io/';
18 | }
19 | }
20 |
21 | export function stripPrefixesFromTxParams(tx) {
22 | return _.mapValues(tx, (v, k) => {
23 | if (k !== 'from' && k !== 'to') {
24 | return ethUtil.stripHexPrefix(v);
25 | } else {
26 | return v;
27 | }
28 | });
29 | }
30 |
31 | export function chainIDToNetworkName(chainID) {
32 | switch (chainID) {
33 | case 1:
34 | return 'mainnet';
35 |
36 | default:
37 | return 'kovan';
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib/decorators/cls/timing.js:
--------------------------------------------------------------------------------
1 | export function time(target, name, descriptor) {
2 | const original = descriptor.value;
3 | if (typeof original === 'function') {
4 | descriptor.value = async function(...args) {
5 | const start = new Date();
6 | try {
7 | console.debug(
8 | `Timing ${name}(${JSON.stringify(
9 | Array.prototype.slice.call(args, 0)
10 | )})`
11 | );
12 | return await original.apply(this, args);
13 | } catch (err) {
14 | console.debug(
15 | `Timing Error ${name}(${JSON.stringify(
16 | Array.prototype.slice.call(args, 0)
17 | )}): ${err.message}`
18 | );
19 | throw err;
20 | } finally {
21 | console.debug(
22 | `Timed ${name}(${JSON.stringify(
23 | Array.prototype.slice.call(args, 0)
24 | )}): Duration: ${new Date() - start}`
25 | );
26 | }
27 | };
28 | }
29 |
30 | return descriptor;
31 | }
32 |
--------------------------------------------------------------------------------
/App/modals/SelectModal/Option.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import { ListItem } from 'react-native-elements';
4 |
5 | export default class Option extends React.PureComponent {
6 | static get propTypes() {
7 | return {
8 | name: PropTypes.string.isRequired,
9 | label: PropTypes.string.isRequired,
10 | index: PropTypes.number.isRequired,
11 | selected: PropTypes.bool.isRequired,
12 | onPress: PropTypes.func.isRequired
13 | };
14 | }
15 |
16 | render() {
17 | const icon = {
18 | name: this.props.selected ? 'circle' : 'circle-o',
19 | type: 'font-awesome'
20 | };
21 | return (
22 |
29 | );
30 | }
31 |
32 | onPress = () => {
33 | this.props.onPress(this.props.name);
34 | };
35 | }
36 |
--------------------------------------------------------------------------------
/App/components/MajorTextWithVectorIcon.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { View } from 'react-native';
4 | import FontAwesome from 'react-native-vector-icons/FontAwesome';
5 | import { styles } from '../../styles';
6 | import MajorText from './MajorText';
7 |
8 | export default class MajorTextWithVectorIcon extends Component {
9 | static get propTypes() {
10 | return {
11 | text: PropTypes.string.isRequired,
12 | iconName: PropTypes.string.isRequired,
13 | IconComponent: PropTypes.any.isRequired
14 | };
15 | }
16 |
17 | static get defaultProps() {
18 | return {
19 | IconComponent: FontAwesome
20 | };
21 | }
22 |
23 | render() {
24 | let { IconComponent, iconName, text } = this.props;
25 | return (
26 |
27 |
28 | {text}
29 |
30 | );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/App/modals/ErrorModal/AssetBuyerError.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { Text } from 'react-native-elements';
4 | import { colors } from '../../../styles';
5 |
6 | // Error message:
7 | // ${error_enum}: ${text}
8 | export default class AssetBuyerError extends Component {
9 | static test(error) {
10 | if (!error) return false;
11 | if (!error.message) return false;
12 | return error.message && error.message.indexOf('ASSET_UNAVAILABLE:') === 0;
13 | }
14 |
15 | render() {
16 | return (
17 |
18 | There is not enough liquidity to fill your order.
19 |
20 | );
21 | }
22 | }
23 |
24 | AssetBuyerError.propTypes = {
25 | error: PropTypes.shape({
26 | message: PropTypes.string.isRequired
27 | }).isRequired
28 | };
29 |
30 | const styles = {
31 | text: {
32 | fontSize: 18,
33 | color: colors.primary,
34 | paddingBottom: 10,
35 | textAlign: 'center'
36 | }
37 | };
38 |
--------------------------------------------------------------------------------
/App/components/Col.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { View } from 'react-native';
4 | import { styles } from '../../styles';
5 | import { styleProp } from '../../types/props';
6 |
7 | export default class Col extends Component {
8 | static get propTypes() {
9 | return {
10 | style: styleProp,
11 | right: PropTypes.bool.isRequired,
12 | size: PropTypes.number.isRequired
13 | };
14 | }
15 |
16 | static get defaultProps() {
17 | return {
18 | size: 1,
19 | right: false
20 | };
21 | }
22 |
23 | render() {
24 | let { right, style, ...rest } = this.props;
25 | return (
26 |
37 | {this.props.children}
38 |
39 | );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/App/screens/trade/DetailsScreen/UnlockConfirmation.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, {Component} from 'react';
3 | import {Text} from 'react-native';
4 | import Entypo from 'react-native-vector-icons/Entypo';
5 | import * as AssetService from '../../../../services/AssetService';
6 | import {fonts, styles} from '../../../../styles';
7 | import TokenIcon from '../../../components/TokenIcon';
8 | import BigCenter from '../../../components/BigCenter';
9 |
10 | export default class UnlockConfirmation extends Component {
11 | static get propTypes() {
12 | return {
13 | tokenAddress: PropTypes.string.isRequired,
14 | };
15 | }
16 |
17 | render() {
18 | const {tokenAddress} = this.props;
19 | const asset = AssetService.findAssetByAddress(tokenAddress);
20 |
21 | return (
22 |
23 |
24 | Unlock {asset.name} for swapping.
25 |
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/App/modals/LoadingModal.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { View, Image } from 'react-native';
3 | import { colors } from '../../styles';
4 | import RotatingView from '../components/RotatingView';
5 |
6 | export default class LoadingScreen extends Component {
7 | render() {
8 | return (
9 |
21 |
22 |
30 |
31 |
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/reducers/wallet.js:
--------------------------------------------------------------------------------
1 | import {handleActions} from 'redux-actions';
2 | import * as Actions from '../constants/actions';
3 |
4 | const initialState = {
5 | address: null,
6 | balances: {},
7 | allowances: {},
8 | };
9 |
10 | export default handleActions(
11 | {
12 | [Actions.SET_ALLOWANCE]: (state, action) => {
13 | const allowances = Object.assign({}, state.allowances);
14 | const [token, sender, allowance] = action.payload;
15 | if (!allowances[token]) {
16 | allowances[token] = {};
17 | }
18 | allowances[token][sender] = allowance;
19 | return {...state, allowances};
20 | },
21 | [Actions.SET_BALANCE]: (state, action) => {
22 | const balances = Object.assign({}, state.balances);
23 | const [token, balance] = action.payload;
24 | balances[token] = balance;
25 | return {...state, balances};
26 | },
27 | [Actions.SET_WALLET_ADDRESS]: (state, action) => {
28 | return {...state, address: action.payload};
29 | },
30 | },
31 | initialState,
32 | );
33 |
--------------------------------------------------------------------------------
/types/props/address.js:
--------------------------------------------------------------------------------
1 | const addressValidator = (
2 | propValue,
3 | key,
4 | componentName,
5 | location,
6 | propFullName
7 | ) => {
8 | const value = key !== null ? propValue[key] : propValue;
9 |
10 | if (typeof value !== 'string') {
11 | throw new Error(
12 | `${componentName}: incorrect prop ${propFullName} -- ${JSON.stringify(
13 | propValue
14 | )}`
15 | );
16 | }
17 |
18 | if (!/^(0x)?[a-fA-F0-9]{40}$/.test(value)) {
19 | throw new Error(
20 | `${componentName}: incorrect prop ${propFullName} -- ${JSON.stringify(
21 | propValue
22 | )}`
23 | );
24 | }
25 | };
26 |
27 | export const addressProp = (
28 | propValue,
29 | key,
30 | componentName,
31 | location,
32 | propFullName
33 | ) => {
34 | const value = key !== null ? propValue[key] : propValue;
35 |
36 | if (value !== null && value !== undefined) {
37 | addressValidator(propValue, key, componentName, location, propFullName);
38 | }
39 | };
40 |
41 | addressProp.isRequired = addressValidator;
42 |
--------------------------------------------------------------------------------
/App/components/AddressText.js:
--------------------------------------------------------------------------------
1 | import ethUtil from 'ethereumjs-util';
2 | import PropTypes from 'prop-types';
3 | import React, { Component } from 'react';
4 | import { Text } from 'react-native-elements';
5 | import { summarizeAddress } from '../../lib/utils';
6 |
7 | export default class AddressText extends Component {
8 | render() {
9 | const {
10 | address,
11 | containerStyle,
12 | leftStyle,
13 | rightStyle,
14 | summarize
15 | } = this.props;
16 | return (
17 |
18 | 0x
19 |
20 | {summarize
21 | ? summarizeAddress(address).substring(2)
22 | : ethUtil.stripHexPrefix(address)}
23 |
24 |
25 | );
26 | }
27 | }
28 |
29 | AddressText.propTypes = {
30 | address: PropTypes.string.isRequired,
31 | containerStyle: PropTypes.object,
32 | leftStyle: PropTypes.object,
33 | rightStyle: PropTypes.object,
34 | summarize: PropTypes.bool
35 | };
36 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | android.useAndroidX=true
21 | android.enableJetifier=true
22 | org.gradle.console=verbose
23 | org.gradle.logging.level=debug
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'mobidex'
2 | include ':react-native-navigation'
3 | project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-navigation/lib/android/app/')
4 | include ':react-native-restart'
5 | project(':react-native-restart').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-restart/android')
6 | include ':react-native-exception-handler'
7 | project(':react-native-exception-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-exception-handler/android/')
8 | include ':react-native-randombytes'
9 | project(':react-native-randombytes').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-randombytes/android/')
10 | include ':react-native-vector-icons'
11 | project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android/')
12 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
13 | include ':app'
14 |
--------------------------------------------------------------------------------
/App/components/Button.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Button as RNEButton } from 'react-native-elements';
3 | import { colors, styles } from '../../styles';
4 |
5 | export default class Button extends Component {
6 | render() {
7 | let { titleStyle, buttonStyle, loadingStyle, ...rest } = this.props;
8 | return (
9 |
16 | );
17 | }
18 | }
19 |
20 | const style = {
21 | button: {
22 | backgroundColor: colors.yellow0,
23 | borderColor: colors.yellow0,
24 | borderRadius: 0,
25 | borderWidth: 1,
26 | marginTop: 5,
27 | marginRight: 5,
28 | marginBottom: 5,
29 | marginLeft: 5,
30 | paddingLeft: 10,
31 | paddingRight: 10
32 | },
33 | disabled: {
34 | opacity: 0.7
35 | },
36 | title: {
37 | backgroundColor: 'transparent',
38 | color: 'white'
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/services/AssetService.js:
--------------------------------------------------------------------------------
1 | import * as _ from 'lodash';
2 |
3 | const ETHEREUM_ASSET = {
4 | address: null,
5 | symbol: 'ETH',
6 | name: 'Ethereum',
7 | decimals: 18,
8 | isEthereum: true,
9 | };
10 |
11 | const WETH_ASSET = {
12 | address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
13 | symbol: 'WETH',
14 | name: 'Wrapped Ethereum',
15 | decimals: 18,
16 | };
17 |
18 | let _store;
19 |
20 | export function setStore(store) {
21 | _store = store;
22 | }
23 |
24 | export function isEthereum(address) {
25 | return address === undefined || address === null || address === 'ETH';
26 | }
27 |
28 | export function isWETH(address) {
29 | return address === WETH_ASSET.address;
30 | }
31 |
32 | export function findAssetByAddress(address) {
33 | if (isEthereum(address)) {
34 | return getETHAsset();
35 | }
36 | if (isWETH(address)) {
37 | return getWETHAsset();
38 | }
39 | const {tokens} = _store.getState();
40 | return _.find(tokens, {address: address.toLowerCase()});
41 | }
42 |
43 | export function getETHAsset() {
44 | return ETHEREUM_ASSET;
45 | }
46 |
47 | export function getWETHAsset() {
48 | return WETH_ASSET;
49 | }
50 |
--------------------------------------------------------------------------------
/ios/Bitski.podspec.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Bitski",
3 | "version": "0.5.0",
4 | "summary": "Bitski SDK for iOS. Interact with Ethereum wallets using simple OpenID auth.",
5 | "description": "Provides tools for connecting to Ethereum wallets,\ncreating transactions, and interacting with the Ethereum\nnetwork through Web3.swift and OpenID Connect.",
6 | "homepage": "https://github.com/BitskiCo/bitski-ios",
7 | "license": {
8 | "type": "MIT",
9 | "file": "LICENSE"
10 | },
11 | "authors": {
12 | "Josh Pyles": "josh@outtherelabs.com"
13 | },
14 | "source": {
15 | "git": "https://github.com/BitskiCo/bitski-ios.git",
16 | "tag": "0.5.0"
17 | },
18 | "platforms": {
19 | "ios": "11.0"
20 | },
21 | "swift_versions": "4.0",
22 | "source_files": "Bitski/Classes/**/*",
23 | "exclude_files": "docs/**/*",
24 | "dependencies": {
25 | "Web3": ["~> 0.3.1"],
26 | "Web3/ContractABI": ["~> 0.3.1"],
27 | "Web3/PromiseKit": ["~> 0.3.1"],
28 | "AppAuth": ["~> 0.93"],
29 | "BigInt": ["~> 3.1"],
30 | "secp256k1.swift": ["~> 0.1"],
31 | "PromiseKit/CorePromise": ["~> 6.0"]
32 | },
33 | "swift_version": "4.0"
34 | }
35 |
--------------------------------------------------------------------------------
/App/components/TouchableListItem.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { TouchableOpacity, View } from 'react-native';
4 | import { ListItem } from 'react-native-elements';
5 | import EntypoIcon from 'react-native-vector-icons/Entypo';
6 | import { styles } from '../../styles';
7 | import MutedText from './MutedText';
8 | import Row from './Row';
9 |
10 | export default class TouchableListItem extends Component {
11 | static get propTypes() {
12 | return {
13 | title: PropTypes.string.isRequired,
14 | subtitle: PropTypes.node.isRequired,
15 | onPress: PropTypes.func.isRequired
16 | };
17 | }
18 |
19 | render() {
20 | return (
21 | {this.props.title}}
23 | subtitle={
24 |
25 |
26 | {this.props.subtitle}
27 |
28 |
29 |
30 | }
31 | />
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/clients/EtherChainGasPriceOracle.js:
--------------------------------------------------------------------------------
1 | import { BigNumber } from '@uniswap/sdk';
2 | import { time } from '../lib/decorators/cls';
3 | import { toBaseUnitAmount, toUnitAmount } from '../lib/utils';
4 |
5 | /**
6 | * Fetches gas recommendations from https://www.etherchain.org/tools/gasPriceOracle
7 | * Response example:
8 | {
9 | "fast": "4.0",
10 | "fastest": "14.0",
11 | "safeLow": "1.1",
12 | "standard": "2.0"
13 | }
14 | * Wait times is estimated based on https://www.etherchain.org/tools/gasPriceOracle.
15 | */
16 | export default class EtherChainGasPriceOracle {
17 | constructor(url = 'https://www.etherchain.org/api/gasPriceOracle') {
18 | this.url = url;
19 | }
20 |
21 | @time
22 | async get() {
23 | /**
24 |
25 | */
26 | const response = await fetch(this.url);
27 | const json = await response.json();
28 | const { fast, safeLow, standard } = json;
29 |
30 | return {
31 | low: toBaseUnitAmount(new BigNumber(safeLow), 9),
32 | lowWait: 30,
33 | standard: toBaseUnitAmount(new BigNumber(standard), 9),
34 | standardWait: 5,
35 | high: toBaseUnitAmount(new BigNumber(fast), 9),
36 | highWait: 1
37 | };
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/patches/zeroex-exchange-bug.sh:
--------------------------------------------------------------------------------
1 | function replace_address {
2 | FROM=$1;shift;
3 | TO=$1;shift;
4 | FILES=$( grep ${FROM} node_modules -RFl );
5 |
6 | for FILENAME in ${FILES}; do
7 | echo sed -i.bk "s/${FROM}/${TO}/g" "${FILENAME}";
8 | sed -i.bk "s/${FROM}/${TO}/g" "${FILENAME}";
9 | done;
10 | }
11 |
12 | # ERC20Proxy
13 | replace_address '0x2240dab907db71e64d3e0dba4800c83b5c502d4e' '0x95e6f48254609a6ee006f7d493c8e5fb97094cef';
14 |
15 | # ERC721Proxy
16 | replace_address '0x208e41fb445f1bb1b6780d58356e81405f3e6127' '0xefc70a1b18c432bdc64b596838b4d138f6bc6cad';
17 |
18 | # MAP
19 | # replace_address '' '0xef701d5389ae74503d633396c4d654eabedc9d78';
20 |
21 | # Exchange
22 | replace_address '0x4f833a24e1f95d70f028921e27040ca56e09ab0b' '0x080bf510fcbf18b91105470639e9561022937712';
23 |
24 | # APOwner
25 | replace_address '0x17992e4ffb22730138e4b62aaa6367fa9d3699a6' '0xdffe798c7172dd6deb32baee68af322e8f495ce0';
26 |
27 | # Forwarder
28 | replace_address '0x7afc2d5107af94c462a194d2c21b5bdd238709d6' '0x76481caa104b5f6bccb540dae4cefaf1c398ebea';
29 |
30 | # OrderValidator
31 | replace_address '0x9463e518dea6810309563c81d5266c1b1d149138' '0xa09329c6003c9a5402102e226417738ee22cf1f2';
32 |
--------------------------------------------------------------------------------
/store.js:
--------------------------------------------------------------------------------
1 | import {BigNumber} from '@uniswap/sdk';
2 | import {applyMiddleware, createStore} from 'redux';
3 | import thunk from 'redux-thunk';
4 | import {saveStateMiddleware} from './lib/middleware/app';
5 | import {getState} from './lib/stores/app';
6 | import rootReducer from './reducers';
7 |
8 | let STORE = null;
9 |
10 | const BIG_NUMBER_FIELDS = ['gasPrice', 'gasLimit'];
11 |
12 | function convertBigNumbers(value, key) {
13 | if (typeof value === 'object') {
14 | for (const key in value) {
15 | value[key] = convertBigNumbers(value[key], key);
16 | }
17 | return value;
18 | } else if (typeof value === 'array') {
19 | return value.map(v => convertBigNumbers(v, key));
20 | } else {
21 | if (~BIG_NUMBER_FIELDS.indexOf(key)) {
22 | return new BigNumber(value);
23 | } else {
24 | return value;
25 | }
26 | }
27 | }
28 |
29 | export async function initialize(next) {
30 | const initialState = await getState(convertBigNumbers);
31 | STORE = createStore(
32 | rootReducer,
33 | initialState,
34 | applyMiddleware(thunk, saveStateMiddleware),
35 | );
36 | next(STORE);
37 | }
38 |
39 | export function get() {
40 | return STORE;
41 | }
42 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 |
33 | # node.js
34 | #
35 | node_modules/
36 | npm-debug.log
37 | yarn-error.log
38 |
39 | # BUCK
40 | buck-out/
41 | \.buckd/
42 | *.keystore
43 |
44 | # fastlane
45 | #
46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47 | # screenshots whenever they are needed.
48 | # For more information about the recommended setup visit:
49 | # https://docs.fastlane.tools/best-practices/source-control/
50 |
51 | */fastlane/report.xml
52 | */fastlane/Preview.html
53 | */fastlane/screenshots
54 |
55 | # Bundle artifact
56 | *.jsbundle
57 |
58 | # App gradle files
59 | android/app/gradle
60 | android/app/gradlew
61 | android/app/gradlew.bat
62 |
63 | # Custom
64 | /ios/Pods/
65 | ios/.gems
66 |
--------------------------------------------------------------------------------
/types/props/transaction.js:
--------------------------------------------------------------------------------
1 | import { BigNumber } from '@uniswap/sdk';
2 | import PropTypes from 'prop-types';
3 | import { addressProp } from './address';
4 |
5 | const transactionIdValidator = (
6 | propValue,
7 | key,
8 | componentName,
9 | location,
10 | propFullName
11 | ) => {
12 | if (typeof propValue !== 'string') {
13 | throw new Error(`${componentName}: incorrect prop ${propFullName}`);
14 | }
15 |
16 | if (!/^(0x)?[a-fA-F0-9]{64}$/.test(propValue)) {
17 | throw new Error(`${componentName}: incorrect prop ${propFullName}`);
18 | }
19 | };
20 |
21 | export const transactionIdProp = (
22 | propValue,
23 | key,
24 | componentName,
25 | location,
26 | propFullName
27 | ) => {
28 | if (propValue !== null && propValue !== undefined) {
29 | transactionIdValidator(
30 | propValue,
31 | key,
32 | componentName,
33 | location,
34 | propFullName
35 | );
36 | }
37 | };
38 |
39 | export const transactionProp = PropTypes.shape({
40 | id: transactionIdProp.isRequired,
41 | from: addressProp.isRequired,
42 | to: addressProp.isRequired,
43 | type: PropTypes.string.isRequired,
44 | amount: PropTypes.instanceOf(BigNumber)
45 | });
46 |
--------------------------------------------------------------------------------
/error-handlers.js:
--------------------------------------------------------------------------------
1 | import 'node-libs-react-native/globals';
2 | import {Alert} from 'react-native';
3 | import {
4 | setJSExceptionHandler,
5 | setNativeExceptionHandler,
6 | } from 'react-native-exception-handler';
7 | import RNRestart from 'react-native-restart';
8 |
9 | export function setExceptionHandlers() {
10 | setJSExceptionHandler((error, isFatal) => {
11 | if (isFatal) {
12 | if (error) {
13 | Alert.alert(
14 | 'Unexpected error occurred',
15 | `Error: ${error.name} ${
16 | error.message
17 | }. We will need to restart the app.`,
18 | [
19 | {
20 | text: 'Restart',
21 | onPress: () => RNRestart.Restart(),
22 | },
23 | ],
24 | {cancelable: false},
25 | );
26 | } else {
27 | Alert.alert(
28 | 'Unexpected error occurred',
29 | 'We will need to restart the app.',
30 | [
31 | {
32 | text: 'Restart',
33 | onPress: () => RNRestart.Restart(),
34 | },
35 | ],
36 | {cancelable: false},
37 | );
38 | }
39 | }
40 | }, true);
41 | }
42 |
--------------------------------------------------------------------------------
/thunks/settings.js:
--------------------------------------------------------------------------------
1 | import { BigNumber } from '@uniswap/sdk';
2 | import { setGasPrice } from '../actions';
3 | import EthGasStationInfo from '../clients/EthGasStationInfo.js';
4 | import EtherChainGasPriceOracle from '../clients/EtherChainGasPriceOracle.js';
5 | import { WalletService } from '../services/WalletService';
6 |
7 | export function refreshGasPrice() {
8 | return async (dispatch, getState) => {
9 | const {
10 | settings: { gasLevel, gasStation }
11 | } = getState();
12 | let gasPrice = null;
13 |
14 | if (gasStation === 'eth-gas-station-info') {
15 | const client = new EthGasStationInfo();
16 | const estimates = await client.get();
17 | gasPrice = estimates[gasLevel];
18 | } else if (gasStation === 'ether-chain-gas-price-oracle') {
19 | const client = new EtherChainGasPriceOracle();
20 | const estimates = await client.get();
21 | gasPrice = estimates[gasLevel];
22 | } else {
23 | const web3 = WalletService.instance.web3;
24 | const ethGasPrice = await web3.eth.getGasPrice();
25 | gasPrice = new BigNumber(ethGasPrice);
26 | }
27 |
28 | dispatch(setGasPrice(gasPrice));
29 |
30 | return gasPrice;
31 | };
32 | }
33 |
--------------------------------------------------------------------------------
/App/components/EthereumAmount.js:
--------------------------------------------------------------------------------
1 | import {BigNumber, formatFixedDecimals} from '@uniswap/sdk';
2 | import PropTypes from 'prop-types';
3 | import React from 'react';
4 | import {Text} from 'react-native-elements';
5 | import * as AssetService from '../../services/AssetService';
6 | import {BigNumberProp} from '../../types/props';
7 |
8 | export default class EthereumAmount extends React.PureComponent {
9 | static get propTypes() {
10 | return {
11 | amount: BigNumberProp.isRequired,
12 | unit: PropTypes.string.isRequired,
13 | decimalPlaces: PropTypes.number.isRequired,
14 | };
15 | }
16 |
17 | static get defaultProps() {
18 | return {
19 | unit: 'ether',
20 | decimalPlaces: 6,
21 | };
22 | }
23 |
24 | render() {
25 | const {unit, decimalPlaces, amount, ...rest} = this.props;
26 | let decimals = 18;
27 | switch (unit) {
28 | case 'wei':
29 | decimals = 0;
30 | break;
31 |
32 | case 'gwei':
33 | decimals = 9;
34 | break;
35 | }
36 | const formattedAmount = formatFixedDecimals(amount, decimals, {
37 | decimalPlaces,
38 | });
39 |
40 | return {formattedAmount};
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/App/components/RotatingView.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { Animated } from 'react-native';
4 |
5 | export default class RotatingView extends Component {
6 | static propTypes = {
7 | duration: PropTypes.number.isRequired
8 | };
9 |
10 | static defaultProps = {
11 | duration: 1000
12 | };
13 |
14 | constructor(props) {
15 | super(props);
16 |
17 | this.rotation = new Animated.Value(0);
18 | }
19 |
20 | async componentDidMount() {
21 | Animated.loop(
22 | Animated.timing(this.rotation, {
23 | toValue: 1,
24 | duration: this.props.duration,
25 | delay: 0,
26 | useNativeDriver: true,
27 | isInteraction: false
28 | })
29 | ).start();
30 | }
31 |
32 | render() {
33 | return (
34 |
46 | {this.props.children}
47 |
48 | );
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/android/app/src/main/java/io/mobidex/MainActivity.java:
--------------------------------------------------------------------------------
1 | package io.mobidex;
2 |
3 | import android.graphics.drawable.Drawable;
4 | import android.os.Bundle;
5 | import android.widget.LinearLayout;
6 |
7 | import androidx.core.content.ContextCompat;
8 |
9 | import com.facebook.react.modules.i18nmanager.I18nUtil;
10 | import com.reactnativenavigation.NavigationActivity;
11 |
12 | public class MainActivity extends NavigationActivity {
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(this.createSplashLayout());
17 | I18nUtil sharedI18nUtilInstance = I18nUtil.getInstance();
18 | sharedI18nUtilInstance.allowRTL(getApplicationContext(), false);
19 | }
20 |
21 | public LinearLayout createSplashLayout() {
22 | LinearLayout splash = new LinearLayout(this);
23 | Drawable launch_screen_bitmap = ContextCompat.getDrawable(getApplicationContext(), R.drawable.launch_screen);
24 | splash.setBackground(launch_screen_bitmap);
25 |
26 | // I18nUtil sharedI18nUtilInstance = I18nUtil.getInstance();
27 | // sharedI18nUtilInstance.allowRTL(context, false);
28 |
29 | return splash;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/cli/build-android.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | pushd android
3 |
4 | read -sp 'If you would like to sign the APK, please add your store passphrase now: ' MOBIDEX_RELEASE_STORE_PASSWORD
5 | echo ""
6 | if [ -z ${MOBIDEX_RELEASE_STORE_PASSWORD+x} ]; then
7 | ./gradlew clean assembleRelease -PMOBIDEX_SIGN=0
8 | else
9 | read -p 'Mobidex keystore path relative to ./android/app (default: ../../mobidex.keystore): ' MOBIDEX_RELEASE_STORE_FILE
10 | read -p 'Mobidex keystore alias (default: mobidex): ' MOBIDEX_RELEASE_KEY_ALIAS
11 | echo ""
12 |
13 | # This was just `assembleRelease`. Had to change for react-native-navigation.
14 | echo "./gradlew clean app:assembleRelease -PMOBIDEX_RELEASE_KEY_ALIAS=${MOBIDEX_RELEASE_KEY_ALIAS+mobidex} -PMOBIDEX_RELEASE_STORE_FILE=${MOBIDEX_RELEASE_STORE_FILE+../mobidex.keystore} -PMOBIDEX_RELEASE_STORE_PASSWORD= -PMOBIDEX_RELEASE_KEY_PASSWORD= -PMOBIDEX_SIGN=1"
15 | ./gradlew clean app:assembleRelease -PMOBIDEX_RELEASE_KEY_ALIAS=${MOBIDEX_RELEASE_KEY_ALIAS+mobidex} -PMOBIDEX_RELEASE_STORE_FILE=${MOBIDEX_RELEASE_STORE_FILE+../../mobidex.keystore} -PMOBIDEX_RELEASE_STORE_PASSWORD=${MOBIDEX_RELEASE_STORE_PASSWORD} -PMOBIDEX_RELEASE_KEY_PASSWORD=${MOBIDEX_RELEASE_STORE_PASSWORD} -PMOBIDEX_SIGN=1;
16 | fi;
17 |
18 | popd android
19 |
--------------------------------------------------------------------------------
/services/UniswapService.js:
--------------------------------------------------------------------------------
1 | import EthereumClient from '../clients/ethereum';
2 | import UniswapClient from '../clients/Uniswap';
3 | import BaseService from './BaseService';
4 | import {WalletService} from './WalletService';
5 |
6 | export class UniswapService extends BaseService {
7 | async getExchangeAddressForToken(tokenAddress) {
8 | const {
9 | settings: {
10 | uniswap: {factoryAddress},
11 | },
12 | } = this.store.getState();
13 |
14 | const ethereumClient = new EthereumClient(WalletService.instance.web3);
15 | const uniswapClient = new UniswapClient(ethereumClient, factoryAddress);
16 | const factoryContract = await uniswapClient.getFactoryContract();
17 | const exchangeAddress = await factoryContract.methods
18 | .getExchange(tokenAddress)
19 | .call();
20 |
21 | return exchangeAddress;
22 | }
23 |
24 | async getExchangeContract(exchangeAddress) {
25 | const {
26 | settings: {
27 | uniswap: {factoryAddress},
28 | },
29 | } = this.store.getState();
30 |
31 | const ethereumClient = new EthereumClient(WalletService.instance.web3);
32 | const uniswapClient = new UniswapClient(ethereumClient, factoryAddress);
33 | return await uniswapClient.getExchangeContract(exchangeAddress);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/clients/Uniswap.js:
--------------------------------------------------------------------------------
1 | import {ContractDefinitionLoader} from 'web3-contracts-loader';
2 | import {time} from '../lib/decorators/cls';
3 |
4 | const FactoryABI = require('../abi/uniswap/Factory.json');
5 | const ExchangeABI = require('../abi/uniswap/Exchange.json');
6 |
7 | export default class UniswapClient {
8 | constructor(ethereumClient, address) {
9 | this.ethereumClient = ethereumClient;
10 | this.address = address;
11 | }
12 |
13 | @time
14 | async getContract(name, abi, address) {
15 | const networkId = await this.ethereumClient.getNetworkId();
16 | const account = await this.ethereumClient.getAccount();
17 | return ContractDefinitionLoader({
18 | web3: this.ethereumClient.getWeb3(),
19 | contractDefinitions: {
20 | [name]: {
21 | ...abi,
22 | networks: {
23 | [networkId]: {
24 | address,
25 | },
26 | },
27 | },
28 | },
29 | options: {
30 | from: account,
31 | },
32 | })[name];
33 | }
34 |
35 | @time
36 | async getFactoryContract() {
37 | return this.getContract('Factory', FactoryABI, this.address);
38 | }
39 |
40 | @time
41 | async getExchangeContract(address) {
42 | return this.getContract('Exchange', ExchangeABI, address);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/android/app/src/main/java/io/mobidex/WalletManager.kt:
--------------------------------------------------------------------------------
1 | package io.mobidex
2 |
3 | import org.kethereum.bip32.model.ExtendedKey
4 | import org.kethereum.bip32.toKey
5 | import org.kethereum.bip39.dirtyPhraseToMnemonicWords
6 | import org.kethereum.bip39.toSeed
7 | import org.kethereum.model.Address
8 | import org.kethereum.model.Transaction
9 | import org.kethereum.model.createTransactionWithDefaults
10 | import java.math.BigInteger
11 |
12 | fun mnemonicToKey(mnemonic: String, password: String): ExtendedKey {
13 | val words = dirtyPhraseToMnemonicWords(mnemonic)
14 | val seed = words.toSeed(password)
15 | val key = seed.toKey("m/44'/60'/0'/0/0")
16 | return key
17 | }
18 |
19 | fun createTransaction(
20 | from: Address,
21 | gasLimit: BigInteger,
22 | gasPrice: BigInteger,
23 | input: ByteArray,
24 | nonce: BigInteger,
25 | to: Address,
26 | value: BigInteger
27 | ): Transaction {
28 | val tx = createTransactionWithDefaults(
29 | chain = null,
30 | creationEpochSecond = null,
31 | from = from,
32 | gasLimit = gasLimit,
33 | gasPrice = gasPrice,
34 | input = input,
35 | nonce = nonce,
36 | to = to,
37 | txHash = null,
38 | value = value)
39 | return tx;
40 | }
--------------------------------------------------------------------------------
/services/TransactionService.js:
--------------------------------------------------------------------------------
1 | import {addActiveTransactions, removeActiveTransactions} from '../actions';
2 | import {cache} from '../lib/utils';
3 | import BaseService from './BaseService';
4 | import {WalletService} from './WalletService';
5 |
6 | export class TransactionService extends BaseService {
7 | async addActiveTransaction(tx) {
8 | this.store.dispatch(addActiveTransactions([tx]));
9 |
10 | const {
11 | settings,
12 | wallet: {activeTransactions},
13 | } = this.store.getState();
14 | await cache(
15 | `transactions:${settings.network}:active`,
16 | async () => {
17 | return activeTransactions;
18 | },
19 | 0,
20 | );
21 | }
22 |
23 | async removeActiveTransaction(tx) {
24 | this.store.dispatch(removeActiveTransactions([tx]));
25 |
26 | const {
27 | settings,
28 | wallet: {activeTransactions},
29 | } = this.store.getState();
30 | await cache(
31 | `transactions:${settings.network}:active`,
32 | async () => {
33 | return activeTransactions;
34 | },
35 | 0,
36 | );
37 | }
38 |
39 | async getActiveTransactions() {
40 | const {settings} = this.store.getState();
41 | return await cache(
42 | `transactions:${settings.network}:active`,
43 | async () => {
44 | return [];
45 | },
46 | 60 * 60 * 24 * 7,
47 | );
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/navigation/permissions.js:
--------------------------------------------------------------------------------
1 | import { Platform, PermissionsAndroid } from 'react-native';
2 | import { showErrorModal } from './methods';
3 |
4 | export async function checkOrRequestExternalStorageRead() {
5 | if (Platform.OS === 'android') {
6 | try {
7 | const granted = await PermissionsAndroid.request(
8 | PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
9 | {
10 | title: 'Mobidex Read From Storage',
11 | message:
12 | 'Mobidex may access to external storage to access your local wallet.'
13 | }
14 | );
15 |
16 | return granted === PermissionsAndroid.RESULTS.GRANTED;
17 | } catch (err) {
18 | showErrorModal(err);
19 | }
20 | } else {
21 | return true;
22 | }
23 | }
24 |
25 | export async function checkOrRequestExternalStorageWrite() {
26 | if (Platform.OS === 'android') {
27 | try {
28 | const granted = await PermissionsAndroid.request(
29 | PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
30 | {
31 | title: 'Mobidex Read From Storage',
32 | message:
33 | 'Mobidex may access to external storage to access your local wallet.'
34 | }
35 | );
36 |
37 | return granted === PermissionsAndroid.RESULTS.GRANTED;
38 | } catch (err) {
39 | showErrorModal(err);
40 | }
41 | } else {
42 | return true;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/lib/utils/cache.js:
--------------------------------------------------------------------------------
1 | import moment from 'moment';
2 | import { AsyncStorage } from 'react-native';
3 |
4 | export async function cache(ns, update, expiration = 60 * 60 * 24) {
5 | let lastUpdatedJson = await AsyncStorage.getItem(`${ns}:last-updated`);
6 | let lastUpdated = lastUpdatedJson ? JSON.parse(lastUpdatedJson).data : null;
7 | let dataJson = await AsyncStorage.getItem(`${ns}:data`);
8 | let data = dataJson ? JSON.parse(dataJson).data : null;
9 |
10 | if (
11 | !data ||
12 | !lastUpdated ||
13 | moment().unix() - parseInt(lastUpdated) > expiration
14 | ) {
15 | data = await update();
16 |
17 | await AsyncStorage.setItem(`${ns}:data`, JSON.stringify({ data: data }));
18 | await AsyncStorage.setItem(
19 | `${ns}:last-updated`,
20 | JSON.stringify({ data: moment().unix() })
21 | );
22 | }
23 |
24 | return data;
25 | }
26 |
27 | export async function invalidate(ns) {
28 | await AsyncStorage.multiRemove([
29 | AsyncStorage.removeItem(`${ns}:last-updated`),
30 | AsyncStorage.removeItem(`${ns}:data`)
31 | ]);
32 | }
33 |
34 | export async function clearCache() {
35 | const keys = await AsyncStorage.getAllKeys();
36 | const dataKeys = keys.filter(key => key.indexOf(':data') !== -1);
37 | const lastUpdatedKeys = keys.filter(
38 | key => key.indexOf(':last-updated') !== -1
39 | );
40 | await AsyncStorage.multiRemove(dataKeys.concat(lastUpdatedKeys));
41 | }
42 |
--------------------------------------------------------------------------------
/App/components/ReferralCodeInput.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { Input } from 'react-native-elements';
4 | import SmallClearButton from './SmallClearButton';
5 | import Row from './Row';
6 |
7 | export default class ReferralCodeInput extends Component {
8 | static get propTyeps() {
9 | return {
10 | onSubmit: PropTypes.func,
11 | containerStyle: PropTypes.object,
12 | wrapperStyle: PropTypes.object
13 | };
14 | }
15 |
16 | constructor(props) {
17 | super(props);
18 |
19 | this.state = {
20 | value: ''
21 | };
22 | }
23 |
24 | render() {
25 | const { ...rest } = this.props;
26 | return (
27 |
28 |
37 |
38 |
39 | );
40 | }
41 |
42 | onChange = value => this.setState({ value });
43 |
44 | onSubmit = () => {
45 | const { value } = this.state;
46 | if (this.props.onSubmit) {
47 | this.props.onSubmit(value);
48 | }
49 | };
50 | }
51 |
--------------------------------------------------------------------------------
/App/components/SmallClearButton.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { StyleSheet } from 'react-native';
4 | import { colors } from '../../styles';
5 | import { styleProp } from '../../types/props';
6 | import Button from './Button';
7 |
8 | export default class SmallClearButton extends Component {
9 | static get propTypes() {
10 | return {
11 | onPress: PropTypes.func,
12 | buttonStyle: styleProp,
13 | titleStyle: styleProp
14 | };
15 | }
16 |
17 | render() {
18 | const { buttonStyle, onPress, titleStyle, ...rest } = this.props;
19 | return (
20 |
27 | );
28 | }
29 | }
30 |
31 | const style = StyleSheet.create({
32 | button: {
33 | backgroundColor: colors.transparent,
34 | borderColor: colors.primary,
35 | borderRadius: 3,
36 | borderWidth: 1,
37 | elevation: 0,
38 | marginTop: 0,
39 | marginRight: 0,
40 | marginBottom: 0,
41 | marginLeft: 0,
42 | paddingLeft: 0,
43 | paddingRight: 0
44 | },
45 | disabled: {
46 | opacity: 0.7
47 | },
48 | title: {
49 | backgroundColor: colors.transparent,
50 | color: colors.primary
51 | }
52 | });
53 |
--------------------------------------------------------------------------------
/clients/EthGasStationInfo.js:
--------------------------------------------------------------------------------
1 | import { BigNumber } from '@uniswap/sdk';
2 | import { time } from '../lib/decorators/cls';
3 | import { toBaseUnitAmount, toUnitAmount } from '../lib/utils';
4 |
5 | /**
6 | * Fetches gas recommendations from https://ethgasstation.info
7 | * Response example:
8 | {
9 | "average": 13.0,
10 | "avgWait": 2.0,
11 | "blockNum": 7165329,
12 | "block_time": 15.679144385026738,
13 | "fast": 40.0,
14 | "fastWait": 0.7,
15 | "fastest": 200.0,
16 | "fastestWait": 0.6,
17 | "safeLow": 11.0,
18 | "safeLowWait": 2.2,
19 | "speed": 0.4966788525885503
20 | }
21 | * Wait times appear to be in minutes.
22 | */
23 | export default class EthGasStationInfo {
24 | constructor(url = 'https://ethgasstation.info/json/ethgasAPI.json') {
25 | this.url = url;
26 | }
27 |
28 | @time
29 | async get() {
30 | const response = await fetch(this.url);
31 | const json = await response.json();
32 | const { average, avgWait, fast, fastWait, safeLow, safeLowWait } = json;
33 |
34 | return {
35 | low: toBaseUnitAmount(new BigNumber(safeLow).div(10), 9),
36 | lowWait: safeLowWait,
37 | // medium: safeLow + (fast - safeLow) / 2,
38 | // mediumWait: safeLowWait - (safeLowWait - fastWait) / 2,
39 | standard: toBaseUnitAmount(new BigNumber(average).div(10), 9),
40 | standardWait: avgWait,
41 | high: toBaseUnitAmount(new BigNumber(fast).div(10), 9),
42 | highWait: fastWait
43 | };
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ios/WalletManagerBridge.m:
--------------------------------------------------------------------------------
1 | //
2 | // WalletManagerBridge.m
3 | // mobidex
4 | //
5 | // Created by Abraham Elmahrek on 6/21/18.
6 | // Copyright © 2018 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import
12 |
13 | @interface RCT_EXTERN_MODULE(WalletManager, NSObject)
14 |
15 | RCT_EXTERN_METHOD(isWalletAvailable:(RCTResponseSenderBlock)callback)
16 | RCT_EXTERN_METHOD(supportsFingerPrintAuthentication:(RCTResponseSenderBlock)callback)
17 | RCT_EXTERN_METHOD(supportsFaceIDAuthentication:(RCTResponseSenderBlock)callback)
18 | RCT_EXTERN_METHOD(cancelFingerPrintAuthentication:(RCTResponseSenderBlock)callback)
19 | RCT_EXTERN_METHOD(cancelFaceIDAuthentication:(RCTResponseSenderBlock)callback)
20 | RCT_EXTERN_METHOD(generateMnemonics:(RCTResponseSenderBlock)callback)
21 | RCT_EXTERN_METHOD(importWalletByMnemonics:(NSString *)mnemonic password:(NSString *)password callback:(RCTResponseSenderBlock)callback)
22 | RCT_EXTERN_METHOD(removeWallet:(RCTResponseSenderBlock)callback)
23 | RCT_EXTERN_METHOD(loadWallet:(NSString *)password callback:(RCTResponseSenderBlock)callback)
24 | RCT_EXTERN_METHOD(loadWalletAddress:(RCTResponseSenderBlock)callback)
25 | RCT_EXTERN_METHOD(signTransaction:(NSDictionary *)tx password:(NSString *)password callback:(RCTResponseSenderBlock)callback)
26 | RCT_EXTERN_METHOD(signMessage:(NSString *)message password:(NSString *)password callback:(RCTResponseSenderBlock)callback)
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/App/components/UserIcon.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, {Component} from 'react';
3 | import {View} from 'react-native';
4 | import {Avatar, Text} from 'react-native-elements';
5 | import * as AssetService from '../../services/AssetService';
6 | import {fonts, images, styles} from '../../styles';
7 | import {addressProp} from '../../types/props';
8 | import AddressText from './AddressText';
9 | import Row from './Row';
10 |
11 | export default class UserIcon extends Component {
12 | static get propTypes() {
13 | return {
14 | address: addressProp.isRequired,
15 | avatarProps: PropTypes.object,
16 | containerStyle: PropTypes.object,
17 | labelProps: PropTypes.object,
18 | };
19 | }
20 |
21 | render() {
22 | const {
23 | address,
24 | avatarProps,
25 | containerStyle,
26 | labelProps,
27 | ...rest
28 | } = this.props;
29 |
30 | return (
31 |
32 |
39 |
40 |
41 |
47 |
48 |
49 | );
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/android/app/src/main/java/io/mobidex/MainApplication.java:
--------------------------------------------------------------------------------
1 | package io.mobidex;
2 |
3 | import com.avishayil.rnrestart.ReactNativeRestartPackage;
4 | import com.bitgo.randombytes.RandomBytesPackage;
5 | import com.facebook.react.ReactNativeHost;
6 | import com.facebook.react.ReactPackage;
7 | import com.masteratul.exceptionhandler.ReactNativeExceptionHandlerPackage;
8 | import com.oblador.vectoricons.VectorIconsPackage;
9 | import com.reactnativenavigation.NavigationApplication;
10 | import com.reactnativenavigation.react.NavigationReactNativeHost;
11 |
12 | import java.util.Arrays;
13 | import java.util.List;
14 |
15 |
16 | public class MainApplication extends NavigationApplication {
17 |
18 | @Override
19 | protected ReactNativeHost createReactNativeHost() {
20 | return new NavigationReactNativeHost(this) {
21 | @Override
22 | protected String getJSMainModuleName() {
23 | return "index";
24 | }
25 | };
26 | }
27 |
28 | @Override
29 | public boolean isDebug() {
30 | return BuildConfig.DEBUG;
31 | }
32 |
33 | @Override
34 | public List createAdditionalReactPackages() {
35 | return Arrays.asList(
36 | new ReactNativeExceptionHandlerPackage(),
37 | new RandomBytesPackage(),
38 | new ReactNativeRestartPackage(),
39 | new VectorIconsPackage(),
40 | new WalletManagerPackage()
41 | );
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/ios/mobidex/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "mobidex-40.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "mobidex-60.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "mobidex-58.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "mobidex-87.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "mobidex-80.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "mobidex-120.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "mobidex-121.png",
43 | "scale" : "2x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "mobidex-180.png",
49 | "scale" : "3x"
50 | },
51 | {
52 | "size" : "1024x1024",
53 | "idiom" : "ios-marketing",
54 | "filename" : "logo-with-text-1024.png",
55 | "scale" : "1x"
56 | }
57 | ],
58 | "info" : {
59 | "version" : 1,
60 | "author" : "xcode"
61 | }
62 | }
--------------------------------------------------------------------------------
/App/modals/ErrorModal/InsufficientFundsError.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { Text } from 'react-native-elements';
4 | import { colors } from '../../../styles';
5 | import { WalletService } from '../../../services/WalletService';
6 |
7 | // Error message:
8 | // ${error_enum}: ${text}
9 | export default class InsufficientFundsError extends Component {
10 | static test(error) {
11 | if (!error) return false;
12 | if (!error.message) return false;
13 | return error.message && error.message.indexOf('Insufficient funds.') === 0;
14 | }
15 |
16 | render() {
17 | const error = this.props.error.message;
18 | const x = error.indexOf('got:');
19 | const web3 = WalletService.instance.web3;
20 |
21 | let required = error.slice(0, x).replace( /[^0-9]/g , '');
22 | let available = error.slice(x).replace( /[^0-9]/g, '' );
23 |
24 | required = web3.utils.fromWei(required, 'ether');
25 | available = web3.utils.fromWei(available, 'ether');
26 |
27 | return (
28 |
29 | Insufficient Funds: Required {required} and got {available} .
30 |
31 | );
32 | }
33 | }
34 |
35 | InsufficientFundsError.propTypes = {
36 | error: PropTypes.shape({
37 | message: PropTypes.string.isRequired
38 | }).isRequired
39 | };
40 |
41 | const styles = {
42 | text: {
43 | fontSize: 18,
44 | color: colors.primary,
45 | paddingBottom: 10,
46 | textAlign: 'center'
47 | }
48 | };
49 |
--------------------------------------------------------------------------------
/android/app/BUCK:
--------------------------------------------------------------------------------
1 | # To learn about Buck see [Docs](https://buckbuild.com/).
2 | # To run your application with Buck:
3 | # - install Buck
4 | # - `npm start` - to start the packager
5 | # - `cd android`
6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
8 | # - `buck install -r android/app` - compile, install and run application
9 | #
10 |
11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")
12 |
13 | lib_deps = []
14 |
15 | create_aar_targets(glob(["libs/*.aar"]))
16 | create_jar_targets(glob(["libs/*.jar"]))
17 |
18 | android_library(
19 | name = "all-libs",
20 | exported_deps = lib_deps,
21 | )
22 |
23 | android_library(
24 | name = "app-code",
25 | srcs = glob([
26 | "src/main/java/**/*.java",
27 | ]),
28 | deps = [
29 | ":all-libs",
30 | ":build_config",
31 | ":res",
32 | ],
33 | )
34 |
35 | android_build_config(
36 | name = "build_config",
37 | package = "io.mobidex",
38 | )
39 |
40 | android_resource(
41 | name = "res",
42 | package = "io.mobidex",
43 | res = "src/main/res",
44 | )
45 |
46 | android_binary(
47 | name = "app",
48 | keystore = "//android/keystores:debug",
49 | manifest = "src/main/AndroidManifest.xml",
50 | package_type = "debug",
51 | deps = [
52 | ":app-code",
53 | ],
54 | )
55 |
--------------------------------------------------------------------------------
/App/screens/trade/DetailsScreen/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Navigation} from 'react-native-navigation';
3 | import FA from 'react-native-vector-icons/FontAwesome';
4 | import {showModal} from '../../../../navigation';
5 | import NavigationProvider from '../../../NavigationProvider';
6 | import Base from './base';
7 |
8 | export default class DetailsScreen extends React.PureComponent {
9 | static options() {
10 | return {
11 | topBar: {
12 | visible: true,
13 | drawBehind: false,
14 | backButton: {
15 | color: 'black',
16 | },
17 | title: {
18 | text: 'Trade',
19 | alignment: 'center',
20 | },
21 | },
22 | };
23 | }
24 |
25 | constructor(props) {
26 | super(props);
27 | Navigation.events().bindComponent(this);
28 | }
29 |
30 | async componentWillMount() {
31 | const source = await FA.getImageSource('send', 24, '#000000');
32 | Navigation.mergeOptions(this.props.componentId, {
33 | topBar: {
34 | rightButtons: [
35 | {
36 | id: 'send',
37 | icon: source,
38 | },
39 | ],
40 | },
41 | });
42 | }
43 |
44 | navigationButtonPressed({buttonId}) {
45 | if (buttonId === 'send') {
46 | showModal('modals.Send', this.props);
47 | }
48 | }
49 |
50 | render() {
51 | return (
52 |
53 |
54 |
55 | );
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/clients/EtherToken.js:
--------------------------------------------------------------------------------
1 | import {ContractDefinitionLoader} from 'web3-contracts-loader';
2 | import {time} from '../lib/decorators/cls';
3 | import {bigIntToEthHex} from '../lib/utils';
4 |
5 | const Weth9ABI = require('../abi/WETH9.json');
6 |
7 | let CONTRACT = null;
8 |
9 | export default class EtherToken {
10 | constructor(ethereumClient, address) {
11 | this.ethereumClient = ethereumClient;
12 | this.address = address;
13 | }
14 |
15 | @time
16 | async getContract() {
17 | if (!CONTRACT) {
18 | const networkId = await this.ethereumClient.getNetworkId();
19 | const account = await this.ethereumClient.getAccount();
20 | CONTRACT = ContractDefinitionLoader({
21 | web3: this.ethereumClient.getWeb3(),
22 | contractDefinitions: {
23 | WETH9: {
24 | ...Weth9ABI,
25 | networks: {
26 | [networkId]: {
27 | address: this.address,
28 | },
29 | },
30 | },
31 | },
32 | options: {
33 | from: account,
34 | },
35 | }).WETH9;
36 | }
37 |
38 | return CONTRACT;
39 | }
40 |
41 | @time
42 | async balanceOf(account) {
43 | const contract = await this.getContract();
44 | const result = await contract.methods.balanceOf(account);
45 | return result;
46 | }
47 |
48 | @time
49 | async withdraw(wad) {
50 | const contract = await this.getContract();
51 | const result = contract.methods.withdraw(bigIntToEthHex(wad)).send();
52 | return result;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/App/screens/trade/ProductScreen/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Navigation } from 'react-native-navigation';
3 | import FontAwesome from 'react-native-vector-icons/FontAwesome';
4 | import { showModal } from '../../../../navigation';
5 | import NavigationProvider from '../../../NavigationProvider';
6 | import Base from './base';
7 |
8 | export default class ProductScreen extends React.PureComponent {
9 | static options() {
10 | return {
11 | topBar: {
12 | visible: true,
13 | drawBehind: false,
14 | backButton: {
15 | color: 'black'
16 | },
17 | title: {
18 | text: 'Trade',
19 | alignment: 'center'
20 | }
21 | }
22 | };
23 | }
24 |
25 | constructor(props) {
26 | super(props);
27 | Navigation.events().bindComponent(this);
28 | }
29 |
30 | async componentWillMount() {
31 | const source = await FontAwesome.getImageSource('qrcode', 24, '#000000');
32 | Navigation.mergeOptions(this.props.componentId, {
33 | topBar: {
34 | rightButtons: [
35 | {
36 | id: 'receive',
37 | icon: source
38 | }
39 | ]
40 | }
41 | });
42 | }
43 |
44 | navigationButtonPressed({ buttonId }) {
45 | if (buttonId === 'receive') {
46 | showModal('modals.Receive');
47 | }
48 | }
49 |
50 | render() {
51 | return (
52 |
53 |
54 |
55 | );
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/App/components/Tabs.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { ButtonGroup } from 'react-native-elements';
4 | import { colors } from '../../styles';
5 |
6 | export default class Tabs extends Component {
7 | static get propTypes() {
8 | return {
9 | containerStyle: PropTypes.object,
10 | buttonStyle: PropTypes.object,
11 | selectedButtonStyle: PropTypes.object
12 | };
13 | }
14 | render() {
15 | let {
16 | containerStyle,
17 | buttonStyle,
18 | selectedButtonStyle,
19 | ...rest
20 | } = this.props;
21 | return (
22 |
30 | );
31 | }
32 | }
33 |
34 | const styles = {
35 | container: {
36 | height: 50,
37 | borderWidth: 0,
38 | borderRadius: 0,
39 | padding: 0,
40 | margin: 0,
41 | marginTop: 0,
42 | marginRight: 0,
43 | marginBottom: 0,
44 | marginLeft: 0
45 | },
46 | button: {
47 | backgroundColor: colors.background,
48 | // color: colors.primary,
49 | borderLeftWidth: 0,
50 | borderRightWidth: 0
51 | },
52 | selectedButton: {
53 | backgroundColor: colors.yellow0
54 | },
55 | innerBorder: {
56 | width: 0,
57 | color: colors.white
58 | }
59 | };
60 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
16 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/patches/zeroex-exchange-bug.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const shell = require('shelljs');
3 |
4 | function replace_address(address, to) {
5 | const paths = shell.find('./node_modules');
6 | const replace_paths = paths.filter(function(filename) {
7 | if (fs.lstatSync(filename).isDirectory()) return false;
8 | return Boolean(shell.grep('-l', address, filename).stdout.trim());
9 | });
10 | for (const pathname of replace_paths) {
11 | console.log(`Replacing ${pathname}...`);
12 | shell.sed('-i', new RegExp(address, 'g'), to, pathname);
13 | }
14 | }
15 |
16 | // ERC20Proxy
17 | replace_address(
18 | '0x2240dab907db71e64d3e0dba4800c83b5c502d4e',
19 | '0x95e6f48254609a6ee006f7d493c8e5fb97094cef'
20 | );
21 |
22 | // ERC721Proxy
23 | replace_address(
24 | '0x208e41fb445f1bb1b6780d58356e81405f3e6127',
25 | '0xefc70a1b18c432bdc64b596838b4d138f6bc6cad'
26 | );
27 |
28 | // MAP
29 | // replace_address(
30 | // '',
31 | // '0xef701d5389ae74503d633396c4d654eabedc9d78'
32 | // );
33 |
34 | // Exchange
35 | replace_address(
36 | '0x4f833a24e1f95d70f028921e27040ca56e09ab0b',
37 | '0x080bf510fcbf18b91105470639e9561022937712'
38 | );
39 |
40 | // APOwner
41 | replace_address(
42 | '0x17992e4ffb22730138e4b62aaa6367fa9d3699a6',
43 | '0xdffe798c7172dd6deb32baee68af322e8f495ce0'
44 | );
45 |
46 | // Forwarder
47 | replace_address(
48 | '0x7afc2d5107af94c462a194d2c21b5bdd238709d6',
49 | '0x76481caa104b5f6bccb540dae4cefaf1c398ebea'
50 | );
51 |
52 | // OrderValidator
53 | replace_address(
54 | '0x9463e518dea6810309563c81d5266c1b1d149138',
55 | '0xa09329c6003c9a5402102e226417738ee22cf1f2'
56 | );
57 |
--------------------------------------------------------------------------------
/ios/Device.swift:
--------------------------------------------------------------------------------
1 | import LocalAuthentication
2 |
3 | enum Device {
4 |
5 | //To check that device has secure enclave or not
6 | public static var hasSecureEnclave: Bool {
7 | return !isSimulator && hasBiometrics
8 | }
9 |
10 | //To Check that this is this simulator
11 | public static var isSimulator: Bool {
12 | return TARGET_OS_SIMULATOR == 1
13 | }
14 |
15 | //Check that this device has Biometrics features available
16 | private static var hasBiometrics: Bool {
17 |
18 | //Local Authentication Context
19 | let localAuthContext = LAContext()
20 | var error: NSError?
21 |
22 | /// Policies can have certain requirements which, when not satisfied, would always cause
23 | /// the policy evaluation to fail - e.g. a passcode set, a fingerprint
24 | /// enrolled with Touch ID or a face set up with Face ID. This method allows easy checking
25 | /// for such conditions.
26 | var isValidPolicy = localAuthContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)
27 |
28 | guard isValidPolicy == true else {
29 |
30 | if #available(iOS 11, *) {
31 |
32 | if error!.code != LAError.biometryNotAvailable.rawValue {
33 | isValidPolicy = true
34 | } else{
35 | isValidPolicy = false
36 | }
37 | }
38 | else {
39 | if error!.code != LAError.touchIDNotAvailable.rawValue {
40 | isValidPolicy = true
41 | }else{
42 | isValidPolicy = false
43 | }
44 | }
45 | return isValidPolicy
46 | }
47 | return isValidPolicy
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/App/hoc/uniswap/FactoryContract.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import {connect} from 'react-redux';
4 | import {getMarketDetails, getTokenReserves} from '@uniswap/sdk';
5 | import EthereumClient from '../../../clients/ethereum';
6 | import UniswapClient from '../../../clients/Uniswap';
7 | import {WalletService} from '../../../services/WalletService';
8 |
9 | export default function withFactoryContract(
10 | WrapperComponent,
11 | passName = 'FactoryContract',
12 | ) {
13 | class BaseFactoryContract extends React.Component {
14 | static get propTypes() {
15 | return {
16 | factoryAddress: PropTypes.string.isRequired,
17 | };
18 | }
19 |
20 | constructor(props) {
21 | super(props);
22 |
23 | this.state = {
24 | [passName]: null,
25 | };
26 | }
27 |
28 | async componentDidMount() {
29 | const ethereumClient = new EthereumClient(WalletService.instance.web3);
30 | const uniswapClient = new UniswapClient(
31 | ethereumClient,
32 | this.props.address,
33 | );
34 |
35 | const contract = await uniswap.getFactoryContract();
36 |
37 | this.setState({[passName]: contract});
38 | }
39 |
40 | render() {
41 | const otherProps = Object.assign({}, this.props);
42 | delete otherProps['factoryAddress'];
43 |
44 | return ;
45 | }
46 | }
47 |
48 | const FactoryContract = connect(
49 | state => ({
50 | factoryAddress: state.settings.uniswap.factoryAddress,
51 | }),
52 | dispatch => ({dispatch}),
53 | )(BaseFactoryContract);
54 |
55 | return FactoryContract;
56 | }
57 |
--------------------------------------------------------------------------------
/App/modals/ErrorModal/TokenError.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { Text } from 'react-native-elements';
4 | import { colors } from '../../../styles';
5 |
6 | export default class ZeroExError extends Component {
7 | static test(error) {
8 | if (!error) return false;
9 | if (!error.message) return false;
10 |
11 | switch (error.message) {
12 | case 'INSUFFICIENT_BALANCE_FOR_TRANSFER':
13 | case 'INSUFFICIENT_WETH_BALANCE_FOR_WITHDRAWAL':
14 | case 'INSUFFICIENT_ETH_BALANCE_FOR_DEPOSIT':
15 | return true;
16 | }
17 |
18 | return false;
19 | }
20 |
21 | render() {
22 | const { error } = this.props;
23 | switch (error.message) {
24 | case 'INSUFFICIENT_WETH_BALANCE_FOR_WITHDRAWAL':
25 | return (
26 |
27 | You are trying to withdraw too much Ether!
28 |
29 | );
30 |
31 | case 'INSUFFICIENT_ETH_BALANCE_FOR_DEPOSIT':
32 | return (
33 |
34 | You do not have enough Ether for the transaction!
35 |
36 | );
37 |
38 | case 'INSUFFICIENT_BALANCE_FOR_TRANSFER':
39 | return (
40 |
41 | You do not have enough tokens to send!
42 |
43 | );
44 | }
45 | }
46 | }
47 |
48 | ZeroExError.propTypes = {
49 | error: PropTypes.shape({
50 | message: PropTypes.string.isRequired
51 | }).isRequired
52 | };
53 |
54 | const styles = {
55 | text: {
56 | fontSize: 18,
57 | color: colors.primary,
58 | paddingBottom: 10,
59 | textAlign: 'center'
60 | }
61 | };
62 |
--------------------------------------------------------------------------------
/App/hoc/ethereum/Balance.js:
--------------------------------------------------------------------------------
1 | import {BigNumber} from '@uniswap/sdk';
2 | import PropTypes from 'prop-types';
3 | import React from 'react';
4 | import EthereumClient from '../../../clients/ethereum';
5 | import {ZERO} from '../../../constants';
6 | import {WalletService} from '../../../services/WalletService';
7 |
8 | export default function withEthereumBalance(
9 | WrapperComponent,
10 | passName = 'balance',
11 | ) {
12 | return class EthereumBalance extends React.Component {
13 | static get propTypes() {
14 | return {
15 | loading: PropTypes.bool,
16 | };
17 | }
18 |
19 | static getDerivedStateFromProps(props, state) {
20 | if (props.refresh) {
21 | return {
22 | ...state,
23 | [passName]: props.refresh,
24 | };
25 | }
26 |
27 | return state;
28 | }
29 |
30 | constructor(props) {
31 | super(props);
32 |
33 | this.state = {
34 | loading: true,
35 | balance: ZERO,
36 | error: false,
37 | };
38 | }
39 |
40 | componentDidMount() {
41 | this.refresh();
42 | }
43 |
44 | componentDidUpdate() {
45 | if (this.state.loading) {
46 | this.refresh();
47 | }
48 | }
49 |
50 | render() {
51 | return (
52 |
59 | );
60 | }
61 |
62 | async refresh() {
63 | const ethereumClient = new EthereumClient(WalletService.instance.web3);
64 | const balance = await ethereumClient.getBalance();
65 | this.setState({[passName]: new BigNumber(balance), loading: false});
66 | }
67 | };
68 | }
69 |
--------------------------------------------------------------------------------
/App/modals/UnlockAndSignModal/UnlockWithPin.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import { connect } from 'react-redux';
4 | import { connect as connectNavigation } from '../../../navigation';
5 | import { styles } from '../../../styles';
6 | import { navigationProp } from '../../../types/props';
7 | import Button from '../../components/Button';
8 | import MutedText from '../../components/MutedText';
9 | import VerticalPadding from '../../components/VerticalPadding';
10 | import PinKeyboardLayout from '../../layouts/PinKeyboardLayout';
11 |
12 | class UnlockWithPin extends PinKeyboardLayout {
13 | static get propTypes() {
14 | return {
15 | navigation: navigationProp.isRequired,
16 | error: PropTypes.object,
17 | showUnlocking: PropTypes.func.isRequired,
18 | cancel: PropTypes.func.isRequired
19 | };
20 | }
21 |
22 | constructor(props) {
23 | super(props);
24 |
25 | this.state = {
26 | pin: [],
27 | focus: 'pin'
28 | };
29 | }
30 |
31 | renderTop() {
32 | return (
33 |
34 |
35 |
36 | Unlock your wallet using your PIN.
37 |
38 |
39 | );
40 | }
41 |
42 | renderBottom() {
43 | return ;
44 | }
45 |
46 | press = () => {
47 | this.props.navigation.dismissModal();
48 | this.props.cancel();
49 | };
50 |
51 | getKeyboardProps() {
52 | return {
53 | decimal: false
54 | };
55 | }
56 |
57 | finish(pin) {
58 | this.props.showUnlocking(pin.join(''));
59 | }
60 | }
61 |
62 | export default connect(() => ({}), dispatch => ({ dispatch }))(
63 | connectNavigation(UnlockWithPin)
64 | );
65 |
--------------------------------------------------------------------------------
/App/views/NotificationView.js:
--------------------------------------------------------------------------------
1 | import * as _ from 'lodash';
2 | import PropTypes from 'prop-types';
3 | import React from 'react';
4 | import { SafeAreaView, ScrollView, View } from 'react-native';
5 | import { styles } from '../../styles';
6 | import { styleProp } from '../../types/props/styles';
7 | import Button from '../components/Button';
8 |
9 | export default class NotificationView extends React.Component {
10 | static get propTypes() {
11 | return {
12 | children: PropTypes.oneOfType([
13 | PropTypes.node,
14 | PropTypes.arrayOf(PropTypes.node)
15 | ]),
16 | buttonProps: PropTypes.object,
17 | scrollViewContainerStyle: styleProp,
18 | press: PropTypes.func.isRequired
19 | };
20 | }
21 |
22 | shouldComponentUpdate(nextProps) {
23 | if (!_.isEqual(this.props.buttonProps, nextProps.buttonProps)) {
24 | return true;
25 | }
26 |
27 | if (!_.isEqual(this.props.children, nextProps.children)) {
28 | return true;
29 | }
30 |
31 | if (this.props.press !== nextProps.press) {
32 | return true;
33 | }
34 |
35 | return false;
36 | }
37 |
38 | render() {
39 | return (
40 |
41 |
42 |
49 | {this.props.children}
50 |
51 |
52 |
58 |
59 | );
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/App/modals/ActionModal/base.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import {Text} from 'react-native-elements';
4 | import {
5 | connect as connectNavigation,
6 | waitForComponentAppear,
7 | } from '../../../navigation';
8 | import {navigationProp} from '../../../types/props';
9 | import BigCenter from '../../components/BigCenter';
10 | import VerticalPadding from '../../components/VerticalPadding';
11 | import RotatingView from '../../components/RotatingView';
12 |
13 | class BaseActionModal extends React.PureComponent {
14 | static get propTypes() {
15 | return {
16 | navigation: navigationProp.isRequired,
17 | action: PropTypes.func.isRequired,
18 | callback: PropTypes.func.isRequired,
19 | icon: PropTypes.node.isRequired,
20 | label: PropTypes.oneOfType([PropTypes.node, PropTypes.string]).isRequired,
21 | };
22 | }
23 |
24 | componentDidMount() {
25 | requestAnimationFrame(async () => {
26 | try {
27 | await this.props.action();
28 | } catch (err) {
29 | waitForComponentAppear(this.props.navigation.componentId, () => {
30 | this.props.callback(err);
31 | this.props.navigation.dismissModal();
32 | });
33 | return;
34 | }
35 |
36 | this.props.navigation.dismissModal();
37 | this.props.callback();
38 | });
39 | }
40 |
41 | render() {
42 | const label =
43 | typeof this.props.label === 'string' ? (
44 | {this.props.label}
45 | ) : (
46 | this.props.label
47 | );
48 | return (
49 |
50 | {this.props.icon}
51 |
52 | {label}
53 |
54 | );
55 | }
56 | }
57 |
58 | export default connectNavigation(BaseActionModal);
59 |
--------------------------------------------------------------------------------
/App/components/MnemonicWordInput.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { TouchableOpacity } from 'react-native';
4 | import { TextInputMask } from 'react-native-masked-text';
5 | import { colors } from '../../styles';
6 |
7 | export default class MnemonicWordInput extends Component {
8 | static get propTypes() {
9 | return {
10 | onChange: PropTypes.func.isRequired,
11 | word: PropTypes.string,
12 | cellStyle: PropTypes.object,
13 | inputStyle: PropTypes.object
14 | };
15 | }
16 | render() {
17 | const { cellStyle, inputStyle, onChange, word, ...rest } = this.props;
18 | return (
19 | this.input.focus()}
22 | >
23 | (this.input = input)}
26 | type={'custom'}
27 | autoCapitalize={'none'}
28 | keyboardType={'ascii-capable'}
29 | value={word}
30 | onChangeText={onChange}
31 | inputStyle={[{ width: 100 }, inputStyle]}
32 | options={{
33 | mask: 'AAAAAAAA',
34 | validator: () => true,
35 | getRawValue: value => value.replace(/\s+/gi, '')
36 | }}
37 | underlineColorAndroid="white"
38 | />
39 |
40 | );
41 | }
42 |
43 | focus() {
44 | this.input.focus();
45 | }
46 | }
47 |
48 | const styles = {
49 | cell: {
50 | width: 90,
51 | height: 50,
52 | margin: 10,
53 | alignItems: 'center',
54 | justifyContent: 'center',
55 | // borderBottomWidth: 1,
56 | // borderBottomColor: colors.grey3,
57 | borderWidth: 1,
58 | borderColor: colors.grey3,
59 | borderRadius: 5
60 | }
61 | };
62 |
--------------------------------------------------------------------------------
/App/modals/NotificationModal/base.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import { SafeAreaView, View } from 'react-native';
4 | import { Text } from 'react-native-elements';
5 | import { connect as connectNavigation } from '../../../navigation';
6 | import { styles } from '../../../styles';
7 | import { navigationProp } from '../../../types/props';
8 | import Button from '../../components/Button';
9 | import VerticalPadding from '../../components/VerticalPadding';
10 |
11 | class BaseNotificationModal extends React.PureComponent {
12 | static get propTypes() {
13 | return {
14 | navigation: navigationProp.isRequired,
15 | ok: PropTypes.func,
16 | icon: PropTypes.node.isRequired,
17 | label: PropTypes.oneOfType([PropTypes.node, PropTypes.string]).isRequired
18 | };
19 | }
20 |
21 | render() {
22 | const label =
23 | typeof this.props.label === 'string' ? (
24 | {this.props.label}
25 | ) : (
26 | this.props.label
27 | );
28 | return (
29 |
30 |
39 | {this.props.icon}
40 |
41 | {label}
42 |
43 |
49 |
50 | );
51 | }
52 |
53 | ok = () => {
54 | if (this.props.ok) {
55 | this.props.ok();
56 | }
57 | this.props.navigation.dismissModal();
58 | };
59 | }
60 |
61 | export default connectNavigation(BaseNotificationModal);
62 |
--------------------------------------------------------------------------------
/ios/mobidex/AppDelegate.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | #import "AppDelegate.h"
9 |
10 | #import
11 | //#import
12 | #import
13 | #import
14 |
15 | @implementation AppDelegate
16 |
17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
18 | {
19 | NSURL *jsCodeLocation;
20 |
21 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
22 | [ReactNativeNavigation bootstrap:jsCodeLocation launchOptions:launchOptions];
23 | // [[RCTI18nUtil sharedInstance] allowRTL:NO];
24 |
25 | // RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
26 | // moduleName:@"mobidex"
27 | // initialProperties:nil
28 | // launchOptions:launchOptions];
29 | // rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
30 | //
31 | // self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
32 | // UIViewController *rootViewController = [UIViewController new];
33 | // rootViewController.view = rootView;
34 | // self.window.rootViewController = rootViewController;
35 | // [self.window makeKeyAndVisible];
36 | return YES;
37 | }
38 |
39 | - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options {
40 | return [self.authorizationFlowManagerDelegate resumeExternalUserAgentFlowWithURL:url];
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/App/components/BlinkingCursor.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { Animated, View } from 'react-native';
4 | import { colors } from '../../styles';
5 |
6 | export default class BlinkingCursor extends Component {
7 | constructor(props) {
8 | super(props);
9 |
10 | this.opacity = new Animated.Value(0);
11 | }
12 |
13 | componentDidMount() {
14 | Animated.loop(
15 | Animated.sequence([
16 | Animated.timing(this.opacity, {
17 | toValue: 1,
18 | duration: 0,
19 | delay: this.props.delay,
20 | useNativeDriver: true,
21 | isInteraction: false
22 | }),
23 | Animated.timing(this.opacity, {
24 | toValue: 0,
25 | duration: 0,
26 | delay: this.props.delay,
27 | useNativeDriver: true,
28 | isInteraction: false
29 | })
30 | ])
31 | ).start();
32 | }
33 |
34 | render() {
35 | let { height, width, style, delay, ...rest } = this.props;
36 | return (
37 |
46 | );
47 | }
48 |
49 | blink() {
50 | this.setState({ show: !this.state.show });
51 | }
52 | }
53 |
54 | BlinkingCursor.propTypes = {
55 | delay: PropTypes.number.isRequired,
56 | height: PropTypes.number.isRequired,
57 | width: PropTypes.number.isRequired,
58 | style: PropTypes.object
59 | };
60 |
61 | BlinkingCursor.defaultProps = {
62 | delay: 300,
63 | height: 16,
64 | width: 2
65 | };
66 |
67 | const styles = {
68 | default: {
69 | backgroundColor: colors.primary
70 | },
71 | show: {
72 | opacity: 1
73 | },
74 | hide: {
75 | opacity: 0
76 | }
77 | };
78 |
--------------------------------------------------------------------------------
/App/layouts/ConfirmationLayout.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {SafeAreaView, ScrollView, View} from 'react-native';
3 | import {styles} from '../../styles';
4 | import Button from '../components/Button';
5 | import Row from '../components/Row';
6 |
7 | export default class ConfirmationLayout extends React.PureComponent {
8 | render() {
9 | return (
10 |
11 |
12 |
13 | {this.renderTop()}
14 |
15 |
16 |
17 |
24 |
31 |
32 |
33 | );
34 | }
35 |
36 | getButtonLeftProps() {
37 | throw new Error('getButtonLeftProps must be implemented.');
38 | }
39 |
40 | getButtonRightProps() {
41 | throw new Error('getButtonRightProps must be implemented.');
42 | }
43 |
44 | renderTop() {
45 | throw new Error('renderTop must be implemented.');
46 | }
47 |
48 | pressLeft() {
49 | throw new Error('pressLeft must be implemented.');
50 | }
51 |
52 | pressRight() {
53 | throw new Error('pressRight must be implemented.');
54 | }
55 |
56 | onRefresh() {
57 | throw new Error('onRefresh must be implemented.');
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/App/components/AddressInput.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { View } from 'react-native';
4 | import { Divider, Input, Text } from 'react-native-elements';
5 | import Icon from 'react-native-vector-icons/Entypo';
6 |
7 | export default class AddressInput extends Component {
8 | render() {
9 | const { onChange, containerStyle, wrapperStyle, ...rest } = this.props;
10 | return (
11 |
12 |
22 |
23 | 0x
24 |
33 |
34 |
35 |
36 | );
37 | }
38 | }
39 |
40 | AddressInput.propTypes = {
41 | avatarProps: PropTypes.shape({
42 | small: PropTypes.bool,
43 | medium: PropTypes.bool,
44 | large: PropTypes.bool,
45 | xlarge: PropTypes.bool
46 | }),
47 | onChange: PropTypes.func,
48 | containerStyle: PropTypes.object,
49 | wrapperStyle: PropTypes.object
50 | };
51 |
52 | AddressInput.defaultProps = {
53 | avatarProps: {
54 | medium: true,
55 | rounded: true,
56 | activeOpacity: 0.7,
57 | overlayContainerStyle: { backgroundColor: 'transparent' }
58 | }
59 | };
60 |
--------------------------------------------------------------------------------
/App/NavigationProvider.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import {Navigation} from 'react-native-navigation';
4 | import {
5 | buildNavigationComponent,
6 | NavigationContext,
7 | showModal,
8 | showErrorModal,
9 | waitForComponentAppear,
10 | waitForComponentDisappear,
11 | } from '../navigation';
12 |
13 | export default class NavigationProvider extends React.Component {
14 | static get propTypes() {
15 | return {
16 | componentId: PropTypes.string.isRequired,
17 | children: PropTypes.node.isRequired,
18 | };
19 | }
20 |
21 | render() {
22 | return (
23 |
35 | {this.props.children}
36 |
37 | );
38 | }
39 |
40 | push = (name, props) => {
41 | Navigation.push(this.props.componentId, {
42 | component: buildNavigationComponent(null, name, props),
43 | });
44 | };
45 |
46 | pop = () => {
47 | Navigation.pop(this.props.componentId);
48 | };
49 |
50 | popToRoot = () => {
51 | Navigation.popToRoot(this.props.componentId);
52 | };
53 |
54 | dismissModal = () => {
55 | Navigation.dismissModal(this.props.componentId);
56 | };
57 |
58 | waitForAppear = (fn, wait = 50, attempts = 20) => {
59 | waitForComponentAppear(this.props.componentId, fn, wait, attempts);
60 | };
61 |
62 | waitForDisappear = (fn, wait = 50, attempts = 20) => {
63 | waitForComponentDisappear(this.props.componentId, fn, wait, attempts);
64 | };
65 | }
66 |
--------------------------------------------------------------------------------
/App/hoc/uniswap/TradeDetails.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import {connect} from 'react-redux';
4 | import {getTradeDetails, getTokenReserves} from '@uniswap/sdk';
5 |
6 | export default function withTradeDetails(
7 | WrapperComponent,
8 | propName = 'tokenAddress',
9 | ) {
10 | class BaseTradeDetails extends React.Component {
11 | static get propTypes() {
12 | return {
13 | [propName]: PropTypes.string.isRequired,
14 | network: PropTypes.number.isRequired,
15 | refresh: PropTypes.bool,
16 | };
17 | }
18 |
19 | static getDerivedStateFromProps(props, state) {
20 | if (props.refresh) {
21 | return {
22 | ...state,
23 | refresh: props.refresh,
24 | };
25 | }
26 |
27 | return state;
28 | }
29 |
30 | constructor(props) {
31 | super(props);
32 |
33 | this.state = {
34 | refresh: true,
35 | loading: true,
36 | tradeDetails: null,
37 | error: false,
38 | success: false,
39 | };
40 | }
41 |
42 | componentDidMount() {
43 | this.refresh();
44 | }
45 |
46 | componentDidUpdate() {
47 | if (this.state.refresh) {
48 | this.refresh();
49 | }
50 | }
51 |
52 | render() {
53 | return ;
54 | }
55 |
56 | async refresh() {
57 | const {network} = this.props;
58 | const address = this.props[propName];
59 | const baseTokenReserves = await getTokenReserves(address, network);
60 | const tradeDetails = await getTradeDetails(undefined, baseTokenReserves);
61 |
62 | this.setState({tradeDetails, refresh: false});
63 | }
64 | }
65 |
66 | const TradeDetails = connect(
67 | state => ({
68 | network: state.settings.network,
69 | }),
70 | dispatch => ({dispatch}),
71 | )(BaseTradeDetails);
72 |
73 | return TradeDetails;
74 | }
75 |
--------------------------------------------------------------------------------
/ios/Web3.podspec.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Web3",
3 | "version": "0.3.1",
4 | "summary": "Web3 library for Swift. Sign transactions and interact with Smart Contracts in the Ethereum Network.",
5 | "description": "Web3 library to sign transactions, interact with Smart Contracts, call\nSmart Contract methods and many things more, all through either a\nHTTP RPC interface provided by this library or a custom RPC interface\n(for example IPC,...).",
6 | "homepage": "https://github.com/Boilertalk/Web3.swift",
7 | "license": {
8 | "type": "MIT",
9 | "file": "LICENSE"
10 | },
11 | "authors": {
12 | "Koray Koska": "koray@koska.at"
13 | },
14 | "source": {
15 | "git": "https://github.com/Boilertalk/Web3.swift.git",
16 | "tag": "0.3.1"
17 | },
18 | "platforms": {
19 | "ios": "8.0",
20 | "osx": "10.10",
21 | "tvos": "9.0",
22 | "watchos": "2.0"
23 | },
24 | "swift_versions": "4.0",
25 | "swift_version": "4.0",
26 | "pod_target_xcconfig": {
27 | "OTHER_SWIFT_FLAGS": "-DWeb3CocoaPods"
28 | },
29 | "default_subspecs": ["Core", "HTTPExtension"],
30 | "subspecs": [
31 | {
32 | "name": "Core",
33 | "source_files": "Web3/Classes/Core/**/*",
34 | "dependencies": {
35 | "BigInt": ["~> 3.1"],
36 | "CryptoSwift": ["~> 0.8"],
37 | "secp256k1.swift": ["~> 0.1"]
38 | }
39 | },
40 | {
41 | "name": "HTTPExtension",
42 | "source_files": "Web3/Classes/FoundationHTTP/**/*",
43 | "dependencies": {
44 | "Web3/Core": []
45 | }
46 | },
47 | {
48 | "name": "PromiseKit",
49 | "source_files": "Web3/Classes/PromiseKit/**/*",
50 | "dependencies": {
51 | "Web3/Core": [],
52 | "PromiseKit/CorePromise": ["~> 6.0"]
53 | }
54 | },
55 | {
56 | "name": "ContractABI",
57 | "source_files": "Web3/Classes/ContractABI/**/*",
58 | "dependencies": {
59 | "Web3/Core": []
60 | }
61 | }
62 | ]
63 | }
64 |
--------------------------------------------------------------------------------
/App/screens/trade/DetailsScreen/EthereumDetails.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, {Component} from 'react';
3 | import {SafeAreaView, Text} from 'react-native';
4 | import Entypo from 'react-native-vector-icons/Entypo';
5 | import {connect} from 'react-redux';
6 | import {UNLOCKED_AMOUNT, ZERO} from '../../../../constants';
7 | import {connect as connectNavigation} from '../../../../navigation';
8 | import * as AssetService from '../../../../services/AssetService';
9 | import {styles} from '../../../../styles';
10 | import {addressProp, BigNumberProp} from '../../../../types/props';
11 | import Loading from '../../../views/Loading';
12 | import EmptyWallet from './EmptyWallet';
13 | import SwapTokens from './SwapTokens';
14 | import UnwrapAllETH from './UnwrapAllETH';
15 | import UnlockConfirmation from './UnlockConfirmation';
16 | import UnlockTokenNotice from './UnlockTokenNotice';
17 |
18 | class BaseEthereumDetails extends Component {
19 | static get propTypes() {
20 | return {
21 | loading: PropTypes.bool,
22 | ethereumBalance: BigNumberProp,
23 | };
24 | }
25 |
26 | render() {
27 | if (this.props.loading) {
28 | return ;
29 | }
30 |
31 | const {ethereumBalance} = this.props;
32 |
33 | if (ZERO.isEqualTo(ethereumBalance)) {
34 | return ;
35 | }
36 |
37 | return (
38 |
39 |
40 |
41 | );
42 | }
43 | }
44 |
45 | function extractProps(state, props) {
46 | const {
47 | wallet: {balances},
48 | settings: {gasPrice},
49 | } = state;
50 | const ethereumBalance = balances[null];
51 |
52 | return {
53 | ethereumBalance,
54 | gasPrice,
55 | };
56 | }
57 |
58 | let EthereumDetails = connectNavigation(BaseEthereumDetails);
59 | EthereumDetails = connect(
60 | extractProps,
61 | dispatch => ({dispatch}),
62 | )(EthereumDetails);
63 |
64 | export default EthereumDetails;
65 |
--------------------------------------------------------------------------------