├── .babelrc
├── .bundle
└── config
├── .env.demo
├── .env.dev
├── .env.release
├── .eslintrc.js
├── .github
├── FUNDING.yml
└── workflows
│ └── codeql-analysis.yml
├── .gitignore
├── .node-version
├── .prettierrc.js
├── .travis.yml
├── .watchmanconfig
├── CONTRIBUTING.md
├── Gemfile
├── Gemfile.lock
├── LICENSE
├── README.md
├── android
├── app
│ ├── _BUCK
│ ├── build.gradle
│ ├── debug.keystore
│ ├── proguard-rules.pro
│ └── src
│ │ ├── debug
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── app
│ │ │ └── ironbelly
│ │ │ └── ReactNativeFlipper.java
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── assets
│ │ │ ├── fonts
│ │ │ │ ├── Poppins-ExtraBold.ttf
│ │ │ │ ├── Poppins-ExtraBoldItalic.ttf
│ │ │ │ ├── Poppins-ExtraLight.ttf
│ │ │ │ ├── Poppins-ExtraLightItalic.ttf
│ │ │ │ ├── Poppins-Italic.ttf
│ │ │ │ ├── Poppins-Light.ttf
│ │ │ │ ├── Poppins-LightItalic.ttf
│ │ │ │ ├── Poppins-Medium.ttf
│ │ │ │ ├── Poppins-MediumItalic.ttf
│ │ │ │ ├── Poppins-Regular.ttf
│ │ │ │ ├── Poppins-SemiBold.ttf
│ │ │ │ ├── Poppins-SemiBoldItalic.ttf
│ │ │ │ ├── Poppins-Thin.ttf
│ │ │ │ └── Poppins-ThinItalic.ttf
│ │ │ └── tor
│ │ │ │ ├── bridges.txt
│ │ │ │ ├── geoip
│ │ │ │ └── geoip6
│ │ ├── java
│ │ │ └── app
│ │ │ │ └── ironbelly
│ │ │ │ ├── CustomGrinBridge.java
│ │ │ │ ├── GrinBridge.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MainApplication.java
│ │ │ │ ├── SplashActivity.java
│ │ │ │ └── tor
│ │ │ │ ├── TorConfig.kt
│ │ │ │ ├── TorProxyManager.kt
│ │ │ │ ├── TorProxyState.kt
│ │ │ │ └── TorResourceInstaller.kt
│ │ ├── jniLibs
│ │ │ └── Android.mk
│ │ └── res
│ │ │ ├── drawable
│ │ │ ├── background_splash.xml
│ │ │ └── rn_edit_text_material.xml
│ │ │ ├── layout
│ │ │ └── launch_screen.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── values-night
│ │ │ └── colors.xml
│ │ │ ├── values
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ │ └── xml
│ │ │ ├── filepaths.xml
│ │ │ └── network_security_config.xml
│ │ └── release
│ │ └── java
│ │ └── app
│ │ └── ironbelly
│ │ └── ReactNativeFlipper.java
├── build.gradle
├── get_apk_from_aab.sh
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── app.json
├── docs
├── balance.png
├── balance.uml
├── navigation.png
├── navigation.uml
├── refresh.png
├── refresh.uml
└── release_test.md
├── e2e
├── config.json
├── init.js
├── utils.js
└── walletInit.spec.js
├── fastlane
├── Appfile
├── Deliverfile
├── Fastfile
├── Pluginfile
├── README.md
├── Snapfile
└── SnapshotHelper.swift
├── index.js
├── ios
├── .xcode.env
├── .xcode.env.local
├── Cartfile
├── Cartfile.resolved
├── Ironbelly.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── Ironbelly.xcscheme
│ │ └── Snapshots.xcscheme
├── Ironbelly.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
├── Ironbelly
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon.png
│ │ │ ├── icon_20pt.png
│ │ │ ├── icon_20pt@2x-1.png
│ │ │ ├── icon_20pt@2x.png
│ │ │ ├── icon_20pt@3x.png
│ │ │ ├── icon_29pt.png
│ │ │ ├── icon_29pt@2x-1.png
│ │ │ ├── icon_29pt@2x.png
│ │ │ ├── icon_29pt@3x.png
│ │ │ ├── icon_40pt.png
│ │ │ ├── icon_40pt@2x-1.png
│ │ │ ├── icon_40pt@2x.png
│ │ │ ├── icon_40pt@3x.png
│ │ │ ├── icon_60pt@2x.png
│ │ │ ├── icon_60pt@3x.png
│ │ │ ├── icon_76pt.png
│ │ │ ├── icon_76pt@2x.png
│ │ │ └── icon_83.5@2x.png
│ │ ├── Contents.json
│ │ └── LaunchLogo.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchLogo.png
│ │ │ ├── LaunchLogo@2x.png
│ │ │ └── LaunchLogo@3x.png
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── GrinBridge.m
│ ├── GrinBridge.swift
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Info.plist
│ ├── LaunchScreen.storyboard
│ ├── Tor
│ │ ├── Helpers
│ │ │ ├── Ipv6Tester.swift
│ │ │ ├── NetworkTools.h
│ │ │ └── NetworkTools.m
│ │ ├── OnionConnector.swift
│ │ ├── OnionManager.swift
│ │ └── OnionSettings.swift
│ ├── Utils.swift
│ ├── Wallet-Bridging-Header.h
│ └── assets
│ │ └── src
│ │ └── assets
│ │ └── images
│ │ ├── ReceiveTX.png
│ │ ├── ReceiveTX@2x.png
│ │ ├── ReceiveTX@3x.png
│ │ ├── SendTX.png
│ │ ├── SendTX@2x.png
│ │ ├── SendTX@3x.png
│ │ ├── Settings.png
│ │ ├── Settings@2x.png
│ │ ├── Settings@3x.png
│ │ ├── Share.png
│ │ ├── Share@2x.png
│ │ ├── Share@3x.png
│ │ ├── x.png
│ │ ├── x@2x.png
│ │ └── x@3x.png
├── IronbellyTests
│ └── IronbellyTests.m
├── Podfile
├── Podfile.lock
├── UITests
│ ├── Info.plist
│ └── UITests.swift
└── Wallet.xcframework
│ └── Info.plist
├── jest.config.js
├── metro.config.js
├── package.json
├── patches
├── react-native-background-timer+2.4.1.patch
├── react-native-config+1.5.1.patch
├── react-native-fs+2.20.0.patch
├── react-native-keep-awake+4.0.0.patch
├── react-native-linear-gradient+2.8.3.patch
├── react-native-navigation-bar-color+2.0.2.patch
├── react-native-splash-screen+3.3.0.patch
└── react-native-vector-icons+10.0.3.patch
├── react-native.config.js
├── rn-polyfill-depricated-proptypes.js
├── rust
├── .gitignore
├── Cargo.lock
├── Cargo.toml
├── build.rs
├── scripts
│ ├── build.sh
│ ├── init.sh
│ └── variables.sh
└── src
│ ├── android.rs
│ ├── errors.rs
│ ├── ios.rs
│ └── lib.rs
├── scripts
├── additional-licenses.js
├── applesimutils.sh
├── licenses.js
├── npm.sh
└── test.sh
├── sign-with-local.sh
├── src
├── App.tsx
├── assets
│ ├── fonts
│ │ ├── Poppins-ExtraBold.ttf
│ │ ├── Poppins-ExtraBoldItalic.ttf
│ │ ├── Poppins-ExtraLight.ttf
│ │ ├── Poppins-ExtraLightItalic.ttf
│ │ ├── Poppins-Italic.ttf
│ │ ├── Poppins-Light.ttf
│ │ ├── Poppins-LightItalic.ttf
│ │ ├── Poppins-Medium.ttf
│ │ ├── Poppins-MediumItalic.ttf
│ │ ├── Poppins-Regular.ttf
│ │ ├── Poppins-SemiBold.ttf
│ │ ├── Poppins-SemiBoldItalic.ttf
│ │ ├── Poppins-Thin.ttf
│ │ └── Poppins-ThinItalic.ttf
│ └── images
│ │ ├── ChevronLeft.png
│ │ ├── ChevronLeft@2x.png
│ │ ├── ChevronLeft@3x.png
│ │ ├── ChevronRight.png
│ │ ├── ChevronRight@2x.png
│ │ ├── ChevronRight@3x.png
│ │ ├── Close.png
│ │ ├── Close@2x.png
│ │ ├── Close@3x.png
│ │ ├── Share.png
│ │ ├── Share@2x.png
│ │ ├── Share@3x.png
│ │ ├── landing.png
│ │ ├── landing@2x.png
│ │ ├── landing@3x.png
│ │ ├── x.png
│ │ ├── x@2x.png
│ │ └── x@3x.png
├── bridges
│ └── wallet.ts
├── common
│ ├── bip39words.ts
│ ├── colors.ts
│ ├── index.ts
│ ├── logger.ts
│ ├── migrations.ts
│ ├── redux.ts
│ ├── sideEffects.ts
│ └── types.ts
├── components
│ ├── Balance.tsx
│ ├── CardTitle.tsx
│ ├── CopyButton.tsx
│ ├── CopyHeader.tsx
│ ├── CustomFont.tsx
│ ├── FormTextInput.tsx
│ ├── Header.tsx
│ ├── HeaderSpan.tsx
│ ├── InputContentRow.tsx
│ ├── Notice.tsx
│ ├── NumericInput.tsx
│ ├── PasteButton.tsx
│ ├── ScanQRCodeButton.tsx
│ ├── SectionTitle.tsx
│ ├── SettingsListItem.tsx
│ ├── ShareButton.tsx
│ ├── ShareRow.tsx
│ ├── ShowQRCodeButton.tsx
│ ├── Textarea.tsx
│ ├── TxListItem.tsx
│ └── TxPostConfirmationModal.tsx
├── documents
│ ├── legal-disclaimer-ios.ts
│ └── receive-from-another-person.ts
├── mocks.ts
├── modules
│ ├── app.ts
│ ├── balance.ts
│ ├── currency-rates.ts
│ ├── navigation.tsx
│ ├── settings.ts
│ ├── toaster.ts
│ ├── tor.ts
│ ├── tx.ts
│ ├── tx
│ │ └── receive.ts
│ └── wallet.ts
├── screens
│ ├── Landing.tsx
│ ├── LegalDisclaimer.tsx
│ ├── License.tsx
│ ├── Licenses.tsx
│ ├── NewPassword.tsx
│ ├── Overview.tsx
│ ├── PaperKey
│ │ ├── Show.tsx
│ │ └── Verify.tsx
│ ├── Password.tsx
│ ├── ScanQRCode.tsx
│ ├── Settings.tsx
│ ├── Settings
│ │ ├── Currency.tsx
│ │ ├── GrinNode.tsx
│ │ └── Support.tsx
│ ├── ShowQRCode.tsx
│ ├── TxDetails.tsx
│ ├── TxIncompleteReceive
│ │ ├── GrinAddress.tsx
│ │ └── TxIncompleteReceive.tsx
│ ├── TxIncompleteSend
│ │ ├── SlateCreated.tsx
│ │ ├── SlateNotCreated.tsx
│ │ └── TxIncompleteSend.tsx
│ └── WalletScan.tsx
└── themes.ts
├── tsconfig.json
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["module:metro-react-native-babel-preset"],
3 | "plugins": [
4 | [
5 | "module-resolver",
6 | {
7 | "root": ["."],
8 | "extensions": [".ts", ".tsx"]
9 | }
10 | ]
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/.bundle/config:
--------------------------------------------------------------------------------
1 | BUNDLE_PATH: "vendor/bundle"
2 | BUNDLE_FORCE_RUBY_PLATFORM: 1
3 |
--------------------------------------------------------------------------------
/.env.demo:
--------------------------------------------------------------------------------
1 | APP_ID=app.ironbelly.demo
2 | APP_DISPLAY_NAME="Ironbelly"
3 | DEMO_MODE=true
4 |
--------------------------------------------------------------------------------
/.env.dev:
--------------------------------------------------------------------------------
1 | APP_ID=app.ironbelly
2 | APP_DISPLAY_NAME="Ironbelly"
3 |
--------------------------------------------------------------------------------
/.env.release:
--------------------------------------------------------------------------------
1 | APP_ID=app.ironbelly
2 | APP_DISPLAY_NAME="Ironbelly"
3 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // module.exports = {
2 | // root: true,
3 | // extends: '@react-native-community',
4 | // parser: '@typescript-eslint/parser',
5 | // plugins: ['@typescript-eslint'],
6 | // rules: {
7 | // semi: 0,
8 | // },
9 | // }
10 |
11 | module.exports = {
12 | root: true,
13 | env: {
14 | browser: true,
15 | amd: true,
16 | node: true,
17 | },
18 | parser: '@typescript-eslint/parser',
19 | plugins: ['react', 'react-native', '@typescript-eslint'],
20 | extends: [
21 | 'eslint:recommended',
22 | 'plugin:@typescript-eslint/recommended',
23 | 'plugin:react-hooks/recommended',
24 | ],
25 | rules: {
26 | semi: ['error', 'never'],
27 | 'object-curly-spacing': ['error', 'always'],
28 | '@typescript-eslint/explicit-module-boundary-types': 'off',
29 | '@typescript-eslint/no-extra-semi': ['off'],
30 | 'react-native/no-unused-styles': 2,
31 | },
32 | }
33 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: i1skn
2 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ master ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ master ]
20 | schedule:
21 | - cron: '27 8 * * 3'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
37 | # Learn more:
38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
39 |
40 | steps:
41 | - name: Checkout repository
42 | uses: actions/checkout@v2
43 |
44 | # Initializes the CodeQL tools for scanning.
45 | - name: Initialize CodeQL
46 | uses: github/codeql-action/init@v1
47 | with:
48 | languages: ${{ matrix.language }}
49 | # If you wish to specify custom queries, you can do so here or in a config file.
50 | # By default, queries listed here will override any specified in a config file.
51 | # Prefix the list here with "+" to use these queries and those in the config file.
52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
53 |
54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
55 | # If this step fails, then you should remove it and run the build manually (see below)
56 | - name: Autobuild
57 | uses: github/codeql-action/autobuild@v1
58 |
59 | # ℹ️ Command-line programs to run using the OS shell.
60 | # 📚 https://git.io/JvXDl
61 |
62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
63 | # and modify them (or add more) to build your code if your project
64 | # uses a compiled language
65 |
66 | #- run: |
67 | # make bootstrap
68 | # make release
69 |
70 | - name: Perform CodeQL Analysis
71 | uses: github/codeql-action/analyze@v1
72 |
--------------------------------------------------------------------------------
/.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 | *.dSYM.zip
23 | *.xcuserstate
24 | project.xcworkspace
25 |
26 | # Android/IntelliJ
27 | #
28 | build/
29 | .idea
30 | .gradle
31 | local.properties
32 | *.iml
33 | *.hprof
34 | .cxx/
35 | *.keystore
36 | !debug.keystore
37 | android/.project
38 | android/.settings/org.eclipse.buildship.core.prefs
39 | android/app/.classpath
40 | android/app/.project
41 | android/app/.settings/org.eclipse.buildship.core.prefs
42 |
43 | # Visual Studio Code
44 | #
45 | .vscode/
46 |
47 | # node.js
48 | #
49 | node_modules/
50 | npm-debug.log
51 | yarn-error.log
52 |
53 | # fastlane
54 | #
55 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
56 | # screenshots whenever they are needed.
57 | # For more information about the recommended setup visit:
58 | # https://docs.fastlane.tools/best-practices/source-control/
59 |
60 | **/fastlane/report.xml
61 | **/fastlane/Preview.html
62 | **/fastlane/screenshots
63 | **/fastlane/metadata
64 | **/fastlane/test_output
65 |
66 | # Bundle artifact
67 | *.jsbundle
68 | android/app/src/main/assets/index.android.bundle
69 |
70 | # Ruby / CocoaPods
71 | /ios/Pods/
72 | /vendor/bundle/
73 |
74 | #Cartage
75 | /ios/Carthage/Checkouts/
76 |
77 | # Android
78 | android/key.json
79 | *.pem
80 | *.apk
81 | *.aab
82 |
83 | # Local tools
84 | slates/*
85 |
86 | # Licenses
87 | licenses.json
88 |
89 | # HTML page with all the snapshots
90 | screenshots/screenshots.html
91 |
92 | .env
93 |
94 | # Wallet compiled libraries and headers
95 | libwallet.*
96 | WalletHeaders.h
97 |
98 |
99 | # Temporary files created by Metro to check the health of the file watcher
100 | .metro-health-check*
101 |
102 | # testing
103 | /coverage
104 |
--------------------------------------------------------------------------------
/.node-version:
--------------------------------------------------------------------------------
1 | 16
2 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: true,
4 | bracketSpacing: false,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | semi: true,
8 | }
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: swift
2 | osx_image: xcode10.2
3 |
4 | if: tag IS blank
5 |
6 | cache:
7 | directories:
8 | - $HOME/.cargo
9 | - $TRAVIS_BUILD_DIR/rust/target
10 | - $TRAVIS_BUILD_DIR/node_modules
11 | - $TRAVIS_BUILD_DIR/ios/Pods
12 | - /usr/local/Cellar/applesimutils
13 | - /usr/local/lib/node_modules
14 | - $HOME/Library/Detox
15 |
16 | env:
17 | global:
18 | - NODE_VERSION=stable
19 | - CODE_SIGNING_REQUIRED=NO
20 | - E2E_TEST=yes
21 |
22 | jobs:
23 | include:
24 | - stage: compile rust code
25 | script: ./scripts/rust.sh
26 | - stage: install applesimutils for detox
27 | script: ./scripts/applesimutils.sh
28 | - stage: npm install
29 | script: ./scripts/npm.sh
30 | - stage: test
31 | script: ./scripts/test.sh
32 |
--------------------------------------------------------------------------------
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4 | ruby '>= 2.6.10'
5 |
6 | gem 'cocoapods', '~> 1.13'
7 | gem 'activesupport', '>= 6.1.7.3', '< 7.1.0'
8 | gem "fastlane"
9 |
10 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
11 | eval_gemfile(plugins_path) if File.exist?(plugins_path)
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NO LONGER SUPPORTED!
2 | Read more here: https://forum.grin.mw/t/ironbelly-is-spitting-fire-no-longer/11003
3 |
4 | # Ironbelly
5 |
6 | Named after a species of dragon - [Ukrainian Ironbelly](http://harrypotter.wikia.com/wiki/Ukrainian_Ironbelly). One of them guarded some of the oldest and deepest vaults in Gringotts.
7 | This wallet uses React-Native for the UI and official [Grin](https://github.com/mimblewimble/grin/) source code written in Rust.
8 |
9 | ## Contributing
10 | ### Install Rust
11 | `curl https://sh.rustup.rs -sSf | sh`
12 |
13 | ### Set up the environment
14 |
15 | Go to project directory and run:
16 | ```
17 | cd rust
18 | ./scripts/init.sh // add needed targets for rust
19 | ```
20 |
21 | ### iOS
22 |
23 | Let's install Xcode build tools first
24 |
25 | `xcode-select --install`
26 |
27 |
28 | #### Build the project
29 |
30 | Go to project directory and run:
31 | ```
32 | cd rust
33 | ./scripts/build.sh release ios
34 | # All iOS related code lives in `ios/` directory
35 | cd ../ios
36 | sudo gem install cocoapods
37 | pod install
38 | cd ..
39 | npm install
40 | npm start # this will start React Native server
41 | ```
42 |
43 | After all of these, please open `ios/Ironbelly.xcworkspace` in XCode and run `Product -> Build (⌘B)`
44 |
45 | ### Android
46 | #### Set up the environment
47 |
48 | Install Android SDK / NDK / Platform Tools
49 | ```
50 | brew cask install android-sdk android-ndk android-platform-tools
51 | ```
52 |
53 | Add to your `.bashprofile` or `.zshrc`:
54 | ```
55 | export ANDROID_HOME="$(brew --prefix)/share/android-sdk"
56 | export PATH=$PATH:$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools
57 | export ANDROID_NDK_HOME="$(brew --prefix)/share/android-ndk"
58 | ```
59 |
60 | #### Build the project
61 | Run Android emulator or connect a real device. Now `adb devices` should show at least one device.
62 |
63 | ```
64 | cd rust
65 | ./scripts/build.sh release android
66 | cd ..
67 | npm install
68 | ```
69 | Go to the root of the repo and run `react-native run-android`
70 |
71 | ## Beta testing
72 | ### iOS - Testflight
73 | [https://testflight.apple.com/join/GrqGPx9W](https://testflight.apple.com/join/GrqGPx9W)
74 | ### Android
75 | [https://play.google.com/store/apps/details?id=app.ironbelly](https://play.google.com/store/apps/details?id=app.ironbelly)
76 |
77 | ## How to verify Android APK signature
78 | 1. Download the key `gpg --keyserver keys.openpgp.org --search-keys ivan@sorokin.io`
79 | 2. Verify `gpg --verify Ironbelly-vX.Y.Z.B.apk.asc Ironbelly-vX.Y.Z.B.apk`
80 |
81 | ## License
82 |
83 | Apache License v2.0.
84 |
--------------------------------------------------------------------------------
/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 | lib_deps = []
12 |
13 | for jarfile in glob(['libs/*.jar']):
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 | )
20 |
21 | for aarfile in glob(['libs/*.aar']):
22 | name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')]
23 | lib_deps.append(':' + name)
24 | android_prebuilt_aar(
25 | name = name,
26 | aar = aarfile,
27 | )
28 |
29 | android_library(
30 | name = "all-libs",
31 | exported_deps = lib_deps,
32 | )
33 |
34 | android_library(
35 | name = "app-code",
36 | srcs = glob([
37 | "src/main/java/**/*.java",
38 | ]),
39 | deps = [
40 | ":all-libs",
41 | ":build_config",
42 | ":res",
43 | ],
44 | )
45 |
46 | android_build_config(
47 | name = "build_config",
48 | package = "app.ironbelly",
49 | )
50 |
51 | android_resource(
52 | name = "res",
53 | package = "app.ironbelly",
54 | res = "src/main/res",
55 | )
56 |
57 | android_binary(
58 | name = "app",
59 | keystore = "//android/keystores:debug",
60 | manifest = "src/main/AndroidManifest.xml",
61 | package_type = "debug",
62 | deps = [
63 | ":app-code",
64 | ],
65 | )
66 |
--------------------------------------------------------------------------------
/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/debug.keystore
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/android/app/src/debug/java/app/ironbelly/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | *
This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package app.ironbelly;
8 | import android.content.Context;
9 | import com.facebook.flipper.android.AndroidFlipperClient;
10 | import com.facebook.flipper.android.utils.FlipperUtils;
11 | import com.facebook.flipper.core.FlipperClient;
12 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
13 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
14 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
15 | import com.facebook.flipper.plugins.inspector.DescriptorMapping;
16 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
17 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
18 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
19 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
20 | import com.facebook.react.ReactInstanceEventListener;
21 | import com.facebook.react.ReactInstanceManager;
22 | import com.facebook.react.bridge.ReactContext;
23 | import com.facebook.react.modules.network.NetworkingModule;
24 | import okhttp3.OkHttpClient;
25 | public class ReactNativeFlipper {
26 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
27 | if (FlipperUtils.shouldEnableFlipper(context)) {
28 | final FlipperClient client = AndroidFlipperClient.getInstance(context);
29 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
30 | client.addPlugin(new DatabasesFlipperPlugin(context));
31 | client.addPlugin(new SharedPreferencesFlipperPlugin(context));
32 | client.addPlugin(CrashReporterPlugin.getInstance());
33 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
34 | NetworkingModule.setCustomClientBuilder(
35 | new NetworkingModule.CustomClientBuilder() {
36 | @Override
37 | public void apply(OkHttpClient.Builder builder) {
38 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
39 | }
40 | });
41 | client.addPlugin(networkFlipperPlugin);
42 | client.start();
43 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
44 | // Hence we run if after all native modules have been initialized
45 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
46 | if (reactContext == null) {
47 | reactInstanceManager.addReactInstanceEventListener(
48 | new ReactInstanceEventListener() {
49 | @Override
50 | public void onReactContextInitialized(ReactContext reactContext) {
51 | reactInstanceManager.removeReactInstanceEventListener(this);
52 | reactContext.runOnNativeModulesQueueThread(
53 | new Runnable() {
54 | @Override
55 | public void run() {
56 | client.addPlugin(new FrescoFlipperPlugin());
57 | }
58 | });
59 | }
60 | });
61 | } else {
62 | client.addPlugin(new FrescoFlipperPlugin());
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
21 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
41 |
42 |
43 |
44 |
45 |
50 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-ExtraBold.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-ExtraBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-ExtraBoldItalic.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-ExtraLight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-ExtraLight.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-ExtraLightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-ExtraLightItalic.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-Italic.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-Light.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-LightItalic.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-Medium.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-MediumItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-MediumItalic.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-Regular.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-SemiBold.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-SemiBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-SemiBoldItalic.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-Thin.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Poppins-ThinItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/assets/fonts/Poppins-ThinItalic.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/tor/bridges.txt:
--------------------------------------------------------------------------------
1 | obfs4 77.81.104.251:443 115C90EBD0EB631C177560A872535772215478D9 cert=UsuF7oN4KNKviZP54JOyTCoCphrdM5gwZK4vT8GnCAcmqLUJEJxyw1dpko9a/ii6He4iZg iat-mode=0
2 | obfs4 5.249.146.133:80 FAF3A0073330D6AD92F3B4874B0D945562A633EF cert=TRe8bAODtjcGij7EPQaUayWEOqR99wDh2l3B4hFtCsn1JTJCph03pRZ9tx8wynpLYKWMQg iat-mode=0
3 | meek_lite 0.0.2.0:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com
4 |
5 |
--------------------------------------------------------------------------------
/android/app/src/main/java/app/ironbelly/CustomGrinBridge.java:
--------------------------------------------------------------------------------
1 | package app.ironbelly;
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 CustomGrinBridge implements ReactPackage {
13 |
14 | @Override
15 | public List createViewManagers(ReactApplicationContext reactContext) {
16 | return Collections.emptyList();
17 | }
18 |
19 | @Override
20 | public List createNativeModules(
21 | ReactApplicationContext reactContext) {
22 | List modules = new ArrayList<>();
23 |
24 | modules.add(new GrinBridge(reactContext));
25 |
26 | return modules;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/android/app/src/main/java/app/ironbelly/MainActivity.java:
--------------------------------------------------------------------------------
1 | package app.ironbelly;
2 | import expo.modules.ReactActivityDelegateWrapper;
3 | import com.facebook.react.ReactActivityDelegate;
4 | import android.content.Intent;
5 | import android.graphics.Color;
6 | import android.net.Uri;
7 | import android.os.Build;
8 | import android.os.Bundle;
9 | import android.util.Log;
10 | import android.view.Window;
11 | import android.view.WindowManager;
12 | import com.facebook.react.ReactActivity;
13 | import com.facebook.react.ReactActivityDelegate;
14 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
15 | import com.facebook.react.defaults.DefaultReactActivityDelegate;
16 | import org.devio.rn.splashscreen.SplashScreen;
17 |
18 | public class MainActivity extends ReactActivity {
19 |
20 | /**
21 | * Returns the name of the main component registered from JavaScript. This is used to schedule
22 | * rendering of the component.
23 | */
24 | @Override
25 | protected String getMainComponentName() {
26 | return "Ironbelly";
27 | }
28 |
29 | @Override
30 | protected void onCreate(Bundle savedInstanceState) {
31 | SplashScreen.show(this);
32 | super.onCreate(savedInstanceState);
33 | Window window = getWindow();
34 | window.setFlags(WindowManager.LayoutParams.FLAG_SECURE,
35 | WindowManager.LayoutParams.FLAG_SECURE);
36 | }
37 |
38 | // @Override
39 | // protected ReactActivityDelegate createReactActivityDelegate() {
40 | // return new ReactActivityDelegateWrapper(this,
41 | // new ReactActivityDelegate(this, getMainComponentName())
42 | // );
43 | // }
44 |
45 | /**
46 | * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
47 | * you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer
48 | * (Paper).
49 | */
50 | @Override
51 | protected ReactActivityDelegate createReactActivityDelegate() {
52 | return new DefaultReactActivityDelegate(
53 | this,
54 | getMainComponentName(),
55 | // If you opted-in for the New Architecture, we enable the Fabric Renderer.
56 | DefaultNewArchitectureEntryPoint.getFabricEnabled());
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/android/app/src/main/java/app/ironbelly/MainApplication.java:
--------------------------------------------------------------------------------
1 | package app.ironbelly;
2 | import android.content.res.Configuration;
3 | import expo.modules.ApplicationLifecycleDispatcher;
4 | import expo.modules.ReactNativeHostWrapper;
5 |
6 | import android.app.Application;
7 | import com.facebook.react.PackageList;
8 | import com.facebook.react.ReactApplication;
9 | import com.facebook.react.ReactNativeHost;
10 | import com.facebook.react.ReactPackage;
11 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
12 | import com.facebook.react.defaults.DefaultReactNativeHost;
13 | import com.facebook.react.shell.MainReactPackage;
14 | import com.facebook.soloader.SoLoader;
15 | import java.util.List;
16 | import java.util.Arrays;
17 |
18 | public class MainApplication extends Application implements ReactApplication {
19 | private final ReactNativeHost mReactNativeHost =
20 | new ReactNativeHostWrapper(this, new DefaultReactNativeHost(this) {
21 | @Override
22 | public boolean getUseDeveloperSupport() {
23 | return BuildConfig.DEBUG;
24 | }
25 |
26 | @Override
27 | protected List getPackages() {
28 | @SuppressWarnings("UnnecessaryLocalVariable")
29 | List packages = new PackageList(this).getPackages();
30 | // Packages that cannot be autolinked yet can be added manually here, for example:
31 | packages.add(new CustomGrinBridge());
32 | return packages;
33 | }
34 |
35 | @Override
36 | protected String getJSMainModuleName() {
37 | return "index";
38 | }
39 |
40 | @Override
41 | protected boolean isNewArchEnabled() {
42 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
43 | }
44 |
45 | @Override
46 | protected Boolean isHermesEnabled() {
47 | return BuildConfig.IS_HERMES_ENABLED;
48 | }
49 | });
50 |
51 | @Override
52 | public ReactNativeHost getReactNativeHost() {
53 | return mReactNativeHost;
54 | }
55 |
56 | @Override
57 | public void onCreate() {
58 | super.onCreate();
59 | SoLoader.init(this, /* native exopackage */ false);
60 | ApplicationLifecycleDispatcher.onApplicationCreate(this);
61 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
62 | // If you opted-in for the New Architecture, we load the native entry point for this app.
63 | DefaultNewArchitectureEntryPoint.load();
64 | }
65 | ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
66 | }
67 |
68 |
69 | @Override
70 | public void onConfigurationChanged(Configuration newConfig) {
71 | super.onConfigurationChanged(newConfig);
72 | ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/android/app/src/main/java/app/ironbelly/SplashActivity.java:
--------------------------------------------------------------------------------
1 | package app.ironbelly;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import androidx.appcompat.app.AppCompatActivity;
6 |
7 | public class SplashActivity extends AppCompatActivity {
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 |
12 | Intent intent = new Intent(this, MainActivity.class);
13 | startActivity(intent);
14 | finish();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/android/app/src/main/java/app/ironbelly/tor/TorConfig.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 The Tari Project
3 | *
4 | * Redistribution and use in source and binary forms, with or
5 | * without modification, are permitted provided that the
6 | * following conditions are met:
7 | *
8 | * 1. Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | *
11 | * 2. Redistributions in binary form must reproduce the above
12 | * copyright notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | *
15 | * 3. Neither the name of the copyright holder nor the names of
16 | * its contributors may be used to endorse or promote products
17 | * derived from this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
20 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
21 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 | */
33 | package app.ironbelly.tor
34 |
35 | /**
36 | * Tor proxy configuration.
37 | *
38 | * @author The Tari Development Team
39 | */
40 | data class TorConfig(
41 | val proxyPort: Int,
42 | val controlHost: String,
43 | val controlPort: Int,
44 | val cookieFilePath: String,
45 | )
--------------------------------------------------------------------------------
/android/app/src/main/java/app/ironbelly/tor/TorProxyState.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 The Tari Project
3 | *
4 | * Redistribution and use in source and binary forms, with or
5 | * without modification, are permitted provided that the
6 | * following conditions are met:
7 | *
8 | * 1. Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | *
11 | * 2. Redistributions in binary form must reproduce the above
12 | * copyright notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | *
15 | * 3. Neither the name of the copyright holder nor the names of
16 | * its contributors may be used to endorse or promote products
17 | * derived from this software without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
20 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
21 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 | */
33 | package app.ironbelly.tor
34 |
35 | /**
36 | * Tor proxy state - is deduced from connection state and bootstrap logs.
37 | *
38 | * @author The Tari Development Team
39 | */
40 | sealed class TorProxyState {
41 | object NotReady : TorProxyState()
42 | object Initializing : TorProxyState()
43 | data class Running(val bootstrapStatus: TorBootstrapStatus) : TorProxyState()
44 | object Failed : TorProxyState()
45 | }
46 |
47 | data class TorBootstrapStatus(val progress: Int, val summary: String, val warning: String? = null) {
48 |
49 | companion object {
50 |
51 | private val warningLogRegex = Regex(".*PROGRESS=(\\d+).*SUMMARY=\"([^\"]*)\".*WARNING=\"([^\"]*)\".*")
52 | private val logRegex = Regex(".*PROGRESS=(\\d+).*SUMMARY=\"([^\"]*)\".*")
53 | const val maxProgress = 100
54 |
55 | fun from(logLine: String): TorBootstrapStatus {
56 | if (warningLogRegex.matches(logLine)) {
57 | val matchResult = warningLogRegex.find(logLine)
58 | val (progress, summary, warning) = matchResult!!.destructured
59 | return TorBootstrapStatus(
60 | progress = progress.toInt(),
61 | summary = summary,
62 | warning = warning
63 | )
64 | } else if (logRegex.matches(logLine)) {
65 | val matchResult = logRegex.find(logLine)
66 | val (progress, summary) = matchResult!!.destructured
67 | return TorBootstrapStatus(
68 | progress = progress.toInt(),
69 | summary = summary
70 | )
71 | }
72 | return TorBootstrapStatus(
73 | progress = 0,
74 | summary = "",
75 | warning = null
76 | )
77 | }
78 | }
79 |
80 | }
--------------------------------------------------------------------------------
/android/app/src/main/jniLibs/Android.mk:
--------------------------------------------------------------------------------
1 | LOCAL_PATH := $(call my-dir)
2 |
3 | include $(CLEAR_VARS)
4 |
5 | LOCAL_MODULE := libwallet
6 | LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libwallet.so
7 | LOCAL_LDLIBS := -llog
8 | include $(PREBUILT_SHARED_LIBRARY)
9 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/background_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/android/app/src/main/res/layout/launch_screen.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #000000
4 |
5 |
6 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ffffff
4 |
5 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/android/app/src/main/res/xml/filepaths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android/app/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 127.0.0.1
5 | 10.0.1.1
6 | 10.0.2.2
7 | localhost
8 |
9 |
10 |
--------------------------------------------------------------------------------
/android/app/src/release/java/app/ironbelly/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package com.rndiffapp;
8 |
9 | import android.content.Context;
10 | import com.facebook.react.ReactInstanceManager;
11 |
12 | /**
13 | * Class responsible of loading Flipper inside your React Native application. This is the release
14 | * flavor of it so it's empty as we don't want to load Flipper.
15 | */
16 | public class ReactNativeFlipper {
17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
18 | // Do nothing as we don't want to initialize Flipper on Release.
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.8.0'
5 | ext {
6 | buildToolsVersion = "34.0.0"
7 | minSdkVersion = 21
8 | compileSdkVersion = 34
9 | targetSdkVersion = 34
10 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
11 | ndkVersion = "23.1.7779620"
12 | }
13 | repositories {
14 | google()
15 | mavenCentral()
16 | }
17 | dependencies {
18 | classpath('com.android.tools.build:gradle:8.1.1')
19 | classpath("com.facebook.react:react-native-gradle-plugin")
20 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
21 | // NOTE: Do not place your application dependencies here; they belong
22 | // in the individual module build.gradle files
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/android/get_apk_from_aab.sh:
--------------------------------------------------------------------------------
1 | aab=$1
2 | apks=app.apks
3 | apk=app.apk
4 | pass=$(security -q find-generic-password -a "Ivan Sorokin" -s "android_keystore" -w)
5 | bundletool build-apks --mode=universal --bundle=$aab --output=$apks --ks=./app/upload-key.keystore --ks-pass="pass:$pass" --ks-key-alias=upload-key-alias --key-pass="pass:$pass"
6 | mv $apks apks.zip
7 | unzip apks.zip -d apks
8 | mv apks/universal.apk $apk
9 | rm -rf apks.zip
10 | rm -rf apks
--------------------------------------------------------------------------------
/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: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
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 | # Set this to pack app in the release mode, but signed with dev keys
21 | # LOCAL_RELEASE=true
22 |
23 | IRONBELLY_UPLOAD_STORE_FILE=upload-key.keystore
24 | IRONBELLY_UPLOAD_KEY_ALIAS=upload-key-alias
25 |
26 | # AndroidX package structure to make it clearer which packages are bundled with the
27 | # Android operating system, and which are packaged with your app's APK
28 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
29 | android.useAndroidX=true
30 |
31 | # Automatically convert third-party libraries to use AndroidX
32 | android.enableJetifier=true
33 |
34 | # Version of flipper SDK to use with React Native
35 | FLIPPER_VERSION=0.182.0
36 |
37 | # android.bundle.enableUncompressedNativeLibs=false
38 |
39 | # Use this property to specify which architecture you want to build.
40 | # You can also override it from the CLI using
41 | # ./gradlew -PreactNativeArchitectures=x86_64
42 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
43 | # Use this property to enable support to the new architecture.
44 | # This will allow you to use TurboModules and the Fabric render in
45 | # your application. You should enable this flag either if you want
46 | # to write custom TurboModules/Fabric components OR use libraries that
47 | # are providing them.
48 | newArchEnabled=false
49 |
50 | # Use this property to enable or disable the Hermes JS engine.
51 | # If set to false, you will be using JSC instead.
52 | hermesEnabled=true
53 | android.defaults.buildfeatures.buildconfig=true
54 | android.nonTransitiveRClass=false
55 | android.nonFinalResIds=false
56 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-all.zip
4 | networkTimeout=10000
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem http://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
34 |
35 | @rem Find java.exe
36 | if defined JAVA_HOME goto findJavaFromJavaHome
37 |
38 | set JAVA_EXE=java.exe
39 | %JAVA_EXE% -version >NUL 2>&1
40 | if %ERRORLEVEL% equ 0 goto execute
41 |
42 | echo.
43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
44 | echo.
45 | echo Please set the JAVA_HOME variable in your environment to match the
46 | echo location of your Java installation.
47 |
48 | goto fail
49 |
50 | :findJavaFromJavaHome
51 | set JAVA_HOME=%JAVA_HOME:"=%
52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
53 |
54 | if exist "%JAVA_EXE%" goto execute
55 |
56 | echo.
57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
58 | echo.
59 | echo Please set the JAVA_HOME variable in your environment to match the
60 | echo location of your Java installation.
61 |
62 | goto fail
63 |
64 | :execute
65 | @rem Setup the command line
66 |
67 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
68 |
69 | @rem Execute Gradle
70 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
71 |
72 | :end
73 | @rem End local scope for the variables with windows NT shell
74 | if %ERRORLEVEL% equ 0 goto mainEnd
75 |
76 | :fail
77 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
78 | rem the _cmd.exe /c_ return code!
79 | set EXIT_CODE=%ERRORLEVEL%
80 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
81 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
82 | exit /b %EXIT_CODE%
83 |
84 | :mainEnd
85 | if "%OS%"=="Windows_NT" endlocal
86 |
87 | :omega
88 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'Ironbelly'
2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
3 | include ':app'
4 | includeBuild('../node_modules/@react-native/gradle-plugin')
5 |
6 | apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle")
7 | useExpoModules()
8 |
9 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Ironbelly",
3 | "displayName": "Ironbelly",
4 | "ios": { "userInterfaceStyle": "automatic" }
5 | }
6 |
--------------------------------------------------------------------------------
/docs/balance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/docs/balance.png
--------------------------------------------------------------------------------
/docs/balance.uml:
--------------------------------------------------------------------------------
1 | @startuml balance.png
2 | title Balance
3 | ReactNative -> Rust: Request balance
4 | Rust -> lmdb: Request list of outputs
5 | lmdb -> Rust: Return list of outputs
6 | Rust -> Rust: Calculate balance
7 | Rust -> ReactNative: Return balance
8 | @enduml
9 |
10 |
--------------------------------------------------------------------------------
/docs/navigation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/docs/navigation.png
--------------------------------------------------------------------------------
/docs/navigation.uml:
--------------------------------------------------------------------------------
1 | @startuml
2 |
3 | start
4 |
5 | if (seed file exists?) then (yes)
6 | #lightgreen:show Locked screen;
7 | repeat :wait for user to enter password;
8 | backward :wait 1 second;
9 | repeat while (is entered password correct?) is (no)
10 | ->yes;
11 | if (restore in progress?) then (yes)
12 | #lightgreen:show Restore screen;
13 | else (no)
14 | #lightgreen:show Overview screen;
15 | endif
16 | else (no)
17 | #lightgreen:show Landing screen;
18 | endif
19 |
20 |
21 | @enduml
22 |
23 |
--------------------------------------------------------------------------------
/docs/refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/docs/refresh.png
--------------------------------------------------------------------------------
/docs/refresh.uml:
--------------------------------------------------------------------------------
1 | @startuml refresh.png
2 | /' skinparam dpi 300 '/
3 | /' scale 1000 width '/
4 | title Refresh
5 | ReactNative -> Rust: Request PMMR
6 | Rust -> GrinNode: Request chain Tip
7 | GrinNode -> Rust: Tip
8 | Rust -> GrinNode: Request PMMR range for Last scanned block..Tip blocks
9 | GrinNode -> Rust: PMMR range
10 | Rust -> ReactNative: PMMR range
11 | ReactNative -> ReactNative: n = PMMR range start
12 | loop while n < PMMR range end
13 | ReactNative -> ReactNative: m = n + CONST
14 | ReactNative -> Rust: Request n..m outputs:\nn < m <= PMMR range end
15 | Rust -> GrinNode: Scan n..m outputs
16 | GrinNode -> Rust: n..m outputs
17 | Rust -> Rust: Find ones, which belong to "us"
18 | Rust -> lmdb: Store "our" outputs
19 | Rust -> ReactNative: Successful scan of n..m outputs
20 | ReactNative -> ReactNative: n = m + 1
21 | end
22 | @enduml
23 |
24 |
25 |
--------------------------------------------------------------------------------
/docs/release_test.md:
--------------------------------------------------------------------------------
1 | # Manual Test
2 |
3 | Perform this test before hitting release button in stores until we have proper e2e testing in place
4 |
5 | ## Cast
6 |
7 | - Android - new user without a paper key
8 | - iPhone - new user with paper key
9 | - Carol - donor
10 |
11 | ## What to test
12 |
13 | 1. Android sends/receives using slatepack/address
14 | 2. iPhone sends/receives using slatepack/address
15 |
16 | ## Scenario
17 |
18 | 1. iPhone restores his wallet.
19 | 2. Android creates a wallet
20 | 3. Android receives 0.1 Grin via grin address from Carol
21 | 4. iPhone receives 0.1 Grin via grin address from Carol
22 |
23 | 5. iPhone sends 0.01 Grin to Android using slatepack
24 |
25 | 6. Android sends 0.1 Grin to iPhone using slatepack
26 |
27 | 7. Android sends 0.1 back to Carol
28 | 8. iPhone sends 0.1 back to Carol
29 | 9. Android and iPhone remove their accounts
30 | ...(Android should have 0 balance), iPhone should have original balance)
31 | 10. iPhone creates a new wallet
32 | 11. Android restores iPhone's wallet
33 |
--------------------------------------------------------------------------------
/e2e/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "setupFilesAfterEnv": ["./init.js"],
3 | "testEnvironment": "node"
4 | }
5 |
--------------------------------------------------------------------------------
/e2e/init.js:
--------------------------------------------------------------------------------
1 | const detox = require('detox')
2 | const config = require('../package.json').detox
3 | const adapter = require('detox/runners/jest/adapter')
4 |
5 | jest.setTimeout(120000)
6 | jasmine.getEnv().addReporter(adapter)
7 |
8 | beforeAll(async () => {
9 | await detox.init(config)
10 | })
11 |
12 | beforeEach(async () => {
13 | await adapter.beforeEach()
14 | })
15 |
16 | afterAll(async () => {
17 | await adapter.afterAll()
18 | await detox.cleanup()
19 | })
20 |
--------------------------------------------------------------------------------
/e2e/utils.js:
--------------------------------------------------------------------------------
1 | export async function readTextValue(testID) {
2 | try {
3 | await expect(element(by.id(testID))).toHaveText('__read_element_error_')
4 | } catch (error) {
5 | const start = `AX.id='${testID}';`
6 | const end = '; AX.frame'
7 | const errorMessage = error.message.toString()
8 | const [, restMessage] = errorMessage.split(start)
9 | const [label] = restMessage.split(end)
10 | const [, value] = label.split('=')
11 |
12 | return value.slice(1, value.length - 1)
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/e2e/walletInit.spec.js:
--------------------------------------------------------------------------------
1 | import { readTextValue } from './utils'
2 |
3 | describe('Ironbelly', () => {
4 | beforeEach(async () => {
5 | await device.reloadReactNative()
6 | })
7 |
8 | it('should create a new wallet', async () => {
9 | await expect(element(by.id('LandingScreen'))).toBeVisible()
10 |
11 | await element(by.id('NewWalletButton')).tap()
12 |
13 | //Legal
14 | let nextButton = element(by.id('IAgree'))
15 | await expect(nextButton).toBeVisible()
16 | await nextButton.tap()
17 | await element(by.text('I agree to the ')).tap()
18 | await nextButton.tap()
19 |
20 | nextButton = element(by.id('SubmitPassword'))
21 |
22 | const passwordField = element(by.id('Password'))
23 | await expect(passwordField).toBeVisible()
24 | await passwordField.typeText('passcode')
25 | const passwordConfirmField = element(by.id('ConfirmPassword'))
26 | await expect(passwordConfirmField).toBeVisible()
27 | await passwordConfirmField.typeText('passcode1')
28 | await expect(nextButton).toBeVisible()
29 | // passwords are not equal, so the button is disabled
30 | // tap should not change anything
31 | await nextButton.tap()
32 | await passwordConfirmField.tap()
33 | await passwordConfirmField.typeText('passcode')
34 | // Now passwords are equal - buton tap should move to the next step
35 | await waitFor(nextButton)
36 | .toBeVisible()
37 | .withTimeout(2000)
38 | await expect(nextButton).toBeVisible()
39 | await nextButton.tap()
40 |
41 | const words = []
42 | for (let i = 0; i < 24; i++) {
43 | words[i] = await readTextValue(`Word${i + 1}`)
44 | }
45 | await element(by.id('ShowPaperKeyScrollView')).scrollTo('bottom')
46 | nextButton = element(by.id('ShowPaperKeyContinueButton'))
47 | await expect(nextButton).toBeVisible()
48 | await nextButton.tap()
49 |
50 | nextButton = element(by.id('VerifyPaperKeyContinueButton'))
51 | const wordsCount = 24
52 | for (let i = 0; i < wordsCount - 1; i++) {
53 | const word = element(by.id(`VerifyWord${i + 1}`))
54 | await word.typeText(words[i])
55 | await word.tapReturnKey()
56 | }
57 | const lastWord = element(by.id(`VerifyWord${wordsCount}`))
58 | await lastWord.typeText('aaaa') // enter wrong word
59 | await lastWord.tapReturnKey()
60 | // Words are invalid - button disabled
61 | await expect(nextButton).toBeVisible()
62 | await nextButton.tap()
63 |
64 | await lastWord.tap()
65 | await expect(lastWord).toBeVisible()
66 | await lastWord.replaceText(words[wordsCount - 1]) // enter correct word
67 | await lastWord.tapReturnKey()
68 |
69 | await expect(nextButton).toBeVisible()
70 | await nextButton.tap()
71 |
72 | nextButton = element(by.id('ShowMeButton'))
73 | await expect(nextButton).toBeVisible()
74 | await nextButton.tap()
75 | })
76 | })
77 |
--------------------------------------------------------------------------------
/fastlane/Appfile:
--------------------------------------------------------------------------------
1 | # iOS
2 | app_identifier("app.ironbelly") # The bundle identifier of your app
3 | apple_id("ivan@sorokin.io") # Your Apple email address
4 |
5 | itc_team_id("120279655") # App Store Connect Team ID
6 | team_id("4496JM56CN") # Developer Portal Team ID
7 |
8 | # Android
9 | json_key_file("android/key.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
10 | package_name("app.ironbelly") # e.g. com.krausefx.app
11 |
12 |
13 | # For more information about the Appfile, see:
14 | # https://docs.fastlane.tools/advanced/#appfile
15 |
--------------------------------------------------------------------------------
/fastlane/Deliverfile:
--------------------------------------------------------------------------------
1 | # The Deliverfile allows you to store various App Store Connect metadata
2 | # For more information, check out the docs
3 | # https://docs.fastlane.tools/actions/deliver/
4 |
--------------------------------------------------------------------------------
/fastlane/Fastfile:
--------------------------------------------------------------------------------
1 | # This file contains the fastlane.tools configuration
2 | # You can find the documentation at https://docs.fastlane.tools
3 | #
4 | # For a list of all available actions, check out
5 | #
6 | # https://docs.fastlane.tools/actions
7 | #
8 | # For a list of all available plugins, check out
9 | #
10 | # https://docs.fastlane.tools/plugins/available-plugins
11 | #
12 |
13 | # Uncomment the line if you want fastlane to automatically update itself
14 | # update_fastlane
15 |
16 | default_platform(:ios)
17 |
18 | platform :ios do
19 | desc "Bump new version for iOS"
20 |
21 | lane :bumpVersion do |options|
22 | if options[:type]
23 | increment_version_number(xcodeproj: "ios/Ironbelly.xcodeproj", bump_type: options[:type])
24 | end
25 | end
26 |
27 | lane :bumpBuildNumber do |options|
28 | increment_build_number(xcodeproj: "ios/Ironbelly.xcodeproj")
29 | end
30 |
31 | desc "Push a new beta build to TestFlight"
32 |
33 | lane :beta do
34 | build_app(workspace: "ios/Ironbelly.xcworkspace", scheme: "Ironbelly", export_xcargs: "-allowProvisioningUpdates")
35 | upload_to_testflight()
36 | end
37 | end
38 |
39 | platform :android do
40 | desc "Submit a new Alpha Build to Play Market"
41 | lane :alpha do
42 | gradle(task: "clean bundleRelease", project_dir: 'android/')
43 | upload_to_play_store(track: 'alpha')
44 | end
45 |
46 | desc "Submit a new Internal Build to Play Market"
47 | lane :internal do
48 | gradle(task: "clean bundleRelease", project_dir: 'android/')
49 | upload_to_play_store(track: 'internal')
50 | end
51 |
52 | desc "Build Release APK"
53 | lane :apk do
54 | gradle(task: "clean assembleRelease", project_dir: 'android/')
55 | end
56 |
57 | lane :bumpVersion do |options|
58 | if options[:type]
59 | increment_version_name(
60 | gradle_file_path: "./android/app/build.gradle",
61 | bump_type: options[:type]
62 | )
63 | end
64 | end
65 | lane :bumpBuildNumber do |options|
66 | if options[:type]
67 | increment_version_code(gradle_file_path: "./android/app/build.gradle")
68 | end
69 | end
70 | end
71 |
72 |
--------------------------------------------------------------------------------
/fastlane/Pluginfile:
--------------------------------------------------------------------------------
1 | # Autogenerated by fastlane
2 | #
3 | # Ensure this file is checked in to source control!
4 |
5 | gem 'fastlane-plugin-increment_version_name'
6 | gem 'fastlane-plugin-increment_version_code'
7 |
--------------------------------------------------------------------------------
/fastlane/README.md:
--------------------------------------------------------------------------------
1 | fastlane documentation
2 | ----
3 |
4 | # Installation
5 |
6 | Make sure you have the latest version of the Xcode command line tools installed:
7 |
8 | ```sh
9 | xcode-select --install
10 | ```
11 |
12 | For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
13 |
14 | # Available Actions
15 |
16 | ## iOS
17 |
18 | ### ios bumpVersion
19 |
20 | ```sh
21 | [bundle exec] fastlane ios bumpVersion
22 | ```
23 |
24 | Bump new version for iOS
25 |
26 | ### ios bumpBuildNumber
27 |
28 | ```sh
29 | [bundle exec] fastlane ios bumpBuildNumber
30 | ```
31 |
32 |
33 |
34 | ### ios beta
35 |
36 | ```sh
37 | [bundle exec] fastlane ios beta
38 | ```
39 |
40 | Push a new beta build to TestFlight
41 |
42 | ----
43 |
44 |
45 | ## Android
46 |
47 | ### android alpha
48 |
49 | ```sh
50 | [bundle exec] fastlane android alpha
51 | ```
52 |
53 | Submit a new Alpha Build to Play Market
54 |
55 | ### android internal
56 |
57 | ```sh
58 | [bundle exec] fastlane android internal
59 | ```
60 |
61 | Submit a new Internal Build to Play Market
62 |
63 | ### android apk
64 |
65 | ```sh
66 | [bundle exec] fastlane android apk
67 | ```
68 |
69 | Build Release APK
70 |
71 | ### android bumpVersion
72 |
73 | ```sh
74 | [bundle exec] fastlane android bumpVersion
75 | ```
76 |
77 |
78 |
79 | ### android bumpBuildNumber
80 |
81 | ```sh
82 | [bundle exec] fastlane android bumpBuildNumber
83 | ```
84 |
85 |
86 |
87 | ----
88 |
89 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
90 |
91 | More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
92 |
93 | The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
94 |
--------------------------------------------------------------------------------
/fastlane/Snapfile:
--------------------------------------------------------------------------------
1 | # Uncomment the lines below you want to change by removing the # in the beginning
2 |
3 | # A list of devices you want to take the screenshots from
4 | devices([
5 | # "iPhone 8",
6 | "iPhone 8 Plus",
7 | # "iPhone SE",
8 | "iPhone 12 Pro Max",
9 | # "iPhone X",
10 | # "iPad Pro (12.9-inch)",
11 | # "iPad Pro (9.7-inch)",
12 | # "Apple TV 1080p"
13 | ])
14 |
15 | languages([
16 | "en-US",
17 | # "de-DE",
18 | # "it-IT",
19 | # ["pt", "pt_BR"] # Portuguese with Brazilian locale
20 | ])
21 |
22 | # Choose which project/workspace to use
23 | # project "./Project.xcodeproj"
24 | workspace "./ios/Ironbelly.xcworkspace"
25 |
26 | # The name of the scheme which contains the UI Tests
27 | scheme("Snapshots")
28 |
29 | # Where should the resulting screenshots be stored?
30 | output_directory("./fastlane/screenshots")
31 |
32 | # remove the '#' to clear all previously generated screenshots before creating new ones
33 | clear_previous_screenshots(true)
34 |
35 | # Remove the '#' to set the status bar to 9:41 AM, and show full battery and reception.
36 | override_status_bar(true)
37 |
38 | # Arguments to pass to the app on launch. See https://docs.fastlane.tools/actions/snapshot/#launch-arguments
39 | # launch_arguments(["-favColor red"])
40 |
41 | # For more information about all available options run
42 | # fastlane action snapshot
43 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import './rn-polyfill-depricated-proptypes'
18 | import {AppRegistry} from 'react-native'
19 | import App from './src/App'
20 | import {name as appName} from './app.json'
21 |
22 | import '@react-native-community/netinfo'
23 | import 'react-native-gesture-handler'
24 |
25 | // NetInfo.configure({
26 | // reachabilityUrl: ' https://node.ironbelly.app/',
27 | // reachabilityTest: async (response) => response.status === 200,
28 | // })
29 |
30 | AppRegistry.registerComponent(appName, () => App)
31 |
--------------------------------------------------------------------------------
/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | # This `.xcode.env` file is versioned and is used to source the environment
2 | # used when running script phases inside Xcode.
3 | # To customize your local environment, you can create an `.xcode.env.local`
4 | # file that is not versioned.
5 |
6 | # NODE_BINARY variable contains the PATH to the node executable.
7 | #
8 | # Customize the NODE_BINARY variable here.
9 | # For example, to use nvm with brew, add the following line
10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use
11 | export NODE_BINARY=$(command -v node)
12 |
--------------------------------------------------------------------------------
/ios/.xcode.env.local:
--------------------------------------------------------------------------------
1 | export NODE_BINARY="/Users/i1skn/.n/bin/node"
2 |
--------------------------------------------------------------------------------
/ios/Cartfile:
--------------------------------------------------------------------------------
1 | github "iCepa/Tor.framework" "master"
2 |
--------------------------------------------------------------------------------
/ios/Cartfile.resolved:
--------------------------------------------------------------------------------
1 | github "iCepa/Tor.framework" "19eb9505bd77d14757322541b26a6dca7f03dfde"
2 |
--------------------------------------------------------------------------------
/ios/Ironbelly.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Ironbelly.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Ironbelly.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildSystemType
6 | Latest
7 | PreviewsEnabled
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Ironbelly/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 |
18 |
19 | import UIKit
20 | import LaunchScreenSnapshot
21 | import ExpoModulesCore
22 | import React
23 |
24 | @UIApplicationMain
25 | class AppDelegate: EXAppDelegateWrapper, RCTBridgeDelegate, UIApplicationDelegate {
26 |
27 | var window: UIWindow?
28 | var bridge: RCTBridge!
29 |
30 | func sourceURL(for bridge: RCTBridge!) -> URL! {
31 | #if DEBUG
32 | return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
33 | #else
34 | Bundle.main.url(forResource: "main", withExtension: "jsbundle")
35 | #endif
36 | }
37 |
38 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
39 |
40 | c_set_logger()
41 |
42 | self.bridge = RCTBridge(delegate: self, launchOptions: launchOptions)
43 | let rootView = RCTRootView(bridge: self.bridge, moduleName: "Ironbelly", initialProperties: nil)
44 | let rootViewController = UIViewController()
45 | rootViewController.view = rootView
46 |
47 | self.window = UIWindow(frame: UIScreen.main.bounds)
48 | self.window?.rootViewController = rootViewController
49 | self.window?.makeKeyAndVisible()
50 |
51 | LaunchScreenSnapshot.protect(with: nil, trigger: .didEnterBackground)
52 | RNSplashScreen.show()
53 |
54 | return true
55 | }
56 |
57 | func application(_ app: UIApplication,
58 | open url: URL,
59 | options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
60 | RCTLinkingManager.application(app, open: url, options: options)
61 | return true
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "icon_20pt@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "icon_20pt@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "icon_29pt@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "icon_29pt@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "icon_40pt@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "icon_40pt@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "icon_60pt@2x.png",
43 | "scale" : "2x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "icon_60pt@3x.png",
49 | "scale" : "3x"
50 | },
51 | {
52 | "size" : "20x20",
53 | "idiom" : "ipad",
54 | "filename" : "icon_20pt.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "icon_20pt@2x-1.png",
61 | "scale" : "2x"
62 | },
63 | {
64 | "size" : "29x29",
65 | "idiom" : "ipad",
66 | "filename" : "icon_29pt.png",
67 | "scale" : "1x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "icon_29pt@2x-1.png",
73 | "scale" : "2x"
74 | },
75 | {
76 | "size" : "40x40",
77 | "idiom" : "ipad",
78 | "filename" : "icon_40pt.png",
79 | "scale" : "1x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "icon_40pt@2x-1.png",
85 | "scale" : "2x"
86 | },
87 | {
88 | "size" : "76x76",
89 | "idiom" : "ipad",
90 | "filename" : "icon_76pt.png",
91 | "scale" : "1x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "icon_76pt@2x.png",
97 | "scale" : "2x"
98 | },
99 | {
100 | "size" : "83.5x83.5",
101 | "idiom" : "ipad",
102 | "filename" : "icon_83.5@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "1024x1024",
107 | "idiom" : "ios-marketing",
108 | "filename" : "Icon.png",
109 | "scale" : "1x"
110 | }
111 | ],
112 | "info" : {
113 | "version" : 1,
114 | "author" : "xcode"
115 | }
116 | }
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/Icon.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_20pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_20pt.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_29pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_29pt.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_40pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_40pt.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_76pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_76pt.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/LaunchLogo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchLogo.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchLogo@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchLogo@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/LaunchLogo.imageset/LaunchLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/LaunchLogo.imageset/LaunchLogo.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/LaunchLogo.imageset/LaunchLogo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/LaunchLogo.imageset/LaunchLogo@2x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Assets.xcassets/LaunchLogo.imageset/LaunchLogo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/Assets.xcassets/LaunchLogo.imageset/LaunchLogo@3x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/ios/Ironbelly/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "scale" : "1x",
46 | "size" : "1024x1024"
47 | }
48 | ],
49 | "info" : {
50 | "author" : "xcode",
51 | "version" : 1
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/ios/Ironbelly/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ios/Ironbelly/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | Ironbelly
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 5.3.0
21 | CFBundleVersion
22 | 52
23 | ITSAppUsesNonExemptEncryption
24 |
25 | LSRequiresIPhoneOS
26 |
27 | LSSupportsOpeningDocumentsInPlace
28 |
29 | NSAppTransportSecurity
30 |
31 | NSAllowsArbitraryLoads
32 |
33 |
34 | NSCameraUsageDescription
35 | To scan QR codes
36 | NSFaceIDUsageDescription
37 | Enabling Face ID allows you quick and secure access to your wallet.
38 | NSLocationAlwaysUsageDescription
39 | Need access while using app to access your location.
40 | NSLocationWhenInUseUsageDescription
41 | Need access while using app to access your location.
42 | NSPhotoLibraryUsageDescription
43 | To read QR codes
44 | UIAppFonts
45 |
46 | FontAwesome5_Regular.ttf
47 | FontAwesome5_Solid.ttf
48 | MaterialCommunityIcons.ttf
49 | FontAwesome.ttf
50 | Ionicons.ttf
51 | Feather.ttf
52 | Poppins-Black.ttf
53 | Poppins-BlackItalic.ttf
54 | Poppins-Bold.ttf
55 | Poppins-BoldItalic.ttf
56 | Poppins-ExtraBold.ttf
57 | Poppins-ExtraBoldItalic.ttf
58 | Poppins-ExtraLight.ttf
59 | Poppins-ExtraLightItalic.ttf
60 | Poppins-Italic.ttf
61 | Poppins-Light.ttf
62 | Poppins-LightItalic.ttf
63 | Poppins-Medium.ttf
64 | Poppins-MediumItalic.ttf
65 | Poppins-Regular.ttf
66 | Poppins-SemiBold.ttf
67 | Poppins-SemiBoldItalic.ttf
68 | Poppins-Thin.ttf
69 | Poppins-ThinItalic.ttf
70 |
71 | UILaunchStoryboardName
72 | LaunchScreen
73 | UIRequiredDeviceCapabilities
74 |
75 | armv7
76 |
77 | UISupportedInterfaceOrientations
78 |
79 | UIInterfaceOrientationPortrait
80 |
81 | UISupportedInterfaceOrientations~ipad
82 |
83 | UIInterfaceOrientationPortrait
84 | UIInterfaceOrientationPortraitUpsideDown
85 | UIInterfaceOrientationLandscapeLeft
86 | UIInterfaceOrientationLandscapeRight
87 |
88 | UIViewControllerBasedStatusBarAppearance
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ios/Ironbelly/Tor/Helpers/NetworkTools.h:
--------------------------------------------------------------------------------
1 | // NetworkTools.h
2 |
3 | /*
4 | Package MobileWallet
5 | Created by S.Shovkoplyas on 01.09.2020
6 | Using Swift 5.0
7 | Running on macOS 10.15
8 |
9 | Copyright 2019 The Tari Project
10 |
11 | Redistribution and use in source and binary forms, with or
12 | without modification, are permitted provided that the
13 | following conditions are met:
14 |
15 | 1. Redistributions of source code must retain the above copyright notice,
16 | this list of conditions and the following disclaimer.
17 |
18 | 2. Redistributions in binary form must reproduce the above
19 | copyright notice, this list of conditions and the following disclaimer in the
20 | documentation and/or other materials provided with the distribution.
21 |
22 | 3. Neither the name of the copyright holder nor the names of
23 | its contributors may be used to endorse or promote products
24 | derived from this software without specific prior written permission.
25 |
26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
27 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
28 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
31 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
33 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
37 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | */
40 |
41 | #import
42 |
43 | NS_ASSUME_NONNULL_BEGIN
44 |
45 | @interface NetworkTools : NSObject
46 |
47 | +(NSDictionary *)addressesForProtocol:(int)ipVersion;
48 |
49 | @end
50 |
51 | NS_ASSUME_NONNULL_END
52 |
--------------------------------------------------------------------------------
/ios/Ironbelly/Utils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Utils.swift
3 | // Ironbelly
4 | //
5 | // Created by Ivan Sorokin on 06.11.20.
6 | // Copyright © 2020 Ivan Sorokin. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | func returnToReact(error: UInt8, cResult: UnsafePointer, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
12 |
13 | let result = String(cString: cResult)
14 | if error == 0 {
15 | resolve(result)
16 | } else {
17 | reject(nil, result, nil)
18 | }
19 | cstr_free(UnsafeMutablePointer(mutating: cResult))
20 | }
21 |
22 | func checkOpenedWallet(_ wallet: UInt?, _ reject: RCTPromiseRejectBlock) -> UInt? {
23 |
24 | if let w = wallet {
25 | return w
26 | } else {
27 | reject(nil, "Wallet was not opened", nil)
28 | return nil
29 | }
30 | }
31 |
32 | extension NSPointerArray {
33 | func addObject(_ object: AnyObject?) {
34 | guard let strongObject = object else { return }
35 |
36 | let pointer = Unmanaged.passUnretained(strongObject).toOpaque()
37 | addPointer(pointer)
38 | }
39 |
40 | func insertObject(_ object: AnyObject?, at index: Int) {
41 | guard index < count, let strongObject = object else { return }
42 |
43 | let pointer = Unmanaged.passUnretained(strongObject).toOpaque()
44 | insertPointer(pointer, at: index)
45 | }
46 |
47 | func replaceObject(at index: Int, withObject object: AnyObject?) {
48 | guard index < count, let strongObject = object else { return }
49 |
50 | let pointer = Unmanaged.passUnretained(strongObject).toOpaque()
51 | replacePointer(at: index, withPointer: pointer)
52 | }
53 |
54 | func object(at index: Int) -> AnyObject? {
55 | guard index < count, let pointer = self.pointer(at: index) else { return nil }
56 | return Unmanaged.fromOpaque(pointer).takeUnretainedValue()
57 | }
58 |
59 | func removeObject(at index: Int) {
60 | guard index < count else { return }
61 |
62 | removePointer(at: index)
63 | }
64 |
65 | func remove(_ object: AnyObject) {
66 | // get pointer to the passed in object
67 | let objPtr = Unmanaged.passUnretained(object).toOpaque()
68 | var objIndex = -1
69 | for i in 0..= 0 && objIndex < count {
81 | removePointer(at: objIndex)
82 | }
83 | }
84 | }
85 |
86 | let dateFormatter = DateFormatter()
87 |
88 | func logTor(_ logMessage: String) {
89 | dateFormatter.dateFormat = "HH:mm:ss.SSS"
90 | print("TOR: \(dateFormatter.string(from: Date())) \(logMessage)")
91 | }
92 |
--------------------------------------------------------------------------------
/ios/Ironbelly/Wallet-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 |
18 |
19 | #ifndef Wallet_Bridging_Header_h
20 | #define Wallet_Bridging_Header_h
21 |
22 | #import
23 | #import "WalletHeaders.h"
24 | #import "Tor/Helpers/NetworkTools.h"
25 | #import "RNSplashScreen.h"
26 | #endif /* Wallet_Bridging_Header_h */
27 |
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/ReceiveTX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/ReceiveTX.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/ReceiveTX@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/ReceiveTX@2x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/ReceiveTX@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/ReceiveTX@3x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/SendTX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/SendTX.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/SendTX@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/SendTX@2x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/SendTX@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/SendTX@3x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/Settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/Settings.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/Settings@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/Settings@2x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/Settings@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/Settings@3x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/Share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/Share.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/Share@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/Share@2x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/Share@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/Share@3x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/x@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/x@2x.png
--------------------------------------------------------------------------------
/ios/Ironbelly/assets/src/assets/images/x@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/ios/Ironbelly/assets/src/assets/images/x@3x.png
--------------------------------------------------------------------------------
/ios/IronbellyTests/IronbellyTests.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
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
10 |
11 | #import
12 | #import
13 |
14 | #define TIMEOUT_SECONDS 600
15 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
16 |
17 | @interface IronbellyTests : XCTestCase
18 |
19 | @end
20 |
21 | @implementation IronbellyTests
22 |
23 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
24 | {
25 | if (test(view)) {
26 | return YES;
27 | }
28 | for (UIView *subview in [view subviews]) {
29 | if ([self findSubviewInView:subview matching:test]) {
30 | return YES;
31 | }
32 | }
33 | return NO;
34 | }
35 |
36 | - (void)testRendersWelcomeScreen
37 | {
38 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
39 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
40 | BOOL foundElement = NO;
41 |
42 | __block NSString *redboxError = nil;
43 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
44 | if (level >= RCTLogLevelError) {
45 | redboxError = message;
46 | }
47 | });
48 |
49 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
50 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
51 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
52 |
53 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
54 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
55 | return YES;
56 | }
57 | return NO;
58 | }];
59 | }
60 |
61 | RCTSetLogFunction(RCTDefaultLogFunction);
62 |
63 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
64 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
65 | }
66 |
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/ios/UITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 5.3.0
19 | CFBundleVersion
20 | 52
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ios/UITests/UITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UITests.swift
3 | // UITests
4 | //
5 | // Created by Ivan Sorokin on 29.11.20.
6 | // Copyright © 2020 Ivan Sorokin. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class UITests: XCTestCase {
12 |
13 | override func setUpWithError() throws {
14 | // Put setup code here. This method is called before the invocation of each test method in the class.
15 |
16 | // In UI tests it is usually best to stop immediately when a failure occurs.
17 | continueAfterFailure = false
18 |
19 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
20 | }
21 |
22 | override func tearDownWithError() throws {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | }
25 |
26 | func testSnapshots() throws {
27 | // UI tests must launch the application that they test.
28 | let app = XCUIApplication()
29 | setupSnapshot(app)
30 | app.launch()
31 |
32 | XCUIApplication().otherElements["UnlockBtn"].waitForExistence(timeout: 30)
33 | XCUIApplication().otherElements["UnlockBtn"].tap()
34 | snapshot("01OverviewScreen")
35 |
36 | //XCUIApplication().otherElements["SendTab"].waitForExistence(timeout: 30)
37 | XCUIApplication().otherElements["SendTab"].tap()
38 | snapshot("02SendScreen")
39 | XCUIApplication().otherElements["GoBackChevron"].tap()
40 |
41 |
42 | //XCUIApplication().otherElements["ReceiveTab"].waitForExistence(timeout: 30)
43 | XCUIApplication().otherElements["ReceiveTab"].tap()
44 | snapshot("03ReceiveScreen")
45 | XCUIApplication().otherElements["GoBackChevron"].tap()
46 |
47 |
48 | // XCUIApplication().otherElements["SettingsTab"].waitForExistence(timeout: 30)
49 | XCUIApplication().otherElements["SettingsTab"].tap()
50 | snapshot("04SettingsScreen")
51 | }
52 |
53 | // func testLaunchPerformance() throws {
54 | // if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) {
55 | // // This measures how long it takes to launch your application.
56 | // measure(metrics: [XCTApplicationLaunchMetric()]) {
57 | // XCUIApplication().launch()
58 | // }
59 | // }
60 | // }
61 | }
62 |
--------------------------------------------------------------------------------
/ios/Wallet.xcframework/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AvailableLibraries
6 |
7 |
8 | HeadersPath
9 | ../WalletHeaders.h
10 | LibraryIdentifier
11 | ios-arm64
12 | LibraryPath
13 | libwallet.a
14 | SupportedArchitectures
15 |
16 | arm64
17 |
18 | SupportedPlatform
19 | ios
20 |
21 |
22 | HeadersPath
23 | ../WalletHeaders.h
24 | LibraryIdentifier
25 | ios-arm64_x86_64-simulator
26 | LibraryPath
27 | libwallet.a
28 | SupportedArchitectures
29 |
30 | arm64
31 | x86_64
32 |
33 | SupportedPlatform
34 | ios
35 | SupportedPlatformVariant
36 | simulator
37 |
38 |
39 | CFBundlePackageType
40 | XFWK
41 | XCFrameworkFormatVersion
42 | 1.0
43 |
44 |
45 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'react-native',
3 | };
4 |
--------------------------------------------------------------------------------
/metro.config.js:
--------------------------------------------------------------------------------
1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
2 |
3 | /**
4 | * Metro configuration
5 | * https://facebook.github.io/metro/docs/configuration
6 | *
7 | * @type {import('metro-config').MetroConfig}
8 | */
9 | const config = {};
10 |
11 | module.exports = mergeConfig(getDefaultConfig(__dirname), config);
12 |
--------------------------------------------------------------------------------
/patches/react-native-background-timer+2.4.1.patch:
--------------------------------------------------------------------------------
1 | diff --git a/node_modules/react-native-background-timer/android/build.gradle b/node_modules/react-native-background-timer/android/build.gradle
2 | index 85cda09..ee0bd3f 100644
3 | --- a/node_modules/react-native-background-timer/android/build.gradle
4 | +++ b/node_modules/react-native-background-timer/android/build.gradle
5 | @@ -7,6 +7,8 @@ def safeExtGet(prop, fallback) {
6 | android {
7 | compileSdkVersion safeExtGet('compileSdkVersion', 28)
8 |
9 | + namespace "com.ocetnik.timer"
10 | +
11 | defaultConfig {
12 | minSdkVersion safeExtGet('minSdkVersion', 16)
13 | targetSdkVersion safeExtGet('targetSdkVersion', 28)
14 | diff --git a/node_modules/react-native-background-timer/android/src/main/AndroidManifest.xml b/node_modules/react-native-background-timer/android/src/main/AndroidManifest.xml
15 | index 73a8a7f..1b9c48f 100755
16 | --- a/node_modules/react-native-background-timer/android/src/main/AndroidManifest.xml
17 | +++ b/node_modules/react-native-background-timer/android/src/main/AndroidManifest.xml
18 | @@ -1,3 +1,3 @@
19 | -
20 | +
21 |
22 |
23 |
--------------------------------------------------------------------------------
/patches/react-native-config+1.5.1.patch:
--------------------------------------------------------------------------------
1 | diff --git a/node_modules/react-native-config/android/build.gradle b/node_modules/react-native-config/android/build.gradle
2 | index c8f7fd4..9ff2c3c 100644
3 | --- a/node_modules/react-native-config/android/build.gradle
4 | +++ b/node_modules/react-native-config/android/build.gradle
5 | @@ -27,6 +27,8 @@ android {
6 | lintOptions {
7 | abortOnError false
8 | }
9 | +
10 | + namespace "com.lugg.RNCConfig"
11 | }
12 |
13 | repositories {
14 | diff --git a/node_modules/react-native-config/android/src/main/AndroidManifest.xml b/node_modules/react-native-config/android/src/main/AndroidManifest.xml
15 | index 12d7c74..a2f47b6 100644
16 | --- a/node_modules/react-native-config/android/src/main/AndroidManifest.xml
17 | +++ b/node_modules/react-native-config/android/src/main/AndroidManifest.xml
18 | @@ -1,3 +1,2 @@
19 | -
21 | +
22 |
23 |
--------------------------------------------------------------------------------
/patches/react-native-fs+2.20.0.patch:
--------------------------------------------------------------------------------
1 | diff --git a/node_modules/react-native-fs/android/build.gradle b/node_modules/react-native-fs/android/build.gradle
2 | index ddef857..6772fc5 100644
3 | --- a/node_modules/react-native-fs/android/build.gradle
4 | +++ b/node_modules/react-native-fs/android/build.gradle
5 | @@ -18,6 +18,8 @@ android {
6 | compileSdkVersion safeExtGet('compileSdkVersion', 26)
7 | buildToolsVersion safeExtGet('buildToolsVersion', '26.0.3')
8 |
9 | + namespace "com.rnfs"
10 | +
11 | defaultConfig {
12 | minSdkVersion safeExtGet('minSdkVersion', 19)
13 | targetSdkVersion safeExtGet('targetSdkVersion', 26)
14 | diff --git a/node_modules/react-native-fs/android/src/main/AndroidManifest.xml b/node_modules/react-native-fs/android/src/main/AndroidManifest.xml
15 | index 6e54f65..7ce2281 100644
16 | --- a/node_modules/react-native-fs/android/src/main/AndroidManifest.xml
17 | +++ b/node_modules/react-native-fs/android/src/main/AndroidManifest.xml
18 | @@ -1,5 +1,4 @@
19 |
20 | -
22 | +
23 |
24 |
25 |
--------------------------------------------------------------------------------
/patches/react-native-keep-awake+4.0.0.patch:
--------------------------------------------------------------------------------
1 | diff --git a/node_modules/react-native-keep-awake/android/build.gradle b/node_modules/react-native-keep-awake/android/build.gradle
2 | index ba4dfe7..41f88d6 100644
3 | --- a/node_modules/react-native-keep-awake/android/build.gradle
4 | +++ b/node_modules/react-native-keep-awake/android/build.gradle
5 | @@ -1,7 +1,7 @@
6 | buildscript {
7 | repositories {
8 | google()
9 | - jcenter()
10 | + mavenCentral()
11 | }
12 |
13 | dependencies {
14 | @@ -23,6 +23,8 @@ android {
15 | compileSdkVersion _compileSdkVersion
16 | buildToolsVersion _buildToolsVersion
17 |
18 | + namespace "com.corbt.keepawake"
19 | +
20 | defaultConfig {
21 | minSdkVersion _minSdkVersion
22 | targetSdkVersion _targetSdkVersion
23 | diff --git a/node_modules/react-native-keep-awake/android/src/main/AndroidManifest.xml b/node_modules/react-native-keep-awake/android/src/main/AndroidManifest.xml
24 | index bc02af3..9a40236 100644
25 | --- a/node_modules/react-native-keep-awake/android/src/main/AndroidManifest.xml
26 | +++ b/node_modules/react-native-keep-awake/android/src/main/AndroidManifest.xml
27 | @@ -1,4 +1,3 @@
28 |
29 | -
31 | +
32 |
33 | diff --git a/node_modules/react-native-keep-awake/react-native-keep-awake.podspec b/node_modules/react-native-keep-awake/react-native-keep-awake.podspec
34 | index 95933a7..756ad5a 100644
35 | --- a/node_modules/react-native-keep-awake/react-native-keep-awake.podspec
36 | +++ b/node_modules/react-native-keep-awake/react-native-keep-awake.podspec
37 | @@ -18,5 +18,5 @@ Pod::Spec.new do |s|
38 | s.preserve_paths = 'README.md', 'package.json', 'index.js'
39 | s.source_files = 'ios/*.{h,m}'
40 |
41 | - s.dependency 'React'
42 | + s.dependency 'React-Core'
43 | end
44 |
--------------------------------------------------------------------------------
/patches/react-native-linear-gradient+2.8.3.patch:
--------------------------------------------------------------------------------
1 | diff --git a/node_modules/react-native-linear-gradient/android/build.gradle b/node_modules/react-native-linear-gradient/android/build.gradle
2 | index e3aacde..8dc1376 100644
3 | --- a/node_modules/react-native-linear-gradient/android/build.gradle
4 | +++ b/node_modules/react-native-linear-gradient/android/build.gradle
5 | @@ -28,6 +28,8 @@ android {
6 | lintOptions {
7 | abortOnError false
8 | }
9 | +
10 | + namespace "com.BV.LinearGradient"
11 | }
12 |
13 | repositories {
14 | diff --git a/node_modules/react-native-linear-gradient/android/src/main/AndroidManifest.xml b/node_modules/react-native-linear-gradient/android/src/main/AndroidManifest.xml
15 | index a7d57a6..cc947c5 100644
16 | --- a/node_modules/react-native-linear-gradient/android/src/main/AndroidManifest.xml
17 | +++ b/node_modules/react-native-linear-gradient/android/src/main/AndroidManifest.xml
18 | @@ -1 +1 @@
19 | -
20 | +
21 |
--------------------------------------------------------------------------------
/patches/react-native-navigation-bar-color+2.0.2.patch:
--------------------------------------------------------------------------------
1 | diff --git a/node_modules/react-native-navigation-bar-color/android/build.gradle b/node_modules/react-native-navigation-bar-color/android/build.gradle
2 | index 9d285c4..835201b 100644
3 | --- a/node_modules/react-native-navigation-bar-color/android/build.gradle
4 | +++ b/node_modules/react-native-navigation-bar-color/android/build.gradle
5 | @@ -19,6 +19,8 @@ android {
6 | compileSdkVersion rootProject.ext.has('compileSdkVersion') ? rootProject.ext.compileSdkVersion : DEFAULT_COMPILE_SDK_VERSION
7 | buildToolsVersion rootProject.ext.has('buildToolsVersion') ? rootProject.ext.buildToolsVersion : DEFAULT_BUILD_TOOLS_VERSION
8 |
9 | + namespace "com.thebylito.navigationbarcolor"
10 | +
11 | defaultConfig {
12 | minSdkVersion rootProject.ext.has('minSdkVersion') ? rootProject.ext.minSdkVersion : DEFAULT_MIN_SDK_VERSION
13 | targetSdkVersion rootProject.ext.has('targetSdkVersion') ? rootProject.ext.targetSdkVersion : DEFAULT_TARGET_SDK_VERSION
14 | diff --git a/node_modules/react-native-navigation-bar-color/android/src/main/AndroidManifest.xml b/node_modules/react-native-navigation-bar-color/android/src/main/AndroidManifest.xml
15 | index 02625c9..a2f47b6 100644
16 | --- a/node_modules/react-native-navigation-bar-color/android/src/main/AndroidManifest.xml
17 | +++ b/node_modules/react-native-navigation-bar-color/android/src/main/AndroidManifest.xml
18 | @@ -1,3 +1,2 @@
19 | -
21 | +
22 |
23 |
--------------------------------------------------------------------------------
/patches/react-native-splash-screen+3.3.0.patch:
--------------------------------------------------------------------------------
1 | diff --git a/node_modules/react-native-splash-screen/android/build.gradle b/node_modules/react-native-splash-screen/android/build.gradle
2 | index baef1a9..5aab4f2 100644
3 | --- a/node_modules/react-native-splash-screen/android/build.gradle
4 | +++ b/node_modules/react-native-splash-screen/android/build.gradle
5 | @@ -25,6 +25,7 @@ android {
6 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
7 | }
8 | }
9 | + namespace "org.devio.rn.splashscreen"
10 | }
11 |
12 | dependencies {
13 | diff --git a/node_modules/react-native-splash-screen/android/src/main/AndroidManifest.xml b/node_modules/react-native-splash-screen/android/src/main/AndroidManifest.xml
14 | index be5bfe9..a2f47b6 100644
15 | --- a/node_modules/react-native-splash-screen/android/src/main/AndroidManifest.xml
16 | +++ b/node_modules/react-native-splash-screen/android/src/main/AndroidManifest.xml
17 | @@ -1,4 +1,2 @@
18 | -
20 | -
21 | +
22 |
23 |
--------------------------------------------------------------------------------
/patches/react-native-vector-icons+10.0.3.patch:
--------------------------------------------------------------------------------
1 | diff --git a/node_modules/react-native-vector-icons/android/build.gradle b/node_modules/react-native-vector-icons/android/build.gradle
2 | index 3e615e9..ea1b87d 100644
3 | --- a/node_modules/react-native-vector-icons/android/build.gradle
4 | +++ b/node_modules/react-native-vector-icons/android/build.gradle
5 | @@ -23,6 +23,10 @@ if (isNewArchitectureEnabled()) {
6 | android {
7 | namespace = "com.oblador.vectoricons"
8 | compileSdkVersion safeExtGet('compileSdkVersion', 31)
9 | + buildFeatures {
10 | + buildConfig = true
11 | + }
12 | + namespace "com.oblador.vectoricons"
13 |
14 | defaultConfig {
15 | minSdkVersion safeExtGet('minSdkVersion', 21)
16 | diff --git a/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml b/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
17 | index 3bd661a..a2f47b6 100755
18 | --- a/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
19 | +++ b/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
20 | @@ -1,2 +1,2 @@
21 | -
22 | +
23 |
24 |
--------------------------------------------------------------------------------
/react-native.config.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | module.exports = {
18 | project: {
19 | ios: {},
20 | android: {},
21 | },
22 | assets: ['./src/assets/fonts/', './src/assets/images/'],
23 | }
24 |
--------------------------------------------------------------------------------
/rn-polyfill-depricated-proptypes.js:
--------------------------------------------------------------------------------
1 | /**
2 | *File: rn-polyfill-depricated-proptypes.js
3 | **/
4 |
5 | const StandardModule = require('react-native');
6 | const dpProps = require('deprecated-react-native-prop-types');
7 |
8 | const txtImputProx = new Proxy(StandardModule.TextInput, {
9 | get(obj, prop) {
10 | if (prop === 'propTypes') return dpProps.TextInputPropTypes;
11 | return Reflect.get(...arguments);
12 | },
13 | });
14 |
15 | Object.defineProperty(StandardModule, 'ColorPropType', {
16 | configurable: true,
17 | get() {
18 | return dpProps.ColorPropType;
19 | },
20 | });
21 |
22 | Object.defineProperty(StandardModule, 'EdgeInsetsPropType', {
23 | configurable: true,
24 | get() {
25 | return dpProps.EdgeInsetsPropType;
26 | },
27 | });
28 |
29 | Object.defineProperty(StandardModule, 'PointPropType', {
30 | configurable: true,
31 | get() {
32 | return dpProps.PointPropType;
33 | },
34 | });
35 |
36 | Object.defineProperty(StandardModule, 'ViewPropTypes', {
37 | configurable: true,
38 | get() {
39 | return dpProps.ViewPropTypes;
40 | },
41 | });
42 |
43 | Object.defineProperty(StandardModule, 'TextPropTypes', {
44 | configurable: true,
45 | get() {
46 | return dpProps.TextPropTypes;
47 | },
48 | });
49 |
50 | Object.defineProperty(StandardModule, 'TextInputPropTypes', {
51 | configurable: true,
52 | get() {
53 | return dpProps.TextInputPropTypes;
54 | },
55 | });
56 |
57 | Object.defineProperty(StandardModule, 'TextInput', {
58 | configurable: true,
59 | get() {
60 | // return dpProps.TextInputPropTypes;
61 | return txtImputProx;
62 | },
63 | });
64 |
65 | // Object.defineProperty(StandardModule, 'TextStylePropTypes', {
66 | // configurable: true,
67 | // get() {
68 | // return dpProps.TextInputPropTypes;
69 | // },
70 | // });
71 |
72 | // Object.defineProperty(StandardModule, 'ImagePropTypes', {
73 | // configurable: true,
74 | // get() {
75 | // return require('deprecated-react-native-prop-types/DeprecatedImagePropType');
76 | // },
77 | // });
78 |
79 | // Object.defineProperty(StandardModule, 'ImageStylePropTypes', {
80 | // configurable: true,
81 | // get() {
82 | // return require('deprecated-react-native-prop-types/DeprecatedImageStylePropTypes');
83 | // },
84 | // });
85 |
86 | // Object.defineProperty(StandardModule, 'ViewStylePropTypes', {
87 | // configurable: true,
88 | // get() {
89 | // return dpProps.ViewPropTypes;
90 | // },
91 | // });
92 |
93 | // console.log("StandardModule--> ", StandardModule.ColorPropType);
94 |
--------------------------------------------------------------------------------
/rust/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | **/*.rs.bk
3 |
--------------------------------------------------------------------------------
/rust/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "ironbelly-wallet"
3 | version = "0.1.0"
4 | authors = ["Ivan Sorokin "]
5 | description = "Ironbelly - Grin mobile wallet"
6 | publish = false
7 | edition = "2018"
8 |
9 | [dependencies]
10 | clap = { version = "2.31", features = ["yaml"] }
11 | rpassword = "2.0.0"
12 | ctrlc = { version = "3.1", features = ["termination"] }
13 | jni = { version = "0.10.2", default-features = false, optional = true }
14 | failure = "0.1"
15 | failure_derive = "0.1"
16 | prettytable-rs = "0.7"
17 | log = "0.4"
18 | uuid = { version = "0.8", features = ["serde", "v4"] }
19 | serde = { version = "1.0", features = ["derive"] }
20 | serde_json = "1"
21 | serde_derive = "1"
22 | simplelog = "^0.7.4"
23 | openssl = { version = "0.10", features = ["vendored"] }
24 | futures = "0.3"
25 |
26 |
27 | # For Release
28 | # ^
29 | # Does not exist yet
30 |
31 | # For bleeding edge
32 | grin_wallet_api = { git = "https://github.com/i1skn/grin-wallet", branch = "master" }
33 | grin_wallet_impls = { git = "https://github.com/i1skn/grin-wallet", branch = "master" }
34 | grin_wallet_libwallet = { git = "https://github.com/i1skn/grin-wallet", branch = "master" }
35 | grin_wallet_config = { git = "https://github.com/i1skn/grin-wallet", branch = "master" }
36 | grin_wallet_util = { git = "https://github.com/i1skn/grin-wallet", branch = "master" }
37 | grin_wallet_controller = { git = "https://github.com/i1skn/grin-wallet", branch = "master" }
38 | grin_core = { git = "https://github.com/mimblewimble/grin", branch = "master" }
39 | grin_keychain = { git = "https://github.com/mimblewimble/grin", branch = "master" }
40 | grin_util = { git = "https://github.com/mimblewimble/grin", branch = "master" }
41 | grin_api = { git = "https://github.com/mimblewimble/grin", branch = "master" }
42 |
43 |
44 | # For local testing
45 | # grin_wallet_api = { path = "../../../i1skn/grin-wallet/api", version = "5.2.0-beta.1" }
46 | # grin_wallet_impls = { path = "../../../i1skn/grin-wallet/impls", version = "5.2.0-beta.1" }
47 | # grin_wallet_libwallet = { path = "../../../i1skn/grin-wallet/libwallet", version = "5.2.0-beta.1" }
48 | # grin_wallet_config = { path = "../../../i1skn/grin-wallet/config", version = "5.2.0-beta.1" }
49 | # grin_wallet_util = { path = "../../../i1skn/grin-wallet/util", version = "5.2.0-beta.1" }
50 | # grin_wallet_controller = { path = "../../../i1skn/grin-wallet/controller", version = "5.2.0-beta.1" }
51 | # grin_core = { git = "https://github.com/mimblewimble/grin", branch = "master" }
52 | # grin_keychain = { git = "https://github.com/mimblewimble/grin", branch = "master" }
53 | # grin_util = { git = "https://github.com/mimblewimble/grin", branch = "master" }
54 | # grin_api = { git = "https://github.com/mimblewimble/grin", branch = "master" }
55 |
56 |
57 | [target.'cfg(target_os = "android")'.dependencies]
58 | android_logger = "0.8"
59 |
60 | [build-dependencies]
61 | built = "0.3"
62 | cbindgen = "0.8.3"
63 |
64 | [lib]
65 | name = "wallet"
66 | crate-type = ["staticlib", "cdylib"]
67 |
68 | [patch.crates-io]
69 | # croaring = { path = "../../../i1skn/croaring-rs/croaring" }
70 | liblmdb-sys = { git = "https://github.com/i1skn/lmdb-rs" }
71 | # openssl-src = { git = "https://github.com/i1skn/openssl-src-rs", branch = "release/111" }
72 |
73 | [features]
74 | default = ["jni"]
75 |
--------------------------------------------------------------------------------
/rust/build.rs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | extern crate cbindgen;
17 |
18 | use std::env;
19 |
20 | fn main() {
21 | let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
22 |
23 | cbindgen::Builder::new()
24 | .with_crate(crate_dir)
25 | .with_language(cbindgen::Language::C)
26 | .with_autogen_warning(
27 | r#"typedef struct api_server {} api_server;
28 | typedef struct wallet {} wallet;"#,
29 | )
30 | .rename_item("ApiServer", "api_server")
31 | .rename_item("Wallet", "wallet")
32 | .generate()
33 | .expect("Unable to generate bindings")
34 | .write_to_file("../ios/Wallet.xcframework/WalletHeaders.h");
35 | }
36 |
--------------------------------------------------------------------------------
/rust/scripts/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | source ./scripts/variables.sh
3 |
4 | mode=$1
5 | platform=$2
6 | if [ -z "$mode" ] || [ "$mode" != "debug" -a "$mode" != "release" ] ; then
7 | echo "Please specify configuration ('debug' or 'release')" 1>&2
8 | exit 1
9 | fi
10 | if [ "$mode" == "debug" ] ; then
11 | rust_mode=""
12 | else
13 | rust_mode="--release"
14 | fi
15 | if [ -z "$platform" ] || [ "$platform" == "android" ] || [ "$platform" == "all" ] ; then
16 | if [ -z ${ANDROID_NDK_HOME+x} ];
17 | then
18 | printf 'Please install android-ndk\n\n'
19 | printf 'from https://developer.android.com/ndk/downloads or with sdkmanager'
20 | exit 1
21 | else
22 | printf "Building Andriod targets in $mode mode...\n";
23 | fi
24 | printf "Building ARM64 Android target...\n";
25 | # needed for rust-bindgen
26 | CLANG_PATH="${ANDROID_PREBUILD_BIN}/aarch64-linux-android${API_LEVEL}-clang" \
27 | CC_aarch64_linux_android="${ANDROID_PREBUILD_BIN}/aarch64-linux-android${API_LEVEL}-clang" \
28 | CXX_aarch64_linux_android="${ANDROID_PREBUILD_BIN}/aarch64-linux-android${API_LEVEL}-clang++" \
29 | CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="${ANDROID_PREBUILD_BIN}/aarch64-linux-android${API_LEVEL}-clang" \
30 | AR_aarch64_linux_android="${ANDROID_PREBUILD_BIN}/aarch64-linux-android-ar" \
31 | cargo build --target aarch64-linux-android $rust_mode --lib
32 |
33 | printf "Building ARMv7 Android target...\n";
34 | # needed for rust-bindgen
35 | CLANG_PATH="${ANDROID_PREBUILD_BIN}/armv7a-linux-androideabi${API_LEVEL}-clang" \
36 | CC_armv7_linux_androideabi="${ANDROID_PREBUILD_BIN}/armv7a-linux-androideabi${API_LEVEL}-clang" \
37 | CXX_armv7_linux_androideabi="${ANDROID_PREBUILD_BIN}/armv7a-linux-androideabi${API_LEVEL}-clang++" \
38 | CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="${ANDROID_PREBUILD_BIN}/armv7a-linux-androideabi${API_LEVEL}-clang" \
39 | AR_armv7_linux_androideabi="${ANDROID_PREBUILD_BIN}/arm-linux-androideabi-ar" \
40 | cargo build --target armv7-linux-androideabi $rust_mode --lib
41 |
42 | printf "Building 64-bit x86 Android target...\n";
43 | # needed for rust-bindgen
44 | CLANG_PATH="${ANDROID_PREBUILD_BIN}/x86_64-linux-android${API_LEVEL}-clang" \
45 | CC_x86_64_linux_android="${ANDROID_PREBUILD_BIN}/x86_64-linux-android${API_LEVEL}-clang" \
46 | CXX_x86_64_linux_android="${ANDROID_PREBUILD_BIN}/x86_64-linux-android${API_LEVEL}-clang++" \
47 | CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER="${ANDROID_PREBUILD_BIN}/x86_64-linux-android${API_LEVEL}-clang" \
48 | AR_x86_64_linux_android="${ANDROID_PREBUILD_BIN}/x86_64-linux-android-ar" \
49 | cargo build --target x86_64-linux-android $rust_mode --lib
50 |
51 | for i in "${!ANDROID_ARCHS[@]}";
52 | do
53 | mkdir -p -v "../android/app/src/main/jniLibs/${ANDROID_FOLDER[$i]}"
54 | cp "./target/${ANDROID_ARCHS[$i]}/$mode/lib${LIB_NAME}.so" "../android/app/src/main/jniLibs/${ANDROID_FOLDER[$i]}/lib${LIB_NAME}.so"
55 | done
56 | fi
57 |
58 | if [ -z "$platform" ] || [ "$platform" == "ios" ] || [ "$platform" == "all" ] ; then
59 | printf "Building iOS targets in $mode mode...\n";
60 | for i in "${IOS_ARCHS[@]}";
61 | do
62 | printf "Building $i target...\n";
63 | cargo build --target "$i" $rust_mode --no-default-features
64 | done
65 |
66 | lipo -create -output "../ios/Wallet.xcframework/ios-arm64_x86_64-simulator/lib${LIB_NAME}.a" target/x86_64-apple-ios/$mode/lib${LIB_NAME}.a target/aarch64-apple-ios-sim/$mode/lib${LIB_NAME}.a
67 | cp target/aarch64-apple-ios/$mode/lib${LIB_NAME}.a ../ios/Wallet.xcframework/ios-arm64/lib${LIB_NAME}.a
68 | fi
69 |
--------------------------------------------------------------------------------
/rust/scripts/init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source ./scripts/variables.sh
4 |
5 | cargo install cargo-lipo
6 |
7 | case "$(uname | tr '[:upper:]' '[:lower:]')" in
8 | darwin)
9 | echo 'Add rust toolchains for android and ios'
10 | for i in "${IOS_ARCHS[@]}";
11 | do rustup target add "$i";
12 | done
13 | for i in "${ANDROID_ARCHS[@]}";
14 | do rustup target add "$i" ;
15 | done
16 | ;;
17 | linux)
18 | echo 'Add rust toolchains for android'
19 | for i in "${ANDROID_ARCHS[@]}";
20 | do rustup target add "$i" ;
21 | done
22 | ;;
23 | *)
24 | echo 'Please use a Linux or Mac to build'
25 | ;;
26 | esac
27 |
28 |
--------------------------------------------------------------------------------
/rust/scripts/variables.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Change this name to the rust library name
4 | LIB_NAME=wallet
5 | API_LEVEL=29
6 |
7 | ANDROID_ARCHS=(aarch64-linux-android armv7-linux-androideabi x86_64-linux-android)
8 | ANDROID_FOLDER=(arm64-v8a armeabi-v7a x86_64)
9 | ANDROID_BIN_PREFIX=(aarch64-linux-android armv7a-linux-androideabi x86_64-linux-android)
10 | IOS_ARCHS=(aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios)
11 | OS_ARCH=$(uname | tr '[:upper:]' '[:lower:]')
12 |
13 | ANDROID_PREBUILD_BIN=${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/${OS_ARCH}-x86_64/bin
14 |
15 |
--------------------------------------------------------------------------------
/scripts/applesimutils.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | if [ ! $(ls -A /usr/local/Cellar/applesimutils | wc -l) -gt 0 ]
4 | then
5 | brew config
6 | brew tap wix/brew
7 | brew install applesimutils
8 | fi
9 |
--------------------------------------------------------------------------------
/scripts/licenses.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const fetch = require('node-fetch')
4 | const util = require('util')
5 | const crypto = require('crypto')
6 | const fs = require('fs')
7 | const path = require('path')
8 | const checker = require('license-checker')
9 | const _ = require('lodash')
10 |
11 | const additionalPackages = require('./additional-licenses')
12 |
13 | const rootDir = path.join(__dirname, `../`)
14 | const packageNameRegexp = /\//g
15 |
16 | function sanitizePackageName(packageName) {
17 | return packageName.replace(packageNameRegexp, '-')
18 | }
19 |
20 | async function main() {
21 | const args = {
22 | start: rootDir,
23 | production: true,
24 | customFormat: {
25 | name: '',
26 | url: false,
27 | version: false,
28 | description: false,
29 | licenses: false,
30 | copyright: false,
31 | licenseFile: false,
32 | licenseText: 'none',
33 | licenseModified: false,
34 | repository: false,
35 | publisher: false,
36 | email: false,
37 | path: false,
38 | },
39 | }
40 |
41 | const pkgs = {
42 | ...(await util.promisify(checker.init)(args)),
43 | ...additionalPackages,
44 | }
45 | const groupedPkgs = _.groupBy(pkgs, (pkg) => pkg.licenseText)
46 |
47 | const result = {
48 | licenses: {},
49 | packages: {},
50 | }
51 |
52 | let licenseId = 0
53 | for (const licenseText of Object.keys(groupedPkgs)) {
54 | result.licenses[licenseId] = licenseText
55 | for (const pkg of groupedPkgs[licenseText]) {
56 | result.packages[pkg.name] = licenseId
57 | }
58 | licenseId++
59 | }
60 | fs.writeFileSync(path.join(rootDir, 'licenses.json'), JSON.stringify(result))
61 | }
62 |
63 | main()
64 |
--------------------------------------------------------------------------------
/scripts/npm.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 | npm install
3 |
--------------------------------------------------------------------------------
/scripts/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | brew unlink applesimutils && brew link applesimutils
4 | cd ios/
5 | pod install
6 | cd ..
7 | npm install -g react-native-cli
8 | npm install -g detox-cli
9 | detox build --configuration ios.sim.release > /dev/null
10 | # detox clean-framework-cache && detox build-framework-cache
11 | detox test --configuration ios.sim.release --cleanup
12 |
--------------------------------------------------------------------------------
/sign-with-local.sh:
--------------------------------------------------------------------------------
1 | #/bin/sh
2 |
3 | if [ -z $1 ]; then
4 | echo "Please provide tx_slate_id"
5 | exit
6 | fi
7 |
8 | SLATE_PATH=slates/$1.grinslate
9 |
10 | adb pull /data/user/0/app.ironbelly/files/$SLATE_PATH $SLATE_PATH
11 | grin-wallet --floonet -p 1 receive -i $SLATE_PATH
12 | adb push $SLATE_PATH.response /sdcard/Download/
13 |
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-ExtraBold.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-ExtraBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-ExtraBoldItalic.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-ExtraLight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-ExtraLight.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-ExtraLightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-ExtraLightItalic.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-Italic.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-Light.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-LightItalic.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-Medium.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-MediumItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-MediumItalic.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-Regular.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-SemiBold.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-SemiBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-SemiBoldItalic.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-Thin.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Poppins-ThinItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/fonts/Poppins-ThinItalic.ttf
--------------------------------------------------------------------------------
/src/assets/images/ChevronLeft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/ChevronLeft.png
--------------------------------------------------------------------------------
/src/assets/images/ChevronLeft@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/ChevronLeft@2x.png
--------------------------------------------------------------------------------
/src/assets/images/ChevronLeft@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/ChevronLeft@3x.png
--------------------------------------------------------------------------------
/src/assets/images/ChevronRight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/ChevronRight.png
--------------------------------------------------------------------------------
/src/assets/images/ChevronRight@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/ChevronRight@2x.png
--------------------------------------------------------------------------------
/src/assets/images/ChevronRight@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/ChevronRight@3x.png
--------------------------------------------------------------------------------
/src/assets/images/Close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/Close.png
--------------------------------------------------------------------------------
/src/assets/images/Close@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/Close@2x.png
--------------------------------------------------------------------------------
/src/assets/images/Close@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/Close@3x.png
--------------------------------------------------------------------------------
/src/assets/images/Share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/Share.png
--------------------------------------------------------------------------------
/src/assets/images/Share@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/Share@2x.png
--------------------------------------------------------------------------------
/src/assets/images/Share@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/Share@3x.png
--------------------------------------------------------------------------------
/src/assets/images/landing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/landing.png
--------------------------------------------------------------------------------
/src/assets/images/landing@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/landing@2x.png
--------------------------------------------------------------------------------
/src/assets/images/landing@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/landing@3x.png
--------------------------------------------------------------------------------
/src/assets/images/x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/x.png
--------------------------------------------------------------------------------
/src/assets/images/x@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/x@2x.png
--------------------------------------------------------------------------------
/src/assets/images/x@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/i1skn/ironbelly/0b3bb276390a99fe6ec7ff764c5d1a5aa9df8cc6/src/assets/images/x@3x.png
--------------------------------------------------------------------------------
/src/common/logger.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { store } from 'src/common/redux'
18 | export const log = (
19 | e: Error | { message: string },
20 | showToUser = false,
21 | ) => {
22 | if (!(e instanceof Error) && e.message) {
23 | e = new Error(e.message)
24 | }
25 |
26 | if (showToUser && e.message) {
27 | store.dispatch({
28 | type: 'TOAST_SHOW',
29 | text: e.message,
30 | })
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/common/migrations.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { MAINNET_DEFAULT_NODE, MAINNET_API_SECRET } from 'src/modules/settings'
18 | import { store } from 'src/common/redux'
19 | export const migrations = {
20 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
21 | 0: (state: any) => {
22 | return {
23 | ...state,
24 | settings: {
25 | ...state.settings,
26 | checkNodeApiHttpAddr:
27 | state.settings.checkNodeApiHttpAddr ===
28 | 'http://grinnode.cycle42.com:23413'
29 | ? MAINNET_DEFAULT_NODE
30 | : state.settings.checkNodeApiHttpAddr,
31 | },
32 | }
33 | },
34 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
35 | 1: (state: any) => {
36 | const unsafeNode =
37 | state.settings.checkNodeApiHttpAddr === 'http://grinnode.cycle42.com:3413'
38 | if (unsafeNode) {
39 | // yeah, a side effect
40 | store.dispatch({ type: 'SET_API_SECRET', apiSecret: MAINNET_API_SECRET })
41 | }
42 | return {
43 | ...state,
44 | settings: {
45 | ...state.settings,
46 | checkNodeApiHttpAddr: unsafeNode
47 | ? MAINNET_DEFAULT_NODE
48 | : state.settings.checkNodeApiHttpAddr,
49 | },
50 | }
51 | },
52 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
53 | 2: (state: any) => {
54 | const oldNode =
55 | state.settings.checkNodeApiHttpAddr === 'https://node.ironbelly.app'
56 | return {
57 | ...state,
58 | settings: {
59 | ...state.settings,
60 | checkNodeApiHttpAddr: oldNode
61 | ? MAINNET_DEFAULT_NODE
62 | : state.settings.checkNodeApiHttpAddr,
63 | },
64 | }
65 | },
66 | }
67 |
--------------------------------------------------------------------------------
/src/common/sideEffects.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { Store, Action, Dispatch } from 'src/common/types'
18 |
19 | type ProbablyAction = Action | null | undefined
20 | type Effect = (a: Action, s: Store) => ProbablyAction | Promise
21 | type Effects = {
22 | [x: string]: Effect
23 | }
24 |
25 | const isAction = (o: ProbablyAction): boolean => {
26 | return !!o?.type
27 | }
28 |
29 | export const createMiddleware = (effects: Effects) => (store: Store) => (
30 | next: Dispatch,
31 | ) => (action: Action) => {
32 | const effect = effects[action.type]
33 | if (effect) {
34 | const result = effect(action, store)
35 |
36 | if (result instanceof Promise) {
37 | result.then((res) => res && isAction(res) && store.dispatch(res))
38 | } else if (result && isAction(result)) {
39 | store.dispatch(result)
40 | }
41 | }
42 |
43 | return next(action)
44 | }
45 |
--------------------------------------------------------------------------------
/src/components/CardTitle.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, { useCallback } from 'react'
18 | import {
19 | TouchableOpacity,
20 | StatusBar,
21 | Text,
22 | View,
23 | ViewProps,
24 | } from 'react-native'
25 | import FeatherIcon from 'react-native-vector-icons/Feather'
26 | import { isAndroid } from 'src/common'
27 | import {
28 | useFocusEffect,
29 | NavigationProp,
30 | ParamListBase,
31 | } from '@react-navigation/native'
32 | import {
33 | slightlyTransparent,
34 | styleSheetFactory,
35 | useThemedStyles,
36 | } from 'src/themes'
37 |
38 | type Props = {
39 | title: string
40 | subTitle?: string
41 | navigation: NavigationProp
42 | style?: ViewProps['style']
43 | }
44 |
45 | const themedStyles = styleSheetFactory(theme => ({
46 | cardTitle: {
47 | paddingVertical: 16,
48 | justifyContent: 'center',
49 | flexDirection: 'row',
50 | backgroundColor: theme.surface,
51 | },
52 | container: {
53 | flexDirection: 'column',
54 | },
55 | chevron: {
56 | position: 'absolute',
57 | paddingLeft: 16,
58 | top: 0,
59 | left: 0,
60 | },
61 | title: {
62 | fontSize: 18,
63 | textAlign: 'center',
64 | fontWeight: '500',
65 | color: theme.onBackground,
66 | },
67 | subTitle: {
68 | fontSize: 14,
69 | textAlign: 'center',
70 | color: slightlyTransparent(theme.onBackground),
71 | },
72 | }))
73 |
74 | export default ({ title, subTitle, navigation, style }: Props) => {
75 | if (isAndroid) {
76 | return null
77 | }
78 | const [styles, theme, themeName] = useThemedStyles(themedStyles)
79 |
80 | useFocusEffect(
81 | useCallback(() => {
82 | if (themeName === 'light') {
83 | StatusBar.setBarStyle('light-content')
84 | }
85 | return () => {
86 | if (themeName === 'light') {
87 | StatusBar.setBarStyle('dark-content')
88 | }
89 | }
90 | }, []),
91 | )
92 |
93 | return (
94 |
95 |
96 | {
100 | navigation.goBack()
101 | }}>
102 |
107 |
108 |
109 | {title}
110 | {subTitle && {subTitle}}
111 |
112 |
113 |
114 | )
115 | }
116 |
--------------------------------------------------------------------------------
/src/components/CopyButton.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react'
18 | import { useDispatch } from 'react-redux'
19 | import Clipboard from '@react-native-clipboard/clipboard'
20 | import { TouchableOpacity, Platform } from 'react-native'
21 | import FontAwesome5Icons from 'react-native-vector-icons/FontAwesome5'
22 | import { Text } from 'src/components/CustomFont'
23 | import { styleSheetFactory, useThemedStyles } from 'src/themes'
24 |
25 | function CopyButton({
26 | subject,
27 | content,
28 | }: {
29 | subject: string
30 | content: string
31 | }) {
32 | const [styles] = useThemedStyles(themedStyles)
33 | const dispatch = useDispatch()
34 | const copyToClipboard = (s: string, subject: string) => {
35 | return () => {
36 | Clipboard.setString(s)
37 | dispatch({
38 | type: 'TOAST_SHOW',
39 | text: subject + ' was copied',
40 | })
41 | }
42 | }
43 |
44 | return (
45 |
46 |
47 | Copy
48 |
49 |
50 | )
51 | }
52 |
53 | const themedStyles = styleSheetFactory(theme => ({
54 | slatepackHeaderCopy: {
55 | fontWeight: Platform.select({ android: '700', ios: '500' }),
56 | color: theme.link,
57 | fontSize: 16,
58 | },
59 | icon: {
60 | color: theme.link,
61 | },
62 | }))
63 |
64 | export default CopyButton
65 |
--------------------------------------------------------------------------------
/src/components/CopyHeader.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react'
18 | import { View, Platform } from 'react-native'
19 | import CopyButton from 'src/components/CopyButton'
20 | import { Text } from 'src/components/CustomFont'
21 | import { styleSheetFactory, useThemedStyles } from 'src/themes'
22 |
23 | type Props = {
24 | content?: string
25 | label: string
26 | }
27 |
28 | function CopyHeader({ content, label }: Props) {
29 | const [styles] = useThemedStyles(themedStyles)
30 | return (
31 |
32 | {label}
33 | {(content && ) || null}
34 |
35 | )
36 | }
37 |
38 | const themedStyles = styleSheetFactory((theme) => ({
39 | copyPasteContent: {
40 | flexDirection: 'row',
41 | justifyContent: 'space-between',
42 | marginVertical: 8,
43 | },
44 | copyPasteContentTitle: {
45 | fontWeight: Platform.select({ android: '700', ios: '500' }),
46 | fontSize: 16,
47 | color: theme.onBackground,
48 | },
49 | }))
50 |
51 | export default CopyHeader
52 |
--------------------------------------------------------------------------------
/src/components/Header.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, { Component } from 'react'
18 | import styled from 'styled-components/native'
19 | import { Text } from 'src/components/CustomFont'
20 | import HeaderSpan from 'src/components/HeaderSpan'
21 | const Body = styled.View`
22 | height: 69;
23 | width: 100%;
24 | flex-direction: row;
25 | padding: 35px 16px 14px 16px;
26 | align-items: center;
27 | `
28 | const Left = styled.TouchableOpacity`
29 | flex-direction: row;
30 | align-items: center;
31 | justify-content: flex-end;
32 | `
33 | const LeftIcon = styled.Image`
34 | height: 20;
35 | width: 20;
36 | `
37 | const LeftText = styled(Text)`
38 | font-size: 18;
39 | margin-top: 2;
40 | margin-left: 6;
41 | line-height: 20;
42 | `
43 | const Title = styled.View`
44 | width: 100%;
45 | position: absolute;
46 | top: 30;
47 | left: 16;
48 | align-items: center;
49 | `
50 | const TitleText = styled(Text)`
51 | font-size: 20;
52 | font-weight: 600;
53 | `
54 | type Props = {
55 | leftIcon?: number
56 | leftText?: string
57 | leftAction?: () => void
58 | title?: string
59 | }
60 | export default class Header extends Component {
61 | render() {
62 | const { leftIcon, leftText, leftAction, title } = this.props
63 | return (
64 |
65 |
66 |
67 |
68 | {title}
69 |
70 |
71 | {leftIcon && }
72 | {leftText && {leftText}}
73 |
74 |
75 |
76 | )
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/components/HeaderSpan.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { Platform, Dimensions } from 'react-native'
18 | import colors from 'src/common/colors'
19 | import styled from 'styled-components/native'
20 |
21 | export default styled.View<{ bgColor?: string }>`
22 | background-color: ${(props) => props.bgColor ?? colors.surface};
23 | height: ${() =>
24 | Platform.OS === 'ios' &&
25 | Dimensions.get('window').height === 812 &&
26 | Dimensions.get('window').width === 375
27 | ? '32px'
28 | : Platform.OS === 'ios' &&
29 | Dimensions.get('window').height === 896 &&
30 | Dimensions.get('window').width === 414
31 | ? '32px'
32 | : '0'};
33 | `
34 |
--------------------------------------------------------------------------------
/src/components/InputContentRow.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react'
18 | import { StyleSheet, View } from 'react-native'
19 | import PasteButton, { SetFunction } from 'src/components/PasteButton'
20 | import ScanQRCodeButton from 'src/components/ScanQRCodeButton'
21 | import { RootStackParamList } from 'src/modules/navigation'
22 |
23 | type Props = {
24 | nextScreen: RootStackParamList['ScanQRCode']['nextScreen']
25 | label: string
26 | setFunction: SetFunction
27 | nextScreenParams?: RootStackParamList['ScanQRCode']['nextScreenParams']
28 | }
29 |
30 | function InputContentRow({
31 | setFunction,
32 | nextScreen,
33 | label,
34 | nextScreenParams,
35 | }: Props) {
36 | return (
37 |
38 |
39 |
44 |
45 | )
46 | }
47 |
48 | const styles = StyleSheet.create({
49 | content: {
50 | flexDirection: 'row',
51 | justifyContent: 'space-around',
52 | marginVertical: 16,
53 | marginHorizontal: 16,
54 | },
55 | })
56 |
57 | export default InputContentRow
58 |
--------------------------------------------------------------------------------
/src/components/Notice.tsx:
--------------------------------------------------------------------------------
1 | import React, { FunctionComponent } from 'react'
2 | import { Text, TextProps, View } from 'react-native'
3 | import {
4 | slightlyTransparent,
5 | styleSheetFactory,
6 | useThemedStyles,
7 | } from 'src/themes'
8 | const themedStyles = styleSheetFactory((theme) => ({
9 | container: {
10 | backgroundColor: theme.surface,
11 | marginTop: 16,
12 | borderRadius: 8,
13 | },
14 | text: {
15 | padding: 8,
16 | fontSize: 16,
17 | lineHeight: 24,
18 | color: slightlyTransparent(theme.onSurface),
19 | textAlign: 'center',
20 | },
21 | }))
22 |
23 | const Notice: FunctionComponent = ({ children }) => {
24 | const [styles] = useThemedStyles(themedStyles)
25 | return (
26 |
27 | {children}
28 |
29 | )
30 | }
31 |
32 | export default Notice
33 |
--------------------------------------------------------------------------------
/src/components/NumericInput.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react'
18 | import { Text, TextInput } from 'src/components/CustomFont'
19 | import { StyleProp, TextStyle, View } from 'react-native'
20 | import { styleSheetFactory, useThemedStyles } from 'src/themes'
21 | type Props = {
22 | units?: string
23 | placeholder?: string
24 | maxLength: number
25 | value: string
26 | onChange: (value: string) => void
27 | autoFocus: boolean
28 | style?: StyleProp
29 | }
30 |
31 | function NumericInput(props: Props) {
32 | const [styles] = useThemedStyles(themedStyles)
33 | const {
34 | units,
35 | maxLength,
36 | style,
37 | onChange,
38 | value,
39 | autoFocus,
40 | placeholder,
41 | } = props
42 | return (
43 |
44 | {units && {units}}
45 |
54 | {units && {units}}
55 |
56 | )
57 | }
58 |
59 | const themedStyles = styleSheetFactory((theme) => ({
60 | layout: {
61 | flexDirection: 'row',
62 | justifyContent: 'flex-start',
63 | flexGrow: 1,
64 | alignItems: 'center',
65 | },
66 | spacer: {
67 | color: theme.onBackground,
68 | fontSize: 36,
69 | height: 58,
70 | lineHeight: 58,
71 | },
72 | hiddenSpacer: {
73 | color: theme.background,
74 | fontSize: 36,
75 | height: 58,
76 | lineHeight: 58,
77 | },
78 | input: {
79 | fontSize: 36,
80 | color: theme.onBackground,
81 | height: 68,
82 | textAlignVertical: 'center',
83 | },
84 | }))
85 |
86 | export default NumericInput
87 |
--------------------------------------------------------------------------------
/src/components/PasteButton.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react'
18 | import Clipboard from '@react-native-clipboard/clipboard'
19 | import { TouchableOpacity, Platform } from 'react-native'
20 | import FontAwesome5Icons from 'react-native-vector-icons/FontAwesome5'
21 | import { Text } from 'src/components/CustomFont'
22 | import { styleSheetFactory, useThemedStyles } from 'src/themes'
23 |
24 | export type SetFunction = (s: string) => void
25 |
26 | type Props = {
27 | setFunction: SetFunction
28 | }
29 | function PasteButton({ setFunction }: Props) {
30 | const [styles] = useThemedStyles(themedStyles)
31 | const pasteToClipboard = () => {
32 | Clipboard.getString().then(setFunction)
33 | }
34 |
35 | return (
36 |
37 |
38 | Paste
39 |
40 |
41 | )
42 | }
43 |
44 | const themedStyles = styleSheetFactory(theme => ({
45 | button: {
46 | fontWeight: Platform.select({ android: '700', ios: '500' }),
47 | color: theme.link,
48 | fontSize: 16,
49 | },
50 | icon: {
51 | color: theme.link,
52 | },
53 | }))
54 |
55 | export default PasteButton
56 |
--------------------------------------------------------------------------------
/src/components/ScanQRCodeButton.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react'
18 | import { TouchableOpacity, Platform } from 'react-native'
19 | import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
20 |
21 | import { Text } from 'src/components/CustomFont'
22 | import { NavigationProp, useNavigation } from '@react-navigation/native'
23 | import { RootStackParamList } from 'src/modules/navigation'
24 | import { styleSheetFactory, useThemedStyles } from 'src/themes'
25 |
26 | function ScanQRCodeButton({
27 | nextScreen,
28 | nextScreenParams,
29 | label,
30 | }: {
31 | nextScreen: RootStackParamList['ScanQRCode']['nextScreen']
32 | nextScreenParams?: RootStackParamList[RootStackParamList['ScanQRCode']['nextScreen']]
33 | label: string
34 | }) {
35 | const [styles] = useThemedStyles(themedStyles)
36 | const navigation = useNavigation>()
37 | const scan = () => {
38 | navigation.navigate('ScanQRCode', {
39 | nextScreen,
40 | nextScreenParams,
41 | label,
42 | })
43 | }
44 |
45 | return (
46 |
47 |
48 | Scan QR{' '}
49 |
54 |
55 |
56 | )
57 | }
58 |
59 | const themedStyles = styleSheetFactory(theme => ({
60 | slatepackHeaderCopy: {
61 | fontWeight: Platform.select({ android: '700', ios: '500' }),
62 | color: theme.link,
63 | fontSize: 16,
64 | },
65 | icon: {
66 | color: theme.link,
67 | },
68 | }))
69 |
70 | export default ScanQRCodeButton
71 |
--------------------------------------------------------------------------------
/src/components/SectionTitle.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react'
18 | import { View, Platform } from 'react-native'
19 | import { Text } from 'src/components/CustomFont'
20 | import { styleSheetFactory, useThemedStyles } from 'src/themes'
21 |
22 | type Props = {
23 | title: string
24 | }
25 |
26 | function SectionTitle({ title }: Props) {
27 | const [styles] = useThemedStyles(themedStyles)
28 | return (
29 |
30 | {title}
31 |
32 | )
33 | }
34 |
35 | const themedStyles = styleSheetFactory((theme) => ({
36 | container: {
37 | flexDirection: 'row',
38 | justifyContent: 'space-between',
39 | marginVertical: 8,
40 | },
41 | title: {
42 | fontWeight: Platform.select({ android: '700', ios: '700' }),
43 | fontSize: 16,
44 | color: theme.onBackground,
45 | },
46 | }))
47 |
48 | export default SectionTitle
49 |
--------------------------------------------------------------------------------
/src/components/ShareButton.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | // Been used previously for sharing files and not in use right now.
18 | // Can be used for sharing Slatepack messages if Copy/QR would not be enough
19 | import React from 'react'
20 | import { TouchableOpacity, Platform } from 'react-native'
21 | import FontAwesome5Icons from 'react-native-vector-icons/FontAwesome5'
22 | import { Text } from 'src/components/CustomFont'
23 | import { styleSheetFactory, useThemedStyles } from 'src/themes'
24 |
25 | function ShareButton({ onClick }: { onClick: () => void }) {
26 | const [styles] = useThemedStyles(themedStyles)
27 | return (
28 |
29 |
30 | Share
31 |
32 |
33 | )
34 | }
35 |
36 | const themedStyles = styleSheetFactory((theme) => ({
37 | slatepackHeaderCopy: {
38 | fontWeight: Platform.select({ android: '700', ios: '500' }),
39 | color: theme.link,
40 | fontSize: 16,
41 | },
42 | icon: {
43 | color: theme.link,
44 | },
45 | }))
46 |
47 | export default ShareButton
48 |
--------------------------------------------------------------------------------
/src/components/ShareRow.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react'
18 | import { View } from 'react-native'
19 | import CopyButton from 'src/components/CopyButton'
20 | import ShowQRCodeButton from 'src/components/ShowQRCodeButton'
21 | import { styleSheetFactory, useThemedStyles } from 'src/themes'
22 |
23 | type Props = {
24 | content?: string
25 | label: string
26 | }
27 |
28 | function ShareRow({ content, label }: Props) {
29 | const [styles] = useThemedStyles(themedStyles)
30 | if (!content) {
31 | return null
32 | }
33 | return (
34 |
35 |
36 |
37 |
38 | )
39 | }
40 |
41 | const themedStyles = styleSheetFactory(() => ({
42 | content: {
43 | flexDirection: 'row',
44 | justifyContent: 'space-around',
45 | marginVertical: 16,
46 | },
47 | }))
48 |
49 | export default ShareRow
50 |
--------------------------------------------------------------------------------
/src/components/ShowQRCodeButton.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react'
18 | import { TouchableOpacity, Platform } from 'react-native'
19 | import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
20 |
21 | import { Text } from 'src/components/CustomFont'
22 | import { useNavigation } from '@react-navigation/native'
23 | import { styleSheetFactory, useThemedStyles } from 'src/themes'
24 |
25 | function ShowQRCodeButton({
26 | label,
27 | content,
28 | }: {
29 | label: string
30 | content: string
31 | }) {
32 | const [styles] = useThemedStyles(themedStyles)
33 | const navigation = useNavigation()
34 | const show = (content: string, label: string) => {
35 | return () => {
36 | navigation.navigate('ShowQRCode', {
37 | content,
38 | label,
39 | })
40 | }
41 | }
42 |
43 | return (
44 |
45 |
46 | Show QR{' '}
47 |
48 |
49 |
50 | )
51 | }
52 |
53 | const themedStyles = styleSheetFactory((theme) => ({
54 | slatepackHeaderCopy: {
55 | fontWeight: Platform.select({ android: '700', ios: '500' }),
56 | color: theme.link,
57 | fontSize: 16,
58 | },
59 | icon: {
60 | color: theme.link,
61 | },
62 | }))
63 |
64 | export default ShowQRCodeButton
65 |
--------------------------------------------------------------------------------
/src/components/Textarea.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react'
18 | import ReactNative, { TextInputProps, View, ViewProps } from 'react-native'
19 | import { TextInput, Text } from 'src/components/CustomFont'
20 | import { styleSheetFactory, useThemedStyles } from 'src/themes'
21 | type Props = TextInputProps & {
22 | title?: string;
23 | getRef?: (instance: ReactNative.TextInput | null) => void;
24 | containerStyle?: ViewProps['style'];
25 | };
26 |
27 | function Textarea(props: Props) {
28 | const [styles] = useThemedStyles(themedStyles)
29 | const { title, getRef, containerStyle, style, ...passProps } = props
30 | return (
31 |
32 | {title && {title}}
33 |
39 |
40 | )
41 | }
42 |
43 | const themedStyles = styleSheetFactory(theme => ({
44 | input: {
45 | paddingTop: 16,
46 | paddingBottom: 16,
47 | paddingHorizontal: 16,
48 | backgroundColor: theme.surface,
49 | color: theme.onSurface,
50 | borderRadius: 8,
51 | fontSize: 18,
52 | fontWeight: '400',
53 | flex: 1,
54 | },
55 | title: {
56 | fontWeight: 500,
57 | fontSize: 16,
58 | marginBottom: 8,
59 | },
60 | }))
61 |
62 | export default Textarea
63 |
--------------------------------------------------------------------------------
/src/documents/legal-disclaimer-ios.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | export default `
18 | # Warranties and Limitation of Liability
19 |
20 | This app is provided on "AS-IS" basis without warranty of any kind. In no event will the author be liable for any loss or damages arising from or related to your use of this app, including but not limited to loss of or inability to access or transact data, profit or cryptocurrency.
21 |
22 | Without limiting the generality of the foregoing, the author takes no responsibility for and will not be liable for any financial or other loss or damage arising from or related to the use of this app, including but not limited to any of the following:
23 |
24 | * Financial loss due to Wallet access being "Brute-forced".
25 | * Financial loss due to data loss.
26 | * Financial loss due to forgotten mnemonics(paper keys) or passwords.
27 | * Financial loss due to inability to transact.
28 | * Financial loss due to errors calculating network fees.
29 | * Financial loss due to incorrectly constructed transactions or mistyped addresses.
30 |
31 | # Your Compliance with Applicable Laws
32 |
33 | You represent and warrant that you are using this app in accordance with applicable law, and not for any purpose not in compliance with applicable law, including but not limited to illegal gambling, fraud, money laundering or terrorist activities.
34 |
35 | # Changes to this app
36 |
37 | The author may add or remove functions or features of this app. You can stop using this app at any time.
38 |
39 | # Responsibility for Mnemonics(Paper Keys), Passwords and Catastrophic Impact of Their Loss
40 |
41 | If you use this app to create a Wallet, the software will use an algorithm to generate a random 24-word phrase as a seed to a BIP32 hierarchical wallet. This 24-word phrase is called a mnemonic(paper key) and if reproduced exactly stores all the information needed to recover your Wallet if access through a password or other authentication means is lost or otherwise not available.
42 |
43 | The author does not store, have access to, or have any way or means of recovering mnemonics(paper keys), passwords or private keys.
44 |
45 | It is your responsibility to keep your mnemonic(paper key) secure. You should not provide it to anyone, including the author.
46 |
47 | If you permanently forget or lose your mnemonic(paper key), you will NEVER be able to recover any cryptocurrency in your Wallet, and you will suffer a complete, irrecoverable and catastrophic loss of all Digital Assets in your Wallet.
48 |
49 | It is your responsibility to safeguard and retain your mnemonic(paper key). The author has no responsibility and will not be liable for any loss or damage you suffer from the loss or misappropriation of your mnemonic(paper key).
50 | `
51 |
--------------------------------------------------------------------------------
/src/documents/receive-from-another-person.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | export default `
18 | # Step 0: Find a Sender
19 |
20 | If you want to receive some Grin, you need to find someone who wants to send some Grin first. We will call this person "Sender".
21 |
22 | # Step 1: Sender initiate the transaction
23 |
24 | On the main screen Sender needs to press "Send", then enter an amount, choose fee, enter an optional message, choose "Share as a file" and then share dialog would appear automatically. The app has generated a partial transaction file, which needs to be signed by a recipient (you). Sender now needs to share this file in any convinient (better secure) way, so you can open it on your phone.
25 |
26 | # Step 2: Receive a partial transaction
27 |
28 | When you've received the file from Sender, open it, press on Share icon and choose "Copy to Ironbelly".
29 |
30 | This will open the app, where you could check the amount and accept the transaction. If accepted, Ironbelly would sign the file and ask you to share it back with Sender. Do that and sit tight, we are not done yet!
31 |
32 | # Step 3: Finalizing and posting to the chain
33 |
34 | When Sender have received the file from you, she would open it, press on Share icon and choose "Copy to Ironbelly".
35 |
36 | This will open the app, where Sender could check and post the transaction. If posted, it would take a couple of minutes until it appear in the chain.
37 |
38 | # Step 4: Wait 10 confirmations
39 |
40 | After the transaction has appeared in the chain it is still very fresh and Ironbelly would wait for 10 confirmations (10 - 20min) until it can be used. After that the funds are officially yours!
41 | #
42 | `
43 |
--------------------------------------------------------------------------------
/src/mocks.ts:
--------------------------------------------------------------------------------
1 | import moment from 'moment'
2 | export const mockRustTransaction = (
3 | id: number,
4 | type: string,
5 | amountCredited: string,
6 | amountDebited: string,
7 | fee: string,
8 | txSlateId: string,
9 | ) => ({
10 | amount_credited: amountCredited,
11 | amount_debited: amountDebited,
12 | confirmation_ts: moment().format(),
13 | confirmed: true,
14 | creation_ts: moment().format(),
15 | fee,
16 | id,
17 | kernel_excess: null,
18 | kernel_lookup_min_height: null,
19 | num_inputs: 0,
20 | num_outputs: 1,
21 | parent_key_id: '0200000000000000000000000000000000',
22 | payment_proof: null,
23 | reverted_after: null,
24 | stored_tx: null,
25 | ttl_cutoff_height: null,
26 | tx_slate_id: txSlateId,
27 | tx_type: type, // 'TxReceived',
28 | })
29 |
30 | export const mockedRustTransactions: { [key: string]: unknown } = {
31 | slateId1: mockRustTransaction(
32 | 0,
33 | 'TxReceived',
34 | '123438749',
35 | '0',
36 | '0',
37 | 'slateId1',
38 | ),
39 | '6ef39b6d-ce3c-4a22-a536-cea395dc4b62': mockRustTransaction(
40 | 1,
41 | 'TxSent',
42 | '0',
43 | '123438749',
44 | '8000000',
45 | '6ef39b6d-ce3c-4a22-a536-cea395dc4b62',
46 | ),
47 | }
48 |
--------------------------------------------------------------------------------
/src/modules/app.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { Epic, combineEpics } from 'redux-observable'
18 | import { filter, mapTo } from 'rxjs/operators'
19 | import { Action } from 'src/common/types'
20 | import { RootState } from 'src/common/redux'
21 | import { of, interval } from 'rxjs'
22 |
23 | const REFRESH_TXS_INTERVAL = 10 * 1000 // 10 sec
24 |
25 | export type State = {
26 | legalAccepted: boolean
27 | }
28 | export const initialState: State = {
29 | legalAccepted: false,
30 | }
31 |
32 | export const appReducer = (
33 | state: State = initialState,
34 | action: Action,
35 | ): State => {
36 | switch (action.type) {
37 | case 'ACCEPT_LEGAL':
38 | return {
39 | ...state,
40 | legalAccepted: action.value,
41 | }
42 | default:
43 | return state
44 | }
45 | }
46 |
47 | const refreshTxsPeriodicallyEpic: Epic = (
48 | _,
49 | state$,
50 | ) =>
51 | interval(REFRESH_TXS_INTERVAL).pipe(
52 | filter(
53 | () =>
54 | state$.value.wallet.isOpened &&
55 | !state$.value.wallet.walletScan.inProgress,
56 | ),
57 | mapTo({
58 | type: 'TX_LIST_REQUEST',
59 | showLoader: false,
60 | refreshFromNode: true,
61 | }),
62 | )
63 |
64 | const checkBiometryEpic: Epic = () => {
65 | return of({
66 | type: 'CHECK_BIOMETRY_REQUEST',
67 | })
68 | }
69 |
70 | export const appEpic: Epic = combineEpics(
71 | checkBiometryEpic,
72 | refreshTxsPeriodicallyEpic,
73 | )
74 |
--------------------------------------------------------------------------------
/src/modules/balance.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { mapRustBalance } from 'src/common'
18 | import { Action, Balance } from 'src/common/types'
19 | export type State = Balance
20 | const initialState: State = {
21 | amountAwaitingConfirmation: '0',
22 | amountCurrentlySpendable: '0',
23 | amountImmature: '0',
24 | amountLocked: '0',
25 | lastConfirmedHeight: '0',
26 | minimumConfirmations: '0',
27 | total: '0',
28 | }
29 | export const reducer = (state: State = initialState, action: Action): State => {
30 | switch (action.type) {
31 | case 'TX_LIST_SUCCESS':
32 | return { ...state, ...mapRustBalance(action.balance) }
33 |
34 | default:
35 | return state
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/modules/currency-rates.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { Action, Store, currencyRatesRequestAction } from 'src/common/types'
18 | import { currencyList } from 'src/common'
19 | export type State = {
20 | rates: Record
21 | inProgress: boolean
22 | lastUpdated: number
23 | disabled: boolean
24 | }
25 | export const initialState: State = {
26 | rates: {},
27 | inProgress: false,
28 | lastUpdated: 0,
29 | disabled: false,
30 | }
31 | export const reducer = (state: State = initialState, action: Action): State => {
32 | switch (action.type) {
33 | case 'CURRENCY_RATES_REQUEST':
34 | return { ...state, inProgress: true }
35 |
36 | case 'CURRENCY_RATES_SUCCESS':
37 | return {
38 | ...state,
39 | rates: action.rates.grin,
40 | inProgress: false,
41 | lastUpdated: Date.now(),
42 | }
43 | case 'CURRENCY_RATES_TOGGLE':
44 | return {
45 | ...state,
46 | disabled: !state.disabled,
47 | }
48 |
49 | case 'CURRENCY_RATES_FAILURE':
50 | return { ...state, inProgress: false }
51 |
52 | default:
53 | return state
54 | }
55 | }
56 | export const sideEffects = {
57 | ['CURRENCY_RATES_REQUEST']: async (
58 | _action: currencyRatesRequestAction,
59 | store: Store,
60 | ) => {
61 | try {
62 | const rates = await fetch(
63 | `https://api.coingecko.com/api/v3/simple/price?ids=grin&vs_currencies=${currencyList
64 | .map((c) => c.code)
65 | .join(',')}`,
66 | ).then((data) => data.json())
67 | store.dispatch({
68 | type: 'CURRENCY_RATES_SUCCESS',
69 | rates,
70 | })
71 | } catch (error) {
72 | store.dispatch({
73 | type: 'CURRENCY_RATES_FAILURE',
74 | message: error.message,
75 | })
76 | }
77 | },
78 | }
79 |
--------------------------------------------------------------------------------
/src/modules/toaster.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { Action } from 'src/common/types'
18 | export type State = {
19 | text: string
20 | duration: number
21 | }
22 | const initialState: State = {
23 | text: '',
24 | duration: 2000,
25 | }
26 | export const reducer = (state: State = initialState, action: Action): State => {
27 | switch (action.type) {
28 | case 'TOAST_SHOW':
29 | return { ...state, ...action }
30 |
31 | case 'TOAST_CLEAR': {
32 | return { ...initialState }
33 | }
34 |
35 | default:
36 | return state
37 | }
38 | }
39 | export const sideEffects = {}
40 |
--------------------------------------------------------------------------------
/src/modules/tx/receive.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { PayloadAction, createSlice } from '@reduxjs/toolkit'
18 | import { catchError, map, mergeMap } from 'rxjs/operators'
19 | import { from, EMPTY } from 'rxjs'
20 | import { RootState } from 'src/common/redux'
21 | import { Epic, combineEpics, ofType } from 'redux-observable'
22 | import { Action, valueof } from 'src/common/types'
23 | import WalletBridge from 'src/bridges/wallet'
24 |
25 | export type State = {
26 | address: string | undefined
27 | }
28 | export const initialState: State = {
29 | address: undefined,
30 | }
31 |
32 | const txReceiveSlice = createSlice({
33 | name: 'txReceive',
34 | initialState,
35 | reducers: {
36 | setAddress: (state, action: PayloadAction) => {
37 | state.address = action.payload
38 | },
39 | },
40 | })
41 |
42 | export const txReceiveReducer = txReceiveSlice.reducer
43 | export const txReceiveActions = txReceiveSlice.actions
44 | export type TxReceiveActions = valueof
45 |
46 | export const startHttpListenEpic: Epic = (action$) =>
47 | action$.pipe(
48 | ofType('SET_WALLET_OPEN'),
49 | mergeMap(() =>
50 | from(WalletBridge.startListenWithHttp('0.0.0.0:3415')).pipe(
51 | map(
52 | (address: string) => txReceiveActions.setAddress(address) as Action,
53 | ),
54 | catchError((error) => {
55 | console.log(error)
56 | return EMPTY
57 | }),
58 | ),
59 | ),
60 | )
61 |
62 | export const stopHttpListenEpic: Epic = (action$) =>
63 | action$.pipe(
64 | ofType('CLOSE_WALLET', 'WALLET_DESTROY_SUCCESS'),
65 | mergeMap(async () => {
66 | await WalletBridge.stopListenWithHttp()
67 | return txReceiveActions.setAddress(undefined) as Action
68 | }),
69 | )
70 |
71 | export const txReceiveEpic: Epic = combineEpics(
72 | startHttpListenEpic,
73 | stopHttpListenEpic,
74 | )
75 |
76 | export const grinAddressSelector = (state: RootState) => state.txReceive.address
77 |
--------------------------------------------------------------------------------
/src/screens/License.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react'
18 | import { ScrollView } from 'react-native'
19 | import { Text } from 'src/components/CustomFont'
20 | import { NavigationProps } from 'src/common/types'
21 | import { styleSheetFactory, useThemedStyles } from 'src/themes'
22 |
23 | type Props = NavigationProps<'License'>
24 |
25 | const License = ({ route }: Props) => {
26 | const [styles] = useThemedStyles(themedStyles)
27 | const { licenseText } = route?.params
28 | return (
29 |
33 | {licenseText}
34 |
35 | )
36 | }
37 |
38 | const themedStyles = styleSheetFactory((theme) => ({
39 | scrollView: {
40 | flexGrow: 1,
41 | padding: 16,
42 | },
43 | licence: {
44 | paddingBottom: 32,
45 | color: theme.onBackground,
46 | },
47 | }))
48 |
49 | export default License
50 |
--------------------------------------------------------------------------------
/src/screens/Licenses.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react'
18 | import IonicIcon from 'react-native-vector-icons/Ionicons'
19 | import { Text } from 'src/components/CustomFont'
20 | import licenses from '../../licenses.json'
21 | import { FlatList, TouchableOpacity, StyleSheet } from 'react-native'
22 | import { useNavigation } from '@react-navigation/native'
23 | import {
24 | slightlyTransparent,
25 | styleSheetFactory,
26 | useThemedStyles,
27 | } from 'src/themes'
28 |
29 | // import { NavigationProps } from 'src/common/types'
30 | // type Props = NavigationProps<'Licenses'>
31 |
32 | type ItemProps = {title: string; licenceId: number};
33 |
34 | const Item = ({ title, licenceId }: ItemProps) => {
35 | const [styles] = useThemedStyles(themedStyles)
36 | const navigation = useNavigation()
37 | const onPress = (licenceId: number) => {
38 | const licenseText = (licenses.licenses as Record)[
39 | licenceId
40 | ]
41 | return () => navigation.navigate('License', { licenseText })
42 | }
43 | return (
44 |
45 |
46 | {title}
47 |
48 |
53 |
54 | )
55 | }
56 |
57 | function renderItem({ item }: {item: string}) {
58 | const licenceId = (licenses.packages as Record)[item]
59 | return
60 | }
61 |
62 | const Licenses = () => {
63 | const [styles] = useThemedStyles(themedStyles)
64 | const packages = Object.keys(licenses.packages)
65 | packages.sort()
66 | return (
67 | item}
74 | />
75 | )
76 | }
77 |
78 | const themedStyles = styleSheetFactory(theme => ({
79 | container: {
80 | paddingHorizontal: 16,
81 | },
82 | item: {
83 | height: 48,
84 | flexDirection: 'row',
85 | alignItems: 'center',
86 | },
87 | chevron: {
88 | color: slightlyTransparent(theme.onBackground),
89 | lineHeight: 30,
90 | },
91 | itemTitle: {
92 | flex: 1,
93 | color: theme.onBackground,
94 | },
95 | }))
96 |
97 | export default Licenses
98 |
--------------------------------------------------------------------------------
/src/screens/ScanQRCode.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, { useEffect, useState } from 'react'
18 | import { ActivityIndicator, StyleSheet, Text, View } from 'react-native'
19 | import colors from 'src/common/colors'
20 | import { NavigationProps } from 'src/common/types'
21 | import CardTitle from 'src/components/CardTitle'
22 | import { BarCodeScanner, PermissionStatus } from 'expo-barcode-scanner'
23 |
24 | type Props = NavigationProps<'ScanQRCode'>
25 |
26 | function ScanQRCode({ route, navigation }: Props) {
27 | const { label, nextScreen, nextScreenParams } = route.params
28 | const [hasPermission, setHasPermission] = useState(null)
29 | const [scanned, setScanned] = useState(false)
30 | useEffect(() => {
31 | ;(async () => {
32 | const { status } = await BarCodeScanner.requestPermissionsAsync()
33 | setHasPermission(status === PermissionStatus.GRANTED)
34 | })()
35 | }, [])
36 |
37 | const handleBarCodeScanned = ({ data }: { data: string }) => {
38 | setScanned(true)
39 | navigation.navigate(nextScreen, { ...nextScreenParams, qrContent: data })
40 | }
41 |
42 | const inner = () => {
43 | if (hasPermission === null) {
44 | return
45 | }
46 | if (hasPermission === false) {
47 | return No access to camera
48 | }
49 | return (
50 |
53 | )
54 | }
55 |
56 | return (
57 | <>
58 |
59 | {inner()}
60 | >
61 | )
62 | }
63 |
64 | const styles = StyleSheet.create({
65 | container: {
66 | flex: 1,
67 | alignItems: 'center',
68 | justifyContent: 'center',
69 | },
70 | viewFinder: {
71 | ...StyleSheet.absoluteFillObject,
72 | },
73 | status: {
74 | fontSize: 24,
75 | textAlign: 'center',
76 | },
77 | })
78 |
79 | export default ScanQRCode
80 |
--------------------------------------------------------------------------------
/src/screens/Settings/Support.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, { useState } from 'react'
18 | import { Linking, ScrollView, View } from 'react-native'
19 | import { SafeAreaView } from 'react-native-safe-area-context'
20 | import { Button, Link, Text } from 'src/components/CustomFont'
21 | import { Currency, Dispatch, NavigationProps } from 'src/common/types'
22 | import { RootState } from 'src/common/redux'
23 | import { State as CurrencyRatesState } from 'src/modules/currency-rates'
24 | import {
25 | slightlyTransparent,
26 | styleSheetFactory,
27 | useThemedStyles,
28 | } from 'src/themes'
29 | type DispatchProps = {
30 | currency: Currency
31 | requestCurrencyRates: () => void
32 | setCurrency: (currency: Currency) => void
33 | currencyRates: CurrencyRatesState
34 | }
35 |
36 | type Props = NavigationProps<'SettingsSupport'> & DispatchProps
37 |
38 | export default function CurrencyList(props: Props) {
39 | const [styles] = useThemedStyles(themedStyles)
40 | return (
41 |
42 | Can I cancel transaction?
43 |
44 | If the transaction has not been sent to the network yet, you can just
45 | swipe it left to cancel. Otherwise it's impossible to revert it!
46 |
47 |
48 | While depositing funds to exchange, I've forgotten to specify a memo.
49 | Can you help?
50 |
51 |
52 | Unfortunately no. Please contact the exchange support, only they could
53 | help you in this situation. In any case, DO NOT repair or destroy the
54 | wallet in Settings. In this case you would loose history of the
55 | transactions and the data, which could help exchange to identify your
56 | transactions.
57 |
58 | Still have questions?
59 |
60 | You can visit {' '}
61 | or in
62 | Telegram.
63 |
64 |
65 | )
66 | }
67 |
68 | const themedStyles = styleSheetFactory(theme => ({
69 | container: {
70 | flexGrow: 1,
71 | backgroundColor: theme.background,
72 | padding: 16,
73 | },
74 | header: {
75 | fontWeight: '600',
76 | fontSize: 24,
77 | color: theme.onBackground,
78 | },
79 | text: {
80 | paddingTop: 8,
81 | paddingBottom: 32,
82 | fontSize: 17,
83 | color: theme.onBackground,
84 | lineHeight: 24,
85 | },
86 | smallText: {
87 | paddingTop: 8,
88 | paddingBottom: 32,
89 | fontSize: 14,
90 | textAlign: 'center',
91 | color: slightlyTransparent(theme.onSurface),
92 | },
93 | }))
94 |
--------------------------------------------------------------------------------
/src/screens/ShowQRCode.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react'
18 | import colors from 'src/common/colors'
19 | import { View, StyleSheet, Dimensions } from 'react-native'
20 | import QRCode from 'react-native-qrcode-svg'
21 | import { NavigationProps } from 'src/common/types'
22 | import CardTitle from 'src/components/CardTitle'
23 |
24 | type Props = NavigationProps<'ShowQRCode'>
25 |
26 | function ScanQRCode({ route, navigation }: Props) {
27 | const { label, content } = route.params
28 | const width = Dimensions.get('window').width - 32
29 | return (
30 | <>
31 |
32 |
33 |
34 |
35 | >
36 | )
37 | }
38 |
39 | const styles = StyleSheet.create({
40 | container: {
41 | flex: 1,
42 | backgroundColor: colors.white,
43 | alignItems: 'center',
44 | justifyContent: 'center',
45 | },
46 | label: {
47 | fontSize: 24,
48 | },
49 | })
50 |
51 | export default ScanQRCode
52 |
--------------------------------------------------------------------------------
/src/screens/TxIncompleteSend/TxIncompleteSend.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2019 Ironbelly Devs
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, { useEffect } from 'react'
18 | import BigNumber from 'bignumber.js'
19 | import { View } from 'react-native'
20 | import { Text } from 'src/components/CustomFont'
21 | import CardTitle from 'src/components/CardTitle'
22 | import { Tx } from 'src/common/types'
23 | import { NavigationProps } from 'src/common/types'
24 | import SlateCreated from 'src/screens/TxIncompleteSend/SlateCreated'
25 | import SlateNotCreated from 'src/screens/TxIncompleteSend/SlateNotCreated'
26 | import { hrGrin } from 'src/common'
27 | import { styleSheetFactory, useThemedStyles } from 'src/themes'
28 |
29 | interface OwnProps {
30 | tx: Tx
31 | }
32 |
33 | type Props = NavigationProps<'TxIncompleteSend'> & OwnProps
34 |
35 | const TxIncompleteSend = ({ navigation, route }: Props) => {
36 | console.log(route)
37 | const [styles] = useThemedStyles(themedStyles)
38 | const tx = route?.params?.tx
39 | const title = tx
40 | ? `Sending ${hrGrin(new BigNumber(tx.amount).abs())}`
41 | : `Send`
42 | const subTitle = tx && `fee: ${hrGrin(tx.fee)}`
43 |
44 | useEffect(() => {
45 | navigation.setParams({ title, subTitle })
46 | }, [title, subTitle])
47 |
48 | return (
49 | <>
50 |
56 |
57 | {tx?.slateId ? (
58 |
59 | ) : (
60 |
61 | )}
62 |
63 | >
64 | )
65 | }
66 |
67 | export function androidHeaderTitle(
68 | params: NavigationProps<'TxIncompleteSend'>['route']['params'],
69 | ) {
70 | const [styles] = useThemedStyles(themedStyles)
71 | return (
72 |
73 | {params?.title}
74 | {params?.subTitle && (
75 | {params?.subTitle}
76 | )}
77 |
78 | )
79 | }
80 |
81 | const themedStyles = styleSheetFactory(theme => ({
82 | androidHeaderTitle: {
83 | fontSize: 21,
84 | color: theme.onBackground,
85 | },
86 | androidHeaderSubTitle: {
87 | color: theme.onBackground,
88 | fontSize: 12,
89 | },
90 | container: {
91 | flexGrow: 1,
92 | },
93 | }))
94 |
95 | export default TxIncompleteSend
96 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@tsconfig/react-native/tsconfig.json",
3 | "compilerOptions": {
4 | "target": "esnext",
5 | "module": "commonjs",
6 | "lib": ["es6", "dom"],
7 | "allowJs": true,
8 | "jsx": "react-native",
9 | "noEmit": true,
10 | "isolatedModules": true,
11 | "strict": true,
12 | "moduleResolution": "node",
13 | "baseUrl": ".",
14 | "allowSyntheticDefaultImports": true,
15 | "esModuleInterop": true,
16 | "resolveJsonModule": true,
17 | "skipLibCheck": true
18 | },
19 | "include": ["src"],
20 | "exclude": [
21 | "node_modules",
22 | "babel.config.js",
23 | "metro.config.js",
24 | "jest.config.js"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------