diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..1ed453a
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,10 @@
+root = true
+
+[*]
+end_of_line = lf
+insert_final_newline = true
+
+[*.{js,json,yml}]
+charset = utf-8
+indent_style = space
+indent_size = 2
diff --git a/.eslintrc.js b/.eslintrc.js
index 187894b..3ac6249 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,4 +1,11 @@
module.exports = {
root: true,
extends: '@react-native',
-};
+ rules: {
+
+ semi: ['error', 'never'],
+ "unused-imports/no-unused-imports": "error"
+
+ },
+ plugins: ['unused-imports']
+}
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..af3ad12
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,4 @@
+/.yarn/** linguist-vendored
+/.yarn/releases/* binary
+/.yarn/plugins/**/* binary
+/.pnp.* binary linguist-generated
diff --git a/.github/workflows/jsCodePush-PROD.yaml b/.github/workflows/jsCodePush-PROD.yaml
new file mode 100644
index 0000000..7f93cbc
--- /dev/null
+++ b/.github/workflows/jsCodePush-PROD.yaml
@@ -0,0 +1,153 @@
+name: Minibits JS bundle code push
+
+# This workflow is manually triggered. Only if package.json version has changed it creates .env file,
+# builds new js bundle and pushes it to devices running app with TEST env and STAGING code push deployment key.
+# At the end it creates and pushes new version tag to github.
+on: workflow_dispatch
+
+jobs:
+ deploy-code-push:
+ runs-on: macos-latest
+ permissions:
+ id-token: write
+ contents: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 2
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 18
+
+ # Fetch javascript bundle version from package.json
+ - name: Read package.json version and detect changes
+ id: version-check
+ uses: salsify/action-detect-and-tag-new-version@v2
+ with:
+ create-tag: false
+
+ - name: Set versions
+ run: |-
+ echo "PREV_JS_VERSION=${{steps.version-check.outputs.previous-version }}" >> $GITHUB_ENV
+ echo "CURRENT_JS_VERSION=${{steps.version-check.outputs.current-version }}" >> $GITHUB_ENV
+
+ # Codepush build will continue only if version changed from previous commit - TEMP SKIP CHECK
+ - name: Detect version change
+ run: |
+ if [ "${{ env.PREV_JS_VERSION }}" != "${{ env.CURRENT_JS_VERSION }}" ]; then
+ echo "IS_VERSION_CHANGED=true" >> $GITHUB_ENV
+ echo "Detected version change"
+ else
+ echo "IS_VERSION_CHANGED=true" >> $GITHUB_ENV
+ echo "No version change, skipping further processing"
+ fi
+
+ # Fetch native app versionName and versionCode from app/build.gradle
+ - name: Get Android native version
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ id: version-reader-android
+ uses: michpohl/android-expose-version-name-action@v1.0.0
+ with:
+ path: android/app/build.gradle
+ expose-version-name: 'true' # sets ANDROID_VERSION_NAME to env
+
+ # Get commit hash
+ - name: Get commit hash
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ id: commit-hash
+ uses: pr-mpt/actions-commit-hash@v2
+
+ - name: Set commit hash
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ run: |-
+ echo "COMMIT_HASH=${{steps.commit-hash.outputs.short }}" >> $GITHUB_ENV
+
+ # Get commit message
+ - name: Get last commit message
+ uses: actions/github-script@v6
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const response = await github.rest.repos.getCommit({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: context.sha
+ });
+ const lastCommit = response.data.commit;
+ const message = lastCommit.message;
+ console.log(message);
+ core.exportVariable('COMMIT_MESSAGE', message);
+
+ # Create .env file
+ - name: Generate .env
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ run: |-
+ echo APP_ENV='PROD' >> .env
+ echo SENTRY_DSN='${{ secrets.SENTRY_DSN }}' >> .env
+ echo CODEPUSH_PRODUCTION_DEPLOYMENT_KEY='${{ secrets.CODEPUSH_PRODUCTION_DEPLOYMENT_KEY }}' >> .env
+ echo NATIVE_VERSION_ANDROID='${{ env.ANDROID_VERSION_NAME }}' >> .env
+ echo JS_BUNDLE_VERSION='${{ env.CURRENT_JS_VERSION }}' >> .env
+ echo MINIBITS_SERVER_API_KEY='${{ secrets.MINIBITS_SERVER_API_KEY }}' >> .env
+ echo MINIBIT_SERVER_NOSTR_PUBKEY='${{ secrets.MINIBIT_SERVER_NOSTR_PUBKEY }}' >> .env
+ echo MINIBITS_SERVER_API_HOST='https://api.minibits.cash' >> .env
+ echo MINIBITS_NIP05_DOMAIN='@minibits.cash' >> .env
+ echo MINIBITS_RELAY_URL='wss://relay.minibits.cash' >> .env
+ echo MINIBITS_MINT_URL='https://mint.minibits.cash/Bitcoin' >> .env
+ echo COMMIT='${{ env.COMMIT_HASH }}' >> .env
+
+ # Install dependecies from package.json
+ - name: Install app dependencies
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ uses: bahmutov/npm-install@v1.10.2
+ # with:
+ # install-command: 'yarn install'
+
+ - name: Install Sentry CLI
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ run: npm install @sentry/cli --legacy-peer-deps
+
+ # Code push with source maps export for Sentry
+ - name: Install AppCenter CLI
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ run: npm install -g appcenter-cli
+
+ - name: Deploy to CodePush Android
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ run: appcenter codepush release-react -a minibits-cash/minibits_wallet_android -d Production --description '${{ env.COMMIT_MESSAGE }} (v${{ env.CURRENT_JS_VERSION }})' --sourcemap-output ./build/index.android.bundle.map --output-dir ./build
+ env:
+ APPCENTER_ACCESS_TOKEN: ${{ secrets.APPCENTER_ACCESS_TOKEN_ANDROID }}
+
+ # Upload source files to Sentry
+ - name: Upload source files to Sentry
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ run: |-
+ ./node_modules/.bin/sentry-cli login --auth-token ${{ secrets.SENTRY_AUTH_TOKEN }}
+ ./node_modules/.bin/sentry-cli releases \
+ files minibits_wallet_android@${{ env.CURRENT_JS_VERSION }} \
+ upload-sourcemaps \
+ --strip-prefix /build \
+ --dist ${{ env.ANDROID_VERSION_NAME }} \
+ --org ${{ secrets.SENTRY_ORG }} \
+ --project minibits-wallet \
+ ./build/index.android.bundle.map ./build/Codepush/index.android.bundle
+
+
+ # Create the release tag in github repo
+ - name: Create tag
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ uses: actions/github-script@v6
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const tagPrefix = "v";
+ const tagName = tagPrefix + process.env.CURRENT_JS_VERSION;
+ github.rest.git.createRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: `refs/tags/${tagName}`,
+ sha: context.sha
+ });
+
diff --git a/.github/workflows/jsCodePush-TEST.yaml b/.github/workflows/jsCodePush-TEST.yaml
new file mode 100644
index 0000000..d2b52bd
--- /dev/null
+++ b/.github/workflows/jsCodePush-TEST.yaml
@@ -0,0 +1,153 @@
+name: Minibits JS bundle code push
+
+# This workflow is manually triggered. Only if package.json version has changed it creates .env file,
+# builds new js bundle and pushes it to devices running app with TEST env and STAGING code push deployment key.
+# At the end it creates and pushes new version tag to github.
+on: workflow_dispatch
+
+jobs:
+ deploy-code-push:
+ runs-on: macos-latest
+ permissions:
+ id-token: write
+ contents: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 2
+
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 18
+
+ # Fetch javascript bundle version from package.json
+ - name: Read package.json version and detect changes
+ id: version-check
+ uses: salsify/action-detect-and-tag-new-version@v2
+ with:
+ create-tag: false
+
+ - name: Set versions
+ run: |-
+ echo "PREV_JS_VERSION=${{steps.version-check.outputs.previous-version }}" >> $GITHUB_ENV
+ echo "CURRENT_JS_VERSION=${{steps.version-check.outputs.current-version }}" >> $GITHUB_ENV
+
+ # Codepush build will continue only if version changed from previous commit
+ - name: Detect version change
+ run: |
+ if [ "${{ env.PREV_JS_VERSION }}" != "${{ env.CURRENT_JS_VERSION }}" ]; then
+ echo "IS_VERSION_CHANGED=true" >> $GITHUB_ENV
+ echo "Detected version change"
+ else
+ echo "IS_VERSION_CHANGED=false" >> $GITHUB_ENV
+ echo "No version change, skipping further processing"
+ fi
+
+ # Fetch native app versionName and versionCode from app/build.gradle
+ - name: Get Android native version
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ id: version-reader-android
+ uses: michpohl/android-expose-version-name-action@v1.0.0
+ with:
+ path: android/app/build.gradle
+ expose-version-name: 'true' # sets ANDROID_VERSION_NAME to env
+
+ # Get commit hash
+ - name: Get commit hash
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ id: commit-hash
+ uses: pr-mpt/actions-commit-hash@v2
+
+ - name: Set commit hash and native version information
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ run: |-
+ echo "COMMIT_HASH=${{steps.commit-hash.outputs.short }}" >> $GITHUB_ENV
+
+ # Get commit message
+ - name: Get last commit message
+ uses: actions/github-script@v6
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const response = await github.rest.repos.getCommit({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: context.sha
+ });
+ const lastCommit = response.data.commit;
+ const message = lastCommit.message;
+ console.log(message);
+ core.exportVariable('COMMIT_MESSAGE', message);
+
+ # Create .env file
+ - name: Generate .env
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ run: |-
+ echo APP_ENV='TEST' >> .env
+ echo SENTRY_DSN='${{ secrets.SENTRY_DSN }}' >> .env
+ echo CODEPUSH_STAGING_DEPLOYMENT_KEY='${{ secrets.CODEPUSH_STAGING_DEPLOYMENT_KEY }}' >> .env
+ echo NATIVE_VERSION_ANDROID='${{ env.ANDROID_VERSION_NAME }}' >> .env
+ echo JS_BUNDLE_VERSION='${{ env.CURRENT_JS_VERSION }}' >> .env
+ echo MINIBITS_SERVER_API_KEY='${{ secrets.MINIBITS_SERVER_API_KEY }}' >> .env
+ echo MINIBIT_SERVER_NOSTR_PUBKEY='${{ secrets.MINIBIT_SERVER_NOSTR_PUBKEY }}' >> .env
+ echo MINIBITS_SERVER_API_HOST='https://api.minibits.cash' >> .env
+ echo MINIBITS_NIP05_DOMAIN='@minibits.cash' >> .env
+ echo MINIBITS_RELAY_URL='wss://relay.minibits.cash/test' >> .env
+ echo MINIBITS_MINT_URL='https://mint.minibits.cash/Bitcoin' >> .env
+ echo COMMIT='${{ env.COMMIT_HASH }}' >> .env
+
+ # Install dependecies from package.json
+ - name: Install app dependencies
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ uses: bahmutov/npm-install@v1.10.2
+ # with:
+ # install-command: 'yarn install'
+
+ - name: Install Sentry CLI
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ run: npm install @sentry/cli --legacy-peer-deps
+
+ # Code push with source maps export for Sentry
+ - name: Install AppCenter CLI
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ run: npm install -g appcenter-cli
+
+ - name: Deploy to CodePush Android
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ run: appcenter codepush release-react -a minibits-cash/minibits_wallet_android -d Staging --description '${{ env.COMMIT_MESSAGE }} (v${{ env.CURRENT_JS_VERSION }})' --sourcemap-output ./build/index.android.bundle.map --output-dir ./build
+ env:
+ APPCENTER_ACCESS_TOKEN: ${{ secrets.APPCENTER_ACCESS_TOKEN_ANDROID }}
+
+ # Upload source files to Sentry
+ - name: Upload source files to Sentry
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ run: |-
+ ./node_modules/.bin/sentry-cli login --auth-token ${{ secrets.SENTRY_AUTH_TOKEN }}
+ ./node_modules/.bin/sentry-cli releases \
+ files minibits_wallet_android@${{ env.CURRENT_JS_VERSION }} \
+ upload-sourcemaps \
+ --strip-prefix /build \
+ --dist ${{ env.NATIVE_VERSION }} \
+ --org ${{ secrets.SENTRY_ORG }} \
+ --project minibits-wallet \
+ ./build/index.android.bundle.map ./build/Codepush/index.android.bundle
+
+
+ # Create the release tag in github repo
+ - name: Create tag
+ if: ${{ env.IS_VERSION_CHANGED == 'true' }}
+ uses: actions/github-script@v6
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const tagPrefix = "v";
+ const tagName = tagPrefix + process.env.CURRENT_JS_VERSION;
+ github.rest.git.createRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: `refs/tags/${tagName}`,
+ sha: context.sha
+ });
+
diff --git a/.prettierrc.js b/.prettierrc.js
index 2b54074..a6271df 100644
--- a/.prettierrc.js
+++ b/.prettierrc.js
@@ -4,4 +4,5 @@ module.exports = {
bracketSpacing: false,
singleQuote: true,
trailingComma: 'all',
+ semi: false,
};
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..116d685
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,5 @@
+{
+ "recommendations": [
+ "inlang.vs-code-extension"
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..3d8caac
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,10 @@
+{
+ "[javascriptreact][typescriptreact]": {
+ "editor.insertSpaces": true,
+ "editor.tabSize": 2
+ },
+ "[javascript][typescript]": {
+ "editor.insertSpaces": true,
+ "editor.tabSize": 2
+ }
+}
\ No newline at end of file
diff --git a/.yarn/releases/yarn-3.6.4.cjs b/.yarn/releases/yarn-3.6.4.cjs
new file mode 100644
index 0000000..ebd9272
Binary files /dev/null and b/.yarn/releases/yarn-3.6.4.cjs differ
diff --git a/.yarnrc.yml b/.yarnrc.yml
new file mode 100644
index 0000000..08d714d
--- /dev/null
+++ b/.yarnrc.yml
@@ -0,0 +1,3 @@
+nodeLinker: node-modules
+
+yarnPath: .yarn/releases/yarn-3.6.4.cjs
diff --git a/App.tsx b/App.tsx
deleted file mode 100644
index 125fe1b..0000000
--- a/App.tsx
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
- * Sample React Native App
- * https://github.com/facebook/react-native
- *
- * @format
- */
-
-import React from 'react';
-import type {PropsWithChildren} from 'react';
-import {
- SafeAreaView,
- ScrollView,
- StatusBar,
- StyleSheet,
- Text,
- useColorScheme,
- View,
-} from 'react-native';
-
-import {
- Colors,
- DebugInstructions,
- Header,
- LearnMoreLinks,
- ReloadInstructions,
-} from 'react-native/Libraries/NewAppScreen';
-
-type SectionProps = PropsWithChildren<{
- title: string;
-}>;
-
-function Section({children, title}: SectionProps): React.JSX.Element {
- const isDarkMode = useColorScheme() === 'dark';
- return (
-
-
- {title}
-
-
- {children}
-
-
- );
-}
-
-function App(): React.JSX.Element {
- const isDarkMode = useColorScheme() === 'dark';
-
- const backgroundStyle = {
- backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
- };
-
- return (
-
-
-
-
-
-
- Edit App.tsx to change this
- screen and then come back to see your edits.
-
-
-
-
- Read the docs to discover what to do next:
-
-
-
-
-
- );
-}
-
-const styles = StyleSheet.create({
- sectionContainer: {
- marginTop: 32,
- paddingHorizontal: 24,
- },
- sectionTitle: {
- fontSize: 24,
- fontWeight: '600',
- },
- sectionDescription: {
- marginTop: 8,
- fontSize: 18,
- fontWeight: '400',
- },
- highlight: {
- fontWeight: '700',
- },
-});
-
-export default App;
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..eb7c50b
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) 2023 Minibits.cash
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index 12470c3..0579194 100644
--- a/README.md
+++ b/README.md
@@ -1,79 +1,207 @@
-This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli).
+
-# Getting Started
->**Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding.
+# Disclaimer
-## Step 1: Start the Metro Server
+⚠️ If you are using this app, please take the following into consideration:
+- This wallet should be used for research purposes only.
+- The wallet is a beta version with incomplete functionality and both known and unknown bugs.
+- Do not use it with large amounts of ecash.
+- The ecash stored in the wallet is issued by the mint. You trust the mint to back it with bitcoin until you transfer your holdings to another bitcoin lightning wallet.
+- The Cashu protocol that the wallet implements has not yet received extensive review or testing.
-First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native.
-To start Metro, run the following command from the _root_ of your React Native project:
+# Minibits Wallet
+
+Minibits is an ecash and lightning wallet with a focus on ease of use and security. Ecash is issued by mints and backed by Bitcoin via the [Cashu](https://cashu.space) protocol and Lightning Network. Ecash is cash-like yet digital token with cheap and instant transfers and high privacy guarantees.
+
+## Roadmap
+
+Platform support
+- [x] Android app
+- [ ] iOS app
+- [x] Light and dark mode
+- [x] i18n support
+- [ ] Other then EN languange support
+
+Mints
+- [x] Multiple currency units issued by mints [✨ New!]
+- [x] Add multiple mints
+- [x] Remove mints
+- [x] Block receiving from mint
+- [x] Show mint balances grouped by currency units [✨ New!]
+- [x] Handle mint keys rotation (not tested)
+- [x] Mint status and information screen
+
+Receive ecash
+- [x] Scan QR code of a ecash token
+- [x] Paste ecash token from the clipboard
+- [x] Notification on received payment (app needs to be in foreground)
+- [x] Receive Nostr zaps or Lightning payments to minibits.cash address
+- [x] Receive ecash from another wallet over NOSTR message sent to minibits.cash address
+- [x] Receive ecash in person while being offline, redeem later (MVP version)
+- [x] Realtime and encrypted push notifications on receive to minibits.cash lightning address [✨ New!]
+
+Send ecash
+- [x] Share ecash token to send through another app
+- [x] Show ecash token as a QR code
+- [x] Notification on payment received by the payee (app needs to come to foreground)
+- [x] Send ecash to contact (minibits.cash or another NOSTR address)
+- [ ] Lock ecash sent offline to the receiver wallet key
+
+Top up wallet
+- [x] Show QR code with bitcoin Lightning invoice to pay
+- [x] Share encoded bitcoin Lightning invoice to pay
+- [x] Share payment request with contact over NOSTR message
+- [x] Top up balance with LNURL Withdraw
+
+Pay / Cash out from wallet
+- [x] One click ZAPS - tip users of NOSTR social network
+- [x] Paste or scan and settle bitcoin Lightning invoice with your ecash
+- [x] Pay payment request received from another contact
+- [x] Pay to LNURL Pay static links / codes
+- [x] Pay to Lightning address
+- [ ] Transfer (swap) ecash to another mint
+
+Transaction history
+- [x] Unified transaction history for all kinds of transactions
+- [x] Audit trail of transaction events
+- [x] Filter pending transactions
+- [x] Retry after recoverable transaction errors [✨ New!]
+- [ ] Revert pending transaction in 1 click (get back tokens not claimed by receiver)
+- [ ] Tags and related filtering of transactions
+- [x] Delete incomplete and failed transactions from history
+
+Contacts
+- [x] Private contacts address book for payments
+- [x] Public contacts (followed users on NOSTR social network) for tipping and donations
+- [x] Load public contacts from custom NOSTR relay
+- [x] Wallet addresses as random public NOSTR addresses (random123@minibits.cash)
+- [x] Custom wallet names (myname@minibits.cash)
+- [x] Wallet addresses usable as Lightning addresses to receive payments from many Lightning wallets
+- [x] Private contacts with other than minibits.cash NOSTR adresses and relays
+
+Backup and recovery
+- [x] Local append-only backup of all ecash in a database separate from wallet storage
+- [x] Recovery tool to recover ecash from local backup
+- [x] Recover wallet in case spent ecash remain in the wallet due to an exception during a transaction
+- [x] Off-device backup and recovery using 12 words menmonic phrase
+- [x] Retry transaction after recoverable errors [✨ New!]
+- [x] Auto-recover funds if wallet failed to receive ecash issued by mint due to network or device failure
+- [x] Smooth migration to another device - recovery of wallet address without balances using mnemonic phrase [✨ New!]
+
+Interoperability
+- [x] Nostr Wallet Connect - lets you initiate payments from another app, such as Nostr client [✨ New!]
+- [x] Deeplinks - app reacts to lightning: and cashu: URIs
+
+
+Security and Privacy
+- [x] Optional AES encryption of wallet storage using a key stored in the device secure key storage
+- [x] Use device biometry to login (if storage encryption is on)
+- [ ] Connect to the mints on .onion Tor addresses using own Tor daemon [discontinued from v0.1.7]
+- [x] Connect to the mints on .onion Tor addresses using Orbot [✨ New!]
+
+Self-funding
+- [X] Donation for custom wallet name
+
+DevOps
+- [x] OTA updates (opt in)
+- [ ] Automated tests
+- [ ] Automated release pipelines for both OTA updates and native releases
+
+
+## Architecture
+
+The wallet's design has been crafted to prioritize the following primary quality properties:
+- Support both Android and iOS mobile platforms
+- Achieve fast UX and startup time (despite using React Native)
+- Minimize the risk of data/ecash loss
+- Bring ecash UX on par with the current standard of traditional finance (tradfi) mobile apps
+
+As a result, the following architectural constraints are in place:
+- Wherever available, use libraries with a fast JSI (JavaScript Interface) to native modules.
+- Avoid Expo modules.
+- Use fastest available storage for most wallet operations and separate local database storage to store data that incrementally grows.
+- Leverage local database as an append-only ecash backup independent from fast storage.
+
+
+
+Open architectural concepts that were still open for discussion when the wallet had been released
+- [x] Contacts management - identities, sharing contacts, send ecash with the UX of tradfi instant payment while keeping privacy towards mints - Implemented as NOSTR keypairs and NIP05 public sharable names that ecash can be sent to
+- [x] Off-device backup strategy - Implemented using @gandlafbtc concept of deterministic secrets
+- [ ] UX and naming conventions - ecash is not always intuitive. UX for new users heavily depends on using the right abstractions or terms to describe what is going on. This wallet wants to serve as a means to test what could work. One of the first ideas is to avoid terms such as token or proof and propose the term --coin ++ecash instead.
+- [ ] Suitable Tor daemon available to replace not maintained react-native-tor. From v0.1.8-beta.33 connection through Orbot in VPN mode is possible.
+
+
+## Download and test
+
+Minibits wallet is in early beta and available as of now only for Android devices. You have the following options to try it out:
+- [x] Download it from Google Play
+- [x] Join testing program on Google Play to get early releases to test (Submit your email to get an invite on [Minibits.cash](https://www.minibits.cash))
+- [x] Download .apk file from Releases page and install it on your phone
+
+
+# Development
+
+Minibits is a bare React Native app written in Typescript. The project structure and code itself are intentionally verbose to support readability. Critical wallet code is reasonably documented. However, there is vast space for existing code improvements, refactoring, and bug fixing. This is an early beta software and the author does not code for a living.
+
+The code is derived from Ignite template, however with many libraries, notably Expo, stripped down to achieve fast startup times. Performance bottleneck on some Android devices is react-native-keychain. To overcome this, it has been patched not to warm-up on startup, caching for wallet operations is in place and its use to encrypt storage is opt-in.
+
+Wallet state is managed by mobx-state-tree and persisted in fast MMKV storage. Only the basic mobx concepts are in place, whole model could be improved. All critical wallet code is in services/walletService.ts and all ecash state changes are in models/ProofsStore.ts. Wallet communication with the mints is in model/Wallet.ts and uses [cashu-ts](https://github.com/cashubtc/cashu-ts) library.
+
+Crypto operations are handled by react-native-quick-crypto, that is fast and does not require awful javascript shims. Transaction history and ecash backup is stored in sqlite, with fast react-native-quick-sqlite driver that enables to run lighter queries synchronously.
+
+Wallet included own Tor daemon using react-native-tor library to connect to the mints over Tor network. However this seems not to be long term approach as this library is
+not properly maintained and future updates of React native will likely break it. Help with replacement would be appreciated.
+
+In case of breaking state and data model changes, versioning and code is ready to run necessary migrations on wallet startup.
+
+# Running in development mode
+
+To run Minibits wallet in dev mode, set up the React Native development environment and the Yarn package manager. Then clone this repository, navigate to the minibits_wallet directory, and run the following:
```bash
-# using npm
-npm start
+yarn install
+```
-# OR using Yarn
+There are post-install patches to some of the libraries that should run automatically and are necessary for a successful run. See the patches directory for more info.
+After the dependecies are installed, continue to create the following .env file in the root folder:
+
+```bash
+APP_ENV='DEV'
+MINIBITS_SERVER_API_KEY='mockkey'
+MINIBITS_SERVER_API_HOST='http://localhost/api'
+MINIBITS_NIP05_DOMAIN='@localhost'
+MINIBITS_RELAY_URL='ws://localhost/relay'
+MINIBITS_MINT_URL='http://localhost/mint'
+```
+Local NOSTR address and Lighnting brigde server are not necessary to run the wallet.
+Then make sure you have the Android device connected by running:
+
+```bash
+yarn adb
+```
+
+Finally run this and pray:
+
+```bash
yarn start
```
-## Step 2: Start your Application
+In case of issues, repo includes commits history from the out of the box react native app up until the complete wallet. You can see build.gradle and other changes one by one and hopefully figure out what's wrong.
-Let Metro Bundler run in its _own_ terminal. Open a _new_ terminal from the _root_ of your React Native project. Run the following command to start your _Android_ or _iOS_ app:
+# Building
-### For Android
+Create debug .apk:
```bash
-# using npm
-npm run android
-
-# OR using Yarn
-yarn android
+yarn android:dev
```
-### For iOS
+# Automated testing
-```bash
-# using npm
-npm run ios
+The app has the scaffolding for automated tests; they are yet to be implemented. For functional bugs or suggestions please raise an issue.
-# OR using Yarn
-yarn ios
-```
+# Contributing
-If everything is set up _correctly_, you should see your new app running in your _Android Emulator_ or _iOS Simulator_ shortly provided you have set up your emulator/simulator correctly.
-
-This is one way to run your app — you can also run it directly from within Android Studio and Xcode respectively.
-
-## Step 3: Modifying your App
-
-Now that you have successfully run the app, let's modify it.
-
-1. Open `App.tsx` in your text editor of choice and edit some lines.
-2. For **Android**: Press the R key twice or select **"Reload"** from the **Developer Menu** (Ctrl + M (on Window and Linux) or Cmd ⌘ + M (on macOS)) to see your changes!
-
- For **iOS**: Hit Cmd ⌘ + R in your iOS Simulator to reload the app and see your changes!
-
-## Congratulations! :tada:
-
-You've successfully run and modified your React Native App. :partying_face:
-
-### Now what?
-
-- If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps).
-- If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started).
-
-# Troubleshooting
-
-If you can't get this to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page.
-
-# Learn More
-
-To learn more about React Native, take a look at the following resources:
-
-- [React Native Website](https://reactnative.dev) - learn more about React Native.
-- [Getting Started](https://reactnative.dev/docs/environment-setup) - an **overview** of React Native and how setup your environment.
-- [Learn the Basics](https://reactnative.dev/docs/getting-started) - a **guided tour** of the React Native **basics**.
-- [Blog](https://reactnative.dev/blog) - read the latest official React Native **Blog** posts.
-- [`@facebook/react-native`](https://github.com/facebook/react-native) - the Open Source; GitHub **repository** for React Native.
+Contributions are welcome, just start and we will figure out what's next.
diff --git a/__tests__/App.test.tsx b/__tests__/App.test.tsx
index 9eac6fb..3279b6a 100644
--- a/__tests__/App.test.tsx
+++ b/__tests__/App.test.tsx
@@ -4,7 +4,7 @@
import 'react-native';
import React from 'react';
-import App from '../App';
+import App from '../src/App';
// Note: import explicitly to use the types shipped with jest.
import {it} from '@jest/globals';
@@ -13,5 +13,5 @@ import {it} from '@jest/globals';
import renderer from 'react-test-renderer';
it('renders correctly', () => {
- renderer.create();
+ renderer.create();
});
diff --git a/__tests__/incorrectTranslationPlaceholders.js b/__tests__/incorrectTranslationPlaceholders.js
new file mode 100644
index 0000000..5192646
--- /dev/null
+++ b/__tests__/incorrectTranslationPlaceholders.js
@@ -0,0 +1,24 @@
+const fs = require('fs');
+const path = require('path');
+const messagesFolder = path.resolve(__dirname, '../src/i18n_messages');
+
+for (const file of fs.readdirSync(messagesFolder)) {
+ const filePath = path.join(messagesFolder, file);
+ const content = fs.readFileSync(filePath, 'utf8');
+ const lines = content.split('\n');
+
+ for (let i = 0; i < lines.length; i++) {
+ const line = lines[i];
+ if (line.includes('${')) {
+ const index = line.indexOf('${');
+ const neighborValue = 10
+ const neighbor = line
+ .trim()
+ .slice(
+ Math.max(0, index - neighborValue),
+ Math.min(line.length, index + neighborValue),
+ )
+ console.log(`${filePath}(${i+1},${index+1}): Likely incorrect placeholder selector \$\{\}: ...${neighbor}...`);
+ }
+ }
+}
\ No newline at end of file
diff --git a/__tests__/missingTranslations.js b/__tests__/missingTranslations.js
new file mode 100644
index 0000000..ed62dbe
--- /dev/null
+++ b/__tests__/missingTranslations.js
@@ -0,0 +1,16 @@
+const { exec } = require('child_process');
+
+exec('tsc --noEmit', (error, stdout, stderr) => {
+ if (error) {
+ const output = stdout;
+ const filteredErrors = output.split('\n').filter(line => line.includes('TxKeyPath'));
+ if (filteredErrors.length > 0) {
+ console.log(filteredErrors.join('\n'));
+ } else {
+ console.log('No errors containing TxKeyPath found.');
+ }
+ // process.exit(1); // Ensure the script returns an error code if there were any errors
+ } else {
+ console.log('No TypeScript errors found.');
+ }
+});
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 9976bdb..98d1c98 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -1,6 +1,10 @@
apply plugin: "com.android.application"
apply plugin: "org.jetbrains.kotlin.android"
apply plugin: "com.facebook.react"
+apply plugin: "com.google.gms.google-services"
+
+import com.android.build.OutputFile
+
/**
* This is the configuration block to customize your React Native Android app.
@@ -72,20 +76,47 @@ def enableProguardInReleaseBuilds = false
*/
def jscFlavor = 'org.webkit:android-jsc:+'
+/**
+ * Private function to get the list of Native Architectures you want to build.
+ * This reads the value from reactNativeArchitectures in your gradle.properties
+ * file and works together with the --active-arch-only flag of react-native run-android.
+ */
+def reactNativeArchitectures() {
+ def value = project.getProperties().get("reactNativeArchitectures")
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
+}
+
android {
ndkVersion rootProject.ext.ndkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
compileSdk rootProject.ext.compileSdkVersion
-
- namespace "com.minibits_wallet_075"
+
+ namespace "com.minibits_wallet"
defaultConfig {
- applicationId "com.minibits_wallet_075"
+ applicationId "com.minibits_wallet"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode 1
- versionName "1.0"
+ versionCode 58001
+ versionName "0.1.9"
+ }
+
+ splits {
+ abi {
+ reset()
+ enable true
+ universalApk true // If true, also generate a universal APK
+ include (*reactNativeArchitectures())
+ }
}
signingConfigs {
+ release {
+ if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
+ storeFile file(project.property('MYAPP_UPLOAD_STORE_FILE'))
+ storePassword project.property('MYAPP_UPLOAD_STORE_PASSWORD')
+ keyAlias project.property('MYAPP_UPLOAD_KEY_ALIAS')
+ keyPassword project.property('MYAPP_UPLOAD_KEY_PASSWORD')
+ }
+ }
debug {
storeFile file('debug.keystore')
storePassword 'android'
@@ -94,22 +125,52 @@ android {
}
}
buildTypes {
- debug {
- signingConfig signingConfigs.debug
- }
release {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
- signingConfig signingConfigs.debug
+ signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
+ debug {
+ signingConfig signingConfigs.debug
+ }
+ }
+
+ // minibits_wallet:build
+ packagingOptions {
+ pickFirst 'lib/arm64-v8a/liblog.so'
+ pickFirst 'lib/x86/liblog.so'
+ pickFirst 'lib/x86_64/liblog.so'
+ pickFirst 'lib/armeabi-v7a/liblog.so'
+ pickFirst 'lib/arm64-v8a/liblog.so'
+ pickFirst 'lib/arm64-v8a/libcrypto.so'
+ pickFirst 'lib/x86/libcrypto.so'
+ pickFirst 'lib/x86_64/libcrypto.so'
+ pickFirst 'lib/armeabi-v7a/libcrypto.so'
+ }
+
+ // applicationVariants are e.g. debug, release
+ applicationVariants.all { variant ->
+ variant.outputs.each { output ->
+ // For each separate APK per architecture, set a unique version code as described here:
+ // https://developer.android.com/studio/build/configure-apk-splits.html
+ // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
+ def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
+ def abi = output.getFilter(OutputFile.ABI)
+ if (abi != null) { // null for the universal-debug, universal-release variants
+ output.versionCodeOverride =
+ defaultConfig.versionCode * 1000 + versionCodes.get(abi)
+ }
+
+ }
}
}
dependencies {
// The version of react-native is set by the React Native Gradle Plugin
- implementation("com.facebook.react:react-android")
+ implementation("com.facebook.react:react-android")
+ implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
@@ -117,3 +178,6 @@ dependencies {
implementation jscFlavor
}
}
+
+// code-push
+apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index e189252..1832f71 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -1,26 +1,57 @@
-
-
-
-
-
+
+
+
+
-
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/assets/fonts/Gluten-Regular.ttf b/android/app/src/main/assets/fonts/Gluten-Regular.ttf
new file mode 100644
index 0000000..ae2e3c2
Binary files /dev/null and b/android/app/src/main/assets/fonts/Gluten-Regular.ttf differ
diff --git a/android/app/src/main/java/com/minibits_wallet_075/MainActivity.kt b/android/app/src/main/java/com/minibits_wallet/MainActivity.kt
similarity index 78%
rename from android/app/src/main/java/com/minibits_wallet_075/MainActivity.kt
rename to android/app/src/main/java/com/minibits_wallet/MainActivity.kt
index 24f8712..f4ea7ea 100644
--- a/android/app/src/main/java/com/minibits_wallet_075/MainActivity.kt
+++ b/android/app/src/main/java/com/minibits_wallet/MainActivity.kt
@@ -1,5 +1,7 @@
-package com.minibits_wallet_075
+package com.minibits_wallet
+// minibits_wallet:react-native-screens
+import android.os.Bundle
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
@@ -11,7 +13,7 @@ class MainActivity : ReactActivity() {
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
- override fun getMainComponentName(): String = "minibits_wallet_075"
+ override fun getMainComponentName(): String = "minibits_wallet"
/**
* Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
@@ -19,4 +21,9 @@ class MainActivity : ReactActivity() {
*/
override fun createReactActivityDelegate(): ReactActivityDelegate =
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
+
+ // minibits_wallet:react-native-screens
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(null)
+ }
}
diff --git a/android/app/src/main/java/com/minibits_wallet_075/MainApplication.kt b/android/app/src/main/java/com/minibits_wallet/MainApplication.kt
similarity index 65%
rename from android/app/src/main/java/com/minibits_wallet_075/MainApplication.kt
rename to android/app/src/main/java/com/minibits_wallet/MainApplication.kt
index 8b8fc8b..e6da12e 100644
--- a/android/app/src/main/java/com/minibits_wallet_075/MainApplication.kt
+++ b/android/app/src/main/java/com/minibits_wallet/MainApplication.kt
@@ -1,4 +1,4 @@
-package com.minibits_wallet_075
+package com.minibits_wallet
import android.app.Application
import com.facebook.react.PackageList
@@ -10,16 +10,17 @@ import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.soloader.SoLoader
+import com.microsoft.codepush.react.CodePush
class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
- override fun getPackages(): List =
- PackageList(this).packages.apply {
- // Packages that cannot be autolinked yet can be added manually here, for example:
- // add(MyReactNativePackage())
- }
+ override fun getPackages(): List {
+ // Packages that cannot be autolinked yet can be added manually here, for example:
+ // packages.add(new MyReactNativePackage());
+ return PackageList(this).packages
+ }
override fun getJSMainModuleName(): String = "index"
@@ -27,6 +28,14 @@ class MainApplication : Application(), ReactApplication {
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
+
+ // minibits_wallet:react-native-code-push
+ // 2. Override the getJSBundleFile method in order to let
+ // the CodePush runtime determine where to get the JS
+ // bundle location from on each app start
+ override fun getJSBundleFile(): String {
+ return CodePush.getJSBundleFile()
+ }
}
override val reactHost: ReactHost
@@ -38,6 +47,6 @@ class MainApplication : Application(), ReactApplication {
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
load()
- }
+ }
}
}
diff --git a/android/app/src/main/res/drawable/rn_edit_text_material.xml b/android/app/src/main/res/drawable/rn_edit_text_material.xml
index 5c25e72..73b37e4 100644
--- a/android/app/src/main/res/drawable/rn_edit_text_material.xml
+++ b/android/app/src/main/res/drawable/rn_edit_text_material.xml
@@ -17,8 +17,7 @@
android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material"
android:insetRight="@dimen/abc_edit_text_inset_horizontal_material"
android:insetTop="@dimen/abc_edit_text_inset_top_material"
- android:insetBottom="@dimen/abc_edit_text_inset_bottom_material"
- >
+ android:insetBottom="@dimen/abc_edit_text_inset_bottom_material">
diff --git a/android/build.gradle b/android/build.gradle
index df1ce4d..82d8513 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -1,7 +1,7 @@
buildscript {
ext {
buildToolsVersion = "34.0.0"
- minSdkVersion = 23
+ minSdkVersion = 24
compileSdkVersion = 34
targetSdkVersion = 34
ndkVersion = "26.1.10909125"
@@ -15,6 +15,13 @@ buildscript {
classpath("com.android.tools.build:gradle")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
+ classpath("com.google.gms:google-services:4.4.1")
+ }
+}
+// minibits_wallet:react-native-camera-kit
+allprojects {
+ repositories {
+ google()
}
}
diff --git a/android/settings.gradle b/android/settings.gradle
index 8af8f8b..8aafb59 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -1,6 +1,8 @@
pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }
plugins { id("com.facebook.react.settings") }
extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
-rootProject.name = 'minibits_wallet_075'
-include ':app'
+rootProject.name = 'minibits_wallet'
includeBuild('../node_modules/@react-native/gradle-plugin')
+// code-push
+include ':app', ':react-native-code-push'
+project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')
diff --git a/app.json b/app.json
index 551deae..ee9aa58 100644
--- a/app.json
+++ b/app.json
@@ -1,4 +1,4 @@
{
- "name": "minibits_wallet_075",
- "displayName": "minibits_wallet_075"
-}
+ "name": "minibits_wallet",
+ "displayName": "Minibits"
+}
\ No newline at end of file
diff --git a/assets/fonts/Gluten-Regular.ttf b/assets/fonts/Gluten-Regular.ttf
new file mode 100644
index 0000000..ae2e3c2
Binary files /dev/null and b/assets/fonts/Gluten-Regular.ttf differ
diff --git a/assets/icons/nostr.png b/assets/icons/nostr.png
new file mode 100644
index 0000000..8274604
Binary files /dev/null and b/assets/icons/nostr.png differ
diff --git a/babel.config.js b/babel.config.js
index f7b3da3..518e738 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -1,3 +1,17 @@
module.exports = {
presets: ['module:@react-native/babel-preset'],
+ plugins: [
+ [
+ 'module-resolver',
+ {
+ alias: {
+ 'crypto': 'react-native-quick-crypto',
+ 'stream': 'stream-browserify',
+ 'buffer': '@craftzdog/react-native-buffer',
+ },
+ },
+ ],
+ 'module:react-native-dotenv',
+ 'react-native-reanimated/plugin'
+ ],
};
diff --git a/index.js b/index.js
index a850d03..b43979c 100644
--- a/index.js
+++ b/index.js
@@ -1,9 +1,22 @@
-/**
- * @format
- */
+import 'react-native-reanimated' // needed for qrcode reader
+import { install } from 'react-native-quick-crypto' // needed for secp256k1, conf in babel.config
+install()
+import 'react-native-url-polyfill/auto' // URL.host etc
+import 'text-encoding-polyfill' // needed in cashu-ts
+import {AppRegistry} from 'react-native'
+import messaging from '@react-native-firebase/messaging';
+import App from './src/App'
+import {name as appName} from './app.json'
+import { NotificationService } from './src/services/notificationService';
-import {AppRegistry} from 'react-native';
-import App from './App';
-import {name as appName} from './app.json';
-AppRegistry.registerComponent(appName, () => App);
+function BootstrapApp() {
+ return
+}
+
+
+// Setup notification listeners and handlers
+messaging().onMessage(NotificationService.onForegroundNotification)
+messaging().setBackgroundMessageHandler(NotificationService.onBackgroundNotification)
+
+AppRegistry.registerComponent(appName, () => BootstrapApp)
diff --git a/ios/Podfile b/ios/Podfile
index fd05241..aa3f3de 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -14,7 +14,7 @@ if linkage != nil
use_frameworks! :linkage => linkage.to_sym
end
-target 'minibits_wallet_075' do
+target 'minibits_wallet' do
config = use_native_modules!
use_react_native!(
@@ -23,7 +23,7 @@ target 'minibits_wallet_075' do
:app_path => "#{Pod::Config.instance.installation_root}/.."
)
- target 'minibits_wallet_075Tests' do
+ target 'minibits_walletTests' do
inherit! :complete
# Pods for testing
end
diff --git a/ios/minibits_wallet_075.xcodeproj/project.pbxproj b/ios/minibits_wallet_075.xcodeproj/project.pbxproj
index 26d3350..35e7823 100644
--- a/ios/minibits_wallet_075.xcodeproj/project.pbxproj
+++ b/ios/minibits_wallet_075.xcodeproj/project.pbxproj
@@ -7,12 +7,12 @@
objects = {
/* Begin PBXBuildFile section */
- 00E356F31AD99517003FC87E /* minibits_wallet_075Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* minibits_wallet_075Tests.m */; };
- 0C80B921A6F3F58F76C31292 /* libPods-minibits_wallet_075.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-minibits_wallet_075.a */; };
+ 00E356F31AD99517003FC87E /* minibits_walletTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* minibits_walletTests.m */; };
+ 0C80B921A6F3F58F76C31292 /* libPods-minibits_wallet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-minibits_wallet.a */; };
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
- 7699B88040F8A987B510C191 /* libPods-minibits_wallet_075-minibits_wallet_075Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-minibits_wallet_075-minibits_wallet_075Tests.a */; };
+ 7699B88040F8A987B510C191 /* libPods-minibits_wallet-minibits_walletTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-minibits_wallet-minibits_walletTests.a */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
@@ -22,28 +22,28 @@
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
- remoteInfo = minibits_wallet_075;
+ remoteInfo = minibits_wallet;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
- 00E356EE1AD99517003FC87E /* minibits_wallet_075Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = minibits_wallet_075Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 00E356EE1AD99517003FC87E /* minibits_walletTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = minibits_walletTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- 00E356F21AD99517003FC87E /* minibits_wallet_075Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = minibits_wallet_075Tests.m; sourceTree = ""; };
- 13B07F961A680F5B00A75B9A /* minibits_wallet_075.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = minibits_wallet_075.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = minibits_wallet_075/AppDelegate.h; sourceTree = ""; };
- 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = minibits_wallet_075/AppDelegate.mm; sourceTree = ""; };
- 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = minibits_wallet_075/Images.xcassets; sourceTree = ""; };
- 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = minibits_wallet_075/Info.plist; sourceTree = ""; };
- 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = minibits_wallet_075/main.m; sourceTree = ""; };
- 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = minibits_wallet_075/PrivacyInfo.xcprivacy; sourceTree = ""; };
- 19F6CBCC0A4E27FBF8BF4A61 /* libPods-minibits_wallet_075-minibits_wallet_075Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-minibits_wallet_075-minibits_wallet_075Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
- 3B4392A12AC88292D35C810B /* Pods-minibits_wallet_075.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-minibits_wallet_075.debug.xcconfig"; path = "Target Support Files/Pods-minibits_wallet_075/Pods-minibits_wallet_075.debug.xcconfig"; sourceTree = ""; };
- 5709B34CF0A7D63546082F79 /* Pods-minibits_wallet_075.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-minibits_wallet_075.release.xcconfig"; path = "Target Support Files/Pods-minibits_wallet_075/Pods-minibits_wallet_075.release.xcconfig"; sourceTree = ""; };
- 5B7EB9410499542E8C5724F5 /* Pods-minibits_wallet_075-minibits_wallet_075Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-minibits_wallet_075-minibits_wallet_075Tests.debug.xcconfig"; path = "Target Support Files/Pods-minibits_wallet_075-minibits_wallet_075Tests/Pods-minibits_wallet_075-minibits_wallet_075Tests.debug.xcconfig"; sourceTree = ""; };
- 5DCACB8F33CDC322A6C60F78 /* libPods-minibits_wallet_075.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-minibits_wallet_075.a"; sourceTree = BUILT_PRODUCTS_DIR; };
- 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = minibits_wallet_075/LaunchScreen.storyboard; sourceTree = ""; };
- 89C6BE57DB24E9ADA2F236DE /* Pods-minibits_wallet_075-minibits_wallet_075Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-minibits_wallet_075-minibits_wallet_075Tests.release.xcconfig"; path = "Target Support Files/Pods-minibits_wallet_075-minibits_wallet_075Tests/Pods-minibits_wallet_075-minibits_wallet_075Tests.release.xcconfig"; sourceTree = ""; };
+ 00E356F21AD99517003FC87E /* minibits_walletTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = minibits_walletTests.m; sourceTree = ""; };
+ 13B07F961A680F5B00A75B9A /* minibits_wallet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = minibits_wallet.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = minibits_wallet/AppDelegate.h; sourceTree = ""; };
+ 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = minibits_wallet/AppDelegate.mm; sourceTree = ""; };
+ 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = minibits_wallet/Images.xcassets; sourceTree = ""; };
+ 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = minibits_wallet/Info.plist; sourceTree = ""; };
+ 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = minibits_wallet/main.m; sourceTree = ""; };
+ 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = minibits_wallet/PrivacyInfo.xcprivacy; sourceTree = ""; };
+ 19F6CBCC0A4E27FBF8BF4A61 /* libPods-minibits_wallet-minibits_walletTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-minibits_wallet-minibits_walletTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 3B4392A12AC88292D35C810B /* Pods-minibits_wallet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-minibits_wallet.debug.xcconfig"; path = "Target Support Files/Pods-minibits_wallet/Pods-minibits_wallet.debug.xcconfig"; sourceTree = ""; };
+ 5709B34CF0A7D63546082F79 /* Pods-minibits_wallet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-minibits_wallet.release.xcconfig"; path = "Target Support Files/Pods-minibits_wallet/Pods-minibits_wallet.release.xcconfig"; sourceTree = ""; };
+ 5B7EB9410499542E8C5724F5 /* Pods-minibits_wallet-minibits_walletTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-minibits_wallet-minibits_walletTests.debug.xcconfig"; path = "Target Support Files/Pods-minibits_wallet-minibits_walletTests/Pods-minibits_wallet-minibits_walletTests.debug.xcconfig"; sourceTree = ""; };
+ 5DCACB8F33CDC322A6C60F78 /* libPods-minibits_wallet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-minibits_wallet.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = minibits_wallet/LaunchScreen.storyboard; sourceTree = ""; };
+ 89C6BE57DB24E9ADA2F236DE /* Pods-minibits_wallet-minibits_walletTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-minibits_wallet-minibits_walletTests.release.xcconfig"; path = "Target Support Files/Pods-minibits_wallet-minibits_walletTests/Pods-minibits_wallet-minibits_walletTests.release.xcconfig"; sourceTree = ""; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
@@ -52,7 +52,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 7699B88040F8A987B510C191 /* libPods-minibits_wallet_075-minibits_wallet_075Tests.a in Frameworks */,
+ 7699B88040F8A987B510C191 /* libPods-minibits_wallet-minibits_walletTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -60,20 +60,20 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 0C80B921A6F3F58F76C31292 /* libPods-minibits_wallet_075.a in Frameworks */,
+ 0C80B921A6F3F58F76C31292 /* libPods-minibits_wallet.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
- 00E356EF1AD99517003FC87E /* minibits_wallet_075Tests */ = {
+ 00E356EF1AD99517003FC87E /* minibits_walletTests */ = {
isa = PBXGroup;
children = (
- 00E356F21AD99517003FC87E /* minibits_wallet_075Tests.m */,
+ 00E356F21AD99517003FC87E /* minibits_walletTests.m */,
00E356F01AD99517003FC87E /* Supporting Files */,
);
- path = minibits_wallet_075Tests;
+ path = minibits_walletTests;
sourceTree = "";
};
00E356F01AD99517003FC87E /* Supporting Files */ = {
@@ -84,7 +84,7 @@
name = "Supporting Files";
sourceTree = "";
};
- 13B07FAE1A68108700A75B9A /* minibits_wallet_075 */ = {
+ 13B07FAE1A68108700A75B9A /* minibits_wallet */ = {
isa = PBXGroup;
children = (
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
@@ -95,15 +95,15 @@
13B07FB71A68108700A75B9A /* main.m */,
13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */,
);
- name = minibits_wallet_075;
+ name = minibits_wallet;
sourceTree = "";
};
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
isa = PBXGroup;
children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
- 5DCACB8F33CDC322A6C60F78 /* libPods-minibits_wallet_075.a */,
- 19F6CBCC0A4E27FBF8BF4A61 /* libPods-minibits_wallet_075-minibits_wallet_075Tests.a */,
+ 5DCACB8F33CDC322A6C60F78 /* libPods-minibits_wallet.a */,
+ 19F6CBCC0A4E27FBF8BF4A61 /* libPods-minibits_wallet-minibits_walletTests.a */,
);
name = Frameworks;
sourceTree = "";
@@ -118,9 +118,9 @@
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
- 13B07FAE1A68108700A75B9A /* minibits_wallet_075 */,
+ 13B07FAE1A68108700A75B9A /* minibits_wallet */,
832341AE1AAA6A7D00B99B32 /* Libraries */,
- 00E356EF1AD99517003FC87E /* minibits_wallet_075Tests */,
+ 00E356EF1AD99517003FC87E /* minibits_walletTests */,
83CBBA001A601CBA00E9B192 /* Products */,
2D16E6871FA4F8E400B85C8A /* Frameworks */,
BBD78D7AC51CEA395F1C20DB /* Pods */,
@@ -133,8 +133,8 @@
83CBBA001A601CBA00E9B192 /* Products */ = {
isa = PBXGroup;
children = (
- 13B07F961A680F5B00A75B9A /* minibits_wallet_075.app */,
- 00E356EE1AD99517003FC87E /* minibits_wallet_075Tests.xctest */,
+ 13B07F961A680F5B00A75B9A /* minibits_wallet.app */,
+ 00E356EE1AD99517003FC87E /* minibits_walletTests.xctest */,
);
name = Products;
sourceTree = "";
@@ -142,10 +142,10 @@
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
isa = PBXGroup;
children = (
- 3B4392A12AC88292D35C810B /* Pods-minibits_wallet_075.debug.xcconfig */,
- 5709B34CF0A7D63546082F79 /* Pods-minibits_wallet_075.release.xcconfig */,
- 5B7EB9410499542E8C5724F5 /* Pods-minibits_wallet_075-minibits_wallet_075Tests.debug.xcconfig */,
- 89C6BE57DB24E9ADA2F236DE /* Pods-minibits_wallet_075-minibits_wallet_075Tests.release.xcconfig */,
+ 3B4392A12AC88292D35C810B /* Pods-minibits_wallet.debug.xcconfig */,
+ 5709B34CF0A7D63546082F79 /* Pods-minibits_wallet.release.xcconfig */,
+ 5B7EB9410499542E8C5724F5 /* Pods-minibits_wallet-minibits_walletTests.debug.xcconfig */,
+ 89C6BE57DB24E9ADA2F236DE /* Pods-minibits_wallet-minibits_walletTests.release.xcconfig */,
);
path = Pods;
sourceTree = "";
@@ -153,9 +153,9 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
- 00E356ED1AD99517003FC87E /* minibits_wallet_075Tests */ = {
+ 00E356ED1AD99517003FC87E /* minibits_walletTests */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "minibits_wallet_075Tests" */;
+ buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "minibits_walletTests" */;
buildPhases = (
A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */,
00E356EA1AD99517003FC87E /* Sources */,
@@ -169,14 +169,14 @@
dependencies = (
00E356F51AD99517003FC87E /* PBXTargetDependency */,
);
- name = minibits_wallet_075Tests;
- productName = minibits_wallet_075Tests;
- productReference = 00E356EE1AD99517003FC87E /* minibits_wallet_075Tests.xctest */;
+ name = minibits_walletTests;
+ productName = minibits_walletTests;
+ productReference = 00E356EE1AD99517003FC87E /* minibits_walletTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
- 13B07F861A680F5B00A75B9A /* minibits_wallet_075 */ = {
+ 13B07F861A680F5B00A75B9A /* minibits_wallet */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "minibits_wallet_075" */;
+ buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "minibits_wallet" */;
buildPhases = (
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */,
13B07F871A680F5B00A75B9A /* Sources */,
@@ -190,9 +190,9 @@
);
dependencies = (
);
- name = minibits_wallet_075;
- productName = minibits_wallet_075;
- productReference = 13B07F961A680F5B00A75B9A /* minibits_wallet_075.app */;
+ name = minibits_wallet;
+ productName = minibits_wallet;
+ productReference = 13B07F961A680F5B00A75B9A /* minibits_wallet.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
@@ -212,7 +212,7 @@
};
};
};
- buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "minibits_wallet_075" */;
+ buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "minibits_wallet" */;
compatibilityVersion = "Xcode 12.0";
developmentRegion = en;
hasScannedForEncodings = 0;
@@ -225,8 +225,8 @@
projectDirPath = "";
projectRoot = "";
targets = (
- 13B07F861A680F5B00A75B9A /* minibits_wallet_075 */,
- 00E356ED1AD99517003FC87E /* minibits_wallet_075Tests */,
+ 13B07F861A680F5B00A75B9A /* minibits_wallet */,
+ 00E356ED1AD99517003FC87E /* minibits_walletTests */,
);
};
/* End PBXProject section */
@@ -273,15 +273,15 @@
files = (
);
inputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet_075/Pods-minibits_wallet_075-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet/Pods-minibits_wallet-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet_075/Pods-minibits_wallet_075-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet/Pods-minibits_wallet-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-minibits_wallet_075/Pods-minibits_wallet_075-frameworks.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-minibits_wallet/Pods-minibits_wallet-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = {
@@ -299,7 +299,7 @@
outputFileListPaths = (
);
outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-minibits_wallet_075-minibits_wallet_075Tests-checkManifestLockResult.txt",
+ "$(DERIVED_FILE_DIR)/Pods-minibits_wallet-minibits_walletTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@@ -321,7 +321,7 @@
outputFileListPaths = (
);
outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-minibits_wallet_075-checkManifestLockResult.txt",
+ "$(DERIVED_FILE_DIR)/Pods-minibits_wallet-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@@ -334,15 +334,15 @@
files = (
);
inputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet_075-minibits_wallet_075Tests/Pods-minibits_wallet_075-minibits_wallet_075Tests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet-minibits_walletTests/Pods-minibits_wallet-minibits_walletTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet_075-minibits_wallet_075Tests/Pods-minibits_wallet_075-minibits_wallet_075Tests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet-minibits_walletTests/Pods-minibits_wallet-minibits_walletTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-minibits_wallet_075-minibits_wallet_075Tests/Pods-minibits_wallet_075-minibits_wallet_075Tests-frameworks.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-minibits_wallet-minibits_walletTests/Pods-minibits_wallet-minibits_walletTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = {
@@ -351,15 +351,15 @@
files = (
);
inputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet_075/Pods-minibits_wallet_075-resources-${CONFIGURATION}-input-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet/Pods-minibits_wallet-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet_075/Pods-minibits_wallet_075-resources-${CONFIGURATION}-output-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet/Pods-minibits_wallet-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-minibits_wallet_075/Pods-minibits_wallet_075-resources.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-minibits_wallet/Pods-minibits_wallet-resources.sh\"\n";
showEnvVarsInLog = 0;
};
F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */ = {
@@ -368,15 +368,15 @@
files = (
);
inputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet_075-minibits_wallet_075Tests/Pods-minibits_wallet_075-minibits_wallet_075Tests-resources-${CONFIGURATION}-input-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet-minibits_walletTests/Pods-minibits_wallet-minibits_walletTests-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet_075-minibits_wallet_075Tests/Pods-minibits_wallet_075-minibits_wallet_075Tests-resources-${CONFIGURATION}-output-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-minibits_wallet-minibits_walletTests/Pods-minibits_wallet-minibits_walletTests-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-minibits_wallet_075-minibits_wallet_075Tests/Pods-minibits_wallet_075-minibits_wallet_075Tests-resources.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-minibits_wallet-minibits_walletTests/Pods-minibits_wallet-minibits_walletTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@@ -386,7 +386,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 00E356F31AD99517003FC87E /* minibits_wallet_075Tests.m in Sources */,
+ 00E356F31AD99517003FC87E /* minibits_walletTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -404,7 +404,7 @@
/* Begin PBXTargetDependency section */
00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- target = 13B07F861A680F5B00A75B9A /* minibits_wallet_075 */;
+ target = 13B07F861A680F5B00A75B9A /* minibits_wallet */;
targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
@@ -412,14 +412,14 @@
/* Begin XCBuildConfiguration section */
00E356F61AD99517003FC87E /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-minibits_wallet_075-minibits_wallet_075Tests.debug.xcconfig */;
+ baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-minibits_wallet-minibits_walletTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
- INFOPLIST_FILE = minibits_wallet_075Tests/Info.plist;
+ INFOPLIST_FILE = minibits_walletTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -433,17 +433,17 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
- TEST_HOST = "$(BUILT_PRODUCTS_DIR)/minibits_wallet_075.app/minibits_wallet_075";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/minibits_wallet.app/minibits_wallet";
};
name = Debug;
};
00E356F71AD99517003FC87E /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-minibits_wallet_075-minibits_wallet_075Tests.release.xcconfig */;
+ baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-minibits_wallet-minibits_walletTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
COPY_PHASE_STRIP = NO;
- INFOPLIST_FILE = minibits_wallet_075Tests/Info.plist;
+ INFOPLIST_FILE = minibits_walletTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -457,19 +457,19 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
- TEST_HOST = "$(BUILT_PRODUCTS_DIR)/minibits_wallet_075.app/minibits_wallet_075";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/minibits_wallet.app/minibits_wallet";
};
name = Release;
};
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-minibits_wallet_075.debug.xcconfig */;
+ baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-minibits_wallet.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
ENABLE_BITCODE = NO;
- INFOPLIST_FILE = minibits_wallet_075/Info.plist;
+ INFOPLIST_FILE = minibits_wallet/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -481,7 +481,7 @@
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
- PRODUCT_NAME = minibits_wallet_075;
+ PRODUCT_NAME = minibits_wallet;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
@@ -490,12 +490,12 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-minibits_wallet_075.release.xcconfig */;
+ baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-minibits_wallet.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
- INFOPLIST_FILE = minibits_wallet_075/Info.plist;
+ INFOPLIST_FILE = minibits_wallet/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -507,7 +507,7 @@
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
- PRODUCT_NAME = minibits_wallet_075;
+ PRODUCT_NAME = minibits_wallet;
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
@@ -655,7 +655,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
- 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "minibits_wallet_075Tests" */ = {
+ 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "minibits_walletTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
00E356F61AD99517003FC87E /* Debug */,
@@ -664,7 +664,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "minibits_wallet_075" */ = {
+ 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "minibits_wallet" */ = {
isa = XCConfigurationList;
buildConfigurations = (
13B07F941A680F5B00A75B9A /* Debug */,
@@ -673,7 +673,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "minibits_wallet_075" */ = {
+ 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "minibits_wallet" */ = {
isa = XCConfigurationList;
buildConfigurations = (
83CBBA201A601CBA00E9B192 /* Debug */,
diff --git a/ios/minibits_wallet_075.xcodeproj/xcshareddata/xcschemes/minibits_wallet_075.xcscheme b/ios/minibits_wallet_075.xcodeproj/xcshareddata/xcschemes/minibits_wallet_075.xcscheme
index d6cc9a8..60e6339 100644
--- a/ios/minibits_wallet_075.xcodeproj/xcshareddata/xcschemes/minibits_wallet_075.xcscheme
+++ b/ios/minibits_wallet_075.xcodeproj/xcshareddata/xcschemes/minibits_wallet_075.xcscheme
@@ -15,9 +15,9 @@
+ BuildableName = "minibits_wallet.app"
+ BlueprintName = "minibits_wallet"
+ ReferencedContainer = "container:minibits_wallet.xcodeproj">
@@ -33,9 +33,9 @@
+ BuildableName = "minibits_walletTests.xctest"
+ BlueprintName = "minibits_walletTests"
+ ReferencedContainer = "container:minibits_wallet.xcodeproj">
@@ -55,9 +55,9 @@
+ BuildableName = "minibits_wallet.app"
+ BlueprintName = "minibits_wallet"
+ ReferencedContainer = "container:minibits_wallet.xcodeproj">
@@ -72,9 +72,9 @@
+ BuildableName = "minibits_wallet.app"
+ BlueprintName = "minibits_wallet"
+ ReferencedContainer = "container:minibits_wallet.xcodeproj">
diff --git a/ios/minibits_wallet_075/AppDelegate.mm b/ios/minibits_wallet_075/AppDelegate.mm
index ba35abf..13edb71 100644
--- a/ios/minibits_wallet_075/AppDelegate.mm
+++ b/ios/minibits_wallet_075/AppDelegate.mm
@@ -6,7 +6,7 @@
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
- self.moduleName = @"minibits_wallet_075";
+ self.moduleName = @"minibits_wallet";
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
diff --git a/ios/minibits_wallet_075/Info.plist b/ios/minibits_wallet_075/Info.plist
index ec18664..ce13e9b 100644
--- a/ios/minibits_wallet_075/Info.plist
+++ b/ios/minibits_wallet_075/Info.plist
@@ -5,7 +5,7 @@
CFBundleDevelopmentRegion
en
CFBundleDisplayName
- minibits_wallet_075
+ minibits_wallet
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
diff --git a/ios/minibits_wallet_075/LaunchScreen.storyboard b/ios/minibits_wallet_075/LaunchScreen.storyboard
index f0faf3f..d54b0e7 100644
--- a/ios/minibits_wallet_075/LaunchScreen.storyboard
+++ b/ios/minibits_wallet_075/LaunchScreen.storyboard
@@ -16,7 +16,7 @@
-