mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-03-25 08:39:06 +00:00
Merge branch 'main' of https://github.com/cake-tech/cake_wallet into mweb-bg-sync-2
This commit is contained in:
commit
a032d86653
325 changed files with 6634 additions and 2578 deletions
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
|
@ -4,7 +4,7 @@ contact_links:
|
||||||
url: https://github.com/cake-tech/cake_wallet/discussions/new?category=feature-requests
|
url: https://github.com/cake-tech/cake_wallet/discussions/new?category=feature-requests
|
||||||
about: Suggest an idea for Cake Wallet
|
about: Suggest an idea for Cake Wallet
|
||||||
- name: Not sure where to start?
|
- name: Not sure where to start?
|
||||||
url: https://guides.cakewallet.com
|
url: https://docs.cakewallet.com
|
||||||
about: Start by reading checking out the guides!
|
about: Start by reading checking out the guides!
|
||||||
- name: Need help?
|
- name: Need help?
|
||||||
url: https://cakewallet.com/#contact
|
url: https://cakewallet.com/#contact
|
||||||
|
|
298
.github/workflows/automated_integration_test.yml
vendored
Normal file
298
.github/workflows/automated_integration_test.yml
vendored
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
name: Automated Integration Tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
# pull_request:
|
||||||
|
# branches: [main, CW-659-Transaction-History-Automated-Tests]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
branch:
|
||||||
|
description: "Branch name to build"
|
||||||
|
required: true
|
||||||
|
default: "main"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Automated_integration_test:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
api-level: [29]
|
||||||
|
# arch: [x86, x86_64]
|
||||||
|
env:
|
||||||
|
STORE_PASS: test@cake_wallet
|
||||||
|
KEY_PASS: test@cake_wallet
|
||||||
|
PR_NUMBER: ${{ github.event.number }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: is pr
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
run: echo "BRANCH_NAME=${GITHUB_HEAD_REF}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: is not pr
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
run: echo "BRANCH_NAME=${{ github.event.inputs.branch }}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Free Disk Space (Ubuntu)
|
||||||
|
uses: insightsengineering/disk-space-reclaimer@v1
|
||||||
|
with:
|
||||||
|
tools-cache: true
|
||||||
|
android: false
|
||||||
|
dotnet: true
|
||||||
|
haskell: true
|
||||||
|
large-packages: true
|
||||||
|
swap-storage: true
|
||||||
|
docker-images: true
|
||||||
|
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
distribution: "temurin"
|
||||||
|
java-version: "17"
|
||||||
|
- name: Configure placeholder git details
|
||||||
|
run: |
|
||||||
|
git config --global user.email "CI@cakewallet.com"
|
||||||
|
git config --global user.name "Cake Github Actions"
|
||||||
|
- name: Flutter action
|
||||||
|
uses: subosito/flutter-action@v1
|
||||||
|
with:
|
||||||
|
flutter-version: "3.24.0"
|
||||||
|
channel: stable
|
||||||
|
|
||||||
|
- name: Install package dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt update
|
||||||
|
sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
|
||||||
|
|
||||||
|
- name: Execute Build and Setup Commands
|
||||||
|
run: |
|
||||||
|
sudo mkdir -p /opt/android
|
||||||
|
sudo chown $USER /opt/android
|
||||||
|
cd /opt/android
|
||||||
|
-y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||||
|
cargo install cargo-ndk
|
||||||
|
git clone https://github.com/cake-tech/cake_wallet.git --branch ${{ env.BRANCH_NAME }}
|
||||||
|
cd cake_wallet/scripts/android/
|
||||||
|
./install_ndk.sh
|
||||||
|
source ./app_env.sh cakewallet
|
||||||
|
chmod +x pubspec_gen.sh
|
||||||
|
./app_config.sh
|
||||||
|
|
||||||
|
- name: Cache Externals
|
||||||
|
id: cache-externals
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
/opt/android/cake_wallet/cw_haven/android/.cxx
|
||||||
|
/opt/android/cake_wallet/scripts/monero_c/release
|
||||||
|
key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
|
||||||
|
|
||||||
|
- if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
|
||||||
|
name: Generate Externals
|
||||||
|
run: |
|
||||||
|
cd /opt/android/cake_wallet/scripts/android/
|
||||||
|
source ./app_env.sh cakewallet
|
||||||
|
./build_monero_all.sh
|
||||||
|
|
||||||
|
- name: Install Flutter dependencies
|
||||||
|
run: |
|
||||||
|
cd /opt/android/cake_wallet
|
||||||
|
flutter pub get
|
||||||
|
|
||||||
|
|
||||||
|
- name: Install go and gomobile
|
||||||
|
run: |
|
||||||
|
# install go > 1.23:
|
||||||
|
wget https://go.dev/dl/go1.23.1.linux-amd64.tar.gz
|
||||||
|
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz
|
||||||
|
export PATH=$PATH:/usr/local/go/bin
|
||||||
|
export PATH=$PATH:~/go/bin
|
||||||
|
go install golang.org/x/mobile/cmd/gomobile@latest
|
||||||
|
gomobile init
|
||||||
|
|
||||||
|
- name: Build mwebd
|
||||||
|
run: |
|
||||||
|
# paths are reset after each step, so we need to set them again:
|
||||||
|
export PATH=$PATH:/usr/local/go/bin
|
||||||
|
export PATH=$PATH:~/go/bin
|
||||||
|
cd /opt/android/cake_wallet/scripts/android/
|
||||||
|
./build_mwebd.sh --dont-install
|
||||||
|
|
||||||
|
- name: Generate KeyStore
|
||||||
|
run: |
|
||||||
|
cd /opt/android/cake_wallet/android/app
|
||||||
|
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS
|
||||||
|
|
||||||
|
- name: Generate key properties
|
||||||
|
run: |
|
||||||
|
cd /opt/android/cake_wallet
|
||||||
|
flutter packages pub run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS
|
||||||
|
|
||||||
|
- name: Generate localization
|
||||||
|
run: |
|
||||||
|
cd /opt/android/cake_wallet
|
||||||
|
flutter packages pub run tool/generate_localization.dart
|
||||||
|
|
||||||
|
- name: Build generated code
|
||||||
|
run: |
|
||||||
|
cd /opt/android/cake_wallet
|
||||||
|
./model_generator.sh
|
||||||
|
|
||||||
|
- name: Add secrets
|
||||||
|
run: |
|
||||||
|
cd /opt/android/cake_wallet
|
||||||
|
touch lib/.secrets.g.dart
|
||||||
|
touch cw_evm/lib/.secrets.g.dart
|
||||||
|
touch cw_solana/lib/.secrets.g.dart
|
||||||
|
touch cw_core/lib/.secrets.g.dart
|
||||||
|
touch cw_nano/lib/.secrets.g.dart
|
||||||
|
touch cw_tron/lib/.secrets.g.dart
|
||||||
|
echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
|
||||||
|
echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const changeNowApiKeyDesktop = '${{ secrets.CHANGE_NOW_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const simpleSwapApiKeyDesktop = '${{ secrets.SIMPLE_SWAP_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const twitterBearerToken = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const trocadorApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const trocadorExchangeMarkup = '${{ secrets.TROCADOR_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const anonPayReferralCode = '${{ secrets.ANON_PAY_REFERRAL_CODE }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
|
||||||
|
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
|
||||||
|
echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const exchangeHelperApiKey = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
|
||||||
|
echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
|
||||||
|
echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
|
||||||
|
echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
|
||||||
|
echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
|
||||||
|
echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
|
||||||
|
echo "const meldTestApiKey = '${{ secrets.MELD_TEST_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const meldTestPublicKey = '${{ secrets.MELD_TEST_PUBLIC_KEY}}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const letsExchangeBearerToken = '${{ secrets.LETS_EXCHANGE_TOKEN }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const letsExchangeAffiliateId = '${{ secrets.LETS_EXCHANGE_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const stealthExBearerToken = '${{ secrets.STEALTH_EX_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const stealthExAdditionalFeePercent = '${{ secrets.STEALTH_EX_ADDITIONAL_FEE_PERCENT }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const moneroTestWalletSeeds ='${{ secrets.MONERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const moneroLegacyTestWalletSeeds = '${{ secrets.MONERO_LEGACY_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const bitcoinTestWalletSeeds = '${{ secrets.BITCOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const ethereumTestWalletSeeds = '${{ secrets.ETHEREUM_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const litecoinTestWalletSeeds = '${{ secrets.LITECOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const bitcoinCashTestWalletSeeds = '${{ secrets.BITCOIN_CASH_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const polygonTestWalletSeeds = '${{ secrets.POLYGON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const solanaTestWalletSeeds = '${{ secrets.SOLANA_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const tronTestWalletSeeds = '${{ secrets.TRON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const nanoTestWalletSeeds = '${{ secrets.NANO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const wowneroTestWalletSeeds = '${{ secrets.WOWNERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const moneroTestWalletReceiveAddress = '${{ secrets.MONERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const bitcoinTestWalletReceiveAddress = '${{ secrets.BITCOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const ethereumTestWalletReceiveAddress = '${{ secrets.ETHEREUM_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const litecoinTestWalletReceiveAddress = '${{ secrets.LITECOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const bitcoinCashTestWalletReceiveAddress = '${{ secrets.BITCOIN_CASH_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const polygonTestWalletReceiveAddress = '${{ secrets.POLYGON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const solanaTestWalletReceiveAddress = '${{ secrets.SOLANA_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const tronTestWalletReceiveAddress = '${{ secrets.TRON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const nanoTestWalletReceiveAddress = '${{ secrets.NANO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const wowneroTestWalletReceiveAddress = '${{ secrets.WOWNERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const moneroTestWalletBlockHeight = '${{ secrets.MONERO_TEST_WALLET_BLOCK_HEIGHT }}';" >> lib/.secrets.g.dart
|
||||||
|
|
||||||
|
- name: Rename app
|
||||||
|
run: |
|
||||||
|
echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cd /opt/android/cake_wallet
|
||||||
|
flutter build apk --release --split-per-abi
|
||||||
|
|
||||||
|
# - name: Rename apk file
|
||||||
|
# run: |
|
||||||
|
# cd /opt/android/cake_wallet/build/app/outputs/flutter-apk
|
||||||
|
# mkdir test-apk
|
||||||
|
# cp app-arm64-v8a-release.apk test-apk/${{env.BRANCH_NAME}}.apk
|
||||||
|
# cp app-x86_64-release.apk test-apk/${{env.BRANCH_NAME}}_x86.apk
|
||||||
|
|
||||||
|
# - name: Upload Artifact
|
||||||
|
# uses: kittaakos/upload-artifact-as-is@v0
|
||||||
|
# with:
|
||||||
|
# path: /opt/android/cake_wallet/build/app/outputs/flutter-apk/test-apk/
|
||||||
|
|
||||||
|
# - name: Send Test APK
|
||||||
|
# continue-on-error: true
|
||||||
|
# uses: adrey/slack-file-upload-action@1.0.5
|
||||||
|
# with:
|
||||||
|
# token: ${{ secrets.SLACK_APP_TOKEN }}
|
||||||
|
# path: /opt/android/cake_wallet/build/app/outputs/flutter-apk/test-apk/${{env.BRANCH_NAME}}.apk
|
||||||
|
# channel: ${{ secrets.SLACK_APK_CHANNEL }}
|
||||||
|
# title: "${{ env.BRANCH_NAME }}.apk"
|
||||||
|
# filename: ${{ env.BRANCH_NAME }}.apk
|
||||||
|
# initial_comment: ${{ github.event.head_commit.message }}
|
||||||
|
|
||||||
|
- name: 🦾 Enable KVM
|
||||||
|
run: |
|
||||||
|
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||||
|
sudo udevadm control --reload-rules
|
||||||
|
sudo udevadm trigger --name-match=kvm
|
||||||
|
|
||||||
|
- name: 🦾 Cache gradle
|
||||||
|
uses: gradle/actions/setup-gradle@v3
|
||||||
|
|
||||||
|
- name: 🦾 Cache AVD
|
||||||
|
uses: actions/cache@v4
|
||||||
|
id: avd-cache
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.android/avd/*
|
||||||
|
~/.android/adb*
|
||||||
|
key: avd-${{ matrix.api-level }}
|
||||||
|
|
||||||
|
- name: 🦾 Create AVD and generate snapshot for caching
|
||||||
|
if: steps.avd-cache.outputs.cache-hit != 'true'
|
||||||
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
|
with:
|
||||||
|
api-level: ${{ matrix.api-level }}
|
||||||
|
force-avd-creation: false
|
||||||
|
# arch: ${{ matrix.arch }}
|
||||||
|
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||||
|
working-directory: /opt/android/cake_wallet
|
||||||
|
disable-animations: false
|
||||||
|
script: echo "Generated AVD snapshot for caching."
|
||||||
|
|
||||||
|
- name: 🚀 Integration tests on Android Emulator
|
||||||
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
|
with:
|
||||||
|
api-level: ${{ matrix.api-level }}
|
||||||
|
force-avd-creation: false
|
||||||
|
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||||
|
disable-animations: true
|
||||||
|
working-directory: /opt/android/cake_wallet
|
||||||
|
script: |
|
||||||
|
chmod a+rx integration_test_runner.sh
|
||||||
|
./integration_test_runner.sh
|
7
.github/workflows/cache_dependencies.yml
vendored
7
.github/workflows/cache_dependencies.yml
vendored
|
@ -34,7 +34,7 @@ jobs:
|
||||||
- name: Flutter action
|
- name: Flutter action
|
||||||
uses: subosito/flutter-action@v1
|
uses: subosito/flutter-action@v1
|
||||||
with:
|
with:
|
||||||
flutter-version: "3.19.6"
|
flutter-version: "3.24.4"
|
||||||
channel: stable
|
channel: stable
|
||||||
|
|
||||||
- name: Install package dependencies
|
- name: Install package dependencies
|
||||||
|
@ -62,6 +62,7 @@ jobs:
|
||||||
/opt/android/cake_wallet/cw_haven/android/.cxx
|
/opt/android/cake_wallet/cw_haven/android/.cxx
|
||||||
/opt/android/cake_wallet/scripts/monero_c/release
|
/opt/android/cake_wallet/scripts/monero_c/release
|
||||||
key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
|
key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
|
||||||
|
|
||||||
- if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
|
- if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
|
||||||
name: Generate Externals
|
name: Generate Externals
|
||||||
run: |
|
run: |
|
||||||
|
@ -73,8 +74,8 @@ jobs:
|
||||||
id: cache-keystore
|
id: cache-keystore
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: /opt/android/cake_wallet/android/app/key.jks
|
path: /opt/android/cake_wallet/android/app
|
||||||
key: $STORE_PASS
|
key: keystore
|
||||||
|
|
||||||
- if: ${{ steps.cache-keystore.outputs.cache-hit != 'true' }}
|
- if: ${{ steps.cache-keystore.outputs.cache-hit != 'true' }}
|
||||||
name: Generate KeyStore
|
name: Generate KeyStore
|
||||||
|
|
21
.github/workflows/no_print_in_dart.yaml
vendored
Normal file
21
.github/workflows/no_print_in_dart.yaml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
name: No print statements in dart files
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
PR_test_build:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Check for print() statements in dart code (use printV() instead)
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
run: |
|
||||||
|
GIT_GREP_OUT="$(git grep ' print(' | (grep .dart: || test $? = 1) | (grep -v print_verbose.dart || test $? = 1) || true)"
|
||||||
|
[[ "x$GIT_GREP_OUT" == "x" ]] && exit 0
|
||||||
|
echo "$GIT_GREP_OUT"
|
||||||
|
echo "There are .dart files which use print() statements"
|
||||||
|
echo "Please use printV from package: cw_core/utils/print_verbose.dart"
|
||||||
|
exit 1
|
44
.github/workflows/pr_test_build_android.yml
vendored
44
.github/workflows/pr_test_build_android.yml
vendored
|
@ -53,7 +53,7 @@ jobs:
|
||||||
- name: Flutter action
|
- name: Flutter action
|
||||||
uses: subosito/flutter-action@v1
|
uses: subosito/flutter-action@v1
|
||||||
with:
|
with:
|
||||||
flutter-version: "3.19.6"
|
flutter-version: "3.24.0"
|
||||||
channel: stable
|
channel: stable
|
||||||
|
|
||||||
- name: Install package dependencies
|
- name: Install package dependencies
|
||||||
|
@ -61,14 +61,32 @@ jobs:
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
|
sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
|
||||||
|
|
||||||
- name: Execute Build and Setup Commands
|
|
||||||
|
- name: Clone Repo
|
||||||
run: |
|
run: |
|
||||||
sudo mkdir -p /opt/android
|
sudo mkdir -p /opt/android
|
||||||
sudo chown $USER /opt/android
|
sudo chown $USER /opt/android
|
||||||
|
cd /opt/android
|
||||||
|
git clone https://github.com/cake-tech/cake_wallet.git --branch ${{ env.BRANCH_NAME }}
|
||||||
|
|
||||||
|
# - name: Cache Keystore
|
||||||
|
# id: cache-keystore
|
||||||
|
# uses: actions/cache@v3
|
||||||
|
# with:
|
||||||
|
# path: /opt/android/cake_wallet/android/app
|
||||||
|
# key: keystore
|
||||||
|
#
|
||||||
|
# - if: ${{ steps.cache-keystore.outputs.cache-hit != 'true' }}
|
||||||
|
- name: Generate KeyStore
|
||||||
|
run: |
|
||||||
|
cd /opt/android/cake_wallet/android/app
|
||||||
|
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS
|
||||||
|
|
||||||
|
- name: Execute Build and Setup Commands
|
||||||
|
run: |
|
||||||
cd /opt/android
|
cd /opt/android
|
||||||
-y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
-y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||||
cargo install cargo-ndk
|
cargo install cargo-ndk
|
||||||
git clone https://github.com/cake-tech/cake_wallet.git --branch ${{ env.BRANCH_NAME }}
|
|
||||||
cd cake_wallet/scripts/android/
|
cd cake_wallet/scripts/android/
|
||||||
./install_ndk.sh
|
./install_ndk.sh
|
||||||
source ./app_env.sh cakewallet
|
source ./app_env.sh cakewallet
|
||||||
|
@ -115,28 +133,15 @@ jobs:
|
||||||
cd /opt/android/cake_wallet/scripts/android/
|
cd /opt/android/cake_wallet/scripts/android/
|
||||||
./build_mwebd.sh --dont-install
|
./build_mwebd.sh --dont-install
|
||||||
|
|
||||||
# - name: Cache Keystore
|
|
||||||
# id: cache-keystore
|
|
||||||
# uses: actions/cache@v3
|
|
||||||
# with:
|
|
||||||
# path: /opt/android/cake_wallet/android/app/key.jks
|
|
||||||
# key: $STORE_PASS
|
|
||||||
#
|
|
||||||
# - if: ${{ steps.cache-keystore.outputs.cache-hit != 'true' }}
|
|
||||||
- name: Generate KeyStore
|
|
||||||
run: |
|
|
||||||
cd /opt/android/cake_wallet/android/app
|
|
||||||
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS
|
|
||||||
|
|
||||||
- name: Generate key properties
|
- name: Generate key properties
|
||||||
run: |
|
run: |
|
||||||
cd /opt/android/cake_wallet
|
cd /opt/android/cake_wallet
|
||||||
flutter packages pub run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS
|
dart run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS
|
||||||
|
|
||||||
- name: Generate localization
|
- name: Generate localization
|
||||||
run: |
|
run: |
|
||||||
cd /opt/android/cake_wallet
|
cd /opt/android/cake_wallet
|
||||||
flutter packages pub run tool/generate_localization.dart
|
dart run tool/generate_localization.dart
|
||||||
|
|
||||||
- name: Build generated code
|
- name: Build generated code
|
||||||
run: |
|
run: |
|
||||||
|
@ -183,6 +188,7 @@ jobs:
|
||||||
echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
|
echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
|
echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
|
||||||
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
|
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
|
||||||
|
echo "const nowNodesApiKey = '${{ secrets.EVM_NOWNODES_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
|
||||||
echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
|
echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
|
||||||
echo "const exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
|
echo "const exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
|
echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
|
||||||
|
@ -201,7 +207,7 @@ jobs:
|
||||||
echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
|
echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
|
||||||
echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
|
echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
|
||||||
echo "const meldTestApiKey = '${{ secrets.MELD_TEST_API_KEY }}';" >> lib/.secrets.g.dart
|
echo "const meldTestApiKey = '${{ secrets.MELD_TEST_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
echo "const meldTestPublicKey = '${{ secrets.MELD_TEST_PUBLIC_KEY}}';" >> lib/.secrets.g.dar
|
echo "const meldTestPublicKey = '${{ secrets.MELD_TEST_PUBLIC_KEY}}';" >> lib/.secrets.g.dart
|
||||||
echo "const letsExchangeBearerToken = '${{ secrets.LETS_EXCHANGE_TOKEN }}';" >> lib/.secrets.g.dart
|
echo "const letsExchangeBearerToken = '${{ secrets.LETS_EXCHANGE_TOKEN }}';" >> lib/.secrets.g.dart
|
||||||
echo "const letsExchangeAffiliateId = '${{ secrets.LETS_EXCHANGE_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
|
echo "const letsExchangeAffiliateId = '${{ secrets.LETS_EXCHANGE_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
|
||||||
echo "const stealthExBearerToken = '${{ secrets.STEALTH_EX_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
|
echo "const stealthExBearerToken = '${{ secrets.STEALTH_EX_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
|
||||||
|
|
5
.github/workflows/pr_test_build_linux.yml
vendored
5
.github/workflows/pr_test_build_linux.yml
vendored
|
@ -38,7 +38,7 @@ jobs:
|
||||||
- name: Flutter action
|
- name: Flutter action
|
||||||
uses: subosito/flutter-action@v1
|
uses: subosito/flutter-action@v1
|
||||||
with:
|
with:
|
||||||
flutter-version: "3.19.6"
|
flutter-version: "3.24.0"
|
||||||
channel: stable
|
channel: stable
|
||||||
|
|
||||||
- name: Install package dependencies
|
- name: Install package dependencies
|
||||||
|
@ -111,7 +111,7 @@ jobs:
|
||||||
- name: Generate localization
|
- name: Generate localization
|
||||||
run: |
|
run: |
|
||||||
cd /opt/android/cake_wallet
|
cd /opt/android/cake_wallet
|
||||||
flutter packages pub run tool/generate_localization.dart
|
dart run tool/generate_localization.dart
|
||||||
|
|
||||||
- name: Build generated code
|
- name: Build generated code
|
||||||
run: |
|
run: |
|
||||||
|
@ -165,6 +165,7 @@ jobs:
|
||||||
echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart
|
echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart
|
||||||
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
|
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
|
echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
|
||||||
|
echo "const nowNodesApiKey = '${{ secrets.EVM_NOWNODES_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
|
||||||
echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
|
echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
|
||||||
echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
|
echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
|
echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
|
11
README.md
11
README.md
|
@ -99,6 +99,17 @@ Cake Wallet includes support for several cryptocurrencies, including:
|
||||||
* F-Droid: https://fdroid.cakelabs.com
|
* F-Droid: https://fdroid.cakelabs.com
|
||||||
* APK: https://github.com/cake-tech/cake_wallet/releases
|
* APK: https://github.com/cake-tech/cake_wallet/releases
|
||||||
|
|
||||||
|
### APK Verification
|
||||||
|
|
||||||
|
APK releases on GitHub, Accrescent, and F-Droid use the same key. They can easily be verified using [apksigner](https://developer.android.com/tools/apksigner#options-verify) or [AppVerifier](https://github.com/soupslurpr/AppVerifier).
|
||||||
|
|
||||||
|
See below for Cake Wallet's SHA-256 signing certificate hash:
|
||||||
|
|
||||||
|
```
|
||||||
|
com.cakewallet.cake_wallet
|
||||||
|
C5:40:53:AB:0F:10:D9:54:17:62:A3:DA:76:65:AE:3D:BA:5E:7C:74:3A:B4:F1:08:A5:34:9D:62:AC:10:6E:F5
|
||||||
|
```
|
||||||
|
|
||||||
# Support
|
# Support
|
||||||
|
|
||||||
We have 24/7 free support. Please contact support@cakewallet.com
|
We have 24/7 free support. Please contact support@cakewallet.com
|
||||||
|
|
|
@ -38,11 +38,14 @@ if (appPropertiesFile.exists()) {
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 34
|
compileSdkVersion 34
|
||||||
|
buildToolsVersion "34.0.0"
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
disable 'InvalidPackage'
|
disable 'InvalidPackage'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace "com.cakewallet.cake_wallet"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId appProperties['id']
|
applicationId appProperties['id']
|
||||||
minSdkVersion 24
|
minSdkVersion 24
|
||||||
|
@ -80,7 +83,7 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ndkVersion "25.1.8937393"
|
ndkVersion "27.0.12077973"
|
||||||
}
|
}
|
||||||
|
|
||||||
flutter {
|
flutter {
|
||||||
|
@ -96,4 +99,4 @@ configurations {
|
||||||
implementation.exclude module:'proto-google-common-protos'
|
implementation.exclude module:'proto-google-common-protos'
|
||||||
implementation.exclude module:'protolite-well-known-types'
|
implementation.exclude module:'protolite-well-known-types'
|
||||||
implementation.exclude module:'protobuf-javalite'
|
implementation.exclude module:'protobuf-javalite'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="com.cakewallet.cake_wallet">
|
|
||||||
<!-- Flutter needs it to communicate with the running application
|
<!-- Flutter needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="__APP_PACKAGE__">
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="com.cakewallet.cake_wallet">
|
|
||||||
<!-- Flutter needs it to communicate with the running application
|
<!-- Flutter needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.8.21'
|
ext.kotlin_version = '2.0.21'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.3.0'
|
classpath 'com.android.tools.build:gradle:8.7.1'
|
||||||
classpath 'com.google.gms:google-services:4.3.8'
|
classpath 'com.google.gms:google-services:4.3.8'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
org.gradle.jvmargs=-Xmx3072M
|
org.gradle.jvmargs=-Xmx4096M
|
||||||
android.enableR8=true
|
android.enableR8=true
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
-
|
|
||||||
uri: electrum.cakewallet.com:50002
|
|
||||||
useSSL: true
|
|
||||||
-
|
-
|
||||||
uri: btc-electrum.cakewallet.com:50002
|
uri: btc-electrum.cakewallet.com:50002
|
||||||
useSSL: true
|
useSSL: true
|
||||||
|
|
|
@ -6,5 +6,7 @@
|
||||||
uri: rpc.flashbots.net
|
uri: rpc.flashbots.net
|
||||||
-
|
-
|
||||||
uri: eth-mainnet.public.blastapi.io
|
uri: eth-mainnet.public.blastapi.io
|
||||||
|
-
|
||||||
|
uri: eth.nownodes.io
|
||||||
-
|
-
|
||||||
uri: ethereum.publicnode.com
|
uri: ethereum.publicnode.com
|
BIN
assets/images/discord.png
Normal file
BIN
assets/images/discord.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
assets/images/discourse.png
Normal file
BIN
assets/images/discourse.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
BIN
assets/images/seed_verified.png
Normal file
BIN
assets/images/seed_verified.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
|
@ -2,6 +2,7 @@
|
||||||
uri: xmr-node.cakewallet.com:18081
|
uri: xmr-node.cakewallet.com:18081
|
||||||
is_default: true
|
is_default: true
|
||||||
trusted: true
|
trusted: true
|
||||||
|
useSSL: true
|
||||||
-
|
-
|
||||||
uri: cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081
|
uri: cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081
|
||||||
is_default: false
|
is_default: false
|
||||||
|
|
|
@ -3,4 +3,6 @@
|
||||||
-
|
-
|
||||||
uri: polygon-bor.publicnode.com
|
uri: polygon-bor.publicnode.com
|
||||||
-
|
-
|
||||||
uri: polygon.llamarpc.com
|
uri: polygon.llamarpc.com
|
||||||
|
-
|
||||||
|
uri: matic.nownodes.io
|
|
@ -1,10 +1,10 @@
|
||||||
-
|
-
|
||||||
uri: rpc.ankr.com
|
uri: rpc.ankr.com
|
||||||
is_default: true
|
|
||||||
useSSL: true
|
useSSL: true
|
||||||
-
|
-
|
||||||
uri: api.mainnet-beta.solana.com:443
|
uri: api.mainnet-beta.solana.com:443
|
||||||
useSSL: true
|
useSSL: true
|
||||||
-
|
-
|
||||||
uri: solana-rpc.publicnode.com:443
|
uri: solana-rpc.publicnode.com:443
|
||||||
useSSL: true
|
useSSL: true
|
||||||
|
is_default: true
|
|
@ -1,3 +1,3 @@
|
||||||
Add airgapped Monero wallet support (best used with our new offline app Cupcake)
|
Support Monero Ledger
|
||||||
New Buy & Sell flow
|
Bug fixes
|
||||||
Bug fixes
|
New designs and better user experience
|
|
@ -1,5 +1,5 @@
|
||||||
Add Litecoin Ledger support
|
Support Monero Ledger
|
||||||
Add airgapped Monero wallet support (best used with our new offline app Cupcake)
|
Prepare for Haven removal
|
||||||
MWEB fixes and enhancements
|
Improve Ethereum and Polygon sending process
|
||||||
New Buy & Sell flow
|
Bug fixes
|
||||||
Bug fixes
|
New designs and better user experience
|
|
@ -4,9 +4,8 @@
|
||||||
useSSL: true
|
useSSL: true
|
||||||
-
|
-
|
||||||
uri: api.trongrid.io
|
uri: api.trongrid.io
|
||||||
is_default: false
|
is_default: true
|
||||||
useSSL: true
|
useSSL: true
|
||||||
-
|
-
|
||||||
uri: trx.nownodes.io
|
uri: trx.nownodes.io
|
||||||
is_default: true
|
|
||||||
useSSL: true
|
useSSL: true
|
|
@ -120,7 +120,7 @@ Install Flutter package dependencies with this command:
|
||||||
|
|
||||||
Your CakeWallet binary will be built with some specific keys for iterate with 3rd party services. You may generate these secret keys placeholders with the following command:
|
Your CakeWallet binary will be built with some specific keys for iterate with 3rd party services. You may generate these secret keys placeholders with the following command:
|
||||||
|
|
||||||
`$ flutter packages pub run tool/generate_new_secrets.dart`
|
`$ dart run tool/generate_new_secrets.dart`
|
||||||
|
|
||||||
We will generate mobx models for the project.
|
We will generate mobx models for the project.
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ We will generate mobx models for the project.
|
||||||
|
|
||||||
Then we need to generate localization files.
|
Then we need to generate localization files.
|
||||||
|
|
||||||
`$ flutter packages pub run tool/generate_localization.dart`
|
`$ dart run tool/generate_localization.dart`
|
||||||
|
|
||||||
### 5. Build!
|
### 5. Build!
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
set -x -e
|
||||||
IOS="ios"
|
IOS="ios"
|
||||||
ANDROID="android"
|
ANDROID="android"
|
||||||
MACOS="macos"
|
MACOS="macos"
|
||||||
|
@ -36,6 +36,6 @@ fi
|
||||||
source ./app_env.sh cakewallet
|
source ./app_env.sh cakewallet
|
||||||
./app_config.sh
|
./app_config.sh
|
||||||
cd ../.. && flutter pub get
|
cd ../.. && flutter pub get
|
||||||
flutter packages pub run tool/generate_localization.dart
|
dart run tool/generate_localization.dart
|
||||||
./model_generator.sh
|
#./model_generator.sh
|
||||||
#cd macos && pod install
|
#cd macos && pod install
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:cw_bitcoin/utils.dart';
|
||||||
import 'package:cw_core/hardware/hardware_account_data.dart';
|
import 'package:cw_core/hardware/hardware_account_data.dart';
|
||||||
import 'package:ledger_bitcoin/ledger_bitcoin.dart';
|
import 'package:ledger_bitcoin/ledger_bitcoin.dart';
|
||||||
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
|
|
||||||
class BitcoinHardwareWalletService {
|
class BitcoinHardwareWalletService {
|
||||||
BitcoinHardwareWalletService(this.ledgerConnection);
|
BitcoinHardwareWalletService(this.ledgerConnection);
|
||||||
|
|
|
@ -106,6 +106,15 @@ class BitcoinWalletService extends WalletService<
|
||||||
final walletInfo = walletInfoSource.values
|
final walletInfo = walletInfoSource.values
|
||||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
.firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
||||||
await walletInfoSource.delete(walletInfo.key);
|
await walletInfoSource.delete(walletInfo.key);
|
||||||
|
|
||||||
|
final unspentCoinsToDelete = unspentCoinsInfoSource.values.where(
|
||||||
|
(unspentCoin) => unspentCoin.walletId == walletInfo.id).toList();
|
||||||
|
|
||||||
|
final keysToDelete = unspentCoinsToDelete.map((unspentCoin) => unspentCoin.key).toList();
|
||||||
|
|
||||||
|
if (keysToDelete.isNotEmpty) {
|
||||||
|
await unspentCoinsInfoSource.deleteAll(keysToDelete);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:bitcoin_base/bitcoin_base.dart';
|
import 'package:bitcoin_base/bitcoin_base.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_amount_format.dart';
|
import 'package:cw_bitcoin/bitcoin_amount_format.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
|
|
||||||
|
@ -117,17 +118,17 @@ class ElectrumClient {
|
||||||
_parseResponse(message);
|
_parseResponse(message);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("socket.listen: $e");
|
printV("socket.listen: $e");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (Object error) {
|
onError: (Object error) {
|
||||||
final errorMsg = error.toString();
|
final errorMsg = error.toString();
|
||||||
print(errorMsg);
|
printV(errorMsg);
|
||||||
unterminatedString = '';
|
unterminatedString = '';
|
||||||
socket = null;
|
socket = null;
|
||||||
},
|
},
|
||||||
onDone: () {
|
onDone: () {
|
||||||
print("SOCKET CLOSED!!!!!");
|
printV("SOCKET CLOSED!!!!!");
|
||||||
unterminatedString = '';
|
unterminatedString = '';
|
||||||
try {
|
try {
|
||||||
if (host == socket?.address.host || socket == null) {
|
if (host == socket?.address.host || socket == null) {
|
||||||
|
@ -136,7 +137,7 @@ class ElectrumClient {
|
||||||
socket = null;
|
socket = null;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("onDone: $e");
|
printV("onDone: $e");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
cancelOnError: true,
|
cancelOnError: true,
|
||||||
|
@ -181,7 +182,7 @@ class ElectrumClient {
|
||||||
unterminatedString = '';
|
unterminatedString = '';
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("parse $e");
|
printV("parse $e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,21 +235,21 @@ class ElectrumClient {
|
||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<List<Map<String, dynamic>>> getListUnspent(String scriptHash) =>
|
Future<List<Map<String, dynamic>>> getListUnspent(String scriptHash) async {
|
||||||
call(method: 'blockchain.scripthash.listunspent', params: [scriptHash])
|
final result = await call(method: 'blockchain.scripthash.listunspent', params: [scriptHash]);
|
||||||
.then((dynamic result) {
|
|
||||||
if (result is List) {
|
|
||||||
return result.map((dynamic val) {
|
|
||||||
if (val is Map<String, dynamic>) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <String, dynamic>{};
|
if (result is List) {
|
||||||
}).toList();
|
return result.map((dynamic val) {
|
||||||
|
if (val is Map<String, dynamic>) {
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return <String, dynamic>{};
|
||||||
});
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<Map<String, dynamic>>> getMempool(String scriptHash) =>
|
Future<List<Map<String, dynamic>>> getMempool(String scriptHash) =>
|
||||||
call(method: 'blockchain.scripthash.get_mempool', params: [scriptHash])
|
call(method: 'blockchain.scripthash.get_mempool', params: [scriptHash])
|
||||||
|
@ -403,7 +404,7 @@ class ElectrumClient {
|
||||||
} on RequestFailedTimeoutException catch (_) {
|
} on RequestFailedTimeoutException catch (_) {
|
||||||
return null;
|
return null;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("getCurrentBlockChainTip: ${e.toString()}");
|
printV("getCurrentBlockChainTip: ${e.toString()}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -434,7 +435,7 @@ class ElectrumClient {
|
||||||
|
|
||||||
return subscription;
|
return subscription;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("subscribe $e");
|
printV("subscribe $e");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -473,7 +474,7 @@ class ElectrumClient {
|
||||||
|
|
||||||
return completer.future;
|
return completer.future;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("callWithTimeout $e");
|
printV("callWithTimeout $e");
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:cw_bitcoin/electrum_transaction_info.dart';
|
||||||
import 'package:cw_core/pathForWallet.dart';
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
import 'package:cw_core/transaction_history.dart';
|
import 'package:cw_core/transaction_history.dart';
|
||||||
import 'package:cw_core/utils/file.dart';
|
import 'package:cw_core/utils/file.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:cw_core/transaction_history.dart';
|
import 'package:cw_core/transaction_history.dart';
|
||||||
|
@ -30,7 +31,10 @@ abstract class ElectrumTransactionHistoryBase
|
||||||
String _password;
|
String _password;
|
||||||
int _height;
|
int _height;
|
||||||
|
|
||||||
Future<void> init() async => await _load();
|
Future<void> init() async {
|
||||||
|
clear();
|
||||||
|
await _load();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void addOne(ElectrumTransactionInfo transaction) => transactions[transaction.id] = transaction;
|
void addOne(ElectrumTransactionInfo transaction) => transactions[transaction.id] = transaction;
|
||||||
|
@ -51,7 +55,7 @@ abstract class ElectrumTransactionHistoryBase
|
||||||
final data = json.encode({'height': _height, 'transactions': txjson});
|
final data = json.encode({'height': _height, 'transactions': txjson});
|
||||||
await encryptionFileUtils.write(path: path, password: _password, data: data);
|
await encryptionFileUtils.write(path: path, password: _password, data: data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error while save bitcoin transaction history: ${e.toString()}');
|
printV('Error while save bitcoin transaction history: ${e.toString()}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +92,7 @@ abstract class ElectrumTransactionHistoryBase
|
||||||
|
|
||||||
_height = content['height'] as int;
|
_height = content['height'] as int;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
printV(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ import 'dart:io';
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
import 'package:bitcoin_base/bitcoin_base.dart';
|
import 'package:bitcoin_base/bitcoin_base.dart';
|
||||||
|
import 'package:cw_bitcoin/litecoin_wallet_addresses.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_wallet.dart';
|
import 'package:cw_bitcoin/bitcoin_wallet.dart';
|
||||||
import 'package:cw_bitcoin/litecoin_wallet.dart';
|
import 'package:cw_bitcoin/litecoin_wallet.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
@ -304,6 +306,7 @@ abstract class ElectrumWalletBase
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
await walletAddresses.init();
|
await walletAddresses.init();
|
||||||
await transactionHistory.init();
|
await transactionHistory.init();
|
||||||
|
await cleanUpDuplicateUnspentCoins();
|
||||||
await save();
|
await save();
|
||||||
|
|
||||||
_autoSaveTimer =
|
_autoSaveTimer =
|
||||||
|
@ -479,8 +482,8 @@ abstract class ElectrumWalletBase
|
||||||
syncStatus = SyncedSyncStatus();
|
syncStatus = SyncedSyncStatus();
|
||||||
}
|
}
|
||||||
} catch (e, stacktrace) {
|
} catch (e, stacktrace) {
|
||||||
print(stacktrace);
|
printV(stacktrace);
|
||||||
print("startSync $e");
|
printV("startSync $e");
|
||||||
syncStatus = FailedSyncStatus();
|
syncStatus = FailedSyncStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -500,10 +503,11 @@ abstract class ElectrumWalletBase
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> updateFeeRates() async {
|
Future<void> updateFeeRates() async {
|
||||||
if (await checkIfMempoolAPIIsEnabled()) {
|
if (await checkIfMempoolAPIIsEnabled() && type == WalletType.bitcoin) {
|
||||||
try {
|
try {
|
||||||
final response =
|
final response = await http
|
||||||
await http.get(Uri.parse("http://mempool.cakewallet.com:8999/api/v1/fees/recommended"));
|
.get(Uri.parse("https://mempool.cakewallet.com/api/v1/fees/recommended"))
|
||||||
|
.timeout(Duration(seconds: 5));
|
||||||
|
|
||||||
final result = json.decode(response.body) as Map<String, dynamic>;
|
final result = json.decode(response.body) as Map<String, dynamic>;
|
||||||
final slowFee = (result['economyFee'] as num?)?.toInt() ?? 0;
|
final slowFee = (result['economyFee'] as num?)?.toInt() ?? 0;
|
||||||
|
@ -518,7 +522,7 @@ abstract class ElectrumWalletBase
|
||||||
_feeRates = [slowFee, mediumFee, fastFee];
|
_feeRates = [slowFee, mediumFee, fastFee];
|
||||||
return;
|
return;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
printV(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,8 +613,8 @@ abstract class ElectrumWalletBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e, stacktrace) {
|
} catch (e, stacktrace) {
|
||||||
print(stacktrace);
|
printV(stacktrace);
|
||||||
print("connectToNode $e");
|
printV("connectToNode $e");
|
||||||
syncStatus = FailedSyncStatus();
|
syncStatus = FailedSyncStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1118,6 +1122,7 @@ abstract class ElectrumWalletBase
|
||||||
)..addListener((transaction) async {
|
)..addListener((transaction) async {
|
||||||
transactionHistory.addOne(transaction);
|
transactionHistory.addOne(transaction);
|
||||||
await updateBalance();
|
await updateBalance();
|
||||||
|
await updateAllUnspents();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1210,6 +1215,7 @@ abstract class ElectrumWalletBase
|
||||||
.removeWhere((utxo) => estimatedTx.utxos.any((e) => e.utxo.txHash == utxo.hash));
|
.removeWhere((utxo) => estimatedTx.utxos.any((e) => e.utxo.txHash == utxo.hash));
|
||||||
|
|
||||||
await updateBalance();
|
await updateBalance();
|
||||||
|
await updateAllUnspents();
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -1365,7 +1371,7 @@ abstract class ElectrumWalletBase
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close({required bool shouldCleanup}) async {
|
Future<void> close({bool shouldCleanup = false}) async {
|
||||||
try {
|
try {
|
||||||
await _receiveStream?.cancel();
|
await _receiveStream?.cancel();
|
||||||
await electrumClient.close();
|
await electrumClient.close();
|
||||||
|
@ -1402,9 +1408,11 @@ abstract class ElectrumWalletBase
|
||||||
|
|
||||||
unspentCoins = updatedUnspentCoins;
|
unspentCoins = updatedUnspentCoins;
|
||||||
|
|
||||||
if (unspentCoinsInfo.length != updatedUnspentCoins.length) {
|
final currentWalletUnspentCoins =
|
||||||
|
unspentCoinsInfo.values.where((element) => element.walletId == id);
|
||||||
|
|
||||||
|
if (currentWalletUnspentCoins.length != updatedUnspentCoins.length) {
|
||||||
unspentCoins.forEach((coin) => addCoinInfo(coin));
|
unspentCoins.forEach((coin) => addCoinInfo(coin));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await updateCoins(unspentCoins);
|
await updateCoins(unspentCoins);
|
||||||
|
@ -1430,6 +1438,7 @@ abstract class ElectrumWalletBase
|
||||||
coin.isFrozen = coinInfo.isFrozen;
|
coin.isFrozen = coinInfo.isFrozen;
|
||||||
coin.isSending = coinInfo.isSending;
|
coin.isSending = coinInfo.isSending;
|
||||||
coin.note = coinInfo.note;
|
coin.note = coinInfo.note;
|
||||||
|
|
||||||
if (coin.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord)
|
if (coin.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord)
|
||||||
coin.bitcoinAddressRecord.balance += coinInfo.value;
|
coin.bitcoinAddressRecord.balance += coinInfo.value;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1467,47 +1476,70 @@ abstract class ElectrumWalletBase
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> addCoinInfo(BitcoinUnspent coin) async {
|
Future<void> addCoinInfo(BitcoinUnspent coin) async {
|
||||||
final newInfo = UnspentCoinsInfo(
|
// Check if the coin is already in the unspentCoinsInfo for the wallet
|
||||||
walletId: id,
|
final existingCoinInfo = unspentCoinsInfo.values
|
||||||
hash: coin.hash,
|
.firstWhereOrNull((element) => element.walletId == walletInfo.id && element == coin);
|
||||||
isFrozen: coin.isFrozen,
|
|
||||||
isSending: coin.isSending,
|
|
||||||
noteRaw: coin.note,
|
|
||||||
address: coin.bitcoinAddressRecord.address,
|
|
||||||
value: coin.value,
|
|
||||||
vout: coin.vout,
|
|
||||||
isChange: coin.isChange,
|
|
||||||
isSilentPayment: coin is BitcoinSilentPaymentsUnspent,
|
|
||||||
);
|
|
||||||
|
|
||||||
await unspentCoinsInfo.add(newInfo);
|
if (existingCoinInfo == null) {
|
||||||
|
final newInfo = UnspentCoinsInfo(
|
||||||
|
walletId: id,
|
||||||
|
hash: coin.hash,
|
||||||
|
isFrozen: coin.isFrozen,
|
||||||
|
isSending: coin.isSending,
|
||||||
|
noteRaw: coin.note,
|
||||||
|
address: coin.bitcoinAddressRecord.address,
|
||||||
|
value: coin.value,
|
||||||
|
vout: coin.vout,
|
||||||
|
isChange: coin.isChange,
|
||||||
|
isSilentPayment: coin is BitcoinSilentPaymentsUnspent,
|
||||||
|
);
|
||||||
|
|
||||||
|
await unspentCoinsInfo.add(newInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _refreshUnspentCoinsInfo() async {
|
Future<void> _refreshUnspentCoinsInfo() async {
|
||||||
try {
|
try {
|
||||||
final List<dynamic> keys = <dynamic>[];
|
final List<dynamic> keys = [];
|
||||||
final currentWalletUnspentCoins =
|
final currentWalletUnspentCoins =
|
||||||
unspentCoinsInfo.values.where((element) => element.walletId.contains(id));
|
unspentCoinsInfo.values.where((record) => record.walletId == id);
|
||||||
|
|
||||||
if (currentWalletUnspentCoins.isNotEmpty) {
|
for (final element in currentWalletUnspentCoins) {
|
||||||
currentWalletUnspentCoins.forEach((element) {
|
if (RegexUtils.addressTypeFromStr(element.address, network) is MwebAddress) continue;
|
||||||
final existUnspentCoins = unspentCoins
|
|
||||||
.where((coin) => element.hash.contains(coin.hash) && element.vout == coin.vout);
|
|
||||||
|
|
||||||
if (existUnspentCoins.isEmpty) {
|
final existUnspentCoins = unspentCoins.where((coin) => element == coin);
|
||||||
keys.add(element.key);
|
|
||||||
}
|
if (existUnspentCoins.isEmpty) {
|
||||||
});
|
keys.add(element.key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keys.isNotEmpty) {
|
if (keys.isNotEmpty) {
|
||||||
await unspentCoinsInfo.deleteAll(keys);
|
await unspentCoinsInfo.deleteAll(keys);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("refreshUnspentCoinsInfo $e");
|
printV("refreshUnspentCoinsInfo $e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> cleanUpDuplicateUnspentCoins() async {
|
||||||
|
final currentWalletUnspentCoins =
|
||||||
|
unspentCoinsInfo.values.where((element) => element.walletId == id);
|
||||||
|
final Map<String, UnspentCoinsInfo> uniqueUnspentCoins = {};
|
||||||
|
final List<dynamic> duplicateKeys = [];
|
||||||
|
|
||||||
|
for (final unspentCoin in currentWalletUnspentCoins) {
|
||||||
|
final key = '${unspentCoin.hash}:${unspentCoin.vout}';
|
||||||
|
if (!uniqueUnspentCoins.containsKey(key)) {
|
||||||
|
uniqueUnspentCoins[key] = unspentCoin;
|
||||||
|
} else {
|
||||||
|
duplicateKeys.add(unspentCoin.key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (duplicateKeys.isNotEmpty) await unspentCoinsInfo.deleteAll(duplicateKeys);
|
||||||
|
}
|
||||||
|
|
||||||
int transactionVSize(String transactionHex) => BtcTransaction.fromRaw(transactionHex).getVSize();
|
int transactionVSize(String transactionHex) => BtcTransaction.fromRaw(transactionHex).getVSize();
|
||||||
|
|
||||||
Future<String?> canReplaceByFee(ElectrumTransactionInfo tx) async {
|
Future<String?> canReplaceByFee(ElectrumTransactionInfo tx) async {
|
||||||
|
@ -1525,14 +1557,22 @@ abstract class ElectrumWalletBase
|
||||||
final bundle = await getTransactionExpanded(hash: txId);
|
final bundle = await getTransactionExpanded(hash: txId);
|
||||||
final outputs = bundle.originalTransaction.outputs;
|
final outputs = bundle.originalTransaction.outputs;
|
||||||
|
|
||||||
final changeAddresses = walletAddresses.allAddresses.where((element) => element.isHidden);
|
final ownAddresses = walletAddresses.allAddresses.map((addr) => addr.address).toSet();
|
||||||
|
|
||||||
// look for a change address in the outputs
|
final receiverAmount = outputs
|
||||||
final changeOutput = outputs.firstWhereOrNull((output) => changeAddresses.any(
|
.where((output) =>
|
||||||
(element) => element.address == addressFromOutputScript(output.scriptPubKey, network)));
|
!ownAddresses.contains(addressFromOutputScript(output.scriptPubKey, network)))
|
||||||
|
.fold<int>(0, (sum, output) => sum + output.amount.toInt());
|
||||||
|
|
||||||
var allInputsAmount = 0;
|
if (receiverAmount == 0) {
|
||||||
|
throw Exception("Receiver output not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
final availableInputs = unspentCoins.where((utxo) => utxo.isSending && !utxo.isFrozen).toList();
|
||||||
|
int totalBalance = availableInputs.fold<int>(
|
||||||
|
0, (previousValue, element) => previousValue + element.value.toInt());
|
||||||
|
|
||||||
|
int allInputsAmount = 0;
|
||||||
for (int i = 0; i < bundle.originalTransaction.inputs.length; i++) {
|
for (int i = 0; i < bundle.originalTransaction.inputs.length; i++) {
|
||||||
final input = bundle.originalTransaction.inputs[i];
|
final input = bundle.originalTransaction.inputs[i];
|
||||||
final inputTransaction = bundle.ins[i];
|
final inputTransaction = bundle.ins[i];
|
||||||
|
@ -1543,12 +1583,10 @@ abstract class ElectrumWalletBase
|
||||||
|
|
||||||
int totalOutAmount = bundle.originalTransaction.outputs
|
int totalOutAmount = bundle.originalTransaction.outputs
|
||||||
.fold<int>(0, (previousValue, element) => previousValue + element.amount.toInt());
|
.fold<int>(0, (previousValue, element) => previousValue + element.amount.toInt());
|
||||||
|
|
||||||
var currentFee = allInputsAmount - totalOutAmount;
|
var currentFee = allInputsAmount - totalOutAmount;
|
||||||
|
|
||||||
int remainingFee = (newFee - currentFee > 0) ? newFee - currentFee : newFee;
|
int remainingFee = (newFee - currentFee > 0) ? newFee - currentFee : newFee;
|
||||||
|
return totalBalance - receiverAmount - remainingFee >= _dustAmount;
|
||||||
return changeOutput != null && changeOutput.amount.toInt() - remainingFee >= 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<PendingBitcoinTransaction> replaceByFee(String hash, int newFee) async {
|
Future<PendingBitcoinTransaction> replaceByFee(String hash, int newFee) async {
|
||||||
|
@ -1556,12 +1594,13 @@ abstract class ElectrumWalletBase
|
||||||
final bundle = await getTransactionExpanded(hash: hash);
|
final bundle = await getTransactionExpanded(hash: hash);
|
||||||
|
|
||||||
final utxos = <UtxoWithAddress>[];
|
final utxos = <UtxoWithAddress>[];
|
||||||
|
final outputs = <BitcoinOutput>[];
|
||||||
List<ECPrivate> privateKeys = [];
|
List<ECPrivate> privateKeys = [];
|
||||||
|
|
||||||
var allInputsAmount = 0;
|
var allInputsAmount = 0;
|
||||||
String? memo;
|
String? memo;
|
||||||
|
|
||||||
// Add inputs
|
// Add original inputs
|
||||||
for (var i = 0; i < bundle.originalTransaction.inputs.length; i++) {
|
for (var i = 0; i < bundle.originalTransaction.inputs.length; i++) {
|
||||||
final input = bundle.originalTransaction.inputs[i];
|
final input = bundle.originalTransaction.inputs[i];
|
||||||
final inputTransaction = bundle.ins[i];
|
final inputTransaction = bundle.ins[i];
|
||||||
|
@ -1572,7 +1611,6 @@ abstract class ElectrumWalletBase
|
||||||
|
|
||||||
final addressRecord =
|
final addressRecord =
|
||||||
walletAddresses.allAddresses.firstWhere((element) => element.address == address);
|
walletAddresses.allAddresses.firstWhere((element) => element.address == address);
|
||||||
|
|
||||||
final btcAddress = RegexUtils.addressTypeFromStr(addressRecord.address, network);
|
final btcAddress = RegexUtils.addressTypeFromStr(addressRecord.address, network);
|
||||||
final privkey = generateECPrivate(
|
final privkey = generateECPrivate(
|
||||||
hd: addressRecord.isHidden ? walletAddresses.sideHd : walletAddresses.mainHd,
|
hd: addressRecord.isHidden ? walletAddresses.sideHd : walletAddresses.mainHd,
|
||||||
|
@ -1595,10 +1633,8 @@ abstract class ElectrumWalletBase
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a list of available outputs
|
// Add original outputs
|
||||||
final outputs = <BitcoinOutput>[];
|
|
||||||
for (final out in bundle.originalTransaction.outputs) {
|
for (final out in bundle.originalTransaction.outputs) {
|
||||||
// Check if the script contains OP_RETURN
|
|
||||||
final script = out.scriptPubKey.script;
|
final script = out.scriptPubKey.script;
|
||||||
if (script.contains('OP_RETURN') && memo == null) {
|
if (script.contains('OP_RETURN') && memo == null) {
|
||||||
final index = script.indexOf('OP_RETURN');
|
final index = script.indexOf('OP_RETURN');
|
||||||
|
@ -1628,17 +1664,95 @@ abstract class ElectrumWalletBase
|
||||||
throw Exception("New fee must be higher than the current fee.");
|
throw Exception("New fee must be higher than the current fee.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deduct Remaining Fee from Main Outputs
|
// Deduct fee from change outputs first, if possible
|
||||||
if (remainingFee > 0) {
|
if (remainingFee > 0) {
|
||||||
|
final changeAddresses = walletAddresses.allAddresses.where((element) => element.isHidden);
|
||||||
for (int i = outputs.length - 1; i >= 0; i--) {
|
for (int i = outputs.length - 1; i >= 0; i--) {
|
||||||
int outputAmount = outputs[i].value.toInt();
|
final output = outputs[i];
|
||||||
|
final isChange = changeAddresses
|
||||||
|
.any((element) => element.address == output.address.toAddress(network));
|
||||||
|
|
||||||
|
if (isChange) {
|
||||||
|
int outputAmount = output.value.toInt();
|
||||||
|
if (outputAmount > _dustAmount) {
|
||||||
|
int deduction = (outputAmount - _dustAmount >= remainingFee)
|
||||||
|
? remainingFee
|
||||||
|
: outputAmount - _dustAmount;
|
||||||
|
outputs[i] = BitcoinOutput(
|
||||||
|
address: output.address, value: BigInt.from(outputAmount - deduction));
|
||||||
|
remainingFee -= deduction;
|
||||||
|
|
||||||
|
if (remainingFee <= 0) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If still not enough, add UTXOs until the fee is covered
|
||||||
|
if (remainingFee > 0) {
|
||||||
|
final unusedUtxos = unspentCoins
|
||||||
|
.where((utxo) => utxo.isSending && !utxo.isFrozen && utxo.confirmations! > 0)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
for (final utxo in unusedUtxos) {
|
||||||
|
final address = RegexUtils.addressTypeFromStr(utxo.address, network);
|
||||||
|
final privkey = generateECPrivate(
|
||||||
|
hd: utxo.bitcoinAddressRecord.isHidden
|
||||||
|
? walletAddresses.sideHd
|
||||||
|
: walletAddresses.mainHd,
|
||||||
|
index: utxo.bitcoinAddressRecord.index,
|
||||||
|
network: network,
|
||||||
|
);
|
||||||
|
privateKeys.add(privkey);
|
||||||
|
|
||||||
|
utxos.add(UtxoWithAddress(
|
||||||
|
utxo: BitcoinUtxo(
|
||||||
|
txHash: utxo.hash,
|
||||||
|
value: BigInt.from(utxo.value),
|
||||||
|
vout: utxo.vout,
|
||||||
|
scriptType: _getScriptType(address)),
|
||||||
|
ownerDetails:
|
||||||
|
UtxoAddressDetails(publicKey: privkey.getPublic().toHex(), address: address),
|
||||||
|
));
|
||||||
|
|
||||||
|
allInputsAmount += utxo.value;
|
||||||
|
remainingFee -= utxo.value;
|
||||||
|
|
||||||
|
if (remainingFee < 0) {
|
||||||
|
final changeOutput = outputs.firstWhereOrNull((output) => walletAddresses.allAddresses
|
||||||
|
.any((addr) => addr.address == output.address.toAddress(network)));
|
||||||
|
if (changeOutput != null) {
|
||||||
|
final newValue = changeOutput.value.toInt() + (-remainingFee);
|
||||||
|
outputs[outputs.indexOf(changeOutput)] =
|
||||||
|
BitcoinOutput(address: changeOutput.address, value: BigInt.from(newValue));
|
||||||
|
} else {
|
||||||
|
final changeAddress = await walletAddresses.getChangeAddress();
|
||||||
|
outputs.add(BitcoinOutput(
|
||||||
|
address: RegexUtils.addressTypeFromStr(changeAddress.address, network),
|
||||||
|
value: BigInt.from(-remainingFee)));
|
||||||
|
}
|
||||||
|
|
||||||
|
remainingFee = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remainingFee <= 0) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deduct from the receiver's output if remaining fee is still greater than 0
|
||||||
|
if (remainingFee > 0) {
|
||||||
|
for (int i = 0; i < outputs.length; i++) {
|
||||||
|
final output = outputs[i];
|
||||||
|
int outputAmount = output.value.toInt();
|
||||||
|
|
||||||
if (outputAmount > _dustAmount) {
|
if (outputAmount > _dustAmount) {
|
||||||
int deduction = (outputAmount - _dustAmount >= remainingFee)
|
int deduction = (outputAmount - _dustAmount >= remainingFee)
|
||||||
? remainingFee
|
? remainingFee
|
||||||
: outputAmount - _dustAmount;
|
: outputAmount - _dustAmount;
|
||||||
|
|
||||||
outputs[i] = BitcoinOutput(
|
outputs[i] = BitcoinOutput(
|
||||||
address: outputs[i].address, value: BigInt.from(outputAmount - deduction));
|
address: output.address, value: BigInt.from(outputAmount - deduction));
|
||||||
remainingFee -= deduction;
|
remainingFee -= deduction;
|
||||||
|
|
||||||
if (remainingFee <= 0) break;
|
if (remainingFee <= 0) break;
|
||||||
|
@ -1677,7 +1791,6 @@ abstract class ElectrumWalletBase
|
||||||
final transaction = txb.buildTransaction((txDigest, utxo, publicKey, sighash) {
|
final transaction = txb.buildTransaction((txDigest, utxo, publicKey, sighash) {
|
||||||
final key =
|
final key =
|
||||||
privateKeys.firstWhereOrNull((element) => element.getPublic().toHex() == publicKey);
|
privateKeys.firstWhereOrNull((element) => element.getPublic().toHex() == publicKey);
|
||||||
|
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
throw Exception("Cannot find private key");
|
throw Exception("Cannot find private key");
|
||||||
}
|
}
|
||||||
|
@ -1708,6 +1821,7 @@ abstract class ElectrumWalletBase
|
||||||
});
|
});
|
||||||
transactionHistory.addOne(transaction);
|
transactionHistory.addOne(transaction);
|
||||||
await updateBalance();
|
await updateBalance();
|
||||||
|
await updateAllUnspents();
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -1729,7 +1843,7 @@ abstract class ElectrumWalletBase
|
||||||
try {
|
try {
|
||||||
final blockHash = await http.get(
|
final blockHash = await http.get(
|
||||||
Uri.parse(
|
Uri.parse(
|
||||||
"http://mempool.cakewallet.com:8999/api/v1/block-height/$height",
|
"https://mempool.cakewallet.com/api/v1/block-height/$height",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1738,7 +1852,7 @@ abstract class ElectrumWalletBase
|
||||||
jsonDecode(blockHash.body) != null) {
|
jsonDecode(blockHash.body) != null) {
|
||||||
final blockResponse = await http.get(
|
final blockResponse = await http.get(
|
||||||
Uri.parse(
|
Uri.parse(
|
||||||
"http://mempool.cakewallet.com:8999/api/v1/block/${blockHash.body}",
|
"https://mempool.cakewallet.com/api/v1/block/${blockHash.body}",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (blockResponse.statusCode == 200 &&
|
if (blockResponse.statusCode == 200 &&
|
||||||
|
@ -1849,7 +1963,7 @@ abstract class ElectrumWalletBase
|
||||||
|
|
||||||
return historiesWithDetails;
|
return historiesWithDetails;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("fetchTransactions $e");
|
printV("fetchTransactions $e");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1973,7 +2087,7 @@ abstract class ElectrumWalletBase
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateTransactions() async {
|
Future<void> updateTransactions() async {
|
||||||
print("updateTransactions() called!");
|
printV("updateTransactions() called!");
|
||||||
try {
|
try {
|
||||||
if (_isTransactionUpdating) {
|
if (_isTransactionUpdating) {
|
||||||
return;
|
return;
|
||||||
|
@ -2005,8 +2119,8 @@ abstract class ElectrumWalletBase
|
||||||
walletAddresses.updateReceiveAddresses();
|
walletAddresses.updateReceiveAddresses();
|
||||||
_isTransactionUpdating = false;
|
_isTransactionUpdating = false;
|
||||||
} catch (e, stacktrace) {
|
} catch (e, stacktrace) {
|
||||||
print(stacktrace);
|
printV(stacktrace);
|
||||||
print(e);
|
printV(e);
|
||||||
_isTransactionUpdating = false;
|
_isTransactionUpdating = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2024,13 +2138,13 @@ abstract class ElectrumWalletBase
|
||||||
try {
|
try {
|
||||||
await _scripthashesUpdateSubject[sh]?.close();
|
await _scripthashesUpdateSubject[sh]?.close();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("failed to close: $e");
|
printV("failed to close: $e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
_scripthashesUpdateSubject[sh] = await electrumClient.scripthashUpdate(sh);
|
_scripthashesUpdateSubject[sh] = await electrumClient.scripthashUpdate(sh);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("failed scripthashUpdate: $e");
|
printV("failed scripthashUpdate: $e");
|
||||||
}
|
}
|
||||||
_scripthashesUpdateSubject[sh]?.listen((event) async {
|
_scripthashesUpdateSubject[sh]?.listen((event) async {
|
||||||
try {
|
try {
|
||||||
|
@ -2040,7 +2154,7 @@ abstract class ElectrumWalletBase
|
||||||
|
|
||||||
await _fetchAddressHistory(address, await getCurrentChainTip());
|
await _fetchAddressHistory(address, await getCurrentChainTip());
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
print("sub error: $e");
|
printV("sub error: $e");
|
||||||
_onError?.call(FlutterErrorDetails(
|
_onError?.call(FlutterErrorDetails(
|
||||||
exception: e,
|
exception: e,
|
||||||
stack: s,
|
stack: s,
|
||||||
|
@ -2048,7 +2162,7 @@ abstract class ElectrumWalletBase
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}, onError: (e, s) {
|
}, onError: (e, s) {
|
||||||
print("sub_listen error: $e $s");
|
printV("sub_listen error: $e $s");
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -2100,7 +2214,7 @@ abstract class ElectrumWalletBase
|
||||||
|
|
||||||
if (balances.isNotEmpty && balances.first['confirmed'] == null) {
|
if (balances.isNotEmpty && balances.first['confirmed'] == null) {
|
||||||
// if we got null balance responses from the server, set our connection status to lost and return our last known balance:
|
// if we got null balance responses from the server, set our connection status to lost and return our last known balance:
|
||||||
print("got null balance responses from the server, setting connection status to lost");
|
printV("got null balance responses from the server, setting connection status to lost");
|
||||||
syncStatus = LostConnectionSyncStatus();
|
syncStatus = LostConnectionSyncStatus();
|
||||||
return balance[currency] ?? ElectrumBalance(confirmed: 0, unconfirmed: 0, frozen: 0);
|
return balance[currency] ?? ElectrumBalance(confirmed: 0, unconfirmed: 0, frozen: 0);
|
||||||
}
|
}
|
||||||
|
@ -2127,7 +2241,7 @@ abstract class ElectrumWalletBase
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateBalance() async {
|
Future<void> updateBalance() async {
|
||||||
print("updateBalance() called!");
|
printV("updateBalance() called!");
|
||||||
balance[currency] = await fetchBalances();
|
balance[currency] = await fetchBalances();
|
||||||
await save();
|
await save();
|
||||||
}
|
}
|
||||||
|
@ -2267,7 +2381,7 @@ abstract class ElectrumWalletBase
|
||||||
}
|
}
|
||||||
|
|
||||||
void _syncStatusReaction(SyncStatus syncStatus) async {
|
void _syncStatusReaction(SyncStatus syncStatus) async {
|
||||||
print("SYNC_STATUS_CHANGE: ${syncStatus}");
|
printV("SYNC_STATUS_CHANGE: ${syncStatus}");
|
||||||
if (syncStatus is SyncingSyncStatus) {
|
if (syncStatus is SyncingSyncStatus) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ import 'dart:io' show Platform;
|
||||||
import 'package:bitcoin_base/bitcoin_base.dart';
|
import 'package:bitcoin_base/bitcoin_base.dart';
|
||||||
import 'package:blockchain_utils/blockchain_utils.dart';
|
import 'package:blockchain_utils/blockchain_utils.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||||
|
import 'package:cw_bitcoin/electrum_wallet.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_unspent.dart';
|
import 'package:cw_bitcoin/bitcoin_unspent.dart';
|
||||||
import 'package:cw_core/wallet_addresses.dart';
|
import 'package:cw_core/wallet_addresses.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
|
@ -193,7 +195,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||||
receiveAddresses.remove(addressRecord);
|
receiveAddresses.remove(addressRecord);
|
||||||
receiveAddresses.insert(0, addressRecord);
|
receiveAddresses.insert(0, addressRecord);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("ElectrumWalletAddressBase: set address ($addr): $e");
|
printV("ElectrumWalletAddressBase: set address ($addr): $e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +485,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||||
|
|
||||||
await saveAddressesInBox();
|
await saveAddressesInBox();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("updateAddresses $e");
|
printV("updateAddresses $e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import 'package:crypto/crypto.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
|
import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
|
||||||
import 'package:cw_core/cake_hive.dart';
|
import 'package:cw_core/cake_hive.dart';
|
||||||
import 'package:cw_core/mweb_utxo.dart';
|
import 'package:cw_core/mweb_utxo.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/node.dart';
|
import 'package:cw_core/node.dart';
|
||||||
import 'package:cw_mweb/mwebd.pbgrpc.dart';
|
import 'package:cw_mweb/mwebd.pbgrpc.dart';
|
||||||
import 'package:fixnum/fixnum.dart';
|
import 'package:fixnum/fixnum.dart';
|
||||||
|
@ -283,7 +284,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> waitForMwebAddresses() async {
|
Future<void> waitForMwebAddresses() async {
|
||||||
print("waitForMwebAddresses() called!");
|
printV("waitForMwebAddresses() called!");
|
||||||
// ensure that we have the full 1000 mweb addresses generated before continuing:
|
// ensure that we have the full 1000 mweb addresses generated before continuing:
|
||||||
// should no longer be needed, but leaving here just in case
|
// should no longer be needed, but leaving here just in case
|
||||||
await (walletAddresses as LitecoinWalletAddresses).ensureMwebAddressUpToIndexExists(1020);
|
await (walletAddresses as LitecoinWalletAddresses).ensureMwebAddressUpToIndexExists(1020);
|
||||||
|
@ -302,8 +303,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
@action
|
@action
|
||||||
@override
|
@override
|
||||||
Future<void> startSync() async {
|
Future<void> startSync() async {
|
||||||
print("startSync() called!");
|
printV("startSync() called!");
|
||||||
print("STARTING SYNC - MWEB ENABLED: $mwebEnabled");
|
printV("STARTING SYNC - MWEB ENABLED: $mwebEnabled");
|
||||||
if (!mwebEnabled) {
|
if (!mwebEnabled) {
|
||||||
try {
|
try {
|
||||||
// in case we're switching from a litecoin wallet that had mweb enabled
|
// in case we're switching from a litecoin wallet that had mweb enabled
|
||||||
|
@ -317,33 +318,33 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
print("STARTING SYNC - MWEB ENABLED: $mwebEnabled");
|
printV("STARTING SYNC - MWEB ENABLED: $mwebEnabled");
|
||||||
_syncTimer?.cancel();
|
_syncTimer?.cancel();
|
||||||
try {
|
try {
|
||||||
mwebSyncStatus = SyncronizingSyncStatus();
|
mwebSyncStatus = SyncronizingSyncStatus();
|
||||||
try {
|
try {
|
||||||
await subscribeForUpdates();
|
await subscribeForUpdates();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("failed to subcribe for updates: $e");
|
printV("failed to subcribe for updates: $e");
|
||||||
}
|
}
|
||||||
updateFeeRates();
|
updateFeeRates();
|
||||||
_feeRatesTimer?.cancel();
|
_feeRatesTimer?.cancel();
|
||||||
_feeRatesTimer =
|
_feeRatesTimer =
|
||||||
Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
|
Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
|
||||||
|
|
||||||
print("START SYNC FUNCS");
|
printV("START SYNC FUNCS");
|
||||||
await waitForMwebAddresses();
|
await waitForMwebAddresses();
|
||||||
await processMwebUtxos();
|
await processMwebUtxos();
|
||||||
await updateTransactions();
|
await updateTransactions();
|
||||||
await updateUnspent();
|
await updateUnspent();
|
||||||
await updateBalance();
|
await updateBalance();
|
||||||
print("DONE SYNC FUNCS");
|
} catch (e) {
|
||||||
} catch (e, s) {
|
printV("failed to start mweb sync: $e");
|
||||||
print("mweb sync failed: $e $s");
|
syncStatus = FailedSyncStatus();
|
||||||
mwebSyncStatus = FailedSyncStatus(error: "mweb sync failed: $e");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_syncTimer?.cancel();
|
||||||
_syncTimer = Timer.periodic(const Duration(milliseconds: 3000), (timer) async {
|
_syncTimer = Timer.periodic(const Duration(milliseconds: 3000), (timer) async {
|
||||||
if (mwebSyncStatus is FailedSyncStatus) {
|
if (mwebSyncStatus is FailedSyncStatus) {
|
||||||
_syncTimer?.cancel();
|
_syncTimer?.cancel();
|
||||||
|
@ -401,7 +402,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
for (var coin in tx.unspents!) {
|
for (var coin in tx.unspents!) {
|
||||||
final utxo = mwebUtxosBox.get(coin.address);
|
final utxo = mwebUtxosBox.get(coin.address);
|
||||||
if (utxo != null) {
|
if (utxo != null) {
|
||||||
print("deleting utxo ${coin.address} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
printV("deleting utxo ${coin.address} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||||
await mwebUtxosBox.delete(coin.address);
|
await mwebUtxosBox.delete(coin.address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -428,7 +429,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("error syncing: $e");
|
printV("error syncing: $e");
|
||||||
mwebSyncStatus = FailedSyncStatus(error: e.toString());
|
mwebSyncStatus = FailedSyncStatus(error: e.toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -437,12 +438,13 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
@action
|
@action
|
||||||
@override
|
@override
|
||||||
Future<void> stopSync() async {
|
Future<void> stopSync() async {
|
||||||
print("stopSync() called!");
|
printV("stopSync() called!");
|
||||||
_syncTimer?.cancel();
|
_syncTimer?.cancel();
|
||||||
_utxoStream?.cancel();
|
_utxoStream?.cancel();
|
||||||
_feeRatesTimer?.cancel();
|
_feeRatesTimer?.cancel();
|
||||||
await CwMweb.stop();
|
await CwMweb.stop();
|
||||||
await super.stopSync();
|
await super.stopSync();
|
||||||
|
printV("stopped syncing!");
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initMwebUtxosBox() async {
|
Future<void> initMwebUtxosBox() async {
|
||||||
|
@ -514,7 +516,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> handleIncoming(MwebUtxo utxo) async {
|
Future<void> handleIncoming(MwebUtxo utxo) async {
|
||||||
print("handleIncoming() called!");
|
printV("handleIncoming() called!");
|
||||||
final status = await CwMweb.status(StatusRequest());
|
final status = await CwMweb.status(StatusRequest());
|
||||||
var date = DateTime.now();
|
var date = DateTime.now();
|
||||||
var confirmations = 0;
|
var confirmations = 0;
|
||||||
|
@ -559,7 +561,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
final addressRecord = walletAddresses.allAddresses
|
final addressRecord = walletAddresses.allAddresses
|
||||||
.firstWhereOrNull((addressRecord) => addressRecord.address == utxo.address);
|
.firstWhereOrNull((addressRecord) => addressRecord.address == utxo.address);
|
||||||
if (addressRecord == null) {
|
if (addressRecord == null) {
|
||||||
print("we don't have this address in the wallet! ${utxo.address}");
|
printV("we don't have this address in the wallet! ${utxo.address}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,13 +582,13 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> processMwebUtxos() async {
|
Future<void> processMwebUtxos() async {
|
||||||
print("processMwebUtxos() called!");
|
printV("processMwebUtxos() called!");
|
||||||
if (!mwebEnabled) {
|
if (!mwebEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int restoreHeight = walletInfo.restoreHeight;
|
int restoreHeight = walletInfo.restoreHeight;
|
||||||
print("SCANNING FROM HEIGHT: $restoreHeight");
|
printV("SCANNING FROM HEIGHT: $restoreHeight");
|
||||||
final req = UtxosRequest(scanSecret: scanSecret, fromHeight: restoreHeight);
|
final req = UtxosRequest(scanSecret: scanSecret, fromHeight: restoreHeight);
|
||||||
|
|
||||||
// process new utxos as they come in:
|
// process new utxos as they come in:
|
||||||
|
@ -621,7 +623,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
// but do update the utxo height if it's somehow different:
|
// but do update the utxo height if it's somehow different:
|
||||||
final existingUtxo = mwebUtxosBox.get(utxo.outputId);
|
final existingUtxo = mwebUtxosBox.get(utxo.outputId);
|
||||||
if (existingUtxo!.height != utxo.height) {
|
if (existingUtxo!.height != utxo.height) {
|
||||||
print(
|
printV(
|
||||||
"updating utxo height for $utxo.outputId: ${existingUtxo.height} -> ${utxo.height}");
|
"updating utxo height for $utxo.outputId: ${existingUtxo.height} -> ${utxo.height}");
|
||||||
existingUtxo.height = utxo.height;
|
existingUtxo.height = utxo.height;
|
||||||
await mwebUtxosBox.put(utxo.outputId, existingUtxo);
|
await mwebUtxosBox.put(utxo.outputId, existingUtxo);
|
||||||
|
@ -644,7 +646,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
await handleIncoming(utxo);
|
await handleIncoming(utxo);
|
||||||
},
|
},
|
||||||
onError: (error) {
|
onError: (error) {
|
||||||
print("error in utxo stream: $error");
|
printV("error in utxo stream: $error");
|
||||||
mwebSyncStatus = FailedSyncStatus(error: error.toString());
|
mwebSyncStatus = FailedSyncStatus(error: error.toString());
|
||||||
},
|
},
|
||||||
cancelOnError: true,
|
cancelOnError: true,
|
||||||
|
@ -652,7 +654,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteSpentUtxos() async {
|
Future<void> deleteSpentUtxos() async {
|
||||||
print("deleteSpentUtxos() called!");
|
printV("deleteSpentUtxos() called!");
|
||||||
final chainHeight = await electrumClient.getCurrentBlockChainTip();
|
final chainHeight = await electrumClient.getCurrentBlockChainTip();
|
||||||
final status = await CwMweb.status(StatusRequest());
|
final status = await CwMweb.status(StatusRequest());
|
||||||
if (chainHeight == null || status.blockHeaderHeight != chainHeight) return;
|
if (chainHeight == null || status.blockHeaderHeight != chainHeight) return;
|
||||||
|
@ -676,7 +678,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> checkMwebUtxosSpent() async {
|
Future<void> checkMwebUtxosSpent() async {
|
||||||
print("checkMwebUtxosSpent() called!");
|
printV("checkMwebUtxosSpent() called!");
|
||||||
if (!mwebEnabled) {
|
if (!mwebEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -757,6 +759,13 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
if (!mwebEnabled) return false;
|
if (!mwebEnabled) return false;
|
||||||
if (!tx.isPending) return false;
|
if (!tx.isPending) return false;
|
||||||
|
|
||||||
|
final isMwebTx = (tx.inputAddresses?.any((addr) => addr.contains("mweb")) ?? false) ||
|
||||||
|
(tx.outputAddresses?.any((addr) => addr.contains("mweb")) ?? false);
|
||||||
|
|
||||||
|
if (!isMwebTx) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
final outputId = <String>[], target = <String>{};
|
final outputId = <String>[], target = <String>{};
|
||||||
final isHash = RegExp(r'^[a-f0-9]{64}$').hasMatch;
|
final isHash = RegExp(r'^[a-f0-9]{64}$').hasMatch;
|
||||||
final spendingOutputIds = tx.inputAddresses?.where(isHash) ?? [];
|
final spendingOutputIds = tx.inputAddresses?.where(isHash) ?? [];
|
||||||
|
@ -791,7 +800,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateUnspent() async {
|
Future<void> updateUnspent() async {
|
||||||
print("updateUnspent() called!");
|
printV("updateUnspent() called!");
|
||||||
await checkMwebUtxosSpent();
|
await checkMwebUtxosSpent();
|
||||||
await updateAllUnspents();
|
await updateAllUnspents();
|
||||||
}
|
}
|
||||||
|
@ -822,7 +831,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
.firstWhereOrNull((addressRecord) => addressRecord.address == utxo.address);
|
.firstWhereOrNull((addressRecord) => addressRecord.address == utxo.address);
|
||||||
|
|
||||||
if (addressRecord == null) {
|
if (addressRecord == null) {
|
||||||
print("utxo contains an address that is not in the wallet: ${utxo.address}");
|
printV("utxo contains an address that is not in the wallet: ${utxo.address}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final unspent = BitcoinUnspent(
|
final unspent = BitcoinUnspent(
|
||||||
|
@ -863,7 +872,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
mwebUtxosBox.values.forEach((utxo) {
|
mwebUtxosBox.values.forEach((utxo) {
|
||||||
bool isConfirmed = utxo.height > 0;
|
bool isConfirmed = utxo.height > 0;
|
||||||
|
|
||||||
print(
|
printV(
|
||||||
"utxo: ${isConfirmed ? "confirmed" : "unconfirmed"} ${utxo.spent ? "spent" : "unspent"} ${utxo.outputId} ${utxo.height} ${utxo.value}");
|
"utxo: ${isConfirmed ? "confirmed" : "unconfirmed"} ${utxo.spent ? "spent" : "unspent"} ${utxo.outputId} ${utxo.height} ${utxo.value}");
|
||||||
|
|
||||||
if (isConfirmed) {
|
if (isConfirmed) {
|
||||||
|
@ -1001,7 +1010,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
final sum1 = _sumOutputAmounts(outputs.map((e) => e.toOutput).toList()) + fee;
|
final sum1 = _sumOutputAmounts(outputs.map((e) => e.toOutput).toList()) + fee;
|
||||||
final sum2 = utxos.sumOfUtxosValue();
|
final sum2 = utxos.sumOfUtxosValue();
|
||||||
if (sum1 != sum2) {
|
if (sum1 != sum2) {
|
||||||
print("@@@@@ WE HAD TO ADJUST THE FEE! @@@@@@@@");
|
printV("@@@@@ WE HAD TO ADJUST THE FEE! @@@@@@@@");
|
||||||
final diff = sum2 - sum1;
|
final diff = sum2 - sum1;
|
||||||
// add the difference to the fee (abs value):
|
// add the difference to the fee (abs value):
|
||||||
fee += diff.abs();
|
fee += diff.abs();
|
||||||
|
@ -1166,7 +1175,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
addressRecord.balance -= utxo.value.toInt();
|
addressRecord.balance -= utxo.value.toInt();
|
||||||
});
|
});
|
||||||
transaction.inputAddresses?.addAll(addresses);
|
transaction.inputAddresses?.addAll(addresses);
|
||||||
print("isPegIn: $isPegIn, isPegOut: $isPegOut");
|
printV("isPegIn: $isPegIn, isPegOut: $isPegOut");
|
||||||
transaction.additionalInfo["isPegIn"] = isPegIn;
|
transaction.additionalInfo["isPegIn"] = isPegIn;
|
||||||
transaction.additionalInfo["isPegOut"] = isPegOut;
|
transaction.additionalInfo["isPegOut"] = isPegOut;
|
||||||
transactionHistory.addOne(transaction);
|
transactionHistory.addOne(transaction);
|
||||||
|
@ -1174,10 +1183,10 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
await updateBalance();
|
await updateBalance();
|
||||||
});
|
});
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
print(e);
|
printV(e);
|
||||||
print(s);
|
printV(s);
|
||||||
if (e.toString().contains("commit failed")) {
|
if (e.toString().contains("commit failed")) {
|
||||||
print(e);
|
printV(e);
|
||||||
throw Exception("Transaction commit failed (no peers responded), please try again.");
|
throw Exception("Transaction commit failed (no peers responded), please try again.");
|
||||||
}
|
}
|
||||||
rethrow;
|
rethrow;
|
||||||
|
@ -1190,7 +1199,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close({required bool shouldCleanup}) async {
|
Future<void> close({bool shouldCleanup = false}) async {
|
||||||
_utxoStream?.cancel();
|
_utxoStream?.cancel();
|
||||||
_feeRatesTimer?.cancel();
|
_feeRatesTimer?.cancel();
|
||||||
_syncTimer?.cancel();
|
_syncTimer?.cancel();
|
||||||
|
|
|
@ -9,6 +9,7 @@ import 'package:cw_bitcoin/bitcoin_unspent.dart';
|
||||||
import 'package:cw_bitcoin/electrum_wallet.dart';
|
import 'package:cw_bitcoin/electrum_wallet.dart';
|
||||||
import 'package:cw_bitcoin/utils.dart';
|
import 'package:cw_bitcoin/utils.dart';
|
||||||
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_mweb/cw_mweb.dart';
|
import 'package:cw_mweb/cw_mweb.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
@ -35,7 +36,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
|
||||||
for (int i = 0; i < mwebAddresses.length; i++) {
|
for (int i = 0; i < mwebAddresses.length; i++) {
|
||||||
mwebAddrs.add(mwebAddresses[i].address);
|
mwebAddrs.add(mwebAddresses[i].address);
|
||||||
}
|
}
|
||||||
print("initialized with ${mwebAddrs.length} mweb addresses");
|
printV("initialized with ${mwebAddrs.length} mweb addresses");
|
||||||
}
|
}
|
||||||
|
|
||||||
final Bip32Slip10Secp256k1? mwebHd;
|
final Bip32Slip10Secp256k1? mwebHd;
|
||||||
|
@ -73,25 +74,25 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
|
||||||
}
|
}
|
||||||
|
|
||||||
while (generating) {
|
while (generating) {
|
||||||
print("generating.....");
|
printV("generating.....");
|
||||||
// this function was called multiple times in multiple places:
|
// this function was called multiple times in multiple places:
|
||||||
await Future.delayed(const Duration(milliseconds: 100));
|
await Future.delayed(const Duration(milliseconds: 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
print("Generating MWEB addresses up to index $index");
|
printV("Generating MWEB addresses up to index $index");
|
||||||
generating = true;
|
generating = true;
|
||||||
try {
|
try {
|
||||||
while (mwebAddrs.length <= (index + 1)) {
|
while (mwebAddrs.length <= (index + 1)) {
|
||||||
final addresses =
|
final addresses =
|
||||||
await CwMweb.addresses(scan, spend, mwebAddrs.length, mwebAddrs.length + 50);
|
await CwMweb.addresses(scan, spend, mwebAddrs.length, mwebAddrs.length + 50);
|
||||||
print("generated up to index ${mwebAddrs.length}");
|
printV("generated up to index ${mwebAddrs.length}");
|
||||||
// sleep for a bit to avoid making the main thread unresponsive:
|
// sleep for a bit to avoid making the main thread unresponsive:
|
||||||
await Future.delayed(Duration(milliseconds: 200));
|
await Future.delayed(Duration(milliseconds: 200));
|
||||||
mwebAddrs.addAll(addresses!);
|
mwebAddrs.addAll(addresses!);
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
generating = false;
|
generating = false;
|
||||||
print("Done generating MWEB addresses len: ${mwebAddrs.length}");
|
printV("Done generating MWEB addresses len: ${mwebAddrs.length}");
|
||||||
|
|
||||||
// ensure mweb addresses are up to date:
|
// ensure mweb addresses are up to date:
|
||||||
// This is the Case if the Litecoin Wallet is a hardware Wallet
|
// This is the Case if the Litecoin Wallet is a hardware Wallet
|
||||||
|
@ -109,7 +110,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
|
||||||
))
|
))
|
||||||
.toList();
|
.toList();
|
||||||
addMwebAddresses(addressRecords);
|
addMwebAddresses(addressRecords);
|
||||||
print("set ${addressRecords.length} mweb addresses");
|
printV("set ${addressRecords.length} mweb addresses");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,15 @@ class LitecoinWalletService extends WalletService<
|
||||||
mwebdLogs.deleteSync();
|
mwebdLogs.deleteSync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final unspentCoinsToDelete = unspentCoinsInfoSource.values.where(
|
||||||
|
(unspentCoin) => unspentCoin.walletId == walletInfo.id).toList();
|
||||||
|
|
||||||
|
final keysToDelete = unspentCoinsToDelete.map((unspentCoin) => unspentCoin.key).toList();
|
||||||
|
|
||||||
|
if (keysToDelete.isNotEmpty) {
|
||||||
|
await unspentCoinsInfoSource.deleteAll(keysToDelete);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:bitcoin_base/bitcoin_base.dart';
|
import 'package:bitcoin_base/bitcoin_base.dart';
|
||||||
import 'package:convert/convert.dart';
|
import 'package:convert/convert.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:ledger_bitcoin/psbt.dart';
|
import 'package:ledger_bitcoin/psbt.dart';
|
||||||
|
|
||||||
class PSBTTransactionBuild {
|
class PSBTTransactionBuild {
|
||||||
|
@ -16,6 +17,10 @@ class PSBTTransactionBuild {
|
||||||
for (var i = 0; i < inputs.length; i++) {
|
for (var i = 0; i < inputs.length; i++) {
|
||||||
final input = inputs[i];
|
final input = inputs[i];
|
||||||
|
|
||||||
|
printV(input.utxo.isP2tr());
|
||||||
|
printV(input.utxo.isSegwit());
|
||||||
|
printV(input.utxo.isP2shSegwit());
|
||||||
|
|
||||||
psbt.setInputPreviousTxId(i, Uint8List.fromList(hex.decode(input.utxo.txHash).reversed.toList()));
|
psbt.setInputPreviousTxId(i, Uint8List.fromList(hex.decode(input.utxo.txHash).reversed.toList()));
|
||||||
psbt.setInputOutputIndex(i, input.utxo.vout);
|
psbt.setInputOutputIndex(i, input.utxo.vout);
|
||||||
psbt.setInputSequence(i, enableRBF ? 0x1 : 0xffffffff);
|
psbt.setInputSequence(i, enableRBF ? 0x1 : 0xffffffff);
|
||||||
|
|
|
@ -29,10 +29,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
|
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.0"
|
version: "2.6.0"
|
||||||
asn1lib:
|
asn1lib:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -145,10 +145,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_daemon
|
name: build_daemon
|
||||||
sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1"
|
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.1"
|
version: "4.0.2"
|
||||||
build_resolvers:
|
build_resolvers:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
@ -161,10 +161,10 @@ packages:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: build_runner
|
name: build_runner
|
||||||
sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22"
|
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.9"
|
version: "2.4.13"
|
||||||
build_runner_core:
|
build_runner_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -250,18 +250,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: convert
|
name: convert
|
||||||
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "3.1.2"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
|
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.3"
|
version: "3.0.6"
|
||||||
cryptography:
|
cryptography:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -360,10 +360,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fixnum
|
name: fixnum
|
||||||
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
|
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.1"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -431,10 +431,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: graphs
|
name: graphs
|
||||||
sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19
|
sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "2.3.2"
|
||||||
grpc:
|
grpc:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -503,10 +503,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.18.1"
|
version: "0.19.0"
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -535,26 +535,26 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.0"
|
version: "10.0.5"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "3.0.5"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_testing
|
name: leak_tracker_testing
|
||||||
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "3.0.1"
|
||||||
ledger_bitcoin:
|
ledger_bitcoin:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -577,7 +577,7 @@ packages:
|
||||||
description:
|
description:
|
||||||
path: "packages/ledger-litecoin"
|
path: "packages/ledger-litecoin"
|
||||||
ref: HEAD
|
ref: HEAD
|
||||||
resolved-ref: "07cd61ef76a2a017b6d5ef233396740163265457"
|
resolved-ref: "3dee36713e6ebec9dceb59b9ccae7f243a53ea9e"
|
||||||
url: "https://github.com/cake-tech/ledger-flutter-plus-plugins"
|
url: "https://github.com/cake-tech/ledger-flutter-plus-plugins"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.2"
|
version: "0.0.2"
|
||||||
|
@ -593,10 +593,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: logging
|
name: logging
|
||||||
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
|
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.3.0"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -609,26 +609,26 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.0"
|
version: "0.11.1"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.0"
|
version: "1.15.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: mime
|
name: mime
|
||||||
sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
|
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.6"
|
version: "2.0.0"
|
||||||
mobx:
|
mobx:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -681,10 +681,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
|
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.4"
|
version: "2.2.12"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -729,10 +729,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
|
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.5"
|
version: "3.1.6"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -809,18 +809,18 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180
|
sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.3"
|
version: "2.3.2"
|
||||||
shared_preferences_android:
|
shared_preferences_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_android
|
name: shared_preferences_android
|
||||||
sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
|
sha256: "3b9febd815c9ca29c9e3520d50ec32f49157711e143b7a4ca039eb87e8ade5ab"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.2"
|
version: "2.3.3"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -849,10 +849,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_web
|
name: shared_preferences_web
|
||||||
sha256: "59dc807b94d29d52ddbb1b3c0d3b9d0a67fc535a64e62a5542c8db0513fcb6c2"
|
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.1"
|
version: "2.4.2"
|
||||||
shared_preferences_windows:
|
shared_preferences_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -873,10 +873,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf_web_socket
|
name: shelf_web_socket
|
||||||
sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
|
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "2.0.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -967,10 +967,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.1"
|
version: "0.7.2"
|
||||||
timing:
|
timing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -991,10 +991,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.4.0"
|
||||||
universal_ble:
|
universal_ble:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1031,10 +1031,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "13.0.0"
|
version: "14.2.4"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: "direct overridden"
|
dependency: "direct overridden"
|
||||||
description:
|
description:
|
||||||
|
@ -1047,18 +1047,26 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web
|
name: web
|
||||||
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
|
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.1"
|
version: "1.1.0"
|
||||||
|
web_socket:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket
|
||||||
|
sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.6"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42"
|
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.5"
|
version: "3.0.1"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1092,5 +1100,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.1"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.3.0 <4.0.0"
|
dart: ">=3.5.0 <4.0.0"
|
||||||
flutter: ">=3.19.0"
|
flutter: ">=3.24.0"
|
||||||
|
|
|
@ -16,7 +16,7 @@ dependencies:
|
||||||
http: ^1.1.0
|
http: ^1.1.0
|
||||||
mobx: ^2.0.7+4
|
mobx: ^2.0.7+4
|
||||||
flutter_mobx: ^2.0.6+1
|
flutter_mobx: ^2.0.6+1
|
||||||
intl: ^0.18.0
|
intl: ^0.19.0
|
||||||
shared_preferences: ^2.0.15
|
shared_preferences: ^2.0.15
|
||||||
cw_core:
|
cw_core:
|
||||||
path: ../cw_core
|
path: ../cw_core
|
||||||
|
|
|
@ -85,6 +85,15 @@ class BitcoinCashWalletService extends WalletService<
|
||||||
final walletInfo = walletInfoSource.values
|
final walletInfo = walletInfoSource.values
|
||||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
.firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
||||||
await walletInfoSource.delete(walletInfo.key);
|
await walletInfoSource.delete(walletInfo.key);
|
||||||
|
|
||||||
|
final unspentCoinsToDelete = unspentCoinsInfoSource.values.where(
|
||||||
|
(unspentCoin) => unspentCoin.walletId == walletInfo.id).toList();
|
||||||
|
|
||||||
|
final keysToDelete = unspentCoinsToDelete.map((unspentCoin) => unspentCoin.key).toList();
|
||||||
|
|
||||||
|
if (keysToDelete.isNotEmpty) {
|
||||||
|
await unspentCoinsInfoSource.deleteAll(keysToDelete);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
const MethodChannel _channel = MethodChannel('com.cake_wallet/native_utils');
|
const MethodChannel _channel = MethodChannel('com.cake_wallet/native_utils');
|
||||||
|
@ -6,17 +7,17 @@ Future<void> requestDisableBatteryOptimization() async {
|
||||||
try {
|
try {
|
||||||
await _channel.invokeMethod('disableBatteryOptimization');
|
await _channel.invokeMethod('disableBatteryOptimization');
|
||||||
} on PlatformException catch (e) {
|
} on PlatformException catch (e) {
|
||||||
print("Failed to disable battery optimization: '${e.message}'.");
|
printV("Failed to disable battery optimization: '${e.message}'.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> isBatteryOptimizationDisabled() async {
|
Future<bool> isBatteryOptimizationDisabled() async {
|
||||||
try {
|
try {
|
||||||
final bool isDisabled = await _channel.invokeMethod('isBatteryOptimizationDisabled') as bool;
|
final bool isDisabled = await _channel.invokeMethod('isBatteryOptimizationDisabled') as bool;
|
||||||
print('It\'s actually disabled? $isDisabled');
|
printV('It\'s actually disabled? $isDisabled');
|
||||||
return isDisabled;
|
return isDisabled;
|
||||||
} on PlatformException catch (e) {
|
} on PlatformException catch (e) {
|
||||||
print("Failed to check battery optimization status: '${e.message}'.");
|
printV("Failed to check battery optimization status: '${e.message}'.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
@ -152,7 +153,7 @@ int getMoneroHeigthByDate({required DateTime date}) {
|
||||||
height = startHeight + daysHeight - heightPerDay;
|
height = startHeight + daysHeight - heightPerDay;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return height;
|
return height;
|
||||||
|
@ -270,7 +271,7 @@ const bitcoinDates = {
|
||||||
Future<int> getBitcoinHeightByDateAPI({required DateTime date}) async {
|
Future<int> getBitcoinHeightByDateAPI({required DateTime date}) async {
|
||||||
final response = await http.get(
|
final response = await http.get(
|
||||||
Uri.parse(
|
Uri.parse(
|
||||||
"http://mempool.cakewallet.com:8999/api/v1/mining/blocks/timestamp/${(date.millisecondsSinceEpoch / 1000).round()}",
|
"https://mempool.cakewallet.com/api/v1/mining/blocks/timestamp/${(date.millisecondsSinceEpoch / 1000).round()}",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ enum DeviceConnectionType {
|
||||||
static List<DeviceConnectionType> supportedConnectionTypes(WalletType walletType,
|
static List<DeviceConnectionType> supportedConnectionTypes(WalletType walletType,
|
||||||
[bool isIOS = false]) {
|
[bool isIOS = false]) {
|
||||||
switch (walletType) {
|
switch (walletType) {
|
||||||
// case WalletType.monero:
|
case WalletType.monero:
|
||||||
case WalletType.bitcoin:
|
case WalletType.bitcoin:
|
||||||
case WalletType.litecoin:
|
case WalletType.litecoin:
|
||||||
case WalletType.ethereum:
|
case WalletType.ethereum:
|
||||||
|
|
|
@ -18,4 +18,5 @@ const SPL_TOKEN_TYPE_ID = 16;
|
||||||
const DERIVATION_INFO_TYPE_ID = 17;
|
const DERIVATION_INFO_TYPE_ID = 17;
|
||||||
const TRON_TOKEN_TYPE_ID = 18;
|
const TRON_TOKEN_TYPE_ID = 18;
|
||||||
const HARDWARE_WALLET_TYPE_TYPE_ID = 19;
|
const HARDWARE_WALLET_TYPE_TYPE_ID = 19;
|
||||||
const MWEB_UTXO_TYPE_ID = 20;
|
const MWEB_UTXO_TYPE_ID = 20;
|
||||||
|
const HAVEN_SEED_STORE_TYPE_ID = 21;
|
|
@ -3,8 +3,8 @@ import 'package:cw_core/monero_amount_format.dart';
|
||||||
|
|
||||||
class MoneroBalance extends Balance {
|
class MoneroBalance extends Balance {
|
||||||
MoneroBalance({required this.fullBalance, required this.unlockedBalance, this.frozenBalance = 0})
|
MoneroBalance({required this.fullBalance, required this.unlockedBalance, this.frozenBalance = 0})
|
||||||
: formattedFullBalance = moneroAmountToString(amount: fullBalance),
|
: formattedFullBalance = moneroAmountToString(amount: frozenBalance + fullBalance),
|
||||||
formattedUnlockedBalance = moneroAmountToString(amount: unlockedBalance - frozenBalance),
|
formattedUnlockedBalance = moneroAmountToString(amount: unlockedBalance),
|
||||||
formattedLockedBalance =
|
formattedLockedBalance =
|
||||||
moneroAmountToString(amount: frozenBalance + fullBalance - unlockedBalance),
|
moneroAmountToString(amount: frozenBalance + fullBalance - unlockedBalance),
|
||||||
super(unlockedBalance, fullBalance);
|
super(unlockedBalance, fullBalance);
|
||||||
|
|
|
@ -203,9 +203,30 @@ class Node extends HiveObject with Keyable {
|
||||||
headers: {'Content-Type': 'application/json'},
|
headers: {'Content-Type': 'application/json'},
|
||||||
body: json.encode(body),
|
body: json.encode(body),
|
||||||
);
|
);
|
||||||
|
|
||||||
client.close();
|
client.close();
|
||||||
|
|
||||||
|
if ((
|
||||||
|
response.body.contains("400 Bad Request") // Some other generic error
|
||||||
|
|| response.body.contains("plain HTTP request was sent to HTTPS port") // Cloudflare
|
||||||
|
|| response.headers["location"] != null // Generic reverse proxy
|
||||||
|
|| response.body.contains("301 Moved Permanently") // Poorly configured generic reverse proxy
|
||||||
|
) && !(useSSL??false)
|
||||||
|
) {
|
||||||
|
|
||||||
|
final oldUseSSL = useSSL;
|
||||||
|
useSSL = true;
|
||||||
|
try {
|
||||||
|
final ret = await requestMoneroNode();
|
||||||
|
if (ret == true) {
|
||||||
|
await save();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
useSSL = oldUseSSL;
|
||||||
|
} catch (e) {
|
||||||
|
useSSL = oldUseSSL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final resBody = json.decode(response.body) as Map<String, dynamic>;
|
final resBody = json.decode(response.body) as Map<String, dynamic>;
|
||||||
return !(resBody['result']['offline'] as bool);
|
return !(resBody['result']['offline'] as bool);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import 'package:cw_core/hive_type_ids.dart';
|
import 'package:cw_core/hive_type_ids.dart';
|
||||||
|
import 'package:cw_core/unspent_comparable_mixin.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
|
||||||
part 'unspent_coins_info.g.dart';
|
part 'unspent_coins_info.g.dart';
|
||||||
|
|
||||||
@HiveType(typeId: UnspentCoinsInfo.typeId)
|
@HiveType(typeId: UnspentCoinsInfo.typeId)
|
||||||
class UnspentCoinsInfo extends HiveObject {
|
class UnspentCoinsInfo extends HiveObject with UnspentComparable {
|
||||||
UnspentCoinsInfo({
|
UnspentCoinsInfo({
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
required this.hash,
|
required this.hash,
|
||||||
|
|
27
cw_core/lib/unspent_comparable_mixin.dart
Normal file
27
cw_core/lib/unspent_comparable_mixin.dart
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
mixin UnspentComparable {
|
||||||
|
String get address;
|
||||||
|
|
||||||
|
String get hash;
|
||||||
|
|
||||||
|
int get value;
|
||||||
|
|
||||||
|
int get vout;
|
||||||
|
|
||||||
|
String? get keyImage;
|
||||||
|
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
|
return other is UnspentComparable &&
|
||||||
|
other.hash == hash &&
|
||||||
|
other.address == address &&
|
||||||
|
other.value == value &&
|
||||||
|
other.vout == vout &&
|
||||||
|
other.keyImage == keyImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(address, hash, value, vout, keyImage);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
class Unspent {
|
import 'package:cw_core/unspent_comparable_mixin.dart';
|
||||||
|
|
||||||
|
class Unspent with UnspentComparable {
|
||||||
Unspent(this.address, this.hash, this.value, this.vout, this.keyImage)
|
Unspent(this.address, this.hash, this.value, this.vout, this.keyImage)
|
||||||
: isSending = true,
|
: isSending = true,
|
||||||
isFrozen = false,
|
isFrozen = false,
|
||||||
|
|
84
cw_core/lib/utils/print_verbose.dart
Normal file
84
cw_core/lib/utils/print_verbose.dart
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
void printV(dynamic content) {
|
||||||
|
CustomTrace programInfo = CustomTrace(StackTrace.current);
|
||||||
|
print("${programInfo.fileName}#${programInfo.lineNumber}:${programInfo.columnNumber} ${programInfo.callerFunctionName}: $content");
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/59386101
|
||||||
|
|
||||||
|
class CustomTrace {
|
||||||
|
final StackTrace _trace;
|
||||||
|
|
||||||
|
String? fileName;
|
||||||
|
String? functionName;
|
||||||
|
String? callerFunctionName;
|
||||||
|
int? lineNumber;
|
||||||
|
int? columnNumber;
|
||||||
|
|
||||||
|
CustomTrace(this._trace) {
|
||||||
|
try {
|
||||||
|
_parseTrace();
|
||||||
|
} catch (e) {
|
||||||
|
print("Unable to parse trace (printV): $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _getFunctionNameFromFrame(String frame) {
|
||||||
|
/* Just giving another nickname to the frame */
|
||||||
|
var currentTrace = frame;
|
||||||
|
/* To get rid off the #number thing, get the index of the first whitespace */
|
||||||
|
var indexOfWhiteSpace = currentTrace.indexOf(' ');
|
||||||
|
|
||||||
|
/* Create a substring from the first whitespace index till the end of the string */
|
||||||
|
var subStr = currentTrace.substring(indexOfWhiteSpace);
|
||||||
|
|
||||||
|
/* Grab the function name using reg expr */
|
||||||
|
var indexOfFunction = subStr.indexOf(RegExp(r'[A-Za-z0-9_]'));
|
||||||
|
|
||||||
|
/* Create a new substring from the function name index till the end of string */
|
||||||
|
subStr = subStr.substring(indexOfFunction);
|
||||||
|
|
||||||
|
indexOfWhiteSpace = subStr.indexOf(RegExp(r'[ .]'));
|
||||||
|
|
||||||
|
/* Create a new substring from start to the first index of a whitespace. This substring gives us the function name */
|
||||||
|
subStr = subStr.substring(0, indexOfWhiteSpace);
|
||||||
|
|
||||||
|
return subStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _parseTrace() {
|
||||||
|
/* The trace comes with multiple lines of strings, (each line is also known as a frame), so split the trace's string by lines to get all the frames */
|
||||||
|
var frames = this._trace.toString().split("\n");
|
||||||
|
|
||||||
|
/* The first frame is the current function */
|
||||||
|
this.functionName = _getFunctionNameFromFrame(frames[0]);
|
||||||
|
|
||||||
|
/* The second frame is the caller function */
|
||||||
|
this.callerFunctionName = _getFunctionNameFromFrame(frames[1]);
|
||||||
|
|
||||||
|
/* The first frame has all the information we need */
|
||||||
|
var traceString = frames[1];
|
||||||
|
|
||||||
|
/* Search through the string and find the index of the file name by looking for the '.dart' regex */
|
||||||
|
var indexOfFileName = traceString.indexOf(RegExp(r'[/A-Za-z_]+.dart'), 1); // 1 to offest and not print the printV function name
|
||||||
|
|
||||||
|
var fileInfo = traceString.substring(indexOfFileName);
|
||||||
|
|
||||||
|
var listOfInfos = fileInfo.split(":");
|
||||||
|
|
||||||
|
/* Splitting fileInfo by the character ":" separates the file name, the line number and the column counter nicely.
|
||||||
|
Example: main.dart:5:12
|
||||||
|
To get the file name, we split with ":" and get the first index
|
||||||
|
To get the line number, we would have to get the second index
|
||||||
|
To get the column number, we would have to get the third index
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
this.fileName = listOfInfos[0];
|
||||||
|
this.lineNumber = int.tryParse(listOfInfos[1]);
|
||||||
|
var columnStr = listOfInfos[2];
|
||||||
|
columnStr = columnStr.replaceFirst(")", "");
|
||||||
|
this.columnNumber = int.tryParse(columnStr);
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:cw_core/address_info.dart';
|
import 'package:cw_core/address_info.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ abstract class WalletAddresses {
|
||||||
await walletInfo.save();
|
await walletInfo.save();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
|
||||||
|
|
||||||
Future<void> rescan({required int height});
|
Future<void> rescan({required int height});
|
||||||
|
|
||||||
Future<void> close({required bool shouldCleanup});
|
Future<void> close({bool shouldCleanup = false});
|
||||||
|
|
||||||
Future<void> changePassword(String password);
|
Future<void> changePassword(String password);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
const MethodChannel _channel = MethodChannel('com.cake_wallet/native_utils');
|
const MethodChannel _channel = MethodChannel('com.cake_wallet/native_utils');
|
||||||
|
@ -14,9 +15,9 @@ Future<void> setDefaultMinimumWindowSize() async {
|
||||||
) as bool;
|
) as bool;
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
print("Failed to set minimum window size.");
|
printV("Failed to set minimum window size.");
|
||||||
}
|
}
|
||||||
} on PlatformException catch (e) {
|
} on PlatformException catch (e) {
|
||||||
print("Failed to set minimum window size: '${e.message}'.");
|
printV("Failed to set minimum window size: '${e.message}'.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,34 +5,39 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: _fe_analyzer_shared
|
name: _fe_analyzer_shared
|
||||||
sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051
|
sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "64.0.0"
|
version: "72.0.0"
|
||||||
|
_macros:
|
||||||
|
dependency: transitive
|
||||||
|
description: dart
|
||||||
|
source: sdk
|
||||||
|
version: "0.3.2"
|
||||||
analyzer:
|
analyzer:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: analyzer
|
name: analyzer
|
||||||
sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893"
|
sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.2.0"
|
version: "6.7.0"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
|
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.2"
|
version: "2.6.0"
|
||||||
asn1lib:
|
asn1lib:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: asn1lib
|
name: asn1lib
|
||||||
sha256: "21afe4333076c02877d14f4a89df111e658a6d466cbfc802eb705eb91bd5adfd"
|
sha256: "6b151826fcc95ff246cd219a0bf4c753ea14f4081ad71c61939becf3aba27f70"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.0"
|
version: "1.5.5"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -69,10 +74,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_daemon
|
name: build_daemon
|
||||||
sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1"
|
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.1"
|
version: "4.0.2"
|
||||||
build_resolvers:
|
build_resolvers:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
@ -85,18 +90,18 @@ packages:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: build_runner
|
name: build_runner
|
||||||
sha256: "581bacf68f89ec8792f5e5a0b2c4decd1c948e97ce659dc783688c8a88fbec21"
|
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.8"
|
version: "2.4.13"
|
||||||
build_runner_core:
|
build_runner_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_runner_core
|
name: build_runner_core
|
||||||
sha256: c9e32d21dd6626b5c163d48b037ce906bbe428bc23ab77bcd77bb21e593b6185
|
sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.2.11"
|
version: "7.3.2"
|
||||||
built_collection:
|
built_collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -109,10 +114,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: built_value
|
name: built_value
|
||||||
sha256: c9aabae0718ec394e5bc3c7272e6bb0dc0b32201a08fe185ec1d8401d3e39309
|
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.8.1"
|
version: "8.9.2"
|
||||||
cake_backup:
|
cake_backup:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -166,42 +171,42 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: convert
|
name: convert
|
||||||
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "3.1.2"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
|
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.3"
|
version: "3.0.6"
|
||||||
cryptography:
|
cryptography:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: cryptography
|
name: cryptography
|
||||||
sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35
|
sha256: d146b76d33d94548cf035233fbc2f4338c1242fa119013bead807d033fc4ae05
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.0"
|
version: "2.7.0"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: cupertino_icons
|
name: cupertino_icons
|
||||||
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
|
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.6"
|
version: "1.0.8"
|
||||||
dart_style:
|
dart_style:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: dart_style
|
name: dart_style
|
||||||
sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368"
|
sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.4"
|
version: "2.3.7"
|
||||||
encrypt:
|
encrypt:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -222,26 +227,26 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
|
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.3"
|
||||||
file:
|
file:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
|
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.0.1"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fixnum
|
name: fixnum
|
||||||
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
|
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.1"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -251,10 +256,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_mobx
|
name: flutter_mobx
|
||||||
sha256: "4a5d062ff85ed3759f4aac6410ff0ffae32e324b2e71ca722ae1b37b32e865f4"
|
sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0+2"
|
version: "2.2.1+1"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -264,10 +269,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: frontend_server_client
|
name: frontend_server_client
|
||||||
sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
|
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.0"
|
version: "4.0.0"
|
||||||
glob:
|
glob:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -280,10 +285,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: graphs
|
name: graphs
|
||||||
sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19
|
sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "2.3.2"
|
||||||
hive:
|
hive:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -304,10 +309,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
|
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.2.2"
|
||||||
http_multi_server:
|
http_multi_server:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -328,10 +333,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.18.1"
|
version: "0.19.0"
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -352,42 +357,50 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: json_annotation
|
name: json_annotation
|
||||||
sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
|
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.8.1"
|
version: "4.9.0"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.0"
|
version: "10.0.5"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "3.0.5"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_testing
|
name: leak_tracker_testing
|
||||||
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "3.0.1"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: logging
|
name: logging
|
||||||
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
|
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.3.0"
|
||||||
|
macros:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: macros
|
||||||
|
sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.2-main.4"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -400,42 +413,42 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.0"
|
version: "0.11.1"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.0"
|
version: "1.15.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: mime
|
name: mime
|
||||||
sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
|
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "2.0.0"
|
||||||
mobx:
|
mobx:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: mobx
|
name: mobx
|
||||||
sha256: "74ee54012dc7c1b3276eaa960a600a7418ef5f9997565deb8fca1fd88fb36b78"
|
sha256: "63920b27b32ad1910adfe767ab1750e4c212e8923232a1f891597b362074ea5e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0+1"
|
version: "2.3.3+2"
|
||||||
mobx_codegen:
|
mobx_codegen:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: mobx_codegen
|
name: mobx_codegen
|
||||||
sha256: b26c7f9c20b38f0ea572c1ed3f29d8e027cb265538bbd1aed3ec198642cfca42
|
sha256: "8e0d8653a0c720ad933cd8358f6f89f740ce89203657c13f25bea772ef1fff7c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.6.0+1"
|
version: "2.6.1"
|
||||||
nested:
|
nested:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -464,26 +477,26 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
|
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.4"
|
||||||
path_provider_android:
|
path_provider_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
|
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.2"
|
version: "2.2.12"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_foundation
|
name: path_provider_foundation
|
||||||
sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
|
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.4.0"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -504,18 +517,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
|
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.3.0"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
|
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.4"
|
version: "3.1.6"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -528,10 +541,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pointycastle
|
name: pointycastle
|
||||||
sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29"
|
sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.7.4"
|
version: "3.9.1"
|
||||||
pool:
|
pool:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -544,10 +557,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: provider
|
name: provider
|
||||||
sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096"
|
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.1"
|
version: "6.1.2"
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -560,10 +573,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pubspec_parse
|
name: pubspec_parse
|
||||||
sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
|
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.3"
|
version: "1.3.0"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -576,10 +589,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf_web_socket
|
name: shelf_web_socket
|
||||||
sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
|
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "2.0.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -589,10 +602,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: socks5_proxy
|
name: socks5_proxy
|
||||||
sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a"
|
sha256: "616818a0ea1064a4823b53c9f7eaf8da64ed82dcd51ed71371c7e54751ed5053"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.6"
|
||||||
source_gen:
|
source_gen:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -661,10 +674,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.1"
|
version: "0.7.2"
|
||||||
timing:
|
timing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -685,10 +698,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.4.0"
|
||||||
unorm_dart:
|
unorm_dart:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -709,10 +722,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "13.0.0"
|
version: "14.2.4"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: "direct overridden"
|
dependency: "direct overridden"
|
||||||
description:
|
description:
|
||||||
|
@ -721,30 +734,38 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web
|
||||||
|
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
|
web_socket:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket
|
||||||
|
sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.6"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
|
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "3.0.1"
|
||||||
win32:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: win32
|
|
||||||
sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "5.0.9"
|
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
|
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.1.0"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -754,5 +775,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.2.0-0 <4.0.0"
|
dart: ">=3.5.0 <4.0.0"
|
||||||
flutter: ">=3.10.0"
|
flutter: ">=3.24.0"
|
||||||
|
|
|
@ -17,7 +17,7 @@ dependencies:
|
||||||
path_provider: ^2.0.11
|
path_provider: ^2.0.11
|
||||||
mobx: ^2.0.7+4
|
mobx: ^2.0.7+4
|
||||||
flutter_mobx: ^2.0.6+1
|
flutter_mobx: ^2.0.6+1
|
||||||
intl: ^0.18.0
|
intl: ^0.19.0
|
||||||
encrypt: ^5.0.1
|
encrypt: ^5.0.1
|
||||||
cake_backup:
|
cake_backup:
|
||||||
git:
|
git:
|
||||||
|
|
|
@ -36,7 +36,18 @@ abstract class EVMChainClient {
|
||||||
|
|
||||||
bool connect(Node node) {
|
bool connect(Node node) {
|
||||||
try {
|
try {
|
||||||
_client = Web3Client(node.uri.toString(), httpClient);
|
Uri? rpcUri;
|
||||||
|
bool isModifiedNodeUri = false;
|
||||||
|
|
||||||
|
if (node.uriRaw == 'eth.nownodes.io' || node.uriRaw == 'matic.nownodes.io') {
|
||||||
|
isModifiedNodeUri = true;
|
||||||
|
String nowNodeApiKey = secrets.nowNodesApiKey;
|
||||||
|
|
||||||
|
rpcUri = Uri.https(node.uriRaw, '/$nowNodeApiKey');
|
||||||
|
}
|
||||||
|
|
||||||
|
_client =
|
||||||
|
Web3Client(isModifiedNodeUri ? rpcUri!.toString() : node.uri.toString(), httpClient);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -83,23 +94,20 @@ abstract class EVMChainClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> getEstimatedGas({
|
Future<int> getEstimatedGasUnitsForTransaction({
|
||||||
String? contractAddress,
|
|
||||||
required EthereumAddress toAddress,
|
required EthereumAddress toAddress,
|
||||||
required EthereumAddress senderAddress,
|
required EthereumAddress senderAddress,
|
||||||
required EtherAmount value,
|
required EtherAmount value,
|
||||||
|
String? contractAddress,
|
||||||
EtherAmount? gasPrice,
|
EtherAmount? gasPrice,
|
||||||
// EtherAmount? maxFeePerGas,
|
EtherAmount? maxFeePerGas,
|
||||||
// EtherAmount? maxPriorityFeePerGas,
|
|
||||||
}) async {
|
}) async {
|
||||||
try {
|
try {
|
||||||
if (contractAddress == null) {
|
if (contractAddress == null) {
|
||||||
final estimatedGas = await _client!.estimateGas(
|
final estimatedGas = await _client!.estimateGas(
|
||||||
sender: senderAddress,
|
sender: senderAddress,
|
||||||
gasPrice: gasPrice,
|
|
||||||
to: toAddress,
|
to: toAddress,
|
||||||
value: value,
|
value: value,
|
||||||
// maxPriorityFeePerGas: maxPriorityFeePerGas,
|
|
||||||
// maxFeePerGas: maxFeePerGas,
|
// maxFeePerGas: maxFeePerGas,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -133,7 +141,9 @@ abstract class EVMChainClient {
|
||||||
required Credentials privateKey,
|
required Credentials privateKey,
|
||||||
required String toAddress,
|
required String toAddress,
|
||||||
required BigInt amount,
|
required BigInt amount,
|
||||||
required BigInt gas,
|
required BigInt gasFee,
|
||||||
|
required int estimatedGasUnits,
|
||||||
|
required int maxFeePerGas,
|
||||||
required EVMChainTransactionPriority priority,
|
required EVMChainTransactionPriority priority,
|
||||||
required CryptoCurrency currency,
|
required CryptoCurrency currency,
|
||||||
required int exponent,
|
required int exponent,
|
||||||
|
@ -152,6 +162,8 @@ abstract class EVMChainClient {
|
||||||
maxPriorityFeePerGas: EtherAmount.fromInt(EtherUnit.gwei, priority.tip),
|
maxPriorityFeePerGas: EtherAmount.fromInt(EtherUnit.gwei, priority.tip),
|
||||||
amount: isNativeToken ? EtherAmount.inWei(amount) : EtherAmount.zero(),
|
amount: isNativeToken ? EtherAmount.inWei(amount) : EtherAmount.zero(),
|
||||||
data: data != null ? hexToBytes(data) : null,
|
data: data != null ? hexToBytes(data) : null,
|
||||||
|
maxGas: estimatedGasUnits,
|
||||||
|
maxFeePerGas: EtherAmount.fromInt(EtherUnit.wei, maxFeePerGas),
|
||||||
);
|
);
|
||||||
|
|
||||||
Uint8List signedTransaction;
|
Uint8List signedTransaction;
|
||||||
|
@ -180,7 +192,7 @@ abstract class EVMChainClient {
|
||||||
return PendingEVMChainTransaction(
|
return PendingEVMChainTransaction(
|
||||||
signedTransaction: signedTransaction,
|
signedTransaction: signedTransaction,
|
||||||
amount: amount.toString(),
|
amount: amount.toString(),
|
||||||
fee: gas,
|
fee: gasFee,
|
||||||
sendTransaction: _sendTransaction,
|
sendTransaction: _sendTransaction,
|
||||||
exponent: exponent,
|
exponent: exponent,
|
||||||
);
|
);
|
||||||
|
@ -191,7 +203,10 @@ abstract class EVMChainClient {
|
||||||
required EthereumAddress to,
|
required EthereumAddress to,
|
||||||
required EtherAmount amount,
|
required EtherAmount amount,
|
||||||
EtherAmount? maxPriorityFeePerGas,
|
EtherAmount? maxPriorityFeePerGas,
|
||||||
|
EtherAmount? gasPrice,
|
||||||
|
EtherAmount? maxFeePerGas,
|
||||||
Uint8List? data,
|
Uint8List? data,
|
||||||
|
int? maxGas,
|
||||||
}) {
|
}) {
|
||||||
return Transaction(
|
return Transaction(
|
||||||
from: from,
|
from: from,
|
||||||
|
@ -199,6 +214,9 @@ abstract class EVMChainClient {
|
||||||
maxPriorityFeePerGas: maxPriorityFeePerGas,
|
maxPriorityFeePerGas: maxPriorityFeePerGas,
|
||||||
value: amount,
|
value: amount,
|
||||||
data: data,
|
data: data,
|
||||||
|
maxGas: maxGas,
|
||||||
|
gasPrice: gasPrice,
|
||||||
|
maxFeePerGas: maxFeePerGas,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,10 @@ abstract class EVMChainTransactionHistoryBase
|
||||||
|
|
||||||
//! Common methods across all child classes
|
//! Common methods across all child classes
|
||||||
|
|
||||||
Future<void> init() async => await _load();
|
Future<void> init() async {
|
||||||
|
clear();
|
||||||
|
await _load();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> save() async {
|
Future<void> save() async {
|
||||||
|
|
|
@ -14,6 +14,7 @@ import 'package:cw_core/pathForWallet.dart';
|
||||||
import 'package:cw_core/pending_transaction.dart';
|
import 'package:cw_core/pending_transaction.dart';
|
||||||
import 'package:cw_core/sync_status.dart';
|
import 'package:cw_core/sync_status.dart';
|
||||||
import 'package:cw_core/transaction_priority.dart';
|
import 'package:cw_core/transaction_priority.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_addresses.dart';
|
import 'package:cw_core/wallet_addresses.dart';
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
|
@ -200,7 +201,7 @@ abstract class EVMChainWalletBase
|
||||||
} else {
|
} else {
|
||||||
// MaxFeePerGas with gasPrice;
|
// MaxFeePerGas with gasPrice;
|
||||||
maxFeePerGas = gasPrice;
|
maxFeePerGas = gasPrice;
|
||||||
debugPrint('MaxFeePerGas with gasPrice: $maxFeePerGas');
|
printV('MaxFeePerGas with gasPrice: $maxFeePerGas');
|
||||||
}
|
}
|
||||||
|
|
||||||
final totalGasFee = estimatedGasUnits * maxFeePerGas;
|
final totalGasFee = estimatedGasUnits * maxFeePerGas;
|
||||||
|
@ -220,7 +221,7 @@ abstract class EVMChainWalletBase
|
||||||
/// - The exact amount the user wants to send,
|
/// - The exact amount the user wants to send,
|
||||||
/// - The addressHex for the receiving wallet,
|
/// - The addressHex for the receiving wallet,
|
||||||
/// - A contract address which would be essential in determining if to calcualate the estimate for ERC20 or native ETH
|
/// - A contract address which would be essential in determining if to calcualate the estimate for ERC20 or native ETH
|
||||||
Future<int> calculateActualEstimatedFeeForCreateTransaction({
|
Future<GasParamsHandler> calculateActualEstimatedFeeForCreateTransaction({
|
||||||
required amount,
|
required amount,
|
||||||
required String? contractAddress,
|
required String? contractAddress,
|
||||||
required String receivingAddressHex,
|
required String receivingAddressHex,
|
||||||
|
@ -239,22 +240,27 @@ abstract class EVMChainWalletBase
|
||||||
maxFeePerGas = gasPrice;
|
maxFeePerGas = gasPrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
final estimatedGas = await _client.getEstimatedGas(
|
final estimatedGas = await _client.getEstimatedGasUnitsForTransaction(
|
||||||
contractAddress: contractAddress,
|
contractAddress: contractAddress,
|
||||||
senderAddress: _evmChainPrivateKey.address,
|
senderAddress: _evmChainPrivateKey.address,
|
||||||
value: EtherAmount.fromBigInt(EtherUnit.wei, amount!),
|
value: EtherAmount.fromBigInt(EtherUnit.wei, amount!),
|
||||||
gasPrice: EtherAmount.fromInt(EtherUnit.wei, gasPrice),
|
gasPrice: EtherAmount.fromInt(EtherUnit.wei, gasPrice),
|
||||||
toAddress: EthereumAddress.fromHex(receivingAddressHex),
|
toAddress: EthereumAddress.fromHex(receivingAddressHex),
|
||||||
// maxFeePerGas: EtherAmount.fromInt(EtherUnit.wei, maxFeePerGas),
|
maxFeePerGas: EtherAmount.fromInt(EtherUnit.wei, maxFeePerGas),
|
||||||
// maxPriorityFeePerGas: EtherAmount.fromInt(EtherUnit.gwei, priority.tip),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final totalGasFee = estimatedGas * maxFeePerGas;
|
final totalGasFee = estimatedGas * maxFeePerGas;
|
||||||
return totalGasFee;
|
|
||||||
|
return GasParamsHandler(
|
||||||
|
estimatedGasUnits: estimatedGas,
|
||||||
|
estimatedGasFee: totalGasFee,
|
||||||
|
maxFeePerGas: maxFeePerGas,
|
||||||
|
gasPrice: gasPrice,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return 0;
|
return GasParamsHandler.zero();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return 0;
|
return GasParamsHandler.zero();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +270,7 @@ abstract class EVMChainWalletBase
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close({required bool shouldCleanup}) async {
|
Future<void> close({bool shouldCleanup = false}) async {
|
||||||
_client.stop();
|
_client.stop();
|
||||||
_transactionsUpdateTimer?.cancel();
|
_transactionsUpdateTimer?.cancel();
|
||||||
_updateFeesTimer?.cancel();
|
_updateFeesTimer?.cancel();
|
||||||
|
@ -317,7 +323,7 @@ abstract class EVMChainWalletBase
|
||||||
|
|
||||||
gasPrice = await _client.getGasUnitPrice();
|
gasPrice = await _client.getGasUnitPrice();
|
||||||
|
|
||||||
estimatedGasUnits = await _client.getEstimatedGas(
|
estimatedGasUnits = await _client.getEstimatedGasUnitsForTransaction(
|
||||||
senderAddress: _evmChainPrivateKey.address,
|
senderAddress: _evmChainPrivateKey.address,
|
||||||
toAddress: _evmChainPrivateKey.address,
|
toAddress: _evmChainPrivateKey.address,
|
||||||
gasPrice: EtherAmount.fromInt(EtherUnit.wei, gasPrice),
|
gasPrice: EtherAmount.fromInt(EtherUnit.wei, gasPrice),
|
||||||
|
@ -348,6 +354,8 @@ abstract class EVMChainWalletBase
|
||||||
int exponent = transactionCurrency is Erc20Token ? transactionCurrency.decimal : 18;
|
int exponent = transactionCurrency is Erc20Token ? transactionCurrency.decimal : 18;
|
||||||
num amountToEVMChainMultiplier = pow(10, exponent);
|
num amountToEVMChainMultiplier = pow(10, exponent);
|
||||||
String? contractAddress;
|
String? contractAddress;
|
||||||
|
int estimatedGasUnitsForTransaction = 0;
|
||||||
|
int maxFeePerGasForTransaction = 0;
|
||||||
String toAddress = _credentials.outputs.first.isParsedAddress
|
String toAddress = _credentials.outputs.first.isParsedAddress
|
||||||
? _credentials.outputs.first.extractedAddress!
|
? _credentials.outputs.first.extractedAddress!
|
||||||
: _credentials.outputs.first.address;
|
: _credentials.outputs.first.address;
|
||||||
|
@ -366,14 +374,16 @@ abstract class EVMChainWalletBase
|
||||||
outputs.fold(0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0)));
|
outputs.fold(0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0)));
|
||||||
totalAmount = BigInt.from(totalOriginalAmount * amountToEVMChainMultiplier);
|
totalAmount = BigInt.from(totalOriginalAmount * amountToEVMChainMultiplier);
|
||||||
|
|
||||||
final estimateFees = await calculateActualEstimatedFeeForCreateTransaction(
|
final gasFeesModel = await calculateActualEstimatedFeeForCreateTransaction(
|
||||||
amount: totalAmount,
|
amount: totalAmount,
|
||||||
receivingAddressHex: toAddress,
|
receivingAddressHex: toAddress,
|
||||||
priority: _credentials.priority!,
|
priority: _credentials.priority!,
|
||||||
contractAddress: contractAddress,
|
contractAddress: contractAddress,
|
||||||
);
|
);
|
||||||
|
|
||||||
estimatedFeesForTransaction = BigInt.from(estimateFees);
|
estimatedFeesForTransaction = BigInt.from(gasFeesModel.estimatedGasFee);
|
||||||
|
estimatedGasUnitsForTransaction = gasFeesModel.estimatedGasUnits;
|
||||||
|
maxFeePerGasForTransaction = gasFeesModel.maxFeePerGas;
|
||||||
|
|
||||||
if (erc20Balance.balance < totalAmount) {
|
if (erc20Balance.balance < totalAmount) {
|
||||||
throw EVMChainTransactionCreationException(transactionCurrency);
|
throw EVMChainTransactionCreationException(transactionCurrency);
|
||||||
|
@ -391,14 +401,16 @@ abstract class EVMChainWalletBase
|
||||||
totalAmount = erc20Balance.balance;
|
totalAmount = erc20Balance.balance;
|
||||||
}
|
}
|
||||||
|
|
||||||
final estimateFees = await calculateActualEstimatedFeeForCreateTransaction(
|
final gasFeesModel = await calculateActualEstimatedFeeForCreateTransaction(
|
||||||
amount: totalAmount,
|
amount: totalAmount,
|
||||||
receivingAddressHex: toAddress,
|
receivingAddressHex: toAddress,
|
||||||
priority: _credentials.priority!,
|
priority: _credentials.priority!,
|
||||||
contractAddress: contractAddress,
|
contractAddress: contractAddress,
|
||||||
);
|
);
|
||||||
|
|
||||||
estimatedFeesForTransaction = BigInt.from(estimateFees);
|
estimatedFeesForTransaction = BigInt.from(gasFeesModel.estimatedGasFee);
|
||||||
|
estimatedGasUnitsForTransaction = gasFeesModel.estimatedGasUnits;
|
||||||
|
maxFeePerGasForTransaction = gasFeesModel.maxFeePerGas;
|
||||||
|
|
||||||
if (output.sendAll && transactionCurrency is! Erc20Token) {
|
if (output.sendAll && transactionCurrency is! Erc20Token) {
|
||||||
totalAmount = (erc20Balance.balance - estimatedFeesForTransaction);
|
totalAmount = (erc20Balance.balance - estimatedFeesForTransaction);
|
||||||
|
@ -419,12 +431,14 @@ abstract class EVMChainWalletBase
|
||||||
}
|
}
|
||||||
|
|
||||||
final pendingEVMChainTransaction = await _client.signTransaction(
|
final pendingEVMChainTransaction = await _client.signTransaction(
|
||||||
|
estimatedGasUnits: estimatedGasUnitsForTransaction,
|
||||||
privateKey: _evmChainPrivateKey,
|
privateKey: _evmChainPrivateKey,
|
||||||
toAddress: toAddress,
|
toAddress: toAddress,
|
||||||
amount: totalAmount,
|
amount: totalAmount,
|
||||||
gas: estimatedFeesForTransaction,
|
gasFee: estimatedFeesForTransaction,
|
||||||
priority: _credentials.priority!,
|
priority: _credentials.priority!,
|
||||||
currency: transactionCurrency,
|
currency: transactionCurrency,
|
||||||
|
maxFeePerGas: maxFeePerGasForTransaction,
|
||||||
exponent: exponent,
|
exponent: exponent,
|
||||||
contractAddress:
|
contractAddress:
|
||||||
transactionCurrency is Erc20Token ? transactionCurrency.contractAddress : null,
|
transactionCurrency is Erc20Token ? transactionCurrency.contractAddress : null,
|
||||||
|
@ -727,3 +741,25 @@ abstract class EVMChainWalletBase
|
||||||
@override
|
@override
|
||||||
final String? passphrase;
|
final String? passphrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GasParamsHandler {
|
||||||
|
final int estimatedGasUnits;
|
||||||
|
final int estimatedGasFee;
|
||||||
|
final int maxFeePerGas;
|
||||||
|
final int gasPrice;
|
||||||
|
|
||||||
|
GasParamsHandler(
|
||||||
|
{required this.estimatedGasUnits,
|
||||||
|
required this.estimatedGasFee,
|
||||||
|
required this.maxFeePerGas,
|
||||||
|
required this.gasPrice});
|
||||||
|
|
||||||
|
static GasParamsHandler zero() {
|
||||||
|
return GasParamsHandler(
|
||||||
|
estimatedGasUnits: 0,
|
||||||
|
estimatedGasFee: 0,
|
||||||
|
maxFeePerGas: 0,
|
||||||
|
gasPrice: 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:cw_core/hardware/device_not_connected_exception.dart'
|
import 'package:cw_core/hardware/device_not_connected_exception.dart'
|
||||||
as exception;
|
as exception;
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:ledger_ethereum/ledger_ethereum.dart';
|
import 'package:ledger_ethereum/ledger_ethereum.dart';
|
||||||
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
||||||
import 'package:web3dart/crypto.dart';
|
import 'package:web3dart/crypto.dart';
|
||||||
|
@ -96,7 +97,7 @@ class EvmLedgerCredentials extends CredentialsWithKnownAddress {
|
||||||
await ethereumLedgerApp!.getAndProvideERC20TokenInformation(
|
await ethereumLedgerApp!.getAndProvideERC20TokenInformation(
|
||||||
erc20ContractAddress: erc20ContractAddress, chainId: chainId);
|
erc20ContractAddress: erc20ContractAddress, chainId: chainId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
printV(e);
|
||||||
rethrow;
|
rethrow;
|
||||||
// if (e.errorCode != -28672) rethrow;
|
// if (e.errorCode != -28672) rethrow;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,14 @@ group 'com.cakewallet.cw_haven'
|
||||||
version '1.0-SNAPSHOT'
|
version '1.0-SNAPSHOT'
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.7.10'
|
ext.kotlin_version = '2.0.21'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.3.0'
|
classpath 'com.android.tools.build:gradle:8.7.1'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,20 @@ apply plugin: 'com.android.library'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 28
|
compileSdkVersion 33
|
||||||
|
|
||||||
|
if (project.android.hasProperty("namespace")) {
|
||||||
|
namespace 'com.cakewallet.cw_haven'
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_17
|
||||||
|
targetCompatibility JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '17'
|
||||||
|
}
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main.java.srcDirs += 'src/main/kotlin'
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:cw_core/account.dart';
|
import 'package:cw_core/account.dart';
|
||||||
import 'package:cw_core/account_list.dart';
|
import 'package:cw_core/account_list.dart';
|
||||||
|
@ -77,7 +78,7 @@ abstract class HavenAccountListBase extends AccountList<Account> with Store {
|
||||||
_isRefreshing = false;
|
_isRefreshing = false;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_isRefreshing = false;
|
_isRefreshing = false;
|
||||||
print(e);
|
printV(e);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_haven/api/structs/subaddress_row.dart';
|
import 'package:cw_haven/api/structs/subaddress_row.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
@ -79,7 +80,7 @@ abstract class HavenSubaddressListBase with Store {
|
||||||
_isRefreshing = false;
|
_isRefreshing = false;
|
||||||
} on PlatformException catch (e) {
|
} on PlatformException catch (e) {
|
||||||
_isRefreshing = false;
|
_isRefreshing = false;
|
||||||
print(e);
|
printV(e);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'dart:io';
|
||||||
import 'package:cw_core/crypto_currency.dart';
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:cw_core/pathForWallet.dart';
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
import 'package:cw_core/transaction_priority.dart';
|
import 'package:cw_core/transaction_priority.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_haven/haven_transaction_creation_credentials.dart';
|
import 'package:cw_haven/haven_transaction_creation_credentials.dart';
|
||||||
import 'package:cw_core/monero_amount_format.dart';
|
import 'package:cw_core/monero_amount_format.dart';
|
||||||
import 'package:cw_haven/haven_transaction_creation_exception.dart';
|
import 'package:cw_haven/haven_transaction_creation_exception.dart';
|
||||||
|
@ -107,7 +108,7 @@ abstract class HavenWalletBase
|
||||||
Future<void>? updateBalance() => null;
|
Future<void>? updateBalance() => null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close({required bool shouldCleanup}) async {
|
Future<void> close({bool shouldCleanup = false}) async {
|
||||||
_listener?.stop();
|
_listener?.stop();
|
||||||
_onAccountChangeReaction?.reaction.dispose();
|
_onAccountChangeReaction?.reaction.dispose();
|
||||||
_autoSaveTimer?.cancel();
|
_autoSaveTimer?.cancel();
|
||||||
|
@ -130,7 +131,7 @@ abstract class HavenWalletBase
|
||||||
syncStatus = ConnectedSyncStatus();
|
syncStatus = ConnectedSyncStatus();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
syncStatus = FailedSyncStatus();
|
syncStatus = FailedSyncStatus();
|
||||||
print(e);
|
printV(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +148,7 @@ abstract class HavenWalletBase
|
||||||
_listener?.start();
|
_listener?.start();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
syncStatus = FailedSyncStatus();
|
syncStatus = FailedSyncStatus();
|
||||||
print(e);
|
printV(e);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,7 +325,7 @@ abstract class HavenWalletBase
|
||||||
await transactionHistory.save();
|
await transactionHistory.save();
|
||||||
_isTransactionUpdating = false;
|
_isTransactionUpdating = false;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
printV(e);
|
||||||
_isTransactionUpdating = false;
|
_isTransactionUpdating = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,7 +404,7 @@ abstract class HavenWalletBase
|
||||||
syncStatus = SyncingSyncStatus(blocksLeft, ptc);
|
syncStatus = SyncingSyncStatus(blocksLeft, ptc);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,7 +414,7 @@ abstract class HavenWalletBase
|
||||||
_askForUpdateBalance();
|
_askForUpdateBalance();
|
||||||
await Future<void>.delayed(Duration(seconds: 1));
|
await Future<void>.delayed(Duration(seconds: 1));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_addresses_with_account.dart';
|
import 'package:cw_core/wallet_addresses_with_account.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/account.dart';
|
import 'package:cw_core/account.dart';
|
||||||
|
@ -60,7 +61,7 @@ abstract class HavenWalletAddressesBase extends WalletAddressesWithAccount<Accou
|
||||||
|
|
||||||
await saveAddressesInBox();
|
await saveAddressesInBox();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:cw_core/monero_wallet_utils.dart';
|
import 'package:cw_core/monero_wallet_utils.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
@ -81,7 +82,7 @@ class HavenWalletService extends WalletService<
|
||||||
return wallet;
|
return wallet;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: Implement Exception for wallet list service.
|
// TODO: Implement Exception for wallet list service.
|
||||||
print('HavenWalletsManager Error: ${e.toString()}');
|
printV('HavenWalletsManager Error: ${e.toString()}');
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,7 +94,7 @@ class HavenWalletService extends WalletService<
|
||||||
return haven_wallet_manager.isWalletExist(path: path);
|
return haven_wallet_manager.isWalletExist(path: path);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: Implement Exception for wallet list service.
|
// TODO: Implement Exception for wallet list service.
|
||||||
print('HavenWalletsManager Error: $e');
|
printV('HavenWalletsManager Error: $e');
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,7 +198,7 @@ class HavenWalletService extends WalletService<
|
||||||
return wallet;
|
return wallet;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: Implement Exception for wallet list service.
|
// TODO: Implement Exception for wallet list service.
|
||||||
print('HavenWalletsManager Error: $e');
|
printV('HavenWalletsManager Error: $e');
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,7 +219,7 @@ class HavenWalletService extends WalletService<
|
||||||
return wallet;
|
return wallet;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: Implement Exception for wallet list service.
|
// TODO: Implement Exception for wallet list service.
|
||||||
print('HavenWalletsManager Error: $e');
|
printV('HavenWalletsManager Error: $e');
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,7 +253,7 @@ class HavenWalletService extends WalletService<
|
||||||
newFile.writeAsBytesSync(file.readAsBytesSync());
|
newFile.writeAsBytesSync(file.readAsBytesSync());
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,18 +21,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611"
|
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.6.0"
|
||||||
asn1lib:
|
asn1lib:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: asn1lib
|
name: asn1lib
|
||||||
sha256: ab96a1cb3beeccf8145c52e449233fe68364c9641623acd3adad66f8184f1039
|
sha256: "6b151826fcc95ff246cd219a0bf4c753ea14f4081ad71c61939becf3aba27f70"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.5.5"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -53,10 +53,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build
|
name: build
|
||||||
sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777"
|
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "2.4.1"
|
||||||
build_config:
|
build_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -69,10 +69,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_daemon
|
name: build_daemon
|
||||||
sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65"
|
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "4.0.2"
|
||||||
build_resolvers:
|
build_resolvers:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
@ -85,18 +85,18 @@ packages:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: build_runner
|
name: build_runner
|
||||||
sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22"
|
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.9"
|
version: "2.4.13"
|
||||||
build_runner_core:
|
build_runner_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_runner_core
|
name: build_runner_core
|
||||||
sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292"
|
sha256: "6d6ee4276b1c5f34f21fdf39425202712d2be82019983d52f351c94aafbc2c41"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.2.7"
|
version: "7.2.10"
|
||||||
built_collection:
|
built_collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -109,10 +109,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: built_value
|
name: built_value
|
||||||
sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725"
|
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.4.3"
|
version: "8.9.2"
|
||||||
cake_backup:
|
cake_backup:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -134,10 +134,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: checked_yaml
|
name: checked_yaml
|
||||||
sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311"
|
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.3"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -150,10 +150,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: code_builder
|
name: code_builder
|
||||||
sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe"
|
sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.4.0"
|
version: "4.10.0"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -166,34 +166,34 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: convert
|
name: convert
|
||||||
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "3.1.2"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
|
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.2"
|
version: "3.0.6"
|
||||||
cryptography:
|
cryptography:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: cryptography
|
name: cryptography
|
||||||
sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35
|
sha256: d146b76d33d94548cf035233fbc2f4338c1242fa119013bead807d033fc4ae05
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.0"
|
version: "2.7.0"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: cupertino_icons
|
name: cupertino_icons
|
||||||
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
|
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.6"
|
version: "1.0.8"
|
||||||
cw_core:
|
cw_core:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -213,10 +213,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: encrypt
|
name: encrypt
|
||||||
sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb"
|
sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.1"
|
version: "5.0.3"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -229,26 +229,26 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
|
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.1.3"
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
|
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.0.1"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fixnum
|
name: fixnum
|
||||||
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
|
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.1"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -258,10 +258,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_mobx
|
name: flutter_mobx
|
||||||
sha256: "0da4add0016387a7bf309a0d0c41d36c6b3ae25ed7a176409267f166509e723e"
|
sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.6+5"
|
version: "2.2.1+1"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -271,10 +271,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: frontend_server_client
|
name: frontend_server_client
|
||||||
sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
|
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.0"
|
version: "4.0.0"
|
||||||
glob:
|
glob:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -287,10 +287,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: graphs
|
name: graphs
|
||||||
sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2
|
sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.3.2"
|
||||||
hive:
|
hive:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -311,10 +311,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
|
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.2.2"
|
||||||
http_multi_server:
|
http_multi_server:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -335,10 +335,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.18.1"
|
version: "0.19.0"
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -359,42 +359,42 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: json_annotation
|
name: json_annotation
|
||||||
sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317
|
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.8.0"
|
version: "4.9.0"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.0"
|
version: "10.0.5"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "3.0.5"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_testing
|
name: leak_tracker_testing
|
||||||
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "3.0.1"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: logging
|
name: logging
|
||||||
sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d"
|
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.3.0"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -407,42 +407,50 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.0"
|
version: "0.11.1"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.0"
|
version: "1.15.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: mime
|
name: mime
|
||||||
sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
|
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "2.0.0"
|
||||||
mobx:
|
mobx:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: mobx
|
name: mobx
|
||||||
sha256: f1862bd92c6a903fab67338f27e2f731117c3cb9ea37cee1a487f9e4e0de314a
|
sha256: "63920b27b32ad1910adfe767ab1750e4c212e8923232a1f891597b362074ea5e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3+1"
|
version: "2.3.3+2"
|
||||||
mobx_codegen:
|
mobx_codegen:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: mobx_codegen
|
name: mobx_codegen
|
||||||
sha256: "86122e410d8ea24dda0c69adb5c2a6ccadd5ce02ad46e144764e0d0184a06181"
|
sha256: d4beb9cea4b7b014321235f8fdc7c2193ee0fe1d1198e9da7403f8bc85c4407c
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.3.0"
|
||||||
|
nested:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: nested
|
||||||
|
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
package_config:
|
package_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -463,26 +471,26 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
|
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.4"
|
||||||
path_provider_android:
|
path_provider_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
|
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.12"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_foundation
|
name: path_provider_foundation
|
||||||
sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
|
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "2.4.0"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -495,42 +503,42 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_platform_interface
|
name: path_provider_platform_interface
|
||||||
sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
|
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.2"
|
||||||
path_provider_windows:
|
path_provider_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
|
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.3.0"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
|
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.6"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: plugin_platform_interface
|
name: plugin_platform_interface
|
||||||
sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
|
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.8"
|
||||||
pointycastle:
|
pointycastle:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pointycastle
|
name: pointycastle
|
||||||
sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346
|
sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.6.2"
|
version: "3.9.1"
|
||||||
pool:
|
pool:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -539,38 +547,46 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.1"
|
version: "1.5.1"
|
||||||
|
provider:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: provider
|
||||||
|
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.1.2"
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pub_semver
|
name: pub_semver
|
||||||
sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17"
|
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.4"
|
||||||
pubspec_parse:
|
pubspec_parse:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pubspec_parse
|
name: pubspec_parse
|
||||||
sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a"
|
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.1"
|
version: "1.3.0"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf
|
name: shelf
|
||||||
sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c
|
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.1"
|
||||||
shelf_web_socket:
|
shelf_web_socket:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf_web_socket
|
name: shelf_web_socket
|
||||||
sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8
|
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.3"
|
version: "2.0.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -580,10 +596,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: socks5_proxy
|
name: socks5_proxy
|
||||||
sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a"
|
sha256: "616818a0ea1064a4823b53c9f7eaf8da64ed82dcd51ed71371c7e54751ed5053"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.6"
|
||||||
source_gen:
|
source_gen:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -652,10 +668,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.1"
|
version: "0.7.2"
|
||||||
timing:
|
timing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -676,10 +692,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.1"
|
version: "1.4.0"
|
||||||
unorm_dart:
|
unorm_dart:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -700,10 +716,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "13.0.0"
|
version: "14.2.4"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: "direct overridden"
|
dependency: "direct overridden"
|
||||||
description:
|
description:
|
||||||
|
@ -712,38 +728,46 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web
|
||||||
|
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
|
web_socket:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket
|
||||||
|
sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.6"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b
|
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "3.0.1"
|
||||||
win32:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: win32
|
|
||||||
sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.1.3"
|
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
|
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.1.0"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: yaml
|
name: yaml
|
||||||
sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370"
|
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.2.0-0 <4.0.0"
|
dart: ">=3.5.0 <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.24.0"
|
||||||
|
|
|
@ -17,7 +17,7 @@ dependencies:
|
||||||
path_provider: ^2.0.11
|
path_provider: ^2.0.11
|
||||||
mobx: ^2.0.7+4
|
mobx: ^2.0.7+4
|
||||||
flutter_mobx: ^2.0.6+1
|
flutter_mobx: ^2.0.6+1
|
||||||
intl: ^0.18.0
|
intl: ^0.19.0
|
||||||
cw_core:
|
cw_core:
|
||||||
path: ../cw_core
|
path: ../cw_core
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,18 @@ int countOfCoins() => monero.Coins_count(coins!);
|
||||||
|
|
||||||
monero.CoinsInfo getCoin(int index) => monero.Coins_coin(coins!, index);
|
monero.CoinsInfo getCoin(int index) => monero.Coins_coin(coins!, index);
|
||||||
|
|
||||||
|
int? getCoinByKeyImage(String keyImage) {
|
||||||
|
final count = countOfCoins();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
final coin = getCoin(i);
|
||||||
|
final coinAddress = monero.CoinsInfo_keyImage(coin);
|
||||||
|
if (keyImage == coinAddress) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
void freezeCoin(int index) => monero.Coins_setFrozen(coins!, index: index);
|
void freezeCoin(int index) => monero.Coins_setFrozen(coins!, index: index);
|
||||||
|
|
||||||
void thawCoin(int index) => monero.Coins_thaw(coins!, index: index);
|
void thawCoin(int index) => monero.Coins_thaw(coins!, index: index);
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:cw_monero/api/exceptions/creation_transaction_exception.dart';
|
||||||
import 'package:cw_monero/api/monero_output.dart';
|
import 'package:cw_monero/api/monero_output.dart';
|
||||||
import 'package:cw_monero/api/structs/pending_transaction.dart';
|
import 'package:cw_monero/api/structs/pending_transaction.dart';
|
||||||
import 'package:cw_monero/api/wallet.dart';
|
import 'package:cw_monero/api/wallet.dart';
|
||||||
|
import 'package:cw_monero/exceptions/monero_transaction_creation_exception.dart';
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/monero.dart' as monero;
|
||||||
import 'package:monero/src/generated_bindings_monero.g.dart' as monero_gen;
|
import 'package:monero/src/generated_bindings_monero.g.dart' as monero_gen;
|
||||||
|
@ -17,7 +18,7 @@ String getTxKey(String txId) {
|
||||||
final status = monero.Wallet_status(wptr!);
|
final status = monero.Wallet_status(wptr!);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final error = monero.Wallet_errorString(wptr!);
|
final error = monero.Wallet_errorString(wptr!);
|
||||||
return txId+"_"+error;
|
return "";
|
||||||
}
|
}
|
||||||
return txKey;
|
return txKey;
|
||||||
}
|
}
|
||||||
|
@ -91,12 +92,23 @@ Future<PendingTransactionDescription> createTransactionSync(
|
||||||
List<String> preferredInputs = const []}) async {
|
List<String> preferredInputs = const []}) async {
|
||||||
|
|
||||||
final amt = amount == null ? 0 : monero.Wallet_amountFromString(amount);
|
final amt = amount == null ? 0 : monero.Wallet_amountFromString(amount);
|
||||||
|
|
||||||
final address_ = address.toNativeUtf8();
|
|
||||||
final paymentId_ = paymentId.toNativeUtf8();
|
|
||||||
final preferredInputs_ = preferredInputs.join(monero.defaultSeparatorStr).toNativeUtf8();
|
|
||||||
|
|
||||||
final waddr = wptr!.address;
|
final waddr = wptr!.address;
|
||||||
|
|
||||||
|
// force reconnection in case the os killed the connection?
|
||||||
|
// fixes failed to get block height error.
|
||||||
|
Isolate.run(() async {
|
||||||
|
monero.Wallet_synchronized(Pointer.fromAddress(waddr));
|
||||||
|
});
|
||||||
|
|
||||||
|
final address_ = address.toNativeUtf8();
|
||||||
|
final paymentId_ = paymentId.toNativeUtf8();
|
||||||
|
if (preferredInputs.isEmpty) {
|
||||||
|
throw MoneroTransactionCreationException("No inputs provided, transaction cannot be constructed");
|
||||||
|
}
|
||||||
|
|
||||||
|
final preferredInputs_ = preferredInputs.join(monero.defaultSeparatorStr).toNativeUtf8();
|
||||||
|
|
||||||
final addraddr = address_.address;
|
final addraddr = address_.address;
|
||||||
final paymentIdAddr = paymentId_.address;
|
final paymentIdAddr = paymentId_.address;
|
||||||
final preferredInputsAddr = preferredInputs_.address;
|
final preferredInputsAddr = preferredInputs_.address;
|
||||||
|
@ -159,8 +171,8 @@ PendingTransactionDescription createTransactionMultDestSync(
|
||||||
final dstAddrs = outputs.map((e) => e.address).toList();
|
final dstAddrs = outputs.map((e) => e.address).toList();
|
||||||
final amounts = outputs.map((e) => monero.Wallet_amountFromString(e.amount)).toList();
|
final amounts = outputs.map((e) => monero.Wallet_amountFromString(e.amount)).toList();
|
||||||
|
|
||||||
// print("multDest: dstAddrs: $dstAddrs");
|
// printV("multDest: dstAddrs: $dstAddrs");
|
||||||
// print("multDest: amounts: $amounts");
|
// printV("multDest: amounts: $amounts");
|
||||||
|
|
||||||
final txptr = monero.Wallet_createTransactionMultDest(
|
final txptr = monero.Wallet_createTransactionMultDest(
|
||||||
wptr!,
|
wptr!,
|
||||||
|
@ -188,19 +200,35 @@ String? commitTransactionFromPointerAddress({required int address, required bool
|
||||||
commitTransaction(transactionPointer: monero.PendingTransaction.fromAddress(address), useUR: useUR);
|
commitTransaction(transactionPointer: monero.PendingTransaction.fromAddress(address), useUR: useUR);
|
||||||
|
|
||||||
String? commitTransaction({required monero.PendingTransaction transactionPointer, required bool useUR}) {
|
String? commitTransaction({required monero.PendingTransaction transactionPointer, required bool useUR}) {
|
||||||
|
final transactionPointerAddress = transactionPointer.address;
|
||||||
final txCommit = useUR
|
final txCommit = useUR
|
||||||
? monero.PendingTransaction_commitUR(transactionPointer, 120)
|
? monero.PendingTransaction_commitUR(transactionPointer, 120)
|
||||||
: monero.PendingTransaction_commit(transactionPointer, filename: '', overwrite: false);
|
: Isolate.run(() {
|
||||||
|
monero.PendingTransaction_commit(
|
||||||
|
Pointer.fromAddress(transactionPointerAddress),
|
||||||
|
filename: '',
|
||||||
|
overwrite: false,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
final String? error = (() {
|
String? error = (() {
|
||||||
final status = monero.PendingTransaction_status(transactionPointer.cast());
|
final status = monero.PendingTransaction_status(transactionPointer.cast());
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return monero.Wallet_errorString(wptr!);
|
return monero.PendingTransaction_errorString(transactionPointer.cast());
|
||||||
})();
|
})();
|
||||||
|
if (error == null) {
|
||||||
|
error = (() {
|
||||||
|
final status = monero.Wallet_status(wptr!);
|
||||||
|
if (status == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return monero.Wallet_errorString(wptr!);
|
||||||
|
})();
|
||||||
|
|
||||||
if (error != null) {
|
}
|
||||||
|
if (error != null && error != "no tx keys found for this txid") {
|
||||||
throw CreationTransactionException(message: error);
|
throw CreationTransactionException(message: error);
|
||||||
}
|
}
|
||||||
if (useUR) {
|
if (useUR) {
|
||||||
|
@ -348,16 +376,7 @@ class Transaction {
|
||||||
confirmations = monero.TransactionInfo_confirmations(txInfo),
|
confirmations = monero.TransactionInfo_confirmations(txInfo),
|
||||||
fee = monero.TransactionInfo_fee(txInfo),
|
fee = monero.TransactionInfo_fee(txInfo),
|
||||||
description = monero.TransactionInfo_description(txInfo),
|
description = monero.TransactionInfo_description(txInfo),
|
||||||
key = getTxKey(txInfo);
|
key = getTxKey(monero.TransactionInfo_hash(txInfo));
|
||||||
|
|
||||||
static String getTxKey(monero.TransactionInfo txInfo) {
|
|
||||||
final txKey = monero.Wallet_getTxKey(wptr!, txid: monero.TransactionInfo_hash(txInfo));
|
|
||||||
final status = monero.Wallet_status(wptr!);
|
|
||||||
if (status != 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return txKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
Transaction.dummy({
|
Transaction.dummy({
|
||||||
required this.displayLabel,
|
required this.displayLabel,
|
||||||
|
|
|
@ -2,15 +2,17 @@ import 'dart:async';
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_monero/api/account_list.dart';
|
import 'package:cw_monero/api/account_list.dart';
|
||||||
import 'package:cw_monero/api/exceptions/setup_wallet_exception.dart';
|
import 'package:cw_monero/api/exceptions/setup_wallet_exception.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/monero.dart' as monero;
|
||||||
import 'package:mutex/mutex.dart';
|
import 'package:mutex/mutex.dart';
|
||||||
|
|
||||||
int getSyncingHeight() {
|
int getSyncingHeight() {
|
||||||
// final height = monero.MONERO_cw_WalletListener_height(getWlptr());
|
// final height = monero.MONERO_cw_WalletListener_height(getWlptr());
|
||||||
final h2 = monero.Wallet_blockChainHeight(wptr!);
|
final h2 = monero.Wallet_blockChainHeight(wptr!);
|
||||||
// print("height: $height / $h2");
|
// printV("height: $height / $h2");
|
||||||
return h2;
|
return h2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,9 +71,9 @@ String getSeedLegacy(String? language) {
|
||||||
Map<int, Map<int, Map<int, String>>> addressCache = {};
|
Map<int, Map<int, Map<int, String>>> addressCache = {};
|
||||||
|
|
||||||
String getAddress({int accountIndex = 0, int addressIndex = 0}) {
|
String getAddress({int accountIndex = 0, int addressIndex = 0}) {
|
||||||
// print("getaddress: ${accountIndex}/${addressIndex}: ${monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)}: ${monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex)}");
|
// printV("getaddress: ${accountIndex}/${addressIndex}: ${monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)}: ${monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex)}");
|
||||||
while (monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)-1 < addressIndex) {
|
while (monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)-1 < addressIndex) {
|
||||||
print("adding subaddress");
|
printV("adding subaddress");
|
||||||
monero.Wallet_addSubaddress(wptr!, accountIndex: accountIndex);
|
monero.Wallet_addSubaddress(wptr!, accountIndex: accountIndex);
|
||||||
}
|
}
|
||||||
addressCache[wptr!.address] ??= {};
|
addressCache[wptr!.address] ??= {};
|
||||||
|
@ -100,7 +102,7 @@ Future<bool> setupNodeSync(
|
||||||
bool useSSL = false,
|
bool useSSL = false,
|
||||||
bool isLightWallet = false,
|
bool isLightWallet = false,
|
||||||
String? socksProxyAddress}) async {
|
String? socksProxyAddress}) async {
|
||||||
print('''
|
printV('''
|
||||||
{
|
{
|
||||||
wptr!,
|
wptr!,
|
||||||
daemonAddress: $address,
|
daemonAddress: $address,
|
||||||
|
@ -119,16 +121,24 @@ Future<bool> setupNodeSync(
|
||||||
daemonUsername: login ?? '',
|
daemonUsername: login ?? '',
|
||||||
daemonPassword: password ?? '');
|
daemonPassword: password ?? '');
|
||||||
});
|
});
|
||||||
// monero.Wallet_init3(wptr!, argv0: '', defaultLogBaseName: 'moneroc', console: true, logPath: '');
|
|
||||||
|
|
||||||
final status = monero.Wallet_status(wptr!);
|
final status = monero.Wallet_status(wptr!);
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final error = monero.Wallet_errorString(wptr!);
|
final error = monero.Wallet_errorString(wptr!);
|
||||||
print("error: $error");
|
printV("error: $error");
|
||||||
throw SetupWalletException(message: error);
|
throw SetupWalletException(message: error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (kDebugMode) {
|
||||||
|
monero.Wallet_init3(
|
||||||
|
wptr!, argv0: '',
|
||||||
|
defaultLogBaseName: 'moneroc',
|
||||||
|
console: true,
|
||||||
|
logPath: '',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return status == 0;
|
return status == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,14 +160,15 @@ final storeMutex = Mutex();
|
||||||
|
|
||||||
int lastStorePointer = 0;
|
int lastStorePointer = 0;
|
||||||
int lastStoreHeight = 0;
|
int lastStoreHeight = 0;
|
||||||
void storeSync() async {
|
void storeSync({bool force = false}) async {
|
||||||
final addr = wptr!.address;
|
final addr = wptr!.address;
|
||||||
final synchronized = await Isolate.run(() {
|
final synchronized = await Isolate.run(() {
|
||||||
return monero.Wallet_synchronized(Pointer.fromAddress(addr));
|
return monero.Wallet_synchronized(Pointer.fromAddress(addr));
|
||||||
});
|
});
|
||||||
if (lastStorePointer == wptr!.address &&
|
if (lastStorePointer == wptr!.address &&
|
||||||
lastStoreHeight + 5000 > monero.Wallet_blockChainHeight(wptr!) &&
|
lastStoreHeight + 5000 > monero.Wallet_blockChainHeight(wptr!) &&
|
||||||
!synchronized) {
|
!synchronized &&
|
||||||
|
!force) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lastStorePointer = wptr!.address;
|
lastStorePointer = wptr!.address;
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:ffi';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_monero/api/account_list.dart';
|
import 'package:cw_monero/api/account_list.dart';
|
||||||
import 'package:cw_monero/api/exceptions/wallet_creation_exception.dart';
|
import 'package:cw_monero/api/exceptions/wallet_creation_exception.dart';
|
||||||
import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
|
import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
|
||||||
|
@ -50,9 +51,9 @@ final monero.WalletManager wmPtr = Pointer.fromAddress((() {
|
||||||
// than plugging gdb in. Especially on windows/android.
|
// than plugging gdb in. Especially on windows/android.
|
||||||
monero.printStarts = false;
|
monero.printStarts = false;
|
||||||
_wmPtr ??= monero.WalletManagerFactory_getWalletManager();
|
_wmPtr ??= monero.WalletManagerFactory_getWalletManager();
|
||||||
print("ptr: $_wmPtr");
|
printV("ptr: $_wmPtr");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
printV(e);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
return _wmPtr!.address;
|
return _wmPtr!.address;
|
||||||
|
@ -81,6 +82,7 @@ void createWalletSync(
|
||||||
wptr = newWptr;
|
wptr = newWptr;
|
||||||
monero.Wallet_store(wptr!, path: path);
|
monero.Wallet_store(wptr!, path: path);
|
||||||
openedWalletsByPath[path] = wptr!;
|
openedWalletsByPath[path] = wptr!;
|
||||||
|
_lastOpenedWallet = path;
|
||||||
|
|
||||||
// is the line below needed?
|
// is the line below needed?
|
||||||
// setupNodeSync(address: "node.moneroworld.com:18089");
|
// setupNodeSync(address: "node.moneroworld.com:18089");
|
||||||
|
@ -116,6 +118,7 @@ void restoreWalletFromSeedSync(
|
||||||
wptr = newWptr;
|
wptr = newWptr;
|
||||||
|
|
||||||
openedWalletsByPath[path] = wptr!;
|
openedWalletsByPath[path] = wptr!;
|
||||||
|
_lastOpenedWallet = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void restoreWalletFromKeysSync(
|
void restoreWalletFromKeysSync(
|
||||||
|
@ -183,6 +186,7 @@ void restoreWalletFromKeysSync(
|
||||||
wptr = newWptr;
|
wptr = newWptr;
|
||||||
|
|
||||||
openedWalletsByPath[path] = wptr!;
|
openedWalletsByPath[path] = wptr!;
|
||||||
|
_lastOpenedWallet = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void restoreWalletFromSpendKeySync(
|
void restoreWalletFromSpendKeySync(
|
||||||
|
@ -220,7 +224,7 @@ void restoreWalletFromSpendKeySync(
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final err = monero.Wallet_errorString(newWptr);
|
final err = monero.Wallet_errorString(newWptr);
|
||||||
print("err: $err");
|
printV("err: $err");
|
||||||
throw WalletRestoreFromKeysException(message: err);
|
throw WalletRestoreFromKeysException(message: err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,6 +235,7 @@ void restoreWalletFromSpendKeySync(
|
||||||
storeSync();
|
storeSync();
|
||||||
|
|
||||||
openedWalletsByPath[path] = wptr!;
|
openedWalletsByPath[path] = wptr!;
|
||||||
|
_lastOpenedWallet = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _lastOpenedWallet = "";
|
String _lastOpenedWallet = "";
|
||||||
|
@ -260,7 +265,7 @@ Future<void> restoreWalletFromHardwareWallet(
|
||||||
throw WalletRestoreFromSeedException(message: error);
|
throw WalletRestoreFromSeedException(message: error);
|
||||||
}
|
}
|
||||||
wptr = newWptr;
|
wptr = newWptr;
|
||||||
|
_lastOpenedWallet = path;
|
||||||
openedWalletsByPath[path] = wptr!;
|
openedWalletsByPath[path] = wptr!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,8 +291,23 @@ Future<void> loadWallet(
|
||||||
/// 0: Software Wallet
|
/// 0: Software Wallet
|
||||||
/// 1: Ledger
|
/// 1: Ledger
|
||||||
/// 2: Trezor
|
/// 2: Trezor
|
||||||
final deviceType = monero.WalletManager_queryWalletDevice(wmPtr,
|
late final deviceType;
|
||||||
keysFileName: "$path.keys", password: password, kdfRounds: 1);
|
|
||||||
|
if (Platform.isAndroid || Platform.isIOS) {
|
||||||
|
deviceType = monero.WalletManager_queryWalletDevice(
|
||||||
|
wmPtr,
|
||||||
|
keysFileName: "$path.keys",
|
||||||
|
password: password,
|
||||||
|
kdfRounds: 1,
|
||||||
|
);
|
||||||
|
final status = monero.WalletManager_errorString(wmPtr);
|
||||||
|
if (status != "") {
|
||||||
|
printV("loadWallet:"+status);
|
||||||
|
throw WalletOpeningException(message: status);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
deviceType = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (deviceType == 1) {
|
if (deviceType == 1) {
|
||||||
final dummyWPtr = wptr ??
|
final dummyWPtr = wptr ??
|
||||||
|
@ -304,15 +324,15 @@ Future<void> loadWallet(
|
||||||
|
|
||||||
final newWptr = Pointer<Void>.fromAddress(newWptrAddr);
|
final newWptr = Pointer<Void>.fromAddress(newWptrAddr);
|
||||||
|
|
||||||
_lastOpenedWallet = path;
|
|
||||||
final status = monero.Wallet_status(newWptr);
|
final status = monero.Wallet_status(newWptr);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final err = monero.Wallet_errorString(newWptr);
|
final err = monero.Wallet_errorString(newWptr);
|
||||||
print(err);
|
printV("loadWallet:"+err);
|
||||||
throw WalletOpeningException(message: err);
|
throw WalletOpeningException(message: err);
|
||||||
}
|
}
|
||||||
|
|
||||||
wptr = newWptr;
|
wptr = newWptr;
|
||||||
|
_lastOpenedWallet = path;
|
||||||
openedWalletsByPath[path] = wptr!;
|
openedWalletsByPath[path] = wptr!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,12 @@ import 'dart:async';
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
||||||
import 'package:ledger_flutter_plus/ledger_flutter_plus_dart.dart';
|
import 'package:ledger_flutter_plus/ledger_flutter_plus_dart.dart';
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/monero.dart' as monero;
|
||||||
// import 'package:polyseed/polyseed.dart';
|
|
||||||
|
|
||||||
LedgerConnection? gLedger;
|
LedgerConnection? gLedger;
|
||||||
|
|
||||||
|
@ -28,9 +29,16 @@ void enableLedgerExchange(monero.wallet ptr, LedgerConnection connection) {
|
||||||
ptr, emptyPointer.cast<UnsignedChar>(), 0);
|
ptr, emptyPointer.cast<UnsignedChar>(), 0);
|
||||||
malloc.free(emptyPointer);
|
malloc.free(emptyPointer);
|
||||||
|
|
||||||
// print("> ${ledgerRequest.toHexString()}");
|
_logLedgerCommand(ledgerRequest, false);
|
||||||
final response = await exchange(connection, ledgerRequest);
|
final response = await exchange(connection, ledgerRequest);
|
||||||
// print("< ${response.toHexString()}");
|
_logLedgerCommand(response, true);
|
||||||
|
|
||||||
|
if (ListEquality().equals(response, [0x55, 0x15])) {
|
||||||
|
await connection.disconnect();
|
||||||
|
// // TODO: Show POPUP pls unlock your device
|
||||||
|
// await Future.delayed(Duration(seconds: 15));
|
||||||
|
// response = await exchange(connection, ledgerRequest);
|
||||||
|
}
|
||||||
|
|
||||||
final Pointer<Uint8> result = malloc<Uint8>(response.length);
|
final Pointer<Uint8> result = malloc<Uint8>(response.length);
|
||||||
for (var i = 0; i < response.length; i++) {
|
for (var i = 0; i < response.length; i++) {
|
||||||
|
@ -82,3 +90,59 @@ class ExchangeOperation extends LedgerRawOperation<Uint8List> {
|
||||||
@override
|
@override
|
||||||
Future<List<Uint8List>> write(ByteDataWriter writer) async => [inputData];
|
Future<List<Uint8List>> write(ByteDataWriter writer) async => [inputData];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _ledgerMoneroCommands = {
|
||||||
|
0x00: "INS_NONE",
|
||||||
|
0x02: "INS_RESET",
|
||||||
|
0x20: "INS_GET_KEY",
|
||||||
|
0x21: "INS_DISPLAY_ADDRESS",
|
||||||
|
0x22: "INS_PUT_KEY",
|
||||||
|
0x24: "INS_GET_CHACHA8_PREKEY",
|
||||||
|
0x26: "INS_VERIFY_KEY",
|
||||||
|
0x28: "INS_MANAGE_SEEDWORDS",
|
||||||
|
0x30: "INS_SECRET_KEY_TO_PUBLIC_KEY",
|
||||||
|
0x32: "INS_GEN_KEY_DERIVATION",
|
||||||
|
0x34: "INS_DERIVATION_TO_SCALAR",
|
||||||
|
0x36: "INS_DERIVE_PUBLIC_KEY",
|
||||||
|
0x38: "INS_DERIVE_SECRET_KEY",
|
||||||
|
0x3A: "INS_GEN_KEY_IMAGE",
|
||||||
|
0x3B: "INS_DERIVE_VIEW_TAG",
|
||||||
|
0x3C: "INS_SECRET_KEY_ADD",
|
||||||
|
0x3E: "INS_SECRET_KEY_SUB",
|
||||||
|
0x40: "INS_GENERATE_KEYPAIR",
|
||||||
|
0x42: "INS_SECRET_SCAL_MUL_KEY",
|
||||||
|
0x44: "INS_SECRET_SCAL_MUL_BASE",
|
||||||
|
0x46: "INS_DERIVE_SUBADDRESS_PUBLIC_KEY",
|
||||||
|
0x48: "INS_GET_SUBADDRESS",
|
||||||
|
0x4A: "INS_GET_SUBADDRESS_SPEND_PUBLIC_KEY",
|
||||||
|
0x4C: "INS_GET_SUBADDRESS_SECRET_KEY",
|
||||||
|
0x70: "INS_OPEN_TX",
|
||||||
|
0x72: "INS_SET_SIGNATURE_MODE",
|
||||||
|
0x74: "INS_GET_ADDITIONAL_KEY",
|
||||||
|
0x76: "INS_STEALTH",
|
||||||
|
0x77: "INS_GEN_COMMITMENT_MASK",
|
||||||
|
0x78: "INS_BLIND",
|
||||||
|
0x7A: "INS_UNBLIND",
|
||||||
|
0x7B: "INS_GEN_TXOUT_KEYS",
|
||||||
|
0x7D: "INS_PREFIX_HASH",
|
||||||
|
0x7C: "INS_VALIDATE",
|
||||||
|
0x7E: "INS_MLSAG",
|
||||||
|
0x7F: "INS_CLSAG",
|
||||||
|
0x80: "INS_CLOSE_TX",
|
||||||
|
0xA0: "INS_GET_TX_PROOF",
|
||||||
|
0xC0: "INS_GET_RESPONSE"
|
||||||
|
};
|
||||||
|
|
||||||
|
void _logLedgerCommand(Uint8List command, [bool isResponse = true]) {
|
||||||
|
String toHexString(Uint8List data) =>
|
||||||
|
data.map((e) => e.toRadixString(16).padLeft(2, '0')).join();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (isResponse) {
|
||||||
|
printV("< ${toHexString(command)}");
|
||||||
|
} else {
|
||||||
|
printV(
|
||||||
|
"> ${_ledgerMoneroCommands[command[1]]} ${toHexString(command.sublist(2))}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:cw_core/monero_amount_format.dart';
|
import 'package:cw_core/monero_amount_format.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:cw_core/account.dart';
|
import 'package:cw_core/account.dart';
|
||||||
import 'package:cw_monero/api/account_list.dart' as account_list;
|
import 'package:cw_monero/api/account_list.dart' as account_list;
|
||||||
|
@ -74,7 +75,7 @@ abstract class MoneroAccountListBase with Store {
|
||||||
_isRefreshing = false;
|
_isRefreshing = false;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_isRefreshing = false;
|
_isRefreshing = false;
|
||||||
print(e);
|
printV(e);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:cw_core/subaddress.dart';
|
import 'package:cw_core/subaddress.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_monero/api/coins_info.dart';
|
import 'package:cw_monero/api/coins_info.dart';
|
||||||
import 'package:cw_monero/api/subaddress_list.dart' as subaddress_list;
|
import 'package:cw_monero/api/subaddress_list.dart' as subaddress_list;
|
||||||
import 'package:cw_monero/api/wallet.dart';
|
import 'package:cw_monero/api/wallet.dart';
|
||||||
|
@ -87,7 +88,7 @@ abstract class MoneroSubaddressListBase with Store {
|
||||||
_isRefreshing = false;
|
_isRefreshing = false;
|
||||||
} on PlatformException catch (e) {
|
} on PlatformException catch (e) {
|
||||||
_isRefreshing = false;
|
_isRefreshing = false;
|
||||||
print(e);
|
printV(e);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,33 @@
|
||||||
import 'package:cw_core/unspent_transaction_output.dart';
|
import 'package:cw_core/unspent_transaction_output.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
|
import 'package:cw_monero/api/coins_info.dart';
|
||||||
|
import 'package:monero/monero.dart' as monero;
|
||||||
|
|
||||||
class MoneroUnspent extends Unspent {
|
class MoneroUnspent extends Unspent {
|
||||||
MoneroUnspent(
|
MoneroUnspent(
|
||||||
String address, String hash, String keyImage, int value, bool isFrozen, this.isUnlocked)
|
String address, String hash, String keyImage, int value, bool isFrozen, this.isUnlocked)
|
||||||
: super(address, hash, value, 0, keyImage) {
|
: super(address, hash, value, 0, keyImage) {
|
||||||
this.isFrozen = isFrozen;
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
set isFrozen(bool freeze) {
|
||||||
|
printV("set isFrozen: $freeze ($keyImage): $freeze");
|
||||||
|
final coinId = getCoinByKeyImage(keyImage!);
|
||||||
|
if (coinId == null) throw Exception("Unable to find a coin for address $address");
|
||||||
|
if (freeze) {
|
||||||
|
freezeCoin(coinId);
|
||||||
|
} else {
|
||||||
|
thawCoin(coinId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isFrozen {
|
||||||
|
printV("get isFrozen");
|
||||||
|
final coinId = getCoinByKeyImage(keyImage!);
|
||||||
|
if (coinId == null) throw Exception("Unable to find a coin for address $address");
|
||||||
|
final coin = getCoin(coinId);
|
||||||
|
return monero.CoinsInfo_frozen(coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
final bool isUnlocked;
|
final bool isUnlocked;
|
||||||
|
|
|
@ -17,6 +17,7 @@ import 'package:cw_core/pending_transaction.dart';
|
||||||
import 'package:cw_core/sync_status.dart';
|
import 'package:cw_core/sync_status.dart';
|
||||||
import 'package:cw_core/transaction_direction.dart';
|
import 'package:cw_core/transaction_direction.dart';
|
||||||
import 'package:cw_core/unspent_coins_info.dart';
|
import 'package:cw_core/unspent_coins_info.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_monero/api/account_list.dart';
|
import 'package:cw_monero/api/account_list.dart';
|
||||||
|
@ -167,7 +168,7 @@ abstract class MoneroWalletBase
|
||||||
Future<void>? updateBalance() => null;
|
Future<void>? updateBalance() => null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close({required bool shouldCleanup}) async {
|
Future<void> close({bool shouldCleanup = false}) async {
|
||||||
_listener?.stop();
|
_listener?.stop();
|
||||||
_onAccountChangeReaction?.reaction.dispose();
|
_onAccountChangeReaction?.reaction.dispose();
|
||||||
_onTxHistoryChangeReaction?.reaction.dispose();
|
_onTxHistoryChangeReaction?.reaction.dispose();
|
||||||
|
@ -191,7 +192,7 @@ abstract class MoneroWalletBase
|
||||||
syncStatus = ConnectedSyncStatus();
|
syncStatus = ConnectedSyncStatus();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
syncStatus = FailedSyncStatus();
|
syncStatus = FailedSyncStatus();
|
||||||
print(e);
|
printV(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +223,7 @@ abstract class MoneroWalletBase
|
||||||
_listener?.start();
|
_listener?.start();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
syncStatus = FailedSyncStatus();
|
syncStatus = FailedSyncStatus();
|
||||||
print(e);
|
printV(e);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,9 +307,8 @@ abstract class MoneroWalletBase
|
||||||
throw MoneroTransactionCreationException('You do not have enough XMR to send this amount.');
|
throw MoneroTransactionCreationException('You do not have enough XMR to send this amount.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!spendAllCoins && (allInputsAmount < totalAmount + estimatedFee)) {
|
if (inputs.isEmpty) MoneroTransactionCreationException(
|
||||||
throw MoneroTransactionNoInputsException(inputs.length);
|
'No inputs selected');
|
||||||
}
|
|
||||||
|
|
||||||
final moneroOutputs = outputs.map((output) {
|
final moneroOutputs = outputs.map((output) {
|
||||||
final outputAddress = output.isParsedAddress ? output.extractedAddress : output.address;
|
final outputAddress = output.isParsedAddress ? output.extractedAddress : output.address;
|
||||||
|
@ -328,29 +328,29 @@ abstract class MoneroWalletBase
|
||||||
final amount = output.sendAll ? null : output.cryptoAmount!.replaceAll(',', '.');
|
final amount = output.sendAll ? null : output.cryptoAmount!.replaceAll(',', '.');
|
||||||
final formattedAmount = output.sendAll ? null : output.formattedCryptoAmount;
|
final formattedAmount = output.sendAll ? null : output.formattedCryptoAmount;
|
||||||
|
|
||||||
if ((formattedAmount != null && unlockedBalance < formattedAmount) ||
|
// if ((formattedAmount != null && unlockedBalance < formattedAmount) ||
|
||||||
(formattedAmount == null && unlockedBalance <= 0)) {
|
// (formattedAmount == null && unlockedBalance <= 0)) {
|
||||||
final formattedBalance = moneroAmountToString(amount: unlockedBalance);
|
// final formattedBalance = moneroAmountToString(amount: unlockedBalance);
|
||||||
|
//
|
||||||
|
// throw MoneroTransactionCreationException(
|
||||||
|
// 'You do not have enough unlocked balance. Unlocked: $formattedBalance. Transaction amount: ${output.cryptoAmount}.');
|
||||||
|
// }
|
||||||
|
|
||||||
throw MoneroTransactionCreationException(
|
final estimatedFee =
|
||||||
'You do not have enough unlocked balance. Unlocked: $formattedBalance. Transaction amount: ${output.cryptoAmount}.');
|
calculateEstimatedFee(_credentials.priority, formattedAmount);
|
||||||
}
|
if (inputs.isEmpty) MoneroTransactionCreationException(
|
||||||
|
'No inputs selected');
|
||||||
final estimatedFee = calculateEstimatedFee(_credentials.priority, formattedAmount);
|
pendingTransactionDescription =
|
||||||
if (!spendAllCoins &&
|
await transaction_history.createTransaction(
|
||||||
((formattedAmount != null && allInputsAmount < (formattedAmount + estimatedFee)) ||
|
address: address!,
|
||||||
formattedAmount == null)) {
|
amount: amount,
|
||||||
throw MoneroTransactionNoInputsException(inputs.length);
|
priorityRaw: _credentials.priority.serialize(),
|
||||||
}
|
accountIndex: walletAddresses.account!.id,
|
||||||
|
preferredInputs: inputs);
|
||||||
pendingTransactionDescription = await transaction_history.createTransaction(
|
|
||||||
address: address!,
|
|
||||||
amount: amount,
|
|
||||||
priorityRaw: _credentials.priority.serialize(),
|
|
||||||
accountIndex: walletAddresses.account!.id,
|
|
||||||
preferredInputs: inputs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// final status = monero.PendingTransaction_status(pendingTransactionDescription);
|
||||||
|
|
||||||
return PendingMoneroTransaction(pendingTransactionDescription);
|
return PendingMoneroTransaction(pendingTransactionDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,8 +391,8 @@ abstract class MoneroWalletBase
|
||||||
try {
|
try {
|
||||||
await backupWalletFiles(name);
|
await backupWalletFiles(name);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("¯\\_(ツ)_/¯");
|
printV("¯\\_(ツ)_/¯");
|
||||||
print(e);
|
printV(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,7 +401,7 @@ abstract class MoneroWalletBase
|
||||||
final currentWalletDirPath = await pathForWalletDir(name: name, type: type);
|
final currentWalletDirPath = await pathForWalletDir(name: name, type: type);
|
||||||
if (openedWalletsByPath["$currentWalletDirPath/$name"] != null) {
|
if (openedWalletsByPath["$currentWalletDirPath/$name"] != null) {
|
||||||
// NOTE: this is realistically only required on windows.
|
// NOTE: this is realistically only required on windows.
|
||||||
print("closing wallet");
|
printV("closing wallet");
|
||||||
final wmaddr = wmPtr.address;
|
final wmaddr = wmPtr.address;
|
||||||
final waddr = openedWalletsByPath["$currentWalletDirPath/$name"]!.address;
|
final waddr = openedWalletsByPath["$currentWalletDirPath/$name"]!.address;
|
||||||
await Isolate.run(() {
|
await Isolate.run(() {
|
||||||
|
@ -409,7 +409,7 @@ abstract class MoneroWalletBase
|
||||||
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
|
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
|
||||||
});
|
});
|
||||||
openedWalletsByPath.remove("$currentWalletDirPath/$name");
|
openedWalletsByPath.remove("$currentWalletDirPath/$name");
|
||||||
print("wallet closed");
|
printV("wallet closed");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// -- rename the waller folder --
|
// -- rename the waller folder --
|
||||||
|
@ -498,7 +498,7 @@ abstract class MoneroWalletBase
|
||||||
for (var i = 0; i < coinCount; i++) {
|
for (var i = 0; i < coinCount; i++) {
|
||||||
final coin = getCoin(i);
|
final coin = getCoin(i);
|
||||||
final coinSpent = monero.CoinsInfo_spent(coin);
|
final coinSpent = monero.CoinsInfo_spent(coin);
|
||||||
if (coinSpent == false) {
|
if (coinSpent == false && monero.CoinsInfo_subaddrAccount(coin) == walletAddresses.account!.id) {
|
||||||
final unspent = MoneroUnspent(
|
final unspent = MoneroUnspent(
|
||||||
monero.CoinsInfo_address(coin),
|
monero.CoinsInfo_address(coin),
|
||||||
monero.CoinsInfo_hash(coin),
|
monero.CoinsInfo_hash(coin),
|
||||||
|
@ -542,7 +542,7 @@ abstract class MoneroWalletBase
|
||||||
await _refreshUnspentCoinsInfo();
|
await _refreshUnspentCoinsInfo();
|
||||||
_askForUpdateBalance();
|
_askForUpdateBalance();
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
onError?.call(FlutterErrorDetails(
|
onError?.call(FlutterErrorDetails(
|
||||||
exception: e,
|
exception: e,
|
||||||
stack: s,
|
stack: s,
|
||||||
|
@ -589,7 +589,7 @@ abstract class MoneroWalletBase
|
||||||
await unspentCoinsInfo.deleteAll(keys);
|
await unspentCoinsInfo.deleteAll(keys);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,7 +621,7 @@ abstract class MoneroWalletBase
|
||||||
await transactionHistory.save();
|
await transactionHistory.save();
|
||||||
_isTransactionUpdating = false;
|
_isTransactionUpdating = false;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
printV(e);
|
||||||
_isTransactionUpdating = false;
|
_isTransactionUpdating = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -708,9 +708,9 @@ abstract class MoneroWalletBase
|
||||||
|
|
||||||
void _askForUpdateBalance() {
|
void _askForUpdateBalance() {
|
||||||
final unlockedBalance = _getUnlockedBalance();
|
final unlockedBalance = _getUnlockedBalance();
|
||||||
final fullBalance = _getFullBalance();
|
final fullBalance = monero_wallet.getFullBalance(
|
||||||
|
accountIndex: walletAddresses.account!.id);
|
||||||
final frozenBalance = _getFrozenBalance();
|
final frozenBalance = _getFrozenBalance();
|
||||||
|
|
||||||
if (balance[currency]!.fullBalance != fullBalance ||
|
if (balance[currency]!.fullBalance != fullBalance ||
|
||||||
balance[currency]!.unlockedBalance != unlockedBalance ||
|
balance[currency]!.unlockedBalance != unlockedBalance ||
|
||||||
balance[currency]!.frozenBalance != frozenBalance) {
|
balance[currency]!.frozenBalance != frozenBalance) {
|
||||||
|
@ -730,10 +730,10 @@ abstract class MoneroWalletBase
|
||||||
var frozenBalance = 0;
|
var frozenBalance = 0;
|
||||||
|
|
||||||
for (var coin in unspentCoinsInfo.values.where((element) =>
|
for (var coin in unspentCoinsInfo.values.where((element) =>
|
||||||
element.walletId == id && element.accountIndex == walletAddresses.account!.id)) {
|
element.walletId == id &&
|
||||||
if (coin.isFrozen) frozenBalance += coin.value;
|
element.accountIndex == walletAddresses.account!.id)) {
|
||||||
|
if (coin.isFrozen && !coin.isSending) frozenBalance += coin.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return frozenBalance;
|
return frozenBalance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,7 +763,7 @@ abstract class MoneroWalletBase
|
||||||
syncStatus = SyncingSyncStatus(blocksLeft, ptc);
|
syncStatus = SyncingSyncStatus(blocksLeft, ptc);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -773,7 +773,7 @@ abstract class MoneroWalletBase
|
||||||
_askForUpdateBalance();
|
_askForUpdateBalance();
|
||||||
await Future<void>.delayed(Duration(seconds: 1));
|
await Future<void>.delayed(Duration(seconds: 1));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:cw_core/account.dart';
|
import 'package:cw_core/account.dart';
|
||||||
import 'package:cw_core/address_info.dart';
|
import 'package:cw_core/address_info.dart';
|
||||||
import 'package:cw_core/subaddress.dart';
|
import 'package:cw_core/subaddress.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_addresses.dart';
|
import 'package:cw_core/wallet_addresses.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_monero/api/subaddress_list.dart' as subaddress_list;
|
import 'package:cw_monero/api/subaddress_list.dart' as subaddress_list;
|
||||||
|
@ -96,7 +97,7 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
|
||||||
|
|
||||||
await saveAddressesInBox();
|
await saveAddressesInBox();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,26 @@
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:cw_core/get_height_by_date.dart';
|
||||||
import 'package:cw_core/monero_wallet_utils.dart';
|
import 'package:cw_core/monero_wallet_utils.dart';
|
||||||
import 'package:cw_core/pathForWallet.dart';
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
import 'package:cw_core/unspent_coins_info.dart';
|
import 'package:cw_core/unspent_coins_info.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:cw_core/wallet_credentials.dart';
|
import 'package:cw_core/wallet_credentials.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/wallet_service.dart';
|
import 'package:cw_core/wallet_service.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
import 'package:cw_core/get_height_by_date.dart';
|
|
||||||
import 'package:cw_monero/api/account_list.dart';
|
import 'package:cw_monero/api/account_list.dart';
|
||||||
import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
|
import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
|
||||||
import 'package:cw_monero/api/wallet_manager.dart';
|
import 'package:cw_monero/api/wallet_manager.dart';
|
||||||
import 'package:cw_monero/ledger.dart';
|
import 'package:cw_monero/ledger.dart';
|
||||||
import 'package:cw_monero/monero_wallet.dart';
|
import 'package:cw_monero/monero_wallet.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
||||||
import 'package:polyseed/polyseed.dart';
|
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/monero.dart' as monero;
|
||||||
|
import 'package:polyseed/polyseed.dart';
|
||||||
|
|
||||||
class MoneroNewWalletCredentials extends WalletCredentials {
|
class MoneroNewWalletCredentials extends WalletCredentials {
|
||||||
MoneroNewWalletCredentials(
|
MoneroNewWalletCredentials(
|
||||||
|
@ -110,7 +113,7 @@ class MoneroWalletService extends WalletService<
|
||||||
return wallet;
|
return wallet;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: Implement Exception for wallet list service.
|
// TODO: Implement Exception for wallet list service.
|
||||||
print('MoneroWalletsManager Error: ${e.toString()}');
|
printV('MoneroWalletsManager Error: ${e.toString()}');
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +125,7 @@ class MoneroWalletService extends WalletService<
|
||||||
return monero_wallet_manager.isWalletExist(path: path);
|
return monero_wallet_manager.isWalletExist(path: path);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: Implement Exception for wallet list service.
|
// TODO: Implement Exception for wallet list service.
|
||||||
print('MoneroWalletsManager Error: $e');
|
printV('MoneroWalletsManager Error: $e');
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,14 +135,12 @@ class MoneroWalletService extends WalletService<
|
||||||
try {
|
try {
|
||||||
final path = await pathForWallet(name: name, type: getType());
|
final path = await pathForWallet(name: name, type: getType());
|
||||||
|
|
||||||
if (walletFilesExist(path)) {
|
if (walletFilesExist(path)) await repairOldAndroidWallet(name);
|
||||||
await repairOldAndroidWallet(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
await monero_wallet_manager
|
await monero_wallet_manager
|
||||||
.openWalletAsync({'path': path, 'password': password});
|
.openWalletAsync({'path': path, 'password': password});
|
||||||
final walletInfo = walletInfoSource.values.firstWhere(
|
final walletInfo = walletInfoSource.values
|
||||||
(info) => info.id == WalletBase.idFor(name, getType()));
|
.firstWhere((info) => info.id == WalletBase.idFor(name, getType()));
|
||||||
final wallet = MoneroWallet(
|
final wallet = MoneroWallet(
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||||
|
@ -168,7 +169,7 @@ class MoneroWalletService extends WalletService<
|
||||||
}
|
}
|
||||||
|
|
||||||
await restoreOrResetWalletFiles(name);
|
await restoreOrResetWalletFiles(name);
|
||||||
return openWallet(name, password, retryOnFailure: false);
|
return await openWallet(name, password, retryOnFailure: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +178,7 @@ class MoneroWalletService extends WalletService<
|
||||||
final path = await pathForWalletDir(name: wallet, type: getType());
|
final path = await pathForWalletDir(name: wallet, type: getType());
|
||||||
if (openedWalletsByPath["$path/$wallet"] != null) {
|
if (openedWalletsByPath["$path/$wallet"] != null) {
|
||||||
// NOTE: this is realistically only required on windows.
|
// NOTE: this is realistically only required on windows.
|
||||||
print("closing wallet");
|
printV("closing wallet");
|
||||||
final wmaddr = wmPtr.address;
|
final wmaddr = wmPtr.address;
|
||||||
final waddr = openedWalletsByPath["$path/$wallet"]!.address;
|
final waddr = openedWalletsByPath["$path/$wallet"]!.address;
|
||||||
// await Isolate.run(() {
|
// await Isolate.run(() {
|
||||||
|
@ -185,7 +186,7 @@ class MoneroWalletService extends WalletService<
|
||||||
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), false);
|
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), false);
|
||||||
// });
|
// });
|
||||||
openedWalletsByPath.remove("$path/$wallet");
|
openedWalletsByPath.remove("$path/$wallet");
|
||||||
print("wallet closed");
|
printV("wallet closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
final file = Directory(path);
|
final file = Directory(path);
|
||||||
|
@ -203,7 +204,7 @@ class MoneroWalletService extends WalletService<
|
||||||
@override
|
@override
|
||||||
Future<void> rename(String currentName, String password, String newName) async {
|
Future<void> rename(String currentName, String password, String newName) async {
|
||||||
final currentWalletInfo = walletInfoSource.values.firstWhere(
|
final currentWalletInfo = walletInfoSource.values.firstWhere(
|
||||||
(info) => info.id == WalletBase.idFor(currentName, getType()));
|
(info) => info.id == WalletBase.idFor(currentName, getType()));
|
||||||
final currentWallet = MoneroWallet(
|
final currentWallet = MoneroWallet(
|
||||||
walletInfo: currentWalletInfo,
|
walletInfo: currentWalletInfo,
|
||||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||||
|
@ -241,7 +242,7 @@ class MoneroWalletService extends WalletService<
|
||||||
return wallet;
|
return wallet;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: Implement Exception for wallet list service.
|
// TODO: Implement Exception for wallet list service.
|
||||||
print('MoneroWalletsManager Error: $e');
|
printV('MoneroWalletsManager Error: $e');
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,14 +255,14 @@ class MoneroWalletService extends WalletService<
|
||||||
final password = credentials.password;
|
final password = credentials.password;
|
||||||
final height = credentials.height;
|
final height = credentials.height;
|
||||||
|
|
||||||
if (wptr == null ) monero_wallet_manager.createWalletPointer();
|
if (wptr == null) monero_wallet_manager.createWalletPointer();
|
||||||
|
|
||||||
enableLedgerExchange(wptr!, credentials.ledgerConnection);
|
enableLedgerExchange(wptr!, credentials.ledgerConnection);
|
||||||
await monero_wallet_manager.restoreWalletFromHardwareWallet(
|
await monero_wallet_manager.restoreWalletFromHardwareWallet(
|
||||||
path: path,
|
path: path,
|
||||||
password: password!,
|
password: password!,
|
||||||
restoreHeight: height!,
|
restoreHeight: height!,
|
||||||
deviceName: 'Ledger');
|
deviceName: 'Ledger');
|
||||||
|
|
||||||
final wallet = MoneroWallet(
|
final wallet = MoneroWallet(
|
||||||
walletInfo: credentials.walletInfo!,
|
walletInfo: credentials.walletInfo!,
|
||||||
|
@ -272,13 +273,14 @@ class MoneroWalletService extends WalletService<
|
||||||
return wallet;
|
return wallet;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: Implement Exception for wallet list service.
|
// TODO: Implement Exception for wallet list service.
|
||||||
print('MoneroWalletsManager Error: $e');
|
printV('MoneroWalletsManager Error: $e');
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<MoneroWallet> restoreFromSeed(MoneroRestoreWalletFromSeedCredentials credentials,
|
Future<MoneroWallet> restoreFromSeed(
|
||||||
|
MoneroRestoreWalletFromSeedCredentials credentials,
|
||||||
{bool? isTestnet}) async {
|
{bool? isTestnet}) async {
|
||||||
// Restore from Polyseed
|
// Restore from Polyseed
|
||||||
if (Polyseed.isValidSeed(credentials.mnemonic)) {
|
if (Polyseed.isValidSeed(credentials.mnemonic)) {
|
||||||
|
@ -301,7 +303,7 @@ class MoneroWalletService extends WalletService<
|
||||||
return wallet;
|
return wallet;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: Implement Exception for wallet list service.
|
// TODO: Implement Exception for wallet list service.
|
||||||
print('MoneroWalletsManager Error: $e');
|
printV('MoneroWalletsManager Error: $e');
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -312,13 +314,14 @@ class MoneroWalletService extends WalletService<
|
||||||
final path = await pathForWallet(name: credentials.name, type: getType());
|
final path = await pathForWallet(name: credentials.name, type: getType());
|
||||||
final polyseedCoin = PolyseedCoin.POLYSEED_MONERO;
|
final polyseedCoin = PolyseedCoin.POLYSEED_MONERO;
|
||||||
final lang = PolyseedLang.getByPhrase(credentials.mnemonic);
|
final lang = PolyseedLang.getByPhrase(credentials.mnemonic);
|
||||||
final polyseed = Polyseed.decode(credentials.mnemonic, lang, polyseedCoin);
|
final polyseed =
|
||||||
|
Polyseed.decode(credentials.mnemonic, lang, polyseedCoin);
|
||||||
|
|
||||||
return _restoreFromPolyseed(
|
return _restoreFromPolyseed(
|
||||||
path, credentials.password!, polyseed, credentials.walletInfo!, lang);
|
path, credentials.password!, polyseed, credentials.walletInfo!, lang);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: Implement Exception for wallet list service.
|
// TODO: Implement Exception for wallet list service.
|
||||||
print('MoneroWalletsManager Error: $e');
|
printV('MoneroWalletsManager Error: $e');
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,24 +357,18 @@ class MoneroWalletService extends WalletService<
|
||||||
|
|
||||||
Future<void> repairOldAndroidWallet(String name) async {
|
Future<void> repairOldAndroidWallet(String name) async {
|
||||||
try {
|
try {
|
||||||
if (!Platform.isAndroid) {
|
if (!Platform.isAndroid) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final oldAndroidWalletDirPath = await outdatedAndroidPathForWalletDir(name: name);
|
final oldAndroidWalletDirPath = await outdatedAndroidPathForWalletDir(name: name);
|
||||||
final dir = Directory(oldAndroidWalletDirPath);
|
final dir = Directory(oldAndroidWalletDirPath);
|
||||||
|
|
||||||
if (!dir.existsSync()) {
|
if (!dir.existsSync()) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final newWalletDirPath = await pathForWalletDir(name: name, type: getType());
|
final newWalletDirPath = await pathForWalletDir(name: name, type: getType());
|
||||||
|
|
||||||
dir.listSync().forEach((f) {
|
dir.listSync().forEach((f) {
|
||||||
final file = File(f.path);
|
final file = File(f.path);
|
||||||
final name = f.path
|
final name = f.path.split('/').last;
|
||||||
.split('/')
|
|
||||||
.last;
|
|
||||||
final newPath = newWalletDirPath + '/$name';
|
final newPath = newWalletDirPath + '/$name';
|
||||||
final newFile = File(newPath);
|
final newFile = File(newPath);
|
||||||
|
|
||||||
|
@ -381,7 +378,7 @@ class MoneroWalletService extends WalletService<
|
||||||
newFile.writeAsBytesSync(file.readAsBytesSync());
|
newFile.writeAsBytesSync(file.readAsBytesSync());
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,9 +387,7 @@ class MoneroWalletService extends WalletService<
|
||||||
try {
|
try {
|
||||||
final path = await pathForWallet(name: name, type: getType());
|
final path = await pathForWallet(name: name, type: getType());
|
||||||
|
|
||||||
if (walletFilesExist(path)) {
|
if (walletFilesExist(path)) await repairOldAndroidWallet(name);
|
||||||
await repairOldAndroidWallet(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
await monero_wallet_manager.openWalletAsync({'path': path, 'password': password});
|
await monero_wallet_manager.openWalletAsync({'path': path, 'password': password});
|
||||||
final walletInfo = walletInfoSource.values
|
final walletInfo = walletInfoSource.values
|
||||||
|
@ -411,8 +406,10 @@ class MoneroWalletService extends WalletService<
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool requireHardwareWalletConnection(String name) {
|
bool requireHardwareWalletConnection(String name) {
|
||||||
final walletInfo = walletInfoSource.values
|
return walletInfoSource.values
|
||||||
.firstWhere((info) => info.id == WalletBase.idFor(name, getType()));
|
.firstWhereOrNull(
|
||||||
return walletInfo.isHardwareWallet;
|
(info) => info.id == WalletBase.idFor(name, getType()))
|
||||||
|
?.isHardwareWallet ??
|
||||||
|
false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:cw_core/amount_converter.dart';
|
import 'package:cw_core/amount_converter.dart';
|
||||||
|
|
||||||
import 'package:cw_core/pending_transaction.dart';
|
import 'package:cw_core/pending_transaction.dart';
|
||||||
|
import 'package:cw_monero/api/wallet.dart';
|
||||||
|
|
||||||
class DoubleSpendException implements Exception {
|
class DoubleSpendException implements Exception {
|
||||||
DoubleSpendException();
|
DoubleSpendException();
|
||||||
|
@ -53,6 +54,7 @@ class PendingMoneroTransaction with PendingTransaction {
|
||||||
|
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
storeSync(force: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
/Users/omarhatem/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/
|
|
@ -21,10 +21,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
|
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.0"
|
version: "2.6.0"
|
||||||
asn1lib:
|
asn1lib:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -77,10 +77,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_daemon
|
name: build_daemon
|
||||||
sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1"
|
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.1"
|
version: "4.0.2"
|
||||||
build_resolvers:
|
build_resolvers:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
@ -93,10 +93,10 @@ packages:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: build_runner
|
name: build_runner
|
||||||
sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22"
|
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.9"
|
version: "2.4.13"
|
||||||
build_runner_core:
|
build_runner_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -174,18 +174,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: convert
|
name: convert
|
||||||
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "3.1.2"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
|
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.3"
|
version: "3.0.6"
|
||||||
cryptography:
|
cryptography:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -253,18 +253,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
|
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.0.1"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fixnum
|
name: fixnum
|
||||||
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
|
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.1"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -311,10 +311,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: graphs
|
name: graphs
|
||||||
sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19
|
sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "2.3.2"
|
||||||
hashlib:
|
hashlib:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -375,10 +375,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.18.1"
|
version: "0.19.0"
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -407,26 +407,26 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.0"
|
version: "10.0.5"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "3.0.5"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_testing
|
name: leak_tracker_testing
|
||||||
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "3.0.1"
|
||||||
ledger_flutter_plus:
|
ledger_flutter_plus:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -447,10 +447,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: logging
|
name: logging
|
||||||
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
|
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.3.0"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -463,26 +463,26 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.0"
|
version: "0.11.1"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.0"
|
version: "1.15.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: mime
|
name: mime
|
||||||
sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
|
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.6"
|
version: "2.0.0"
|
||||||
mobx:
|
mobx:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -503,8 +503,8 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "impls/monero.dart"
|
path: "impls/monero.dart"
|
||||||
ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4
|
ref: af5277f96073917185864d3596e82b67bee54e78
|
||||||
resolved-ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4
|
resolved-ref: af5277f96073917185864d3596e82b67bee54e78
|
||||||
url: "https://github.com/mrcyjanek/monero_c"
|
url: "https://github.com/mrcyjanek/monero_c"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
@ -552,10 +552,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
|
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.4"
|
version: "2.2.12"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -600,10 +600,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
|
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.5"
|
version: "3.1.6"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -680,10 +680,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf_web_socket
|
name: shelf_web_socket
|
||||||
sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
|
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "2.0.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -765,10 +765,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.1"
|
version: "0.7.2"
|
||||||
timing:
|
timing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -789,10 +789,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.4.0"
|
||||||
universal_ble:
|
universal_ble:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -829,10 +829,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "13.0.0"
|
version: "14.2.4"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: "direct overridden"
|
dependency: "direct overridden"
|
||||||
description:
|
description:
|
||||||
|
@ -845,18 +845,26 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web
|
name: web
|
||||||
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
|
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.1"
|
version: "1.1.0"
|
||||||
|
web_socket:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket
|
||||||
|
sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.6"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42"
|
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.5"
|
version: "3.0.1"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -882,5 +890,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.3.0 <4.0.0"
|
dart: ">=3.5.0 <4.0.0"
|
||||||
flutter: ">=3.19.0"
|
flutter: ">=3.24.0"
|
||||||
|
|
|
@ -17,7 +17,7 @@ dependencies:
|
||||||
path_provider: ^2.0.11
|
path_provider: ^2.0.11
|
||||||
mobx: ^2.0.7+4
|
mobx: ^2.0.7+4
|
||||||
flutter_mobx: ^2.0.6+1
|
flutter_mobx: ^2.0.6+1
|
||||||
intl: ^0.18.0
|
intl: ^0.19.0
|
||||||
encrypt: ^5.0.1
|
encrypt: ^5.0.1
|
||||||
polyseed: ^0.0.6
|
polyseed: ^0.0.6
|
||||||
cw_core:
|
cw_core:
|
||||||
|
@ -25,7 +25,7 @@ dependencies:
|
||||||
monero:
|
monero:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/mrcyjanek/monero_c
|
url: https://github.com/mrcyjanek/monero_c
|
||||||
ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4
|
ref: af5277f96073917185864d3596e82b67bee54e78
|
||||||
# ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash
|
# ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash
|
||||||
path: impls/monero.dart
|
path: impls/monero.dart
|
||||||
mutex: ^3.1.0
|
mutex: ^3.1.0
|
||||||
|
|
|
@ -2,14 +2,14 @@ group 'com.cakewallet.mweb'
|
||||||
version '1.0-SNAPSHOT'
|
version '1.0-SNAPSHOT'
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.7.10'
|
ext.kotlin_version = '2.0.21'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.3.0'
|
classpath 'com.android.tools.build:gradle:8.7.1'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,15 +33,19 @@ apply plugin: 'com.android.library'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 31
|
compileSdkVersion 33
|
||||||
|
|
||||||
|
if (project.android.hasProperty("namespace")) {
|
||||||
|
namespace 'com.cakewallet.mweb'
|
||||||
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_17
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_17
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = '1.8'
|
jvmTarget = '17'
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
rootProject.name = 'cw_mweb'
|
rootProject.name = 'cw_mweb'
|
||||||
|
id "com.android.application" version "8.3.2" apply false
|
||||||
|
id "org.jetbrains.kotlin.android" version "2.0.20" apply false
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'dart:developer';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:grpc/grpc.dart';
|
import 'package:grpc/grpc.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'cw_mweb_platform_interface.dart';
|
import 'cw_mweb_platform_interface.dart';
|
||||||
|
@ -39,18 +40,18 @@ class CwMweb {
|
||||||
final fileStream = file.openRead(lastLength, currentLength);
|
final fileStream = file.openRead(lastLength, currentLength);
|
||||||
final newLines = await fileStream.transform(utf8.decoder).join();
|
final newLines = await fileStream.transform(utf8.decoder).join();
|
||||||
lastLength = currentLength;
|
lastLength = currentLength;
|
||||||
log(newLines);
|
printV(newLines);
|
||||||
}
|
}
|
||||||
} on GrpcError catch (e) {
|
} on GrpcError catch (e) {
|
||||||
log('Caught grpc error: ${e.message}');
|
printV('Caught grpc error: ${e.message}');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('The mwebd debug log probably is not initialized yet.');
|
printV('The mwebd debug log probably is not initialized yet.');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> _initializeClient() async {
|
static Future<void> _initializeClient() async {
|
||||||
print("_initializeClient() called!");
|
printV("_initializeClient() called!");
|
||||||
final appDir = await getApplicationSupportDirectory();
|
final appDir = await getApplicationSupportDirectory();
|
||||||
const ltcNodeUri = "ltc-electrum.cakewallet.com:9333";
|
const ltcNodeUri = "ltc-electrum.cakewallet.com:9333";
|
||||||
|
|
||||||
|
@ -61,14 +62,14 @@ class CwMweb {
|
||||||
if (_port == null || _port == 0) {
|
if (_port == null || _port == 0) {
|
||||||
throw Exception("Failed to start server");
|
throw Exception("Failed to start server");
|
||||||
}
|
}
|
||||||
log("Attempting to connect to server on port: $_port");
|
printV("Attempting to connect to server on port: $_port");
|
||||||
|
|
||||||
// wait for the server to finish starting up before we try to connect to it:
|
// wait for the server to finish starting up before we try to connect to it:
|
||||||
await Future.delayed(const Duration(seconds: 8));
|
await Future.delayed(const Duration(seconds: 8));
|
||||||
|
|
||||||
_clientChannel = ClientChannel('127.0.0.1', port: _port!, channelShutdownHandler: () {
|
_clientChannel = ClientChannel('127.0.0.1', port: _port!, channelShutdownHandler: () {
|
||||||
_rpcClient = null;
|
_rpcClient = null;
|
||||||
log("Channel is shutting down!");
|
printV("Channel is shutting down!");
|
||||||
},
|
},
|
||||||
options: const ChannelOptions(
|
options: const ChannelOptions(
|
||||||
credentials: ChannelCredentials.insecure(),
|
credentials: ChannelCredentials.insecure(),
|
||||||
|
@ -90,14 +91,14 @@ class CwMweb {
|
||||||
}
|
}
|
||||||
return _rpcClient!;
|
return _rpcClient!;
|
||||||
} on GrpcError catch (e) {
|
} on GrpcError catch (e) {
|
||||||
log("Attempt $i failed: $e");
|
printV("Attempt $i failed: $e");
|
||||||
log('Caught grpc error: ${e.message}');
|
printV('Caught grpc error: ${e.message}');
|
||||||
_rpcClient = null;
|
_rpcClient = null;
|
||||||
// necessary if the database isn't open:
|
// necessary if the database isn't open:
|
||||||
await stop();
|
await stop();
|
||||||
await Future.delayed(const Duration(seconds: 3));
|
await Future.delayed(const Duration(seconds: 3));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Attempt $i failed: $e");
|
printV("Attempt $i failed: $e");
|
||||||
_rpcClient = null;
|
_rpcClient = null;
|
||||||
await stop();
|
await stop();
|
||||||
await Future.delayed(const Duration(seconds: 3));
|
await Future.delayed(const Duration(seconds: 3));
|
||||||
|
@ -111,9 +112,9 @@ class CwMweb {
|
||||||
await CwMwebPlatform.instance.stop();
|
await CwMwebPlatform.instance.stop();
|
||||||
await cleanup();
|
await cleanup();
|
||||||
} on GrpcError catch (e) {
|
} on GrpcError catch (e) {
|
||||||
log('Caught grpc error: ${e.message}');
|
printV('Caught grpc error: ${e.message}');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Error stopping server: $e");
|
printV("Error stopping server: $e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,9 +124,9 @@ class CwMweb {
|
||||||
?.split(',')
|
?.split(',')
|
||||||
.first;
|
.first;
|
||||||
} on GrpcError catch (e) {
|
} on GrpcError catch (e) {
|
||||||
log('Caught grpc error: ${e.message}');
|
printV('Caught grpc error: ${e.message}');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Error getting address: $e");
|
printV("Error getting address: $e");
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -159,9 +160,9 @@ class CwMweb {
|
||||||
_rpcClient = await stub();
|
_rpcClient = await stub();
|
||||||
return await _rpcClient!.spent(request, options: CallOptions(timeout: TIMEOUT_DURATION));
|
return await _rpcClient!.spent(request, options: CallOptions(timeout: TIMEOUT_DURATION));
|
||||||
} on GrpcError catch (e) {
|
} on GrpcError catch (e) {
|
||||||
log('Caught grpc error: ${e.message}');
|
printV('Caught grpc error: ${e.message}');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Error getting spent: $e");
|
printV("Error getting spent: $e");
|
||||||
}
|
}
|
||||||
return SpentResponse();
|
return SpentResponse();
|
||||||
}
|
}
|
||||||
|
@ -172,9 +173,9 @@ class CwMweb {
|
||||||
_rpcClient = await stub();
|
_rpcClient = await stub();
|
||||||
return await _rpcClient!.status(request, options: CallOptions(timeout: TIMEOUT_DURATION));
|
return await _rpcClient!.status(request, options: CallOptions(timeout: TIMEOUT_DURATION));
|
||||||
} on GrpcError catch (e) {
|
} on GrpcError catch (e) {
|
||||||
log('Caught grpc error: ${e.message}');
|
printV('Caught grpc error: ${e.message}');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Error getting status: $e");
|
printV("Error getting status: $e");
|
||||||
}
|
}
|
||||||
return StatusResponse();
|
return StatusResponse();
|
||||||
}
|
}
|
||||||
|
@ -185,9 +186,9 @@ class CwMweb {
|
||||||
_rpcClient = await stub();
|
_rpcClient = await stub();
|
||||||
return await _rpcClient!.create(request, options: CallOptions(timeout: TIMEOUT_DURATION));
|
return await _rpcClient!.create(request, options: CallOptions(timeout: TIMEOUT_DURATION));
|
||||||
} on GrpcError catch (e) {
|
} on GrpcError catch (e) {
|
||||||
log('Caught grpc error: ${e.message}');
|
printV('Caught grpc error: ${e.message}');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Error getting create: $e");
|
printV("Error getting create: $e");
|
||||||
}
|
}
|
||||||
return CreateResponse();
|
return CreateResponse();
|
||||||
}
|
}
|
||||||
|
@ -201,9 +202,9 @@ class CwMweb {
|
||||||
log("got utxo stream");
|
log("got utxo stream");
|
||||||
return resp;
|
return resp;
|
||||||
} on GrpcError catch (e) {
|
} on GrpcError catch (e) {
|
||||||
log('Caught grpc error: ${e.message}');
|
printV('Caught grpc error: ${e.message}');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Error getting utxos: $e");
|
printV("Error getting utxos: $e");
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -217,7 +218,7 @@ class CwMweb {
|
||||||
log('Caught grpc error: ${e.message}');
|
log('Caught grpc error: ${e.message}');
|
||||||
throw "error from broadcast mweb: $e";
|
throw "error from broadcast mweb: $e";
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Error getting create: $e");
|
printV("Error getting utxos: $e");
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ dependencies:
|
||||||
grpc: ^3.2.4
|
grpc: ^3.2.4
|
||||||
path_provider: ^2.1.2
|
path_provider: ^2.1.2
|
||||||
plugin_platform_interface: ^2.0.2
|
plugin_platform_interface: ^2.0.2
|
||||||
|
cw_core:
|
||||||
|
path: ../cw_core
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:cw_core/nano_account_info_response.dart';
|
import 'package:cw_core/nano_account_info_response.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_nano/nano_block_info_response.dart';
|
import 'package:cw_nano/nano_block_info_response.dart';
|
||||||
import 'package:cw_core/n2_node.dart';
|
import 'package:cw_core/n2_node.dart';
|
||||||
import 'package:cw_nano/nano_balance.dart';
|
import 'package:cw_nano/nano_balance.dart';
|
||||||
|
@ -106,7 +107,7 @@ class NanoClient {
|
||||||
final data = await jsonDecode(response.body);
|
final data = await jsonDecode(response.body);
|
||||||
return AccountInfoResponse.fromJson(data as Map<String, dynamic>);
|
return AccountInfoResponse.fromJson(data as Map<String, dynamic>);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("error while getting account info $e");
|
printV("error while getting account info $e");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +128,7 @@ class NanoClient {
|
||||||
final data = await jsonDecode(response.body);
|
final data = await jsonDecode(response.body);
|
||||||
return BlockContentsResponse.fromJson(data["contents"] as Map<String, dynamic>);
|
return BlockContentsResponse.fromJson(data["contents"] as Map<String, dynamic>);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("error while getting block info $e");
|
printV("error while getting block info $e");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -508,7 +509,7 @@ class NanoClient {
|
||||||
.map<NanoTransactionModel>((transaction) => NanoTransactionModel.fromJson(transaction))
|
.map<NanoTransactionModel>((transaction) => NanoTransactionModel.fromJson(transaction))
|
||||||
.toList();
|
.toList();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
printV(e);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
import 'package:cw_core/pathForWallet.dart';
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/encryption_file_utils.dart';
|
import 'package:cw_core/encryption_file_utils.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
@ -27,7 +28,10 @@ abstract class NanoTransactionHistoryBase extends TransactionHistoryBase<NanoTra
|
||||||
final EncryptionFileUtils encryptionFileUtils;
|
final EncryptionFileUtils encryptionFileUtils;
|
||||||
String _password;
|
String _password;
|
||||||
|
|
||||||
Future<void> init() async => await _load();
|
Future<void> init() async {
|
||||||
|
clear();
|
||||||
|
await _load();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> save() async {
|
Future<void> save() async {
|
||||||
|
@ -37,7 +41,7 @@ abstract class NanoTransactionHistoryBase extends TransactionHistoryBase<NanoTra
|
||||||
final data = json.encode({'transactions': transactions});
|
final data = json.encode({'transactions': transactions});
|
||||||
await encryptionFileUtils.write(path: path, password: _password, data: data);
|
await encryptionFileUtils.write(path: path, password: _password, data: data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error while save nano transaction history: ${e.toString()}');
|
printV('Error while save nano transaction history: ${e.toString()}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +76,7 @@ abstract class NanoTransactionHistoryBase extends TransactionHistoryBase<NanoTra
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
printV(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import 'package:cw_core/pending_transaction.dart';
|
||||||
import 'package:cw_core/sync_status.dart';
|
import 'package:cw_core/sync_status.dart';
|
||||||
import 'package:cw_core/transaction_direction.dart';
|
import 'package:cw_core/transaction_direction.dart';
|
||||||
import 'package:cw_core/transaction_priority.dart';
|
import 'package:cw_core/transaction_priority.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/wallet_keys_file.dart';
|
import 'package:cw_core/wallet_keys_file.dart';
|
||||||
|
@ -149,7 +150,7 @@ abstract class NanoWalletBase
|
||||||
Future<void> changePassword(String password) => throw UnimplementedError("changePassword");
|
Future<void> changePassword(String password) => throw UnimplementedError("changePassword");
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close({required bool shouldCleanup}) async {
|
Future<void> close({bool shouldCleanup = false}) async {
|
||||||
_client.stop();
|
_client.stop();
|
||||||
_receiveTimer?.cancel();
|
_receiveTimer?.cancel();
|
||||||
}
|
}
|
||||||
|
@ -170,12 +171,12 @@ abstract class NanoWalletBase
|
||||||
await _updateRep();
|
await _updateRep();
|
||||||
await _receiveAll();
|
await _receiveAll();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
printV(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
syncStatus = ConnectedSyncStatus();
|
syncStatus = ConnectedSyncStatus();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
printV(e);
|
||||||
syncStatus = FailedSyncStatus();
|
syncStatus = FailedSyncStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -367,7 +368,7 @@ abstract class NanoWalletBase
|
||||||
|
|
||||||
syncStatus = SyncedSyncStatus();
|
syncStatus = SyncedSyncStatus();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
printV(e);
|
||||||
syncStatus = FailedSyncStatus();
|
syncStatus = FailedSyncStatus();
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
@ -444,7 +445,7 @@ abstract class NanoWalletBase
|
||||||
try {
|
try {
|
||||||
balance[currency] = await _client.getBalance(_publicAddress!);
|
balance[currency] = await _client.getBalance(_publicAddress!);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("Failed to get balance $e");
|
printV("Failed to get balance $e");
|
||||||
// if we don't have a balance, we should at least create one, since it's a late binding
|
// if we don't have a balance, we should at least create one, since it's a late binding
|
||||||
// otherwise, it's better to just leave it as whatever it was before:
|
// otherwise, it's better to just leave it as whatever it was before:
|
||||||
if (balance[currency] == null) {
|
if (balance[currency] == null) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:cw_core/cake_hive.dart';
|
import 'package:cw_core/cake_hive.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_addresses.dart';
|
import 'package:cw_core/wallet_addresses.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/nano_account.dart';
|
import 'package:cw_core/nano_account.dart';
|
||||||
|
@ -47,7 +48,7 @@ abstract class NanoWalletAddressesBase extends WalletAddresses with Store {
|
||||||
addressesMap[address] = '';
|
addressesMap[address] = '';
|
||||||
await saveAddressesInBox();
|
await saveAddressesInBox();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,18 +21,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
|
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.2"
|
version: "2.6.0"
|
||||||
asn1lib:
|
asn1lib:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: asn1lib
|
name: asn1lib
|
||||||
sha256: "58082b3f0dca697204dbab0ef9ff208bfaea7767ea771076af9a343488428dda"
|
sha256: "6b151826fcc95ff246cd219a0bf4c753ea14f4081ad71c61939becf3aba27f70"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.3"
|
version: "1.5.5"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -77,10 +77,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build
|
name: build
|
||||||
sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777"
|
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "2.4.1"
|
||||||
build_config:
|
build_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -93,10 +93,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_daemon
|
name: build_daemon
|
||||||
sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1"
|
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.1"
|
version: "4.0.2"
|
||||||
build_resolvers:
|
build_resolvers:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -109,10 +109,10 @@ packages:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: build_runner
|
name: build_runner
|
||||||
sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22"
|
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.9"
|
version: "2.4.13"
|
||||||
build_runner_core:
|
build_runner_core:
|
||||||
dependency: "direct overridden"
|
dependency: "direct overridden"
|
||||||
description:
|
description:
|
||||||
|
@ -190,18 +190,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: convert
|
name: convert
|
||||||
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "3.1.2"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
|
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.3"
|
version: "3.0.6"
|
||||||
cryptography:
|
cryptography:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -245,18 +245,18 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: ed25519_hd_key
|
name: ed25519_hd_key
|
||||||
sha256: c5c9f11a03f5789bf9dcd9ae88d641571c802640851f1cacdb13123f171b3a26
|
sha256: "31e191ec97492873067e46dc9cc0c7d55170559c83a478400feffa0627acaccf"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.3.0"
|
||||||
encrypt:
|
encrypt:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: encrypt
|
name: encrypt
|
||||||
sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb"
|
sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.1"
|
version: "5.0.3"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -269,26 +269,26 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
|
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.3"
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
|
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.0.1"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fixnum
|
name: fixnum
|
||||||
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
|
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.1"
|
||||||
fixnum_nanodart:
|
fixnum_nanodart:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -306,10 +306,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_mobx
|
name: flutter_mobx
|
||||||
sha256: "0da4add0016387a7bf309a0d0c41d36c6b3ae25ed7a176409267f166509e723e"
|
sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.6+5"
|
version: "2.2.1+1"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -324,10 +324,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: frontend_server_client
|
name: frontend_server_client
|
||||||
sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
|
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.0"
|
version: "4.0.0"
|
||||||
glob:
|
glob:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -340,10 +340,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: graphs
|
name: graphs
|
||||||
sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19
|
sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "2.3.2"
|
||||||
hex:
|
hex:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -372,10 +372,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
|
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.2.2"
|
||||||
http_multi_server:
|
http_multi_server:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -396,10 +396,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.18.1"
|
version: "0.19.0"
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -420,34 +420,34 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: json_annotation
|
name: json_annotation
|
||||||
sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
|
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.8.1"
|
version: "4.9.0"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.0"
|
version: "10.0.5"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "3.0.5"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_testing
|
name: leak_tracker_testing
|
||||||
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "3.0.1"
|
||||||
libcrypto:
|
libcrypto:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -460,10 +460,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: logging
|
name: logging
|
||||||
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
|
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.3.0"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -476,26 +476,26 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.0"
|
version: "0.11.1"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.0"
|
version: "1.15.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: mime
|
name: mime
|
||||||
sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
|
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "2.0.0"
|
||||||
mobx:
|
mobx:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -529,6 +529,14 @@ packages:
|
||||||
url: "https://github.com/perishllc/nanoutil.git"
|
url: "https://github.com/perishllc/nanoutil.git"
|
||||||
source: git
|
source: git
|
||||||
version: "1.0.3"
|
version: "1.0.3"
|
||||||
|
nested:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: nested
|
||||||
|
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
package_config:
|
package_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -549,26 +557,26 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
|
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.4"
|
||||||
path_provider_android:
|
path_provider_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
|
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.12"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_foundation
|
name: path_provider_foundation
|
||||||
sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
|
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "2.4.0"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -581,34 +589,34 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_platform_interface
|
name: path_provider_platform_interface
|
||||||
sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
|
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.2"
|
||||||
path_provider_windows:
|
path_provider_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
|
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.3.0"
|
||||||
pinenacl:
|
pinenacl:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pinenacl
|
name: pinenacl
|
||||||
sha256: "3a5503637587d635647c93ea9a8fecf48a420cc7deebe6f1fc85c2a5637ab327"
|
sha256: "57e907beaacbc3c024a098910b6240758e899674de07d6949a67b52fd984cbdf"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.1"
|
version: "0.6.0"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
|
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.6"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -621,10 +629,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pointycastle
|
name: pointycastle
|
||||||
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
|
sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.7.3"
|
version: "3.9.1"
|
||||||
pool:
|
pool:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -633,6 +641,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.1"
|
version: "1.5.1"
|
||||||
|
provider:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: provider
|
||||||
|
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.1.2"
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -645,50 +661,50 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pubspec_parse
|
name: pubspec_parse
|
||||||
sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
|
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.3"
|
version: "1.3.0"
|
||||||
rational:
|
rational:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: rational
|
name: rational
|
||||||
sha256: ba58e9e18df9abde280e8b10051e4bce85091e41e8e7e411b6cde2e738d357cf
|
sha256: cb808fb6f1a839e6fc5f7d8cb3b0a10e1db48b3be102de73938c627f0b636336
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.2"
|
version: "2.2.3"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
|
sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.2"
|
version: "2.3.2"
|
||||||
shared_preferences_android:
|
shared_preferences_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_android
|
name: shared_preferences_android
|
||||||
sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
|
sha256: "3b9febd815c9ca29c9e3520d50ec32f49157711e143b7a4ca039eb87e8ade5ab"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.3.3"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_foundation
|
name: shared_preferences_foundation
|
||||||
sha256: "671e7a931f55a08aa45be2a13fe7247f2a41237897df434b30d2012388191833"
|
sha256: "07e050c7cd39bad516f8d64c455f04508d09df104be326d8c02551590a0d513d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.0"
|
version: "2.5.3"
|
||||||
shared_preferences_linux:
|
shared_preferences_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_linux
|
name: shared_preferences_linux
|
||||||
sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
|
sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.4.1"
|
||||||
shared_preferences_platform_interface:
|
shared_preferences_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -701,18 +717,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_web
|
name: shared_preferences_web
|
||||||
sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
|
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.4.2"
|
||||||
shared_preferences_windows:
|
shared_preferences_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_windows
|
name: shared_preferences_windows
|
||||||
sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
|
sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.4.1"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -725,10 +741,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf_web_socket
|
name: shelf_web_socket
|
||||||
sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
|
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "2.0.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -738,10 +754,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: socks5_proxy
|
name: socks5_proxy
|
||||||
sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a"
|
sha256: "616818a0ea1064a4823b53c9f7eaf8da64ed82dcd51ed71371c7e54751ed5053"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.6"
|
||||||
source_gen:
|
source_gen:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -810,10 +826,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.1"
|
version: "0.7.2"
|
||||||
timing:
|
timing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -834,10 +850,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.4.0"
|
||||||
unorm_dart:
|
unorm_dart:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -858,10 +874,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "13.0.0"
|
version: "14.2.4"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: "direct overridden"
|
dependency: "direct overridden"
|
||||||
description:
|
description:
|
||||||
|
@ -870,30 +886,38 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web
|
||||||
|
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
|
web_socket:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket
|
||||||
|
sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.6"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
|
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "3.0.1"
|
||||||
win32:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: win32
|
|
||||||
sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "5.5.0"
|
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
|
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.1.0"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -903,5 +927,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.3.0 <4.0.0"
|
dart: ">=3.5.0 <4.0.0"
|
||||||
flutter: ">=3.16.6"
|
flutter: ">=3.24.0"
|
||||||
|
|
|
@ -14,11 +14,19 @@ class PolygonClient extends EVMChainClient {
|
||||||
required EtherAmount amount,
|
required EtherAmount amount,
|
||||||
EtherAmount? maxPriorityFeePerGas,
|
EtherAmount? maxPriorityFeePerGas,
|
||||||
Uint8List? data,
|
Uint8List? data,
|
||||||
|
int? maxGas,
|
||||||
|
EtherAmount? gasPrice,
|
||||||
|
EtherAmount? maxFeePerGas,
|
||||||
}) {
|
}) {
|
||||||
return Transaction(
|
return Transaction(
|
||||||
from: from,
|
from: from,
|
||||||
to: to,
|
to: to,
|
||||||
value: amount,
|
value: amount,
|
||||||
|
// data: data,
|
||||||
|
maxGas: maxGas,
|
||||||
|
// gasPrice: gasPrice,
|
||||||
|
// maxFeePerGas: maxFeePerGas,
|
||||||
|
// maxPriorityFeePerGas: maxPriorityFeePerGas,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,20 @@ apply plugin: 'com.android.library'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 30
|
compileSdkVersion 33
|
||||||
|
|
||||||
|
if (project.android.hasProperty("namespace")) {
|
||||||
|
namespace 'com.cakewallet.cw_shared_external'
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_17
|
||||||
|
targetCompatibility JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '17'
|
||||||
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main.java.srcDirs += 'src/main/kotlin'
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:math';
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:cw_core/crypto_currency.dart';
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:cw_core/node.dart';
|
import 'package:cw_core/node.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_solana/pending_solana_transaction.dart';
|
import 'package:cw_solana/pending_solana_transaction.dart';
|
||||||
import 'package:cw_solana/solana_balance.dart';
|
import 'package:cw_solana/solana_balance.dart';
|
||||||
|
import 'package:cw_solana/solana_exceptions.dart';
|
||||||
import 'package:cw_solana/solana_transaction_model.dart';
|
import 'package:cw_solana/solana_transaction_model.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:solana/dto.dart';
|
import 'package:solana/dto.dart';
|
||||||
|
@ -179,7 +181,7 @@ class SolanaWalletClient {
|
||||||
bool isOutgoingTx = transfer.source == publicKey.toBase58();
|
bool isOutgoingTx = transfer.source == publicKey.toBase58();
|
||||||
|
|
||||||
double amount = (double.tryParse(transfer.amount) ?? 0.0) /
|
double amount = (double.tryParse(transfer.amount) ?? 0.0) /
|
||||||
pow(10, splTokenDecimal ?? 9);
|
math.pow(10, splTokenDecimal ?? 9);
|
||||||
|
|
||||||
transactions.add(
|
transactions.add(
|
||||||
SolanaTransactionModel(
|
SolanaTransactionModel(
|
||||||
|
@ -275,6 +277,7 @@ class SolanaWalletClient {
|
||||||
required String destinationAddress,
|
required String destinationAddress,
|
||||||
required Ed25519HDKeyPair ownerKeypair,
|
required Ed25519HDKeyPair ownerKeypair,
|
||||||
required bool isSendAll,
|
required bool isSendAll,
|
||||||
|
required double solBalance,
|
||||||
String? tokenMint,
|
String? tokenMint,
|
||||||
List<String> references = const [],
|
List<String> references = const [],
|
||||||
}) async {
|
}) async {
|
||||||
|
@ -289,6 +292,7 @@ class SolanaWalletClient {
|
||||||
ownerKeypair: ownerKeypair,
|
ownerKeypair: ownerKeypair,
|
||||||
commitment: commitment,
|
commitment: commitment,
|
||||||
isSendAll: isSendAll,
|
isSendAll: isSendAll,
|
||||||
|
solBalance: solBalance,
|
||||||
);
|
);
|
||||||
return pendingNativeTokenTransaction;
|
return pendingNativeTokenTransaction;
|
||||||
} else {
|
} else {
|
||||||
|
@ -300,6 +304,7 @@ class SolanaWalletClient {
|
||||||
destinationAddress: destinationAddress,
|
destinationAddress: destinationAddress,
|
||||||
ownerKeypair: ownerKeypair,
|
ownerKeypair: ownerKeypair,
|
||||||
commitment: commitment,
|
commitment: commitment,
|
||||||
|
solBalance: solBalance,
|
||||||
);
|
);
|
||||||
return pendingSPLTokenTransaction;
|
return pendingSPLTokenTransaction;
|
||||||
}
|
}
|
||||||
|
@ -352,6 +357,23 @@ class SolanaWalletClient {
|
||||||
return fee;
|
return fee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> hasSufficientFundsLeftForRent({
|
||||||
|
required double inputAmount,
|
||||||
|
required double solBalance,
|
||||||
|
required double fee,
|
||||||
|
}) async {
|
||||||
|
final rent =
|
||||||
|
await _client!.getMinimumBalanceForMintRentExemption(commitment: Commitment.confirmed);
|
||||||
|
|
||||||
|
final rentInSol = (rent / lamportsPerSol).toDouble();
|
||||||
|
|
||||||
|
final remnant = solBalance - (inputAmount + fee);
|
||||||
|
|
||||||
|
if (remnant > rentInSol) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Future<PendingSolanaTransaction> _signNativeTokenTransaction({
|
Future<PendingSolanaTransaction> _signNativeTokenTransaction({
|
||||||
required String tokenTitle,
|
required String tokenTitle,
|
||||||
required int tokenDecimals,
|
required int tokenDecimals,
|
||||||
|
@ -360,6 +382,7 @@ class SolanaWalletClient {
|
||||||
required Ed25519HDKeyPair ownerKeypair,
|
required Ed25519HDKeyPair ownerKeypair,
|
||||||
required Commitment commitment,
|
required Commitment commitment,
|
||||||
required bool isSendAll,
|
required bool isSendAll,
|
||||||
|
required double solBalance,
|
||||||
}) async {
|
}) async {
|
||||||
// Convert SOL to lamport
|
// Convert SOL to lamport
|
||||||
int lamports = (inputAmount * lamportsPerSol).toInt();
|
int lamports = (inputAmount * lamportsPerSol).toInt();
|
||||||
|
@ -377,6 +400,16 @@ class SolanaWalletClient {
|
||||||
commitment,
|
commitment,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
bool hasSufficientFundsLeft = await hasSufficientFundsLeftForRent(
|
||||||
|
inputAmount: inputAmount,
|
||||||
|
fee: fee,
|
||||||
|
solBalance: solBalance,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!hasSufficientFundsLeft) {
|
||||||
|
throw SolanaSignNativeTokenTransactionRentException();
|
||||||
|
}
|
||||||
|
|
||||||
SignedTx signedTx;
|
SignedTx signedTx;
|
||||||
if (isSendAll) {
|
if (isSendAll) {
|
||||||
final feeInLamports = (fee * lamportsPerSol).toInt();
|
final feeInLamports = (fee * lamportsPerSol).toInt();
|
||||||
|
@ -424,6 +457,7 @@ class SolanaWalletClient {
|
||||||
required String destinationAddress,
|
required String destinationAddress,
|
||||||
required Ed25519HDKeyPair ownerKeypair,
|
required Ed25519HDKeyPair ownerKeypair,
|
||||||
required Commitment commitment,
|
required Commitment commitment,
|
||||||
|
required double solBalance,
|
||||||
}) async {
|
}) async {
|
||||||
final destinationOwner = Ed25519HDPublicKey.fromBase58(destinationAddress);
|
final destinationOwner = Ed25519HDPublicKey.fromBase58(destinationAddress);
|
||||||
final mint = Ed25519HDPublicKey.fromBase58(tokenMint);
|
final mint = Ed25519HDPublicKey.fromBase58(tokenMint);
|
||||||
|
@ -446,7 +480,7 @@ class SolanaWalletClient {
|
||||||
// Throw an appropriate exception if the sender has no associated
|
// Throw an appropriate exception if the sender has no associated
|
||||||
// token account
|
// token account
|
||||||
if (associatedSenderAccount == null) {
|
if (associatedSenderAccount == null) {
|
||||||
throw NoAssociatedTokenAccountException(ownerKeypair.address, mint.toBase58());
|
throw SolanaNoAssociatedTokenAccountException(ownerKeypair.address, mint.toBase58());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -456,11 +490,11 @@ class SolanaWalletClient {
|
||||||
funder: ownerKeypair,
|
funder: ownerKeypair,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception('Insufficient SOL balance to complete this transaction: ${e.toString()}');
|
throw SolanaCreateAssociatedTokenAccountException(e.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input by the user
|
// Input by the user
|
||||||
final amount = (inputAmount * pow(10, tokenDecimals)).toInt();
|
final amount = (inputAmount * math.pow(10, tokenDecimals)).toInt();
|
||||||
|
|
||||||
final instruction = TokenInstruction.transfer(
|
final instruction = TokenInstruction.transfer(
|
||||||
source: Ed25519HDPublicKey.fromBase58(associatedSenderAccount.pubkey),
|
source: Ed25519HDPublicKey.fromBase58(associatedSenderAccount.pubkey),
|
||||||
|
@ -482,6 +516,16 @@ class SolanaWalletClient {
|
||||||
commitment,
|
commitment,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
bool hasSufficientFundsLeft = await hasSufficientFundsLeftForRent(
|
||||||
|
inputAmount: inputAmount,
|
||||||
|
fee: fee,
|
||||||
|
solBalance: solBalance,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!hasSufficientFundsLeft) {
|
||||||
|
throw SolanaSignSPLTokenTransactionRentException();
|
||||||
|
}
|
||||||
|
|
||||||
final signedTx = await _signTransactionInternal(
|
final signedTx = await _signTransactionInternal(
|
||||||
message: message,
|
message: message,
|
||||||
signers: signers,
|
signers: signers,
|
||||||
|
@ -529,7 +573,7 @@ class SolanaWalletClient {
|
||||||
|
|
||||||
return signature;
|
return signature;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error while sending transaction: ${e.toString()}');
|
printV('Error while sending transaction: ${e.toString()}');
|
||||||
throw Exception(e);
|
throw Exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -546,7 +590,7 @@ class SolanaWalletClient {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error occurred while fetching token image: \n${e.toString()}');
|
printV('Error occurred while fetching token image: \n${e.toString()}');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,3 +19,20 @@ class SolanaTransactionWrongBalanceException implements Exception {
|
||||||
@override
|
@override
|
||||||
String toString() => exceptionMessage;
|
String toString() => exceptionMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SolanaSignNativeTokenTransactionRentException implements Exception {}
|
||||||
|
|
||||||
|
class SolanaCreateAssociatedTokenAccountException implements Exception {
|
||||||
|
final String exceptionMessage;
|
||||||
|
|
||||||
|
SolanaCreateAssociatedTokenAccountException(this.exceptionMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SolanaSignSPLTokenTransactionRentException implements Exception {}
|
||||||
|
|
||||||
|
class SolanaNoAssociatedTokenAccountException implements Exception {
|
||||||
|
const SolanaNoAssociatedTokenAccountException(this.account, this.mint);
|
||||||
|
|
||||||
|
final String account;
|
||||||
|
final String mint;
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
import 'package:cw_core/encryption_file_utils.dart';
|
import 'package:cw_core/encryption_file_utils.dart';
|
||||||
import 'package:cw_core/pathForWallet.dart';
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_solana/solana_transaction_info.dart';
|
import 'package:cw_solana/solana_transaction_info.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
@ -25,7 +26,10 @@ abstract class SolanaTransactionHistoryBase extends TransactionHistoryBase<Solan
|
||||||
final EncryptionFileUtils encryptionFileUtils;
|
final EncryptionFileUtils encryptionFileUtils;
|
||||||
String _password;
|
String _password;
|
||||||
|
|
||||||
Future<void> init() async => await _load();
|
Future<void> init() async {
|
||||||
|
clear();
|
||||||
|
await _load();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> save() async {
|
Future<void> save() async {
|
||||||
|
@ -36,8 +40,8 @@ abstract class SolanaTransactionHistoryBase extends TransactionHistoryBase<Solan
|
||||||
final data = json.encode({'transactions': transactionMaps});
|
final data = json.encode({'transactions': transactionMaps});
|
||||||
await encryptionFileUtils.write(path: path, password: _password, data: data);
|
await encryptionFileUtils.write(path: path, password: _password, data: data);
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
print('Error while saving solana transaction history: ${e.toString()}');
|
printV('Error while saving solana transaction history: ${e.toString()}');
|
||||||
print(s);
|
printV(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +76,7 @@ abstract class SolanaTransactionHistoryBase extends TransactionHistoryBase<Solan
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
printV(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import 'package:cw_core/pending_transaction.dart';
|
||||||
import 'package:cw_core/sync_status.dart';
|
import 'package:cw_core/sync_status.dart';
|
||||||
import 'package:cw_core/transaction_direction.dart';
|
import 'package:cw_core/transaction_direction.dart';
|
||||||
import 'package:cw_core/transaction_priority.dart';
|
import 'package:cw_core/transaction_priority.dart';
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_addresses.dart';
|
import 'package:cw_core/wallet_addresses.dart';
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
|
@ -179,7 +180,7 @@ abstract class SolanaWalletBase
|
||||||
Future<void> changePassword(String password) => throw UnimplementedError("changePassword");
|
Future<void> changePassword(String password) => throw UnimplementedError("changePassword");
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close({required bool shouldCleanup}) async {
|
Future<void> close({bool shouldCleanup = false}) async {
|
||||||
_client.stop();
|
_client.stop();
|
||||||
_transactionsUpdateTimer?.cancel();
|
_transactionsUpdateTimer?.cancel();
|
||||||
}
|
}
|
||||||
|
@ -227,6 +228,8 @@ abstract class SolanaWalletBase
|
||||||
|
|
||||||
final walletBalanceForCurrency = balance[transactionCurrency]!.balance;
|
final walletBalanceForCurrency = balance[transactionCurrency]!.balance;
|
||||||
|
|
||||||
|
final solBalance = balance[CryptoCurrency.sol]!.balance;
|
||||||
|
|
||||||
double totalAmount = 0.0;
|
double totalAmount = 0.0;
|
||||||
|
|
||||||
bool isSendAll = false;
|
bool isSendAll = false;
|
||||||
|
@ -278,6 +281,7 @@ abstract class SolanaWalletBase
|
||||||
? solCredentials.outputs.first.extractedAddress!
|
? solCredentials.outputs.first.extractedAddress!
|
||||||
: solCredentials.outputs.first.address,
|
: solCredentials.outputs.first.address,
|
||||||
isSendAll: isSendAll,
|
isSendAll: isSendAll,
|
||||||
|
solBalance: solBalance,
|
||||||
);
|
);
|
||||||
|
|
||||||
return pendingSolanaTransaction;
|
return pendingSolanaTransaction;
|
||||||
|
@ -454,7 +458,7 @@ abstract class SolanaWalletBase
|
||||||
SolanaBalance(0.0);
|
SolanaBalance(0.0);
|
||||||
balance[token] = tokenBalance;
|
balance[token] = tokenBalance;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error fetching spl token (${token.symbol}) balance ${e.toString()}');
|
printV('Error fetching spl token (${token.symbol}) balance ${e.toString()}');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
balance.remove(token);
|
balance.remove(token);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_core/wallet_addresses.dart';
|
import 'package:cw_core/wallet_addresses.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
@ -30,7 +31,7 @@ abstract class SolanaWalletAddressesBase extends WalletAddresses with Store {
|
||||||
addressesMap[address] = '';
|
addressesMap[address] = '';
|
||||||
await saveAddressesInBox();
|
await saveAddressesInBox();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
printV(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,10 @@ abstract class TronTransactionHistoryBase extends TransactionHistoryBase<TronTra
|
||||||
final WalletInfo walletInfo;
|
final WalletInfo walletInfo;
|
||||||
final EncryptionFileUtils encryptionFileUtils;
|
final EncryptionFileUtils encryptionFileUtils;
|
||||||
|
|
||||||
Future<void> init() async => await _load();
|
Future<void> init() async {
|
||||||
|
clear();
|
||||||
|
await _load();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> save() async {
|
Future<void> save() async {
|
||||||
|
|
|
@ -217,7 +217,7 @@ abstract class TronWalletBase
|
||||||
Future<void> changePassword(String password) => throw UnimplementedError("changePassword");
|
Future<void> changePassword(String password) => throw UnimplementedError("changePassword");
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close({required bool shouldCleanup}) async => _transactionsUpdateTimer?.cancel();
|
Future<void> close({bool shouldCleanup = false}) async => _transactionsUpdateTimer?.cancel();
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@override
|
@override
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue