Created
September 25, 2024 14:19
-
-
Save LaurentMT/891bc518bc94cc549e6af25647d66a4d to your computer and use it in GitHub Desktop.
Verification of Ashigaru Wallet 1.0.0 codebase (WIP)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
------------------------- | |
CHECK FIRST COMMIT: OK | |
------------------------- | |
I've been able to check the first commit of Ashigaru Wallet (http://ashicodepbnpvslzsl2bz7l2pwrjvajgumgac423pp3y2deprbnzz7id.onion/Ashigaru/Ashigaru-Mobile/src/commit/2fbad89bf357c99b852ba70aad74b52e72e395e2) | |
by comparing it with this commit of the Samourai Wallet Archive (https://github.com/Archive-Samourai-Wallet/samourai-wallet-android/tree/cc2b4492514d00de39b8390b7ca3792a284cb8f2) | |
I've selected this specific commit based on the statement made in the blog post (https://ashigaru.rs/news/release-wallet-v1-0-0/) that the new wallet was based on v0.99.98ii of Samourai Wallet) | |
Everything seems ok. | |
------------------------- | |
CHECK SECOND COMMIT: WIP | |
------------------------- | |
This commit requires a lot more work as it seems that many different things are done in this single commit: | |
- Content of the extlibj library in included in the repository of Ashigaru Wallet (it was previously stored in a separate repository) | |
- New code waiting in the develop branch of Samourai Wallet have been included in Ashigaru wallet | |
- Additional modifications done to the code of the wallet | |
I don't know why all these modifications have been merged with a single commit but it clearly makes peer review far more difficult. :( | |
EXTLIBJ CODE CHECK | |
------------------------- | |
Anyway, I've first checked the extlib repo by comparing the content of the extlibj directory found in the second commit of Ashigaru Wallet (http://ashicodepbnpvslzsl2bz7l2pwrjvajgumgac423pp3y2deprbnzz7id.onion/Ashigaru/Ashigaru-Mobile/src/commit/6b37843e5d1f7748836471cd1e3621a5fb1cc29f) | |
with this commit of the extlibj repo from the Samourai Wallet Archive (https://github.com/Archive-Samourai-Wallet/extlibj/tree/f57adf1a54d593ed624622476f4d78d85bec0c55). | |
I've converged to this commit after a few trials (startinf from v1.0.6) that were returning weird diffs between the 2 projects. | |
As far as I can tell, everything seems ok. The number of modifications is limited, each modification seems to make sense and doesn't seem malicious. | |
Here are the results of the diff comparing the directories and files: | |
$ diff -qrs /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/ /home/laurent/dev_samourai/extlibj/ | grep -v "are identical" | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/: build.gradle | |
Only in /home/laurent/dev_samourai/extlibj/: .git | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/.gitignore and /home/laurent/dev_samourai/extlibj/.gitignore differ | |
Only in /home/laurent/dev_samourai/extlibj/: java | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/: LICENSE | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/pom.xml and /home/laurent/dev_samourai/extlibj/pom.xml differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/README.md and /home/laurent/dev_samourai/extlibj/README.md differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/src: main | |
Only in /home/laurent/dev_samourai/extlibj/src: test | |
Only in /home/laurent/dev_samourai/extlibj/: target | |
Only in /home/laurent/dev_samourai/extlibj/: .travis.yml | |
$ diff -qrs /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/src/main/java/com/samourai/wallet/ /home/laurent/dev_samourai/extlibj/java/com/samourai/wallet/ | grep -v "are identical" | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/src/main/java/com/samourai/wallet/api/backend/BackendApi.java /home/laurent/dev_samourai/extlibj/java/com/samourai/wallet/api/backend/BackendApi.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/src/main/java/com/samourai/wallet/api/paynym/PaynymServer.java /home/laurent/dev_samourai/extlibj/java/com/samourai/wallet/api/paynym/PaynymServer.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/src/main/java/com/samourai/wallet/dexConfig/SamouraiConfig.java /home/laurent/dev_samourai/extlibj/java/com/samourai/wallet/dexConfig/SamouraiConfig.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/src/main/java/com/samourai/wallet/SamouraiWalletConst.java /home/laurent/dev_samourai/extlibj/java/com/samourai/wallet/SamouraiWalletConst.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/src/main/java/com/samourai/wallet/util/Util.java /home/laurent/dev_samourai/extlibj/java/com/samourai/wallet/util/Util.java differ | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/src/main/java/com/samourai/wallet/api/backend/BackendApi.java /home/laurent/dev_samourai/extlibj/java/com/samourai/wallet/api/backend/BackendApi.java | |
3,13c3 | |
< import static org.apache.commons.lang3.StringUtils.stripEnd; | |
< | |
< import com.samourai.wallet.api.backend.beans.BackendPushTxException; | |
< import com.samourai.wallet.api.backend.beans.BackendPushTxResponse; | |
< import com.samourai.wallet.api.backend.beans.MultiAddrResponse; | |
< import com.samourai.wallet.api.backend.beans.TxDetail; | |
< import com.samourai.wallet.api.backend.beans.TxsResponse; | |
< import com.samourai.wallet.api.backend.beans.UnspentOutput; | |
< import com.samourai.wallet.api.backend.beans.UnspentResponse; | |
< import com.samourai.wallet.api.backend.beans.WalletResponse; | |
< import com.samourai.wallet.api.backend.beans.XPubResponse; | |
--- | |
> import com.samourai.wallet.api.backend.beans.*; | |
24d13 | |
< | |
29,35c18 | |
< import java.util.ArrayList; | |
< import java.util.Arrays; | |
< import java.util.Collection; | |
< import java.util.HashMap; | |
< import java.util.LinkedHashMap; | |
< import java.util.List; | |
< import java.util.Map; | |
--- | |
> import java.util.*; | |
91c74 | |
< String url = computeAuthUrl(getStrippedUrlBackend() + URL_UNSPENT + zpubStr); | |
--- | |
> String url = computeAuthUrl(urlBackend + URL_UNSPENT + zpubStr); | |
107c90 | |
< String url = computeAuthUrl(getStrippedUrlBackend() + URL_MULTIADDR + zpubStr); | |
--- | |
> String url = computeAuthUrl(urlBackend + URL_MULTIADDR + zpubStr); | |
144c127 | |
< String url = computeAuthUrl(getStrippedUrlBackend() + URL_TXS + zpubStr+"&page="+page+"&count="+count); | |
--- | |
> String url = computeAuthUrl(urlBackend + URL_TXS + zpubStr+"&page="+page+"&count="+count); | |
153c136 | |
< String url = computeAuthUrl(getStrippedUrlBackend() + URL_TX + txid + (fees ? "?fees=1" : "")); | |
--- | |
> String url = computeAuthUrl(urlBackend + URL_TX + txid + (fees ? "?fees=1" : "")); | |
163c146 | |
< String url = computeAuthUrl(getStrippedUrlBackend() + URL_WALLET + zpubStr); | |
--- | |
> String url = computeAuthUrl(urlBackend + URL_WALLET + zpubStr); | |
180c163 | |
< String url = computeAuthUrl(getStrippedUrlBackend() + URL_XPUB + xpub); | |
--- | |
> String url = computeAuthUrl(urlBackend + URL_XPUB + xpub); | |
193c176 | |
< String url = computeAuthUrl(getStrippedUrlBackend() + URL_INIT_BIP84); | |
--- | |
> String url = computeAuthUrl(urlBackend + URL_INIT_BIP84); | |
206c189 | |
< String url = computeAuthUrl(getStrippedUrlBackend() + URL_MINER_FEES); | |
--- | |
> String url = computeAuthUrl(urlBackend + URL_MINER_FEES); | |
218c201 | |
< String url = computeAuthUrl(getStrippedUrlBackend() + URL_SEEN + Util.encodeUrl(addressesStr)); | |
--- | |
> String url = computeAuthUrl(urlBackend + URL_SEEN + Util.encodeUrl(addressesStr)); | |
243c226 | |
< String url = computeAuthUrl(getStrippedUrlBackend() + URL_PUSHTX); | |
--- | |
> String url = computeAuthUrl(urlBackend + URL_PUSHTX); | |
326,329d308 | |
< } | |
< | |
< public String getStrippedUrlBackend() { | |
< return stripEnd(urlBackend, "/"); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/src/main/java/com/samourai/wallet/api/paynym/PaynymServer.java /home/laurent/dev_samourai/extlibj/java/com/samourai/wallet/api/paynym/PaynymServer.java | |
4c4 | |
< PAYNYM_IS("https://paynym.rs/api/v1"); | |
--- | |
> PAYNYM_IS("https://paynym.is/api/v1"); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/src/main/java/com/samourai/wallet/dexConfig/SamouraiConfig.java /home/laurent/dev_samourai/extlibj/java/com/samourai/wallet/dexConfig/SamouraiConfig.java | |
14,17c14,17 | |
< private String sorobanServerTestnetClear = "https://soroban.paynym.rs/test"; | |
< private String sorobanServerTestnetOnion = "http://ashi5c6obifqi2thzkxqrqlkewywzucgglusc3n7qusnei75nrkwwyad.onion:4242"; | |
< private String sorobanServerMainnetClear = "https://soroban.paynym.rs"; | |
< private String sorobanServerMainnetOnion = "http://ashi5c6obifqi2thzkxqrqlkewywzucgglusc3n7qusnei75nrkwwyad.onion:4242"; | |
--- | |
> private String sorobanServerTestnetClear = "https://soroban.samouraiwallet.com/test"; | |
> private String sorobanServerTestnetOnion = "http://sorob4sg7yiopktgz4eom7hl5mcodr6quvhmdpljl5qqhmt6po7oebid.onion/test"; | |
> private String sorobanServerMainnetClear = "https://soroban.samouraiwallet.com"; | |
> private String sorobanServerMainnetOnion = "http://sorob4sg7yiopktgz4eom7hl5mcodr6quvhmdpljl5qqhmt6po7oebid.onion"; | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/src/main/java/com/samourai/wallet/SamouraiWalletConst.java /home/laurent/dev_samourai/extlibj/java/com/samourai/wallet/SamouraiWalletConst.java | |
18,19c18,19 | |
< public static final String SAAS_PCODE_MAINNET = "___"; | |
< public static final String SAAS_PCODE_TESTNET = "____"; | |
--- | |
> public static final String SAAS_PCODE_MAINNET = "PM8TJUYeU1rF5zcVkNsiN6LEzikQXH4NTtgzL7bCbnznNtef5mWVi9i3LetDByv9HHMTq5czDppAP4gyimC7LyNLiC1hfAyQCHvDBP3EzPU5sx3yyxRY"; | |
> public static final String SAAS_PCODE_TESTNET = "PM8TJXBr2UNrPuhTFrmiCrww74GCFm1WbTqpxEXACpfzAsKqM3xvgZPG2PhDGycW2Ud9RiCzVHb3NprRvGffpYbi9bw6sYjU5nZJm94syV1J67V9fRND"; | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ExtLibJ/src/main/java/com/samourai/wallet/util/Util.java /home/laurent/dev_samourai/extlibj/java/com/samourai/wallet/util/Util.java | |
99,102d98 | |
< public static String sha256ToString(byte[] b) { | |
< return new String(Hex.encodeHex(sha256(b))); | |
< } | |
< | |
WALLET CODE CHECK | |
------------------------- | |
In order to check the modifications done on the code of the wallet itself, I've compared the second commit of Ashigaru Wallet (http://ashicodepbnpvslzsl2bz7l2pwrjvajgumgac423pp3y2deprbnzz7id.onion/Ashigaru/Ashigaru-Mobile/src/commit/6b37843e5d1f7748836471cd1e3621a5fb1cc29f) | |
with the code of the develop branch in the Samourai Wallet Archive (https://github.com/Archive-Samourai-Wallet/samourai-wallet-android/tree/e7270d263d62775dc9ebecd27ab733b65c41aa8f) | |
The initial diff returns 286 entries (directories, files). This number can be reduced to 125 entries if we remove files that don't store code (images, layout files, etc). | |
Here are the result of the diff (with "static" files being marked as "OK"): | |
$ diff -qrs /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/ /home/laurent/dev_samourai/samourai-wallet-android/ | grep -v "are identical" | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/: accompanying-release-files | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/build.gradle and /home/laurent/dev_samourai/samourai-wallet-android/app/build.gradle differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/AndroidManifest.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/AndroidManifest.xml differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/http/client/AndroidHttpClient.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/http/client/AndroidHttpClient.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/api/APIFactory.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/api/APIFactory.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/api/fee/EnumFeeRepresentation.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/api/fee/EnumFeeRepresentation.java differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/api: ping | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/api: txs | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/api: wallet | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/api: xpub | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/bip47/BIP47Meta.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/bip47/BIP47Meta.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/bip47/BIP47Util.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/bip47/BIP47Util.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/bip47/paynym/WebUtil.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/bip47/paynym/WebUtil.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/bip47/SendNotifTxFactory.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/bip47/SendNotifTxFactory.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/collaborate/CollaborateActivity.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/collaborate/CollaborateActivity.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/collaborate/ParticipateSegment.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/collaborate/ParticipateSegment.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/collaborate/Paynym.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/collaborate/Paynym.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/collaborate/TransactionSetup.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/collaborate/TransactionSetup.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/collaborate/viewmodels/CahootsTransactionViewModel.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/collaborate/viewmodels/CahootsTransactionViewModel.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/collaborate/viewmodels/CollaborateViewModel.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/collaborate/viewmodels/CollaborateViewModel.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/CreateWalletActivity.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/CreateWalletActivity.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/explorer/ExplorerActivity.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/explorer/ExplorerActivity.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/fragments/PaynymSelectModalFragment.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/fragments/PaynymSelectModalFragment.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/home/AccountSelectionActivity.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/home/AccountSelectionActivity.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/home/BalanceActivity.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/home/BalanceActivity.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/home/BalanceViewModel.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/home/BalanceViewModel.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/MainActivity2.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/MainActivity2.java differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/network/dojo: DojoDetailsActivity.kt | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/network/dojo: DojoQRBottomsheet.kt | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/network/dojo/DojoUtil.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/network/dojo/DojoUtil.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/network/NetworkDashboard.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/network/NetworkDashboard.java differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard: CreateOrRestoreActivity.kt | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard: OfflineDojoActivityScreen.kt | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard/OnBoardSlidesActivity.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/onboard/OnBoardSlidesActivity.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard/RestoreOptionActivity.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/onboard/RestoreOptionActivity.kt differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard: SetDojoActivity.kt | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard/SetUpWalletActivity.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/onboard/SetUpWalletActivity.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard/SetUpWalletViewModel.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/onboard/SetUpWalletViewModel.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/pairing/PairingMenu.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/pairing/PairingMenu.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/payload/ExternalBackupManager.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/payload/ExternalBackupManager.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/payload/PayloadUtil.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/payload/PayloadUtil.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/addPaynym/AddPaynymActivity.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/addPaynym/AddPaynymActivity.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/api/PayNymApiService.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/api/PayNymApiService.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/fragments/EditPaynymBottomSheet.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/fragments/EditPaynymBottomSheet.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/fragments/PaynymListFragment.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/fragments/PaynymListFragment.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/paynymDetails/PayNymDetailsActivity.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/paynymDetails/PayNymDetailsActivity.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/PayNymHome.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/PayNymHome.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/PayNymViewModel.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/PayNymViewModel.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/pin/PinEntryActivity.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/pin/PinEntryActivity.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/pin/PinEntryManager.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/pin/PinEntryManager.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/ReceiveActivity.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/ReceiveActivity.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/RecoveryWordsActivity.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/RecoveryWordsActivity.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/RestoreSeedWalletActivity.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/RestoreSeedWalletActivity.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/ricochet/RicochetMeta.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/ricochet/RicochetMeta.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/SamouraiActivity.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/SamouraiActivity.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/SamouraiApplication.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/SamouraiApplication.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/SamouraiWallet.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/SamouraiWallet.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/batch/BatchSpendActivity.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/batch/BatchSpendActivity.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/cahoots/SelectCahootsType.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/cahoots/SelectCahootsType.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/FeeUtil.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/FeeUtil.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/broadcast/SpendRicochetTxBroadcaster.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/broadcast/SpendRicochetTxBroadcaster.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/CoinSelectionManagerBottomSheet.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/CoinSelectionManagerBottomSheet.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/preview/BatchPreviewTx.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/preview/BatchPreviewTx.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/preview/CustomPreviewTx.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/preview/CustomPreviewTx.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/preview/RicochetCustomPreviewTx.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/preview/RicochetCustomPreviewTx.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/preview/RicochetPreviewTx.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/preview/RicochetPreviewTx.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/preview/SimplePreviewTx.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/preview/SimplePreviewTx.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/preview/StonewallPreviewTx.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/preview/StonewallPreviewTx.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/ref/EnumTransactionPriority.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/ref/EnumTransactionPriority.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/ref/EnumTxAlert.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/ref/EnumTxAlert.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/ReviewTxActivity.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/ReviewTxActivity.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/ReviewTxAlert.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/ReviewTxAlert.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/ReviewTxFeeManagerBottomSheet.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/ReviewTxFeeManagerBottomSheet.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/ReviewTxModel.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/ReviewTxModel.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/sendbutton/SwipeSendButton.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/sendbutton/SwipeSendButton.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/SendActivity.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/SendActivity.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/service/WalletRefreshWorker.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/service/WalletRefreshWorker.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/service/WebSocketHandler.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/service/WebSocketHandler.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/service/WebSocketService.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/service/WebSocketService.java differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/settings: CustomPreference.java | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/settings/SettingsActivity.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/settings/SettingsActivity.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/settings/SettingsDetailsFragment.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/settings/SettingsDetailsFragment.kt differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet: sync | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/theme/Color.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/theme/Color.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tools/Auth47BottomSheet.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tools/Auth47BottomSheet.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tools/BroadcastHexBottomSheet.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tools/BroadcastHexBottomSheet.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tools/SignPSBTBottomSheet.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tools/SignPSBTBottomSheet.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tools/SweepPrivateKey.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tools/SweepPrivateKey.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tools/ToolsBottomSheet.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tools/ToolsBottomSheet.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tools/viewmodels/SweepViewModel.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tools/viewmodels/SweepViewModel.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tor/kpm/TorKmpManager.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tor/kpm/TorKmpManager.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tor/SamouraiTorManager.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tor/SamouraiTorManager.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tx/TxDetailsActivity.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tx/TxDetailsActivity.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/activity/ActivityHelper.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/activity/ActivityHelper.java differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util: AppUpdateAvailableBottomSheet.kt | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/func/AddressHelper.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/func/AddressHelper.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/func/BatchSendUtil.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/func/BatchSendUtil.java differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/func: PaymentCodeHelper.java | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/func/PayNymUtil.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/func/PayNymUtil.kt differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/func: WalletRefreshUtil.kt | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/func/WalletUtil.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/func/WalletUtil.java differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/network: AshigaruNetworkException.java | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/network/BackendApiAndroid.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/network/BackendApiAndroid.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/network/BlockExplorerUtil.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/network/BlockExplorerUtil.java differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/network: DojoNetworkUtils.kt | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/network/WebUtil.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/network/WebUtil.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/PrefsUtil.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/PrefsUtil.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/tech/AppUtil.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/tech/AppUtil.java differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/tech: AshigaruException.java | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/tech/HapticHelper.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/tech/HapticHelper.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/tech/SimpleTaskRunner.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/tech/SimpleTaskRunner.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/tech/ThreadHelper.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/tech/ThreadHelper.java differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/tech: VerifyPGPSignedClearMessageUtil.java | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/view/SamCheckbox.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/view/SamCheckbox.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/utxos/UTXODetailsActivity.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/utxos/UTXODetailsActivity.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/utxos/UTXOSActivity.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/utxos/UTXOSActivity.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/whirlpool/newPool/fragments/SelectPoolFragment.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/whirlpool/newPool/fragments/SelectPoolFragment.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/whirlpool/WhirlpoolHome.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/whirlpool/WhirlpoolHome.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/whirlpool/WhirlPoolHomeViewModel.kt and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/whirlpool/WhirlPoolHomeViewModel.kt differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/widgets/TransactionProgressView.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/widgets/TransactionProgressView.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/whirlpool/client/wallet/data/AndroidMinerFeeSupplier.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/whirlpool/client/wallet/data/AndroidMinerFeeSupplier.java differ | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ashigaru_standing.png | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable/divider_grey.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable/divider_grey.xml differ | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: dojo_logo.png | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_alert_box.xml | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_ashigaru_logo.png | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_ashigaru_tor_connected.png | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_ashigaru_tor_data_transfer.png | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_ashigaru_tor_idle.png | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_checkbox_blank_outline.xml | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_checkbox_marked.xml | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_check.xml | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_close_box.xml | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_layers_triple.xml | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable/ic_network_check_black_24dp.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable/ic_network_check_black_24dp.xml differ | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_piggy_bank.xml | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_plus_icon.xml | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable: ic_samourai_logo_splash_vect.xml | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable: ic_samourai_logo.xml | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable: ic_samourai_mono_launcher_icon.xml | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable: ic_samourai_tor_data_transfer.xml | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable: ic_samourai_tor_enabled.xml | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable: ic_samourai_tor_idle.xml | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_sync.xml | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: ic_whirlpool_v2.xml | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable: launch_screen.xml | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: notes_scroll.xml | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: qrcode_scan.xml | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: rounded_rectangle_bottom_sheet.xml | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: rounded_rectangle.xml | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable/samourai_splash.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable/samourai_splash.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable/tag_round_shape.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable/tag_round_shape.xml differ | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable: utxo_list.xml | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res: drawable-anydpi | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-hdpi: ic_crop_free_white_24dp.png | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable-hdpi/ic_launcher_round.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-hdpi/ic_launcher_round.png differ | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-hdpi: ic_samourai_logo_splash.png | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable-hdpi: ic_sync_in_progress.png | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-hdpi: samourai_logo_splash.png | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: drawable-ldpi | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-mdpi: ic_crop_free_white_24dp.png | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable-mdpi/ic_launcher_round.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-mdpi/ic_launcher_round.png differ | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-mdpi: ic_samourai_logo_splash.png | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable-mdpi: ic_sync_in_progress.png | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-mdpi: samourai_logo_splash.png | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: drawable-v23 | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-xhdpi: ic_crop_free_white_24dp.png | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable-xhdpi/ic_launcher_round.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-xhdpi/ic_launcher_round.png differ | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-xhdpi: ic_samourai_logo_splash.png | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable-xhdpi: ic_sync_in_progress.png | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-xhdpi: samourai_logo_splash.png | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-xxhdpi: ic_crop_free_white_24dp.png | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable-xxhdpi/ic_launcher_round.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-xxhdpi/ic_launcher_round.png differ | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-xxhdpi: ic_samourai_logo_splash.png | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable-xxhdpi: ic_sync_in_progress.png | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-xxhdpi: samourai_logo_splash.png | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-xxxhdpi: ic_crop_free_white_24dp.png | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/drawable-xxxhdpi/ic_launcher_round.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-xxxhdpi/ic_launcher_round.png differ | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-xxxhdpi: ic_samourai_logo_splash.png | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/drawable-xxxhdpi: samourai_logo_splash.png | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/activity_add_paynym.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/activity_add_paynym.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/activity_balance.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/activity_balance.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/activity_create_wallet.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/activity_create_wallet.xml differ | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout: activity_dojo_details.xml | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/activity_main.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/activity_main.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/activity_network_dashboard.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/activity_network_dashboard.xml differ | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout: activity_offline_mode_dojo.xml | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/activity_on_board_slides.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/activity_on_board_slides.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/activity_pairing_menu.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/activity_pairing_menu.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/activity_paynym_details.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/activity_paynym_details.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/activity_receive.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/activity_receive.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/activity_restore_option.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/activity_restore_option.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/activity_restore_wallet_activity.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/activity_restore_wallet_activity.xml differ | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout: activity_set_dojo.xml | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/activity_set_up_wallet.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/activity_set_up_wallet.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/activity_tx.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/activity_tx.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/bottomsheet_edit_paynym.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/bottomsheet_edit_paynym.xml differ | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout: create_or_restore.xml | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/fragment_choose_cahoots_type.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/fragment_choose_cahoots_type.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/fragment_choose_pools.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/fragment_choose_pools.xml differ | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout: fragment_dojo_bottomsheet.xml | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/fragment_import_wallet.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/fragment_import_wallet.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/paynym_list_item.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/paynym_list_item.xml differ | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout: release_notes_content.xml | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/send_transaction_main_segment.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/send_transaction_main_segment.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/transaction_progress_view.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/transaction_progress_view.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/tx_item_layout_.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/tx_item_layout_.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout/tx_item_section_layout.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/layout/tx_item_section_layout.xml differ | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/layout: update_available_content.xml | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/menu/batch_menu.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/menu/batch_menu.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/menu/bip47_menu.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/menu/bip47_menu.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/menu/home_tools_menu.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/menu/home_tools_menu.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/menu/main.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/menu/main.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/menu/receive_activity_menu.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/menu/receive_activity_menu.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/menu/send_menu.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/menu/send_menu.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/menu/utxo_details_action_menu.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/menu/utxo_details_action_menu.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/menu/utxo_details_menu.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/menu/utxo_details_menu.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/menu/whirlpool_main.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/menu/whirlpool_main.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-hdpi/ic_launcher.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-mdpi/ic_launcher.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/values/attrs_tor_kmp.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/values/attrs_tor_kmp.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/values/colors.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/values/colors.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/values/dimens.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/values/dimens.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/values/ic_launcher_background.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/values/ic_launcher_background.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/values/strings.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/values/strings.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/values/styles.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/values/styles.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/values/themes.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/values/themes.xml differ | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-bg | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-cn | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-cs | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-de | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-es | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-fr | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-hu | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-id | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-ir | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-it | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-my | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-nl | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-pt | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-pt-rBR | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-ru | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-sk | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-tr | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res: values-zh-rCN | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/xml/settings_other.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/xml/settings_other.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/xml/settings_troubleshoot.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/xml/settings_troubleshoot.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/xml/settings_txs.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/xml/settings_txs.xml differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/res/xml/settings_wallet.xml and /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/res/xml/settings_wallet.xml differ | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/test/java/com/samourai/wallet/util: VerifyPGPSignedClearMessageUtilTest.java | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/test/java/com/samourai/whirlpool/client/wallet/AbstractWhirlpoolTest.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/test/java/com/samourai/whirlpool/client/wallet/AbstractWhirlpoolTest.java differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/test/java/com/samourai/whirlpool/client/wallet/WhirlpoolWalletTest.java and /home/laurent/dev_samourai/samourai-wallet-android/app/src/test/java/com/samourai/whirlpool/client/wallet/WhirlpoolWalletTest.java differ | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/: ashigaru.api | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/build.gradle and /home/laurent/dev_samourai/samourai-wallet-android/build.gradle differ | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/: docs | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/: ExtLibJ | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/: .git | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/.gitignore and /home/laurent/dev_samourai/samourai-wallet-android/.gitignore differ | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/.gradle: 8.2 | |
OK - Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/.gradle: 8.9 | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/.gradle/buildOutputCleanup/buildOutputCleanup.lock and /home/laurent/dev_samourai/samourai-wallet-android/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/.gradle/buildOutputCleanup/cache.properties and /home/laurent/dev_samourai/samourai-wallet-android/.gradle/buildOutputCleanup/cache.properties differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/gradle/wrapper/gradle-wrapper.jar and /home/laurent/dev_samourai/samourai-wallet-android/gradle/wrapper/gradle-wrapper.jar differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/gradle/wrapper/gradle-wrapper.properties and /home/laurent/dev_samourai/samourai-wallet-android/gradle/wrapper/gradle-wrapper.properties differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/gradlew and /home/laurent/dev_samourai/samourai-wallet-android/gradlew differ | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/gradlew.bat and /home/laurent/dev_samourai/samourai-wallet-android/gradlew.bat differ | |
OK - Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/README.md and /home/laurent/dev_samourai/samourai-wallet-android/README.md differ | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/: ReproducibleBuilds.md | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/: samourai.api | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/: Samourai-Wallet-features.md | |
Files /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/settings.gradle and /home/laurent/dev_samourai/samourai-wallet-android/settings.gradle differ | |
OK - Only in /home/laurent/dev_samourai/samourai-wallet-android/: .travis.yml | |
WALLET CODE CHECK - REMAINING 125 ENTRIES | |
----------------------------------------- | |
The diff for the remaining 125 entries (what I haven't checked yet) are: | |
New files and directories | |
------------------------- | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/api: ping | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/api: txs | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/api: wallet | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/api: xpub | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/network/dojo: DojoDetailsActivity.kt | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/network/dojo: DojoQRBottomsheet.kt | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard: CreateOrRestoreActivity.kt | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard: OfflineDojoActivityScreen.kt | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard: SetDojoActivity.kt | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/func: PaymentCodeHelper.java | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/settings: CustomPreference.java | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet: sync | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util: AppUpdateAvailableBottomSheet.kt | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/func: WalletRefreshUtil.kt | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/network: AshigaruNetworkException.java | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/network: DojoNetworkUtils.kt | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/tech: AshigaruException.java | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/tech: VerifyPGPSignedClearMessageUtil.java | |
Only in /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/test/java/com/samourai/wallet/util: VerifyPGPSignedClearMessageUtilTest.java | |
Changed files | |
------------------------- | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/AndroidManifest.xml /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/AndroidManifest.xml | |
52d51 | |
< android:screenOrientation="portrait" | |
70d68 | |
< android:screenOrientation="portrait" | |
76d73 | |
< android:screenOrientation="portrait" | |
92d88 | |
< android:screenOrientation="portrait" | |
99d94 | |
< android:screenOrientation="portrait" | |
106d100 | |
< android:screenOrientation="portrait" | |
113d106 | |
< android:screenOrientation="portrait" | |
128d120 | |
< android:screenOrientation="portrait" | |
143d134 | |
< android:screenOrientation="portrait" | |
158d148 | |
< android:screenOrientation="portrait" | |
163d152 | |
< android:screenOrientation="portrait" | |
168d156 | |
< android:screenOrientation="portrait" | |
185d172 | |
< android:screenOrientation="portrait" | |
191d177 | |
< android:screenOrientation="portrait" | |
197d182 | |
< android:screenOrientation="portrait" | |
204d188 | |
< android:screenOrientation="portrait" | |
208,224d191 | |
< android:screenOrientation="portrait" | |
< android:name=".onboard.SetDojoActivity" | |
< android:theme="@style/Theme.Samourai.Material" /> | |
< <activity | |
< android:screenOrientation="portrait" | |
< android:name=".network.dojo.DojoDetailsActivity" | |
< android:theme="@style/Theme.Samourai.Material" /> | |
< <activity | |
< android:screenOrientation="portrait" | |
< android:name=".onboard.OfflineDojoActivityScreen" | |
< android:theme="@style/Theme.Samourai.Material" /> | |
< <activity | |
< android:screenOrientation="portrait" | |
< android:name=".onboard.CreateOrRestoreActivity" | |
< android:theme="@style/Theme.Samourai.Material" /> | |
< <activity | |
< android:screenOrientation="portrait" | |
228d194 | |
< android:screenOrientation="portrait" | |
232d197 | |
< android:screenOrientation="portrait" | |
236d200 | |
< android:screenOrientation="portrait" | |
241d204 | |
< android:screenOrientation="portrait" | |
247d209 | |
< android:screenOrientation="portrait" | |
253d214 | |
< android:screenOrientation="portrait" | |
259d219 | |
< android:screenOrientation="portrait" | |
264d223 | |
< android:screenOrientation="portrait" | |
269d227 | |
< android:screenOrientation="portrait" | |
274d231 | |
< android:screenOrientation="portrait" | |
277,283c234 | |
< android:theme="@style/Theme.Samourai.Material" | |
< android:launchMode="singleTask" /> | |
< <activity | |
< android:screenOrientation="portrait" | |
< android:name=".sync.SyncWalletActivity" | |
< android:theme="@style/SamouraiAppSyncWallet" | |
< android:launchMode="singleTask" /> | |
--- | |
> android:theme="@style/Theme.Samourai.Material" /> | |
285d235 | |
< android:screenOrientation="portrait" | |
289d238 | |
< android:screenOrientation="portrait" | |
294d242 | |
< android:screenOrientation="portrait" | |
301d248 | |
< android:screenOrientation="portrait" | |
307d253 | |
< android:screenOrientation="portrait" | |
309c255,256 | |
< android:label="@string/app_name" /> | |
--- | |
> android:label="@string/app_name" | |
> android:screenOrientation="landscape" /> | |
311d257 | |
< android:screenOrientation="portrait" | |
315,316c261 | |
< android:theme="@style/Theme.Samourai.Material" | |
< android:launchMode="singleTask" /> | |
--- | |
> android:theme="@style/Theme.Samourai.Material" /> | |
318d262 | |
< android:screenOrientation="portrait" | |
323d266 | |
< android:screenOrientation="portrait" | |
328d270 | |
< android:screenOrientation="portrait" | |
332d273 | |
< android:screenOrientation="portrait" | |
336d276 | |
< android:screenOrientation="portrait" | |
340d279 | |
< android:screenOrientation="portrait" | |
344d282 | |
< android:screenOrientation="portrait" | |
350d287 | |
< android:screenOrientation="portrait" | |
355d291 | |
< android:screenOrientation="portrait" | |
363d298 | |
< android:screenOrientation="portrait" | |
368d302 | |
< android:screenOrientation="portrait" | |
373d306 | |
< android:screenOrientation="portrait" | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/http/client/AndroidHttpClient.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/http/client/AndroidHttpClient.java | |
80c80,84 | |
< return webUtil.tor_postURL(url, jsonBody, headers); | |
--- | |
> if (SamouraiTorManager.INSTANCE.isRequired()) { | |
> return webUtil.tor_postURL(url, jsonBody, headers); | |
> } else { | |
> return webUtil.postURL(WebUtil.CONTENT_TYPE_APPLICATION_JSON, url, jsonBody, headers); | |
> } | |
85c89,96 | |
< return webUtil.tor_postURL(url, body, headers); | |
--- | |
> if (SamouraiTorManager.INSTANCE.isRequired()) { | |
> // tor enabled | |
> return webUtil.tor_postURL(url, body, headers); | |
> } else { | |
> // tor disabled | |
> String jsonString = queryString(body); | |
> return webUtil.postURL(null, url, jsonString, headers); | |
> } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/api/APIFactory.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/api/APIFactory.java | |
19d18 | |
< import androidx.annotation.NonNull; | |
24d22 | |
< import com.google.common.collect.ImmutableListMultimap; | |
26d23 | |
< import com.google.common.collect.ListMultimap; | |
28,29d24 | |
< import com.google.common.collect.MultimapBuilder; | |
< import com.google.common.collect.Multimaps; | |
57d51 | |
< import com.samourai.wallet.util.func.EnumAddressType; | |
264,271c258,262 | |
< try { | |
< byte[] xorSegments0 = Base64.decode(BuildConfig.XOR_1); | |
< byte[] xorSegments1 = Base64.decode(BuildConfig.XOR_2); | |
< return xor(xorSegments0, xorSegments1); | |
< } catch (final Exception e) { | |
< return null; | |
< } | |
< } else { | |
--- | |
> byte[] xorSegments0 = Base64.decode(BuildConfig.XOR_1); | |
> byte[] xorSegments1 = Base64.decode(BuildConfig.XOR_2); | |
> return xor(xorSegments0, xorSegments1); | |
> } | |
> else { | |
401,414c392 | |
< public synchronized JSONObject getXPUB( | |
< final Collection<String> addresses, | |
< final boolean parse) { | |
< | |
< return getXPUB( | |
< ImmutableListMultimap.<EnumAddressType, String>builder() | |
< .putAll(EnumAddressType.BIP44_LEGACY, addresses) | |
< .build(), | |
< parse); | |
< } | |
< | |
< private synchronized JSONObject getXPUB( | |
< final ListMultimap<EnumAddressType, String> addressesByType, | |
< final boolean parse) { | |
--- | |
> private synchronized JSONObject getXPUB(String[] xpubs, boolean parse) { | |
416c394 | |
< final String walletapiService = BackendApiAndroid.getApiServiceUrl("wallet?"); | |
--- | |
> String _url = WebUtil.getAPIUrl(context); | |
429,452c407,409 | |
< final StringBuilder args = new StringBuilder(); | |
< for (final EnumAddressType type : addressesByType.keySet()) { | |
< switch (type) { | |
< case BIP44_LEGACY: | |
< args.append("active="); | |
< args.append(StringUtils.join(addressesByType.get(type), URLEncoder.encode("|", "UTF-8"))); | |
< args.append("&"); | |
< break; | |
< case BIP49_SEGWIT_COMPAT: | |
< args.append("bip49="); | |
< args.append(StringUtils.join(addressesByType.get(type), URLEncoder.encode("|", "UTF-8"))); | |
< args.append("&"); | |
< break; | |
< case BIP84_SEGWIT_NATIVE: | |
< args.append("bip84="); | |
< args.append(StringUtils.join(addressesByType.get(type), URLEncoder.encode("|", "UTF-8"))); | |
< args.append("&"); | |
< break; | |
< default: | |
< info("APIFactory", "unknown EnumAddressType:" + type); | |
< break; | |
< } | |
< } | |
< | |
--- | |
> StringBuilder args = new StringBuilder(); | |
> args.append("active="); | |
> args.append(StringUtils.join(xpubs, URLEncoder.encode("|", "UTF-8"))); | |
454c411 | |
< args.append("at="); | |
--- | |
> args.append("&at="); | |
456c413 | |
< response = WebUtil.getInstance(context).postURL(walletapiService, args.toString()); | |
--- | |
> response = WebUtil.getInstance(context).postURL(_url + "wallet?", args.toString()); | |
460,478c417,418 | |
< final Map<String,String> args = Maps.newHashMap(); | |
< | |
< for (final EnumAddressType type : addressesByType.keySet()) { | |
< switch (type) { | |
< case BIP44_LEGACY: | |
< args.put("active", StringUtils.join(addressesByType.get(type), "|")); | |
< break; | |
< case BIP49_SEGWIT_COMPAT: | |
< args.put("bip49", StringUtils.join(addressesByType.get(type), "|")); | |
< break; | |
< case BIP84_SEGWIT_NATIVE: | |
< args.put("bip84", StringUtils.join(addressesByType.get(type), "|")); | |
< break; | |
< default: | |
< info("APIFactory", "unknown EnumAddressType:" + type); | |
< break; | |
< } | |
< } | |
< | |
--- | |
> HashMap<String,String> args = new HashMap<String,String>(); | |
> args.put("active", StringUtils.join(xpubs, "|")); | |
482c422 | |
< response = WebUtil.getInstance(context).tor_postURL(walletapiService, args); | |
--- | |
> response = WebUtil.getInstance(context).tor_postURL(_url + "wallet", args); | |
491,492c431 | |
< | |
< xpub_txs.put(ImmutableList.copyOf(addressesByType.values()).get(0), new ArrayList<Tx>()); | |
--- | |
> xpub_txs.put(xpubs[0], new ArrayList<Tx>()); | |
513,516c452,454 | |
< public synchronized JSONObject registerXPUB( | |
< final String xpub, | |
< final int purpose, | |
< final String tag) { | |
--- | |
> private synchronized JSONObject registerXPUB(String xpub, int purpose, String tag) { | |
> | |
> String _url = WebUtil.getAPIUrl(context); | |
551,552c489 | |
< final String xpubApiService = BackendApiAndroid.getApiServiceUrl("xpub?"); | |
< response = WebUtil.getInstance(context).postURL(xpubApiService, args.toString()); | |
--- | |
> response = WebUtil.getInstance(context).postURL(_url + "xpub?", args.toString()); | |
554c491,492 | |
< } else { | |
--- | |
> } | |
> else { | |
575,576c513 | |
< final String xpubApiService = BackendApiAndroid.getApiServiceUrl("xpub"); | |
< response = WebUtil.getInstance(context).tor_postURL(xpubApiService, args); | |
--- | |
> response = WebUtil.getInstance(context).tor_postURL(_url + "xpub", args); | |
899a837,838 | |
> String _url = WebUtil.getAPIUrl(context); | |
> | |
911,912c850 | |
< xpub.equals(BIP84Util.getInstance(context).getWallet().getAccount(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()).zpubstr()) || | |
< xpub.equals(BIP84Util.getInstance(context).getWallet().getAccount(RicochetMeta.getInstance(context).getRicochetAccount()).zpubstr()) | |
--- | |
> xpub.equals(BIP84Util.getInstance(context).getWallet().getAccount(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()).zpubstr()) | |
927,929d864 | |
< else if(tag != null && tag.equals(PrefsUtil.XPUBRICOCHETLOCK)) { | |
< addr = BIP84Util.getInstance(context).getWallet().getAccount(RicochetMeta.getInstance(context).getRicochetAccount()).getChange().getAddressAt(0); | |
< } | |
969,970c904 | |
< final String xpubApiService = BackendApiAndroid.getApiServiceUrl("xpub/" + xpub + "/lock/"); | |
< response = WebUtil.getInstance(context).postURL(xpubApiService , args.toString()); | |
--- | |
> response = WebUtil.getInstance(context).postURL(_url + "xpub/" + xpub + "/lock/", args.toString()); | |
972c906,907 | |
< } else { | |
--- | |
> } | |
> else { | |
978c913 | |
< info("APIFactory", "lock XPUB:" + BackendApiAndroid.getApiBaseUrl()); | |
--- | |
> info("APIFactory", "lock XPUB:" + _url); | |
980,981c915 | |
< final String xpubApiService = BackendApiAndroid.getApiServiceUrl("xpub/" + xpub + "/lock/"); | |
< response = WebUtil.getInstance(context).tor_postURL(xpubApiService, args); | |
--- | |
> response = WebUtil.getInstance(context).tor_postURL(_url + "xpub/" + xpub + "/lock/", args); | |
1044c978,980 | |
< public Pair<String, JSONObject> getNotifTx(String hash, String addr) { | |
--- | |
> public JSONObject getNotifTx(String hash, String addr) { | |
> | |
> String _url = WebUtil.getAPIUrl(context); | |
1047d982 | |
< String pcode = null; | |
1050c985,987 | |
< StringBuilder url = new StringBuilder(BackendApiAndroid.getApiServiceUrl("tx/" + hash)); | |
--- | |
> StringBuilder url = new StringBuilder(_url); | |
> url.append("tx/"); | |
> url.append(hash); | |
1059c996 | |
< pcode = parseNotifTx(jsonObject, addr, hash); | |
--- | |
> parseNotifTx(jsonObject, addr, hash); | |
1071c1008 | |
< return isNull(jsonObject) ? null : new Pair<>(pcode, jsonObject); | |
--- | |
> return jsonObject; | |
1075a1013,1014 | |
> String _url = WebUtil.getAPIUrl(context); | |
> | |
1079,1080c1018,1019 | |
< StringBuilder url = new StringBuilder(BackendApiAndroid.getApiServiceUrl("wallet")); | |
< url.append("?active="); | |
--- | |
> StringBuilder url = new StringBuilder(_url); | |
> url.append("wallet?active="); | |
1132c1071 | |
< public String parseNotifTx(JSONObject jsonObject, String addr, String hash) throws JSONException { | |
--- | |
> public void parseNotifTx(JSONObject jsonObject, String addr, String hash) throws JSONException { | |
1137,1138d1075 | |
< String pcodeAsString = null; | |
< | |
1228,1229c1165 | |
< pcodeAsString = pcode.toString(); | |
< info("APIFactory", "incoming payment code:" + pcodeAsString); | |
--- | |
> info("APIFactory", "incoming payment code:" + pcode.toString()); | |
1231,1233c1167,1168 | |
< if(!pcodeAsString.equals(BIP47Util.getInstance(context).getPaymentCode().toString()) && | |
< pcode.isValid() && !BIP47Meta.getInstance().incomingExists(pcodeAsString)) { | |
< BIP47Meta.getInstance().setLabel(pcodeAsString, ""); | |
--- | |
> if(!pcode.toString().equals(BIP47Util.getInstance(context).getPaymentCode().toString()) && pcode.isValid() && !BIP47Meta.getInstance().incomingExists(pcode.toString())) { | |
> BIP47Meta.getInstance().setLabel(pcode.toString(), ""); | |
1254,1257c1189,1191 | |
< final String receivePubKey = BIP47Util.getInstance(context).getReceivePubKey(pcode, i); | |
< info("APIFactory", "receive from " + i + ":" + receivePubKey); | |
< BIP47Meta.getInstance().getIdx4AddrLookup().put(receivePubKey, i); | |
< BIP47Meta.getInstance().getPCode4AddrLookup().put(receivePubKey, pcodeAsString); | |
--- | |
> info("APIFactory", "receive from " + i + ":" + BIP47Util.getInstance(context).getReceivePubKey(pcode, i)); | |
> BIP47Meta.getInstance().getIdx4AddrLookup().put(BIP47Util.getInstance(context).getReceivePubKey(pcode, i), i); | |
> BIP47Meta.getInstance().getPCode4AddrLookup().put(BIP47Util.getInstance(context).getReceivePubKey(pcode, i), pcode.toString()); | |
1267,1268d1200 | |
< return pcodeAsString; | |
< | |
1278a1211 | |
> String _url = WebUtil.getAPIUrl(context); | |
1283c1216,1218 | |
< StringBuilder url = new StringBuilder(BackendApiAndroid.getApiServiceUrl("tx/" + hash)); | |
--- | |
> StringBuilder url = new StringBuilder(_url); | |
> url.append("tx/"); | |
> url.append(hash); | |
1322c1257 | |
< public static synchronized boolean parseUnspentOutputs(String unspents) { | |
--- | |
> private synchronized boolean parseUnspentOutputs(String unspents) { | |
1440c1375,1377 | |
< public synchronized JSONObject getAddressInfo(final Pair<EnumAddressType, String> addrByType) { | |
--- | |
> public synchronized JSONObject getAddressInfo(String addr) { | |
> | |
> return getXPUB(new String[] { addr }, false); | |
1442,1448d1378 | |
< final ListMultimap<EnumAddressType, String> addressesByType = | |
< ImmutableListMultimap.<EnumAddressType, String>builder() | |
< .put(addrByType.first, addrByType.second) | |
< .build(); | |
< return getXPUB( | |
< addressesByType, | |
< false); | |
1452a1383 | |
> String _url = WebUtil.getAPIUrl(context); | |
1457c1388,1390 | |
< StringBuilder url = new StringBuilder(BackendApiAndroid.getApiServiceUrl("tx/" + hash)); | |
--- | |
> StringBuilder url = new StringBuilder(_url); | |
> url.append("tx/"); | |
> url.append(hash); | |
1514c1447 | |
< private static RawFees putMock1DollarFeesEstimator() { | |
--- | |
> private RawFees putMock1DollarFeesEstimator() { | |
1526a1460 | |
> final String _url = WebUtil.getAPIUrl(context); | |
1529,1530c1463 | |
< final String feesApiService = BackendApiAndroid.getApiServiceUrl("fees"); | |
< response = WebUtil.getInstance(null).getURL(feesApiService + "?at=" + getAccessToken()); | |
--- | |
> response = WebUtil.getInstance(null).getURL(_url + "fees" + "?at=" + getAccessToken()); | |
1538c1471 | |
< public static RawFees parse1DollarFeesEstimator(final JSONObject payload) throws JSONException { | |
--- | |
> private RawFees parse1DollarFeesEstimator(final JSONObject payload) throws JSONException { | |
1565c1498 | |
< public static void parseDynamicFees_bitcoind(JSONObject payload) throws JSONException { | |
--- | |
> private void parseDynamicFees_bitcoind(JSONObject payload) throws JSONException { | |
1695c1628 | |
< | |
--- | |
> List<String> addressStrings = new ArrayList<>(); | |
1698a1632,1652 | |
> if(PrefsUtil.getInstance(context).getValue(PrefsUtil.XPUB44REG, false) == false && PrefsUtil.getInstance(context).getValue(PrefsUtil.FIRST_RUN, true)) { | |
> registerXPUB(HD_WalletFactory.getInstance(context).get().getAccount(0).xpubstr(), 44, null); | |
> } | |
> if(PrefsUtil.getInstance(context).getValue(PrefsUtil.XPUB49REG, false) == false && PrefsUtil.getInstance(context).getValue(PrefsUtil.FIRST_RUN, true)) { | |
> registerXPUB(BIP49Util.getInstance(context).getWallet().getAccount(0).xpubstr(), 49, null); | |
> } | |
> if(PrefsUtil.getInstance(context).getValue(PrefsUtil.XPUB84REG, false) == false && PrefsUtil.getInstance(context).getValue(PrefsUtil.FIRST_RUN, true)) { | |
> registerXPUB(BIP84Util.getInstance(context).getWallet().getAccount(0).xpubstr(), 84, null); | |
> } | |
> if(PrefsUtil.getInstance(context).getValue(PrefsUtil.XPUBPREREG, false) == false && PrefsUtil.getInstance(context).getValue(PrefsUtil.FIRST_RUN, true)) { | |
> registerXPUB(BIP84Util.getInstance(context).getWallet().getAccount(WhirlpoolMeta.getInstance(context).getWhirlpoolPremixAccount()).xpubstr(), 84, PrefsUtil.XPUBPREREG); | |
> } | |
> if(PrefsUtil.getInstance(context).getValue(PrefsUtil.XPUBPOSTREG, false) == false && PrefsUtil.getInstance(context).getValue(PrefsUtil.FIRST_RUN, true)) { | |
> registerXPUB(BIP84Util.getInstance(context).getWallet().getAccount(WhirlpoolMeta.getInstance(context).getWhirlpoolPostmix()).xpubstr(), 84, PrefsUtil.XPUBPOSTREG); | |
> } | |
> if(PrefsUtil.getInstance(context).getValue(PrefsUtil.XPUBBADBANKREG, false) == false && PrefsUtil.getInstance(context).getValue(PrefsUtil.FIRST_RUN, true)) { | |
> registerXPUB(BIP84Util.getInstance(context).getWallet().getAccount(WhirlpoolMeta.getInstance(context).getWhirlpoolBadBank()).xpubstr(), 84, PrefsUtil.XPUBBADBANKLOCK); | |
> } | |
> if(PrefsUtil.getInstance(context).getValue(PrefsUtil.XPUBRICOCHETREG, false) == false && PrefsUtil.getInstance(context).getValue(PrefsUtil.FIRST_RUN, true)) { | |
> registerXPUB(BIP84Util.getInstance(context).getWallet().getAccount(RicochetMeta.getInstance(context).getRicochetAccount()).zpubstr(), 84, PrefsUtil.XPUBRICOCHETREG); | |
> } | |
1702,1704c1656,1679 | |
< final List<String> bip47Addresses = BIP47Util.getBip47Addresses(context); | |
< if(bip47Addresses.size() > 0) { | |
< s = bip47Addresses.toArray(new String[0]); | |
--- | |
> addressStrings.addAll(Arrays.asList(BIP47Meta.getInstance().getIncomingAddresses(false))); | |
> for(String _s : Arrays.asList(BIP47Meta.getInstance().getIncomingLookAhead(context))) { | |
> if(!addressStrings.contains(_s)) { | |
> addressStrings.add(_s); | |
> } | |
> } | |
> for(String pcode : BIP47Meta.getInstance().getUnspentProviders()) { | |
> for(String addr : BIP47Meta.getInstance().getUnspentAddresses(context, pcode)) { | |
> if(!addressStrings.contains(addr)) { | |
> addressStrings.add(addr); | |
> } | |
> } | |
> List<Integer> idxs = BIP47Meta.getInstance().getUnspent(pcode); | |
> for(Integer idx : idxs) { | |
> String receivePubKey = BIP47Util.getInstance(context).getReceivePubKey(new PaymentCode(pcode), idx); | |
> BIP47Meta.getInstance().getIdx4AddrLookup().put(receivePubKey, idx); | |
> BIP47Meta.getInstance().getPCode4AddrLookup().put(receivePubKey, pcode.toString()); | |
> if(!addressStrings.contains(receivePubKey)) { | |
> addressStrings.add(receivePubKey); | |
> } | |
> } | |
> } | |
> if(addressStrings.size() > 0) { | |
> s = addressStrings.toArray(new String[0]); | |
1709,1712c1684 | |
< final ListMultimap<EnumAddressType, String> addressesByType = MultimapBuilder.linkedHashKeys().arrayListValues().build(); | |
< addressesByType.put(EnumAddressType.BIP44_LEGACY, BIP49Util.getInstance(context).getWallet().getAccount(0).xpubstr()); | |
< addressesByType.put(EnumAddressType.BIP44_LEGACY, BIP84Util.getInstance(context).getWallet().getAccount(0).xpubstr()); | |
< addressesByType.putAll(EnumAddressType.BIP44_LEGACY, ImmutableList.copyOf(hdw.getXPUBs())); | |
--- | |
> String[] all = null; | |
1714c1686,1690 | |
< addressesByType.putAll(EnumAddressType.BIP44_LEGACY, ImmutableList.copyOf(s)); | |
--- | |
> all = new String[hdw.getXPUBs().length + 2 + s.length]; | |
> all[0] = BIP49Util.getInstance(context).getWallet().getAccount(0).xpubstr(); | |
> all[1] = BIP84Util.getInstance(context).getWallet().getAccount(0).xpubstr(); | |
> System.arraycopy(hdw.getXPUBs(), 0, all, 2, hdw.getXPUBs().length); | |
> System.arraycopy(s, 0, all, hdw.getXPUBs().length + 2, s.length); | |
1716c1692,1702 | |
< JSONObject jObj = APIFactory.getInstance(context).getXPUB(addressesByType, true); | |
--- | |
> else { | |
> all = new String[hdw.getXPUBs().length + 2]; | |
> all[0] = BIP49Util.getInstance(context).getWallet().getAccount(0).xpubstr(); | |
> all[1] = BIP84Util.getInstance(context).getWallet().getAccount(0).xpubstr(); | |
> System.arraycopy(hdw.getXPUBs(), 0, all, 2, hdw.getXPUBs().length); | |
> } | |
> JSONObject jObj = APIFactory.getInstance(context).getXPUB(all, true); | |
> String[] xs = new String[3]; | |
> xs[0] = HD_WalletFactory.getInstance(context).get().getAccount(0).xpubstr(); | |
> xs[1] = BIP49Util.getInstance(context).getWallet().getAccount(0).xpubstr(); | |
> xs[2] = BIP84Util.getInstance(context).getWallet().getAccount(0).xpubstr(); | |
1755,1759c1741 | |
< final ListMultimap<EnumAddressType, String> addressesByType = ImmutableListMultimap.<EnumAddressType, String>builder() | |
< .putAll(EnumAddressType.BIP44_LEGACY, strPreMix, strPostMix) | |
< .build(); | |
< | |
< final JSONObject mixMultiAddrObj = getRawXPUB(addressesByType); | |
--- | |
> final JSONObject mixMultiAddrObj = getRawXPUB(new String[] { strPreMix, strPostMix }); | |
1830c1812 | |
< public synchronized int syncBIP47Incoming(final String[] addresses) { | |
--- | |
> public synchronized int syncBIP47Incoming(String[] addresses) { | |
1832,1838c1814,1815 | |
< final ListMultimap<EnumAddressType, String> addressesByType = MultimapBuilder | |
< .linkedHashKeys() | |
< .arrayListValues() | |
< .build(); | |
< addressesByType.putAll(EnumAddressType.BIP44_LEGACY, ImmutableList.copyOf(addresses)); | |
< JSONObject jsonObject = getXPUB(addressesByType, false); | |
< debug("APIFactory", String.format("sync BIP47 incoming:%s", jsonObject)); | |
--- | |
> JSONObject jsonObject = getXPUB(addresses, false); | |
> debug("APIFactory", "sync BIP47 incoming:" + jsonObject.toString()); | |
1926c1903 | |
< public synchronized int syncBIP47Outgoing(final String[] addresses) { | |
--- | |
> public synchronized int syncBIP47Outgoing(String[] addresses) { | |
1928,1933c1905 | |
< final ListMultimap<EnumAddressType, String> addressesByType = MultimapBuilder | |
< .linkedHashKeys() | |
< .arrayListValues() | |
< .build(); | |
< addressesByType.putAll(EnumAddressType.BIP44_LEGACY, ImmutableList.copyOf(addresses)); | |
< final JSONObject jsonObject = getXPUB(addressesByType, false); | |
--- | |
> JSONObject jsonObject = getXPUB(addresses, false); | |
2152,2153c2124,2126 | |
< private synchronized JSONObject getRawXPUB( | |
< final ListMultimap<EnumAddressType, String> addressesByType) { | |
--- | |
> private synchronized JSONObject getRawXPUB(String[] xpubs) { | |
> | |
> String _url = WebUtil.getAPIUrl(context); | |
2166,2190c2139,2141 | |
< final StringBuilder args = new StringBuilder(); | |
< | |
< for (final EnumAddressType type : addressesByType.keySet()) { | |
< switch (type) { | |
< case BIP44_LEGACY: | |
< args.append("active="); | |
< args.append(StringUtils.join(addressesByType.get(type), URLEncoder.encode("|", "UTF-8"))); | |
< args.append("&"); | |
< break; | |
< case BIP49_SEGWIT_COMPAT: | |
< args.append("bip49="); | |
< args.append(StringUtils.join(addressesByType.get(type), URLEncoder.encode("|", "UTF-8"))); | |
< args.append("&"); | |
< break; | |
< case BIP84_SEGWIT_NATIVE: | |
< args.append("bip84="); | |
< args.append(StringUtils.join(addressesByType.get(type), URLEncoder.encode("|", "UTF-8"))); | |
< args.append("&"); | |
< break; | |
< default: | |
< info("APIFactory", "unknown EnumAddressType:" + type); | |
< break; | |
< } | |
< } | |
< | |
--- | |
> StringBuilder args = new StringBuilder(); | |
> args.append("active="); | |
> args.append(StringUtils.join(xpubs, URLEncoder.encode("|", "UTF-8"))); | |
2198c2149,2150 | |
< } else { | |
--- | |
> } | |
> else { | |
2203,2204c2155 | |
< final String walletApiService = BackendApiAndroid.getApiServiceUrl("wallet?"); | |
< response = WebUtil.getInstance(context).postURL(walletApiService, args.toString()); | |
--- | |
> response = WebUtil.getInstance(context).postURL(_url + "wallet?", args.toString()); | |
2206,2225c2157,2160 | |
< } else { | |
< | |
< final Map<String,String> args = Maps.newHashMap(); | |
< for (final EnumAddressType type : addressesByType.keySet()) { | |
< switch (type) { | |
< case BIP44_LEGACY: | |
< args.put("active", StringUtils.join(addressesByType.get(type), "|")); | |
< break; | |
< case BIP49_SEGWIT_COMPAT: | |
< args.put("bip49", StringUtils.join(addressesByType.get(type), "|")); | |
< break; | |
< case BIP84_SEGWIT_NATIVE: | |
< args.put("bip84", StringUtils.join(addressesByType.get(type), "|")); | |
< break; | |
< default: | |
< info("APIFactory", "unknown EnumAddressType:" + type); | |
< break; | |
< } | |
< } | |
< | |
--- | |
> } | |
> else { | |
> HashMap<String,String> args = new HashMap<String,String>(); | |
> args.put("active", StringUtils.join(xpubs, "|")); | |
2238,2239c2173 | |
< final String walletApiService = BackendApiAndroid.getApiServiceUrl("wallet"); | |
< response = WebUtil.getInstance(context).tor_postURL(walletApiService, args); | |
--- | |
> response = WebUtil.getInstance(context).tor_postURL(_url + "wallet", args); | |
2607,2612c2541,2542 | |
< final String[] s = new String[] { BIP84Util.getInstance(context).getWallet().getAccount(RicochetMeta.getInstance(context).getRicochetAccount()).xpubstr() }; | |
< | |
< final ListMultimap<EnumAddressType, String> addressesByType = ImmutableListMultimap.<EnumAddressType, String>builder() | |
< .putAll(EnumAddressType.BIP44_LEGACY, s) | |
< .build(); | |
< JSONObject jsonObject = getRawXPUB(addressesByType); | |
--- | |
> String[] s = new String[] { BIP84Util.getInstance(context).getWallet().getAccount(RicochetMeta.getInstance(context).getRicochetAccount()).zpubstr() }; | |
> JSONObject jsonObject = getRawXPUB(s); | |
2667c2597 | |
< private static void onUtxoChange() { | |
--- | |
> private void onUtxoChange() { | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/api/fee/EnumFeeRepresentation.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/api/fee/EnumFeeRepresentation.java | |
39,40c39,40 | |
< final Integer feeForNextBlockAt10 = nonNull(rawFees.getFee(EnumFeeRate.RATE_100)) | |
< ? rawFees.getFee(EnumFeeRate.RATE_100) | |
--- | |
> final Integer feeForNextBlockAt20 = nonNull(rawFees.getFee(EnumFeeRate.RATE_200)) | |
> ? rawFees.getFee(EnumFeeRate.RATE_200) | |
43c43 | |
< if (nonNull(feeForNextBlockAt10)) { | |
--- | |
> if (nonNull(feeForNextBlockAt20)) { | |
45c45 | |
< suggestedFee.setDefaultPerKB(BigInteger.valueOf(feeForNextBlockAt10 * 1000L)); | |
--- | |
> suggestedFee.setDefaultPerKB(BigInteger.valueOf(feeForNextBlockAt20 * 1000L)); | |
51,52c51,52 | |
< if (isNull(rawFees.getFee(EnumFeeRate.RATE_100))) { | |
< rawFees.putFee(EnumFeeRate.RATE_100.getRateAsString(), feeForNextBlockAt10); | |
--- | |
> if (isNull(rawFees.getFee(EnumFeeRate.RATE_200))) { | |
> rawFees.putFee(EnumFeeRate.RATE_200.getRateAsString(), feeForNextBlockAt20); | |
110,117d109 | |
< | |
< public boolean is1DolFeeEstimator() { | |
< return this == NEXT_BLOCK_RATE; | |
< } | |
< | |
< public boolean isBitcoindFeeEstimator() { | |
< return this == BLOCK_COUNT; | |
< } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/bip47/BIP47Meta.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/bip47/BIP47Meta.java | |
5d4 | |
< import static org.apache.commons.lang3.StringUtils.isNotBlank; | |
13,14d11 | |
< import com.google.common.collect.Maps; | |
< import com.google.common.collect.Sets; | |
25d21 | |
< import java.util.Collection; | |
39,41c35 | |
< public static final String ashigaruDonationPcodeMainnet = "PM8TJUhHJzVgoxaay8njgTDdNVE8i6PuFbgsJEiKpfbX7umkVHQ9bamF1pZgEYWAmkecLt81Mcg6ybKbDW4PN41GsskGXLV89fb5ARF3ZexopEgDBs3v"; | |
< public static final String ashigaruDonationPcodeTestnet = "PM8TJQuX14xb5VhpYUFM165WjbYHTnQvH2zdyrTJijnjYrfGM8u5tTiQ3qCFAoESb1xDnLXaqD4iqR6zFUFy3Yi1C1nN4F3hLMp7LJngjgB4gvumHnc3"; | |
< public static final String strSamouraiDonationPCode = SamouraiWallet.getInstance().isTestNet() ? ashigaruDonationPcodeTestnet : ashigaruDonationPcodeMainnet;// public static final String strSamouraiDonationMeta = "?title=Samourai Donations&desc=Donate to help fund development of Samourai Bitcoin Wallet&user=K6tS2X8"; | |
--- | |
> public static final String strSamouraiDonationPCode = SamouraiWallet.samouraiDonationPCode;// public static final String strSamouraiDonationMeta = "?title=Samourai Donations&desc=Donate to help fund development of Samourai Bitcoin Wallet&user=K6tS2X8"; | |
52d45 | |
< private static Map<String, String> pcodeNames = null; | |
54d46 | |
< private static Map<String, String> notFoundPcodeLabels = null; // useful to keep the pcode from backup on sync task | |
56c48 | |
< private static Map<String, Boolean> followings = null; | |
--- | |
> private static Map<String, Boolean> pcodeRoles = null; | |
58c50 | |
< private static Map<String, Map<String,Integer>> pcodeUnspentIdxs = null; // unused => could be removed | |
--- | |
> private static Map<String, Map<String,Integer>> pcodeUnspentIdxs = null; | |
67a60 | |
> private static List<String> followingPcodes = null; | |
76d68 | |
< pcodeNames = new ConcurrentHashMap<>(); | |
78d69 | |
< notFoundPcodeLabels = new ConcurrentHashMap<>(); | |
80c71 | |
< followings = new ConcurrentHashMap<>(); | |
--- | |
> pcodeRoles = new ConcurrentHashMap<>(); | |
91a83 | |
> followingPcodes = new ArrayList<>(); | |
100d91 | |
< pcodeNames.clear(); | |
102d92 | |
< notFoundPcodeLabels.clear(); | |
104c94 | |
< followings.clear(); | |
--- | |
> pcodeRoles.clear(); | |
116,124c106 | |
< } | |
< | |
< public void partialClearOnRestoringWallet() { | |
< pcodeNames.clear(); | |
< pcodeLabels.clear(); | |
< labelsPcode.clear(); | |
< followings.clear(); | |
< pcodeSegwit.clear(); | |
< pcodeUnspentIdxs.clear(); | |
--- | |
> followingPcodes.clear(); | |
129c111 | |
< if (StringUtils.equals(label, "Ashigaru as mixing partner")) { | |
--- | |
> if (StringUtils.equals(label, "Samourai as mixing partner")) { | |
135,138d116 | |
< public String getName(final String pcode) { | |
< return pcodeNames.getOrDefault(pcode, ""); | |
< } | |
< | |
144c122 | |
< return "Ashigaru as mixing partner"; | |
--- | |
> return "Samourai as mixing partner"; | |
153,171c131,133 | |
< public boolean isFollowing(final String pcode) { | |
< return followings.getOrDefault(pcode, false); | |
< } | |
< | |
< public Set<String> getFollowings() { | |
< final Set<String> followingsFound = Sets.newHashSet(); | |
< for (final String pcode : followings.keySet()) { | |
< if (isFollowing(pcode)) { | |
< followingsFound.add(pcode); | |
< } | |
< } | |
< return followingsFound; | |
< } | |
< | |
< synchronized public void setFollowings(final Collection<String> pcodes) { | |
< followings.clear(); | |
< for (final String pcode : pcodes) { | |
< followings.put(pcode, true); | |
< } | |
--- | |
> public void addFollowings(final List<String> pcodes){ | |
> followingPcodes.clear(); | |
> followingPcodes.addAll(pcodes); | |
174,175c136,137 | |
< public void setFollowing(final String pcode, final boolean isFollowing) { | |
< followings.put(pcode, isFollowing); | |
--- | |
> public boolean isFollowing(final String pcode){ | |
> return followingPcodes.contains(pcode); | |
190,197c152 | |
< public void setName(final String pcode, final String name) { | |
< pcodeNames.put(pcode, name); | |
< } | |
< | |
< public void setLabel(final String pcode, final String label) { | |
< if (StringUtils.isBlank(label) && pcodeNames.containsKey(pcode)) { | |
< return; | |
< } | |
--- | |
> public void setLabel(final String pcode, final String label) { | |
202,203c157,158 | |
< public void putNotFoundPcodes(final String pcode, final String label) { | |
< notFoundPcodeLabels.put(pcode, label); | |
--- | |
> public void setRole (final String pcode, final boolean isFollowing) { | |
> pcodeRoles.put(pcode, isFollowing); | |
206c161 | |
< public Set<String> getPcodes() { | |
--- | |
> public Set<String> getLabels() { | |
210,213d164 | |
< public Map<String, String> getCopyOfPcodeLabels() { | |
< return Maps.newHashMap(pcodeLabels); | |
< } | |
< | |
240c191 | |
< final int outgoingStatus = getOutgoingStatus(key); | |
--- | |
> final int outgoingStatus = BIP47Meta.getInstance().getOutgoingStatus(key); | |
242c193 | |
< && (!confirmed || outgoingStatus == BIP47Meta.STATUS_SENT_CFM)) { | |
--- | |
> && outgoingStatus == BIP47Meta.STATUS_SENT_CFM) { | |
285c236,241 | |
< return pcodeArchived.getOrDefault(pcode, false); | |
--- | |
> if(!pcodeArchived.containsKey(pcode)) { | |
> pcodeArchived.put(pcode, false); | |
> return false; | |
> } else { | |
> return pcodeArchived.get(pcode); | |
> } | |
305c261,270 | |
< | |
--- | |
> /* | |
> public void incIncomingIdx(String pcode) { | |
> if(!pcodeIncomingIdxs.containsKey(pcode)) { | |
> pcodeIncomingIdxs.put(pcode, 1); | |
> } | |
> else { | |
> pcodeIncomingIdxs.put(pcode, pcodeIncomingIdxs.get(pcode) + 1); | |
> } | |
> } | |
> */ | |
343,344c308 | |
< if(!includeArchived && getArchived(pcode)) continue; | |
< if(isNull(pcodeUnspentIdxs.get(pcode))) continue; | |
--- | |
> if(!includeArchived && nonNull(pcodeArchived.get(pcode))) continue; | |
424,430d387 | |
< public boolean isOutgoingStatusSent(final String pcode) { | |
< final Pair<String, Integer> txAndStatus = pcodeOutgoingStatus.get(pcode); | |
< if (isNull(txAndStatus)) return false; | |
< return txAndStatus.getValue() == STATUS_SENT_CFM || | |
< txAndStatus.getValue() == STATUS_SENT_NO_CFM; | |
< } | |
< | |
443,451c400,408 | |
< | |
< for(final Map.Entry<String, Pair<String, Integer>> pcodeToTxInfo : pcodeOutgoingStatus.entrySet()) { | |
< final Pair<String, Integer> txInfo = pcodeToTxInfo.getValue(); | |
< final Integer confirmedStatus = nonNull(txInfo.getRight()) ? txInfo.getRight() : STATUS_NOT_SENT; | |
< final String txHash = txInfo.getLeft(); | |
< if (confirmedStatus == STATUS_SENT_NO_CFM && isNotBlank(txHash)) { | |
< final String pcode = pcodeToTxInfo.getKey(); | |
< ret.add(Pair.of(pcode, txHash)); | |
< } | |
--- | |
> // info("BIP47Meta", "key set:" + pcodeOutgoingStatus.keySet().size()); | |
> for(final String pcode : pcodeOutgoingStatus.keySet()) { | |
> // info("BIP47Meta", "pcode:" + pcode.toString()); | |
> // info("BIP47Meta", "tx:" + pcodeOutgoingStatus.get(pcode).getLeft()); | |
> // info("BIP47Meta", "status:" + pcodeOutgoingStatus.get(pcode).getRight()); | |
> // if(pcodeOutgoingStatus.get(pcode).getRight() != STATUS_SENT_CFM && pcodeOutgoingStatus.get(pcode).getLeft() != null && pcodeOutgoingStatus.get(pcode).getLeft().length() > 0) { | |
> // ret.add(Pair.of(pcode, pcodeOutgoingStatus.get(pcode).getLeft())); | |
> // } | |
> ret.add(Pair.of(pcode, pcodeOutgoingStatus.get(pcode).getLeft())); | |
529,530c486 | |
< synchronized public void remove(final String pcode) { | |
< pcodeNames.remove(pcode); | |
--- | |
> synchronized public void remove(final String pcode) { | |
533,534c489 | |
< notFoundPcodeLabels.remove(pcode); | |
< followings.remove(pcode); | |
--- | |
> pcodeRoles.remove(pcode); | |
569c524 | |
< for(final String pcode : getPcodes()) { | |
--- | |
> for(final String pcode : getLabels()) { | |
608d562 | |
< pobj.put("name", pcodeNames.get(pcode)); | |
612c566 | |
< pobj.put("following", followings.get(pcode)); | |
--- | |
> pobj.put("following", pcodeRoles.get(pcode)); | |
646c600,601 | |
< } else { | |
--- | |
> } | |
> else { | |
669,677d623 | |
< final JSONArray notFoundPcodes = new JSONArray(); | |
< for (final Map.Entry<String, String> pcodeLabel : notFoundPcodeLabels.entrySet()) { | |
< final JSONObject pobj = new JSONObject(); | |
< pobj.put("payment_code", pcodeLabel.getKey()); | |
< pobj.put("label", pcodeLabel.getValue()); | |
< notFoundPcodes.put(pobj); | |
< } | |
< jsonPayload.put("not_found_pcodes", notFoundPcodes); | |
< | |
699,701c645,648 | |
< final JSONArray pcodes = jsonPayload.has("pcodes") | |
< ? jsonPayload.getJSONArray("pcodes") | |
< : new JSONArray(); | |
--- | |
> JSONArray pcodes = new JSONArray(); | |
> if(jsonPayload.has("pcodes")) { | |
> pcodes = jsonPayload.getJSONArray("pcodes"); | |
> } | |
711,718c658,659 | |
< if (obj.has("name")) { | |
< pcodeNames.put(paymentCode, obj.getString("name")); | |
< } else { | |
< pcodeNames.put(paymentCode, label); // to manage old version | |
< } | |
< if (obj.has("following")) { | |
< followings.put(paymentCode, obj.getBoolean("following")); | |
< } | |
--- | |
> if (obj.has("following")) | |
> pcodeRoles.put(paymentCode, obj.getBoolean("following")); | |
772,782d712 | |
< } | |
< | |
< final JSONArray notFoundPcodes = jsonPayload.has("not_found_pcodes") | |
< ? jsonPayload.getJSONArray("not_found_pcodes") | |
< : new JSONArray(); | |
< | |
< for(int i = 0; i < notFoundPcodes.length(); i++) { | |
< final JSONObject obj = notFoundPcodes.getJSONObject(i); | |
< final String paymentCode = obj.getString("payment_code"); | |
< final String label = obj.getString("label"); | |
< notFoundPcodeLabels.put(paymentCode, label); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/bip47/BIP47Util.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/bip47/BIP47Util.java | |
3,6d2 | |
< import static com.samourai.wallet.bip47.BIP47Meta.STATUS_SENT_CFM; | |
< import static org.apache.commons.lang3.StringUtils.isBlank; | |
< import static java.util.Objects.nonNull; | |
< | |
10d5 | |
< import android.util.Log; | |
13,17d7 | |
< import androidx.annotation.NonNull; | |
< import androidx.core.content.ContextCompat; | |
< import androidx.lifecycle.LiveData; | |
< import androidx.lifecycle.MutableLiveData; | |
< | |
20d9 | |
< import com.samourai.wallet.api.backend.beans.HttpException; | |
30d18 | |
< import com.samourai.wallet.util.tech.ThreadHelper; | |
35a24 | |
> import org.jetbrains.annotations.Nullable; | |
41,43d29 | |
< import java.util.ArrayList; | |
< import java.util.Arrays; | |
< import java.util.List; | |
44a31,33 | |
> import androidx.core.content.ContextCompat; | |
> import androidx.lifecycle.LiveData; | |
> import androidx.lifecycle.MutableLiveData; | |
52,54c41,42 | |
< public class BIP47Util extends BIP47UtilGeneric { | |
< | |
< public static final String TAG = "BIP47Util"; | |
--- | |
> import static com.samourai.wallet.bip47.BIP47Meta.STATUS_SENT_CFM; | |
> import static org.apache.commons.lang3.StringUtils.isBlank; | |
56c44 | |
< private static final boolean ALWAYS_ACCEPT_SEGWIT = true; | |
--- | |
> public class BIP47Util extends BIP47UtilGeneric { | |
90c78 | |
< private static NetworkParameters getNetworkParams() { | |
--- | |
> private NetworkParameters getNetworkParams() { | |
152,154c140,141 | |
< public void setAvatar(final Bitmap bitmap) { | |
< paynymLogo.postValue(null); // reset in order to ensure the push with the next post | |
< if (nonNull(bitmap)) { | |
--- | |
> public void setAvatar(@Nullable Bitmap bitmap) { | |
> if (bitmap != null) { | |
156,157d142 | |
< } else { | |
< Log.d(TAG, "bitmap is null in setAvatar()"); | |
168c153,167 | |
< loadBotImage(finalUrl, 3); | |
--- | |
> Request.Builder rb = new Request.Builder().url(finalUrl); | |
> OkHttpClient.Builder builder = com.samourai.wallet.util.network.WebUtil.getInstance(context).httpClientBuilder(finalUrl); | |
> OkHttpClient client = builder.build(); | |
> Response response = client.newCall(rb.build()).execute(); | |
> if (response.isSuccessful()) { | |
> File file = avatarImage(); | |
> if (!file.exists()) { | |
> file.createNewFile(); | |
> } | |
> byte[] stream = response.body().bytes(); | |
> OutputStream outStream = new FileOutputStream(file); | |
> outStream.write(stream); | |
> Bitmap bitmap = BitmapFactory.decodeFile(file.getPath()); | |
> setAvatar(bitmap); | |
> } | |
174,215c173 | |
< private void loadBotImage(final String finalUrl, final int maxRetry) | |
< throws HttpException, IOException { | |
< | |
< final Request.Builder rb = new Request.Builder().url(finalUrl); | |
< final OkHttpClient client = com.samourai.wallet.util.network.WebUtil | |
< .getInstance(context) | |
< .httpClientBuilder(finalUrl) | |
< .build(); | |
< final Response response = client.newCall(rb.build()).execute(); | |
< if (response.isSuccessful()) { | |
< | |
< final File file = avatarImage(); | |
< if (!file.exists()) { | |
< file.createNewFile(); | |
< } | |
< | |
< boolean status = true; | |
< try (final OutputStream outStream = new FileOutputStream(file)) { | |
< outStream.write(response.body().bytes()); | |
< } catch (final Exception e) { | |
< Log.e(TAG, "issue on creating paynym bitmap"); | |
< status = false; | |
< } | |
< | |
< if (status) { | |
< final Bitmap bitmap = BitmapFactory.decodeFile(file.getPath()); | |
< if (nonNull(bitmap)) { | |
< setAvatar(bitmap); | |
< return; | |
< } | |
< } | |
< } | |
< | |
< if (maxRetry > 0) { | |
< ThreadHelper.pauseMillis(5_000L); | |
< loadBotImage(finalUrl, maxRetry-1); | |
< } else { | |
< Log.e(TAG, "loading bot image failed"); | |
< } | |
< } | |
< | |
< synchronized public String getSendAddressString( | |
--- | |
> synchronized public String getDestinationAddrFromPcode( | |
219c177 | |
< return getSendAddressString(pcodeAsString, 0); | |
--- | |
> return getDestinationAddrFromPcode(pcodeAsString, 0); | |
223c181 | |
< synchronized public String getSendAddressString( | |
--- | |
> synchronized public String getDestinationAddrFromPcode( | |
236c194 | |
< if (ALWAYS_ACCEPT_SEGWIT || BIP47Meta.getInstance().getSegwit(pcodeAsString)) { | |
--- | |
> if (BIP47Meta.getInstance().getSegwit(pcodeAsString)) { | |
239c197 | |
< getNetworkParams()).getBech32AsString(); | |
--- | |
> SamouraiWallet.getInstance().getCurrentNetworkParams()).getBech32AsString(); | |
243c201 | |
< .toAddress(getNetworkParams()).toString(); | |
--- | |
> .toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString(); | |
258a217,228 | |
> public String getSendAddressString(final String pcode) throws Exception { | |
> final PaymentAddress paymentAddress = getPaymentAddressSend(pcode, 0); | |
> if (BIP47Meta.getInstance().getSegwit(pcode)) { | |
> return new SegwitAddress(paymentAddress.getSendECKey(), getNetworkParams()) | |
> .getBech32AsString(); | |
> } else { | |
> return paymentAddress.getSendECKey().toAddress(getNetworkParams()).toString(); | |
> } | |
> } | |
> | |
> | |
> | |
280,307d249 | |
< } | |
< | |
< @NonNull | |
< public static List<String> getBip47Addresses(final Context context) throws Exception { | |
< final List<String> addressStrings = new ArrayList<>(); | |
< addressStrings.addAll(Arrays.asList(BIP47Meta.getInstance().getIncomingAddresses(false))); | |
< for(String _s : Arrays.asList(BIP47Meta.getInstance().getIncomingLookAhead(context))) { | |
< if(!addressStrings.contains(_s)) { | |
< addressStrings.add(_s); | |
< } | |
< } | |
< for(String pcode : BIP47Meta.getInstance().getUnspentProviders()) { | |
< for(String addr : BIP47Meta.getInstance().getUnspentAddresses(context, pcode)) { | |
< if(!addressStrings.contains(addr)) { | |
< addressStrings.add(addr); | |
< } | |
< } | |
< List<Integer> idxs = BIP47Meta.getInstance().getUnspent(pcode); | |
< for(Integer idx : idxs) { | |
< String receivePubKey = BIP47Util.getInstance(context).getReceivePubKey(new PaymentCode(pcode), idx); | |
< BIP47Meta.getInstance().getIdx4AddrLookup().put(receivePubKey, idx); | |
< BIP47Meta.getInstance().getPCode4AddrLookup().put(receivePubKey, pcode.toString()); | |
< if(!addressStrings.contains(receivePubKey)) { | |
< addressStrings.add(receivePubKey); | |
< } | |
< } | |
< } | |
< return addressStrings; | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/bip47/paynym/WebUtil.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/bip47/paynym/WebUtil.java | |
5,6d4 | |
< import com.samourai.wallet.paynym.api.PayNymApiService; | |
< | |
15c13 | |
< public static final String PAYNYM_API = PayNymApiService.PAYNYM_API; | |
--- | |
> public static final String PAYNYM_API = "https://paynym.is/"; | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/bip47/SendNotifTxFactory.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/bip47/SendNotifTxFactory.java | |
17,18c17,18 | |
< public String SAMOURAI_NOTIF_TX_FEE_ADDRESS = "bc1qca73k4dt9sfr47rr3wvpmpl08xs5f7tvhsxhdt"; | |
< public String TESTNET_SAMOURAI_NOTIF_TX_FEE_ADDRESS = "tb1qe2s3cre37j2ajlrk0gpdkymujqxs7zt47htwm7"; | |
--- | |
> public String SAMOURAI_NOTIF_TX_FEE_ADDRESS = "bc1qncfysagz0072a894kvzyxqwpvj5ckfj5kctmtk"; | |
> public String TESTNET_SAMOURAI_NOTIF_TX_FEE_ADDRESS = "tb1qh287jqsh6mkpqmd8euumyfam00fkr78qhrdnde"; | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/collaborate/CollaborateActivity.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/collaborate/CollaborateActivity.kt | |
76,77d75 | |
< getWindow().statusBarColor = resources.getColor(R.color.grey_accent) | |
< getWindow().navigationBarColor = resources.getColor(R.color.window) | |
508a507 | |
> var url by remember { mutableStateOf("${WebUtil.PAYNYM_API}${pcode}/avatar") } | |
509a509,511 | |
> LaunchedEffect(pcode) { | |
> url = "${WebUtil.PAYNYM_API}${pcode}/avatar" | |
> } | |
517c519 | |
< pcode = pcode, | |
--- | |
> url = url, | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/collaborate/ParticipateSegment.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/collaborate/ParticipateSegment.kt | |
249a250,251 | |
> val url = "${WebUtil.PAYNYM_API}${sorobanRequest!!.sender.toString()}/avatar" | |
> | |
267c269 | |
< pcode = sorobanRequest!!.sender.toString(), | |
--- | |
> url = url, | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/collaborate/Paynym.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/collaborate/Paynym.kt | |
11,19c11 | |
< import androidx.compose.foundation.layout.Arrangement | |
< import androidx.compose.foundation.layout.Box | |
< import androidx.compose.foundation.layout.Column | |
< import androidx.compose.foundation.layout.Row | |
< import androidx.compose.foundation.layout.fillMaxWidth | |
< import androidx.compose.foundation.layout.height | |
< import androidx.compose.foundation.layout.padding | |
< import androidx.compose.foundation.layout.requiredHeight | |
< import androidx.compose.foundation.layout.size | |
--- | |
> import androidx.compose.foundation.layout.* | |
27,38c19 | |
< import androidx.compose.material.Divider | |
< import androidx.compose.material.ExperimentalMaterialApi | |
< import androidx.compose.material.Icon | |
< import androidx.compose.material.IconButton | |
< import androidx.compose.material.LinearProgressIndicator | |
< import androidx.compose.material.ModalBottomSheetState | |
< import androidx.compose.material.ModalBottomSheetValue | |
< import androidx.compose.material.Scaffold | |
< import androidx.compose.material.Text | |
< import androidx.compose.material.TextField | |
< import androidx.compose.material.TextFieldDefaults | |
< import androidx.compose.material.TopAppBar | |
--- | |
> import androidx.compose.material.* | |
42,44c23 | |
< import androidx.compose.runtime.Composable | |
< import androidx.compose.runtime.LaunchedEffect | |
< import androidx.compose.runtime.getValue | |
--- | |
> import androidx.compose.runtime.* | |
46,49d24 | |
< import androidx.compose.runtime.mutableStateOf | |
< import androidx.compose.runtime.remember | |
< import androidx.compose.runtime.rememberCoroutineScope | |
< import androidx.compose.runtime.setValue | |
70a46 | |
> import com.samourai.wallet.bip47.paynym.WebUtil | |
75d50 | |
< import com.samourai.wallet.paynym.api.PayNymApiService | |
100d74 | |
< val spendable by collaborateViewModel.spendable.observeAsState(initial = listOf()) | |
105,111c79 | |
< var paynyms = arrayListOf<String>().apply { | |
< if (paynymChooserType == PaynymChooserType.SPEND) { | |
< addAll(spendable) | |
< } else { | |
< addAll(following) | |
< } | |
< } | |
--- | |
> var paynyms = arrayListOf<String>().apply { addAll(following) } | |
112a81,86 | |
> if (cahootType?.cahootsMode == CahootsMode.SOROBAN && cahootType?.cahootsType != CahootsType.STOWAWAY) { | |
> paynyms = arrayListOf<String>().apply { | |
> add(BIP47Meta.getMixingPartnerCode()) | |
> addAll(following) | |
> } | |
> } | |
122c96 | |
< addAll(paynyms.filter { | |
--- | |
> addAll(following.filter { | |
164c138 | |
< collaborateViewModel.applySearch(it, paynymChooserType) | |
--- | |
> collaborateViewModel.applySearch(it) | |
168c142 | |
< collaborateViewModel.applySearch(null, paynymChooserType) | |
--- | |
> collaborateViewModel.applySearch(null) | |
200c174 | |
< if (paynymChooserType == PaynymChooserType.COLLABORATE && it == BIP47Meta.getMixingPartnerCode()) { | |
--- | |
> if (it == BIP47Meta.getMixingPartnerCode()) { | |
214c188 | |
< PaynymAvatar(pcode = it, nym = "${BIP47Meta.getInstance().getDisplayLabel(it)} ${if(connected) "(connected)" else ""}", | |
--- | |
> PaynymAvatar(pcode = it, nym = "${BIP47Meta.getInstance().getLabel(it)} ${if(connected) "(connected)" else ""}", | |
296a271,272 | |
> val url = "${WebUtil.PAYNYM_API}${pcode}/avatar" | |
> | |
315c291 | |
< pcode = pcode, | |
--- | |
> url = url, | |
342,343c318 | |
< pcode: String, | |
< modifier: Modifier = Modifier, | |
--- | |
> url: String, modifier: Modifier = Modifier, | |
349c324 | |
< LaunchedEffect(pcode) { | |
--- | |
> LaunchedEffect(url) { | |
352c327 | |
< .load("${PayNymApiService.PAYNYM_API}${pcode}/avatar") | |
--- | |
> .load(url) | |
362,378d336 | |
< scope.launch { | |
< Picasso.get() | |
< .load("${PayNymApiService.PAYNYM_API}preview/${pcode}") | |
< .into(object : Target { | |
< override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) { | |
< if (bitmap != null) { | |
< imageBitMap = bitmap.asImageBitmap(); | |
< } | |
< } | |
< | |
< override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) { | |
< } | |
< | |
< override fun onPrepareLoad(placeHolderDrawable: Drawable?) { | |
< } | |
< }) | |
< } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/collaborate/TransactionSetup.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/collaborate/TransactionSetup.kt | |
3,10c3 | |
< import androidx.compose.animation.AnimatedContent | |
< import androidx.compose.animation.ExperimentalAnimationApi | |
< import androidx.compose.animation.SizeTransform | |
< import androidx.compose.animation.fadeIn | |
< import androidx.compose.animation.fadeOut | |
< import androidx.compose.animation.slideInVertically | |
< import androidx.compose.animation.slideOutVertically | |
< import androidx.compose.animation.with | |
--- | |
> import androidx.compose.animation.* | |
13,23c6 | |
< import androidx.compose.foundation.layout.Arrangement | |
< import androidx.compose.foundation.layout.Box | |
< import androidx.compose.foundation.layout.BoxWithConstraints | |
< import androidx.compose.foundation.layout.Column | |
< import androidx.compose.foundation.layout.PaddingValues | |
< import androidx.compose.foundation.layout.Row | |
< import androidx.compose.foundation.layout.fillMaxHeight | |
< import androidx.compose.foundation.layout.fillMaxWidth | |
< import androidx.compose.foundation.layout.padding | |
< import androidx.compose.foundation.layout.requiredHeight | |
< import androidx.compose.foundation.layout.size | |
--- | |
> import androidx.compose.foundation.layout.* | |
29,44c12 | |
< import androidx.compose.material.Button | |
< import androidx.compose.material.ButtonDefaults | |
< import androidx.compose.material.ExperimentalMaterialApi | |
< import androidx.compose.material.Icon | |
< import androidx.compose.material.IconButton | |
< import androidx.compose.material.ListItem | |
< import androidx.compose.material.MaterialTheme | |
< import androidx.compose.material.Scaffold | |
< import androidx.compose.material.Slider | |
< import androidx.compose.material.SliderDefaults | |
< import androidx.compose.material.Surface | |
< import androidx.compose.material.Text | |
< import androidx.compose.material.TextButton | |
< import androidx.compose.material.TextField | |
< import androidx.compose.material.TextFieldDefaults | |
< import androidx.compose.material.TopAppBar | |
--- | |
> import androidx.compose.material.* | |
48,50c16 | |
< import androidx.compose.runtime.Composable | |
< import androidx.compose.runtime.LaunchedEffect | |
< import androidx.compose.runtime.getValue | |
--- | |
> import androidx.compose.runtime.* | |
52,55d17 | |
< import androidx.compose.runtime.mutableStateOf | |
< import androidx.compose.runtime.remember | |
< import androidx.compose.runtime.rememberCoroutineScope | |
< import androidx.compose.runtime.setValue | |
71,76c33 | |
< import androidx.compose.ui.text.input.ImeAction | |
< import androidx.compose.ui.text.input.KeyboardType | |
< import androidx.compose.ui.text.input.OffsetMapping | |
< import androidx.compose.ui.text.input.TextFieldValue | |
< import androidx.compose.ui.text.input.TransformedText | |
< import androidx.compose.ui.text.input.VisualTransformation | |
--- | |
> import androidx.compose.ui.text.input.* | |
92,99c49 | |
< import com.samourai.wallet.theme.samouraiAccent | |
< import com.samourai.wallet.theme.samouraiBottomSheetBackground | |
< import com.samourai.wallet.theme.samouraiError | |
< import com.samourai.wallet.theme.samouraiSurface | |
< import com.samourai.wallet.theme.samouraiTextFieldBg | |
< import com.samourai.wallet.theme.samouraiTextPrimary | |
< import com.samourai.wallet.theme.samouraiTextSecondary | |
< import com.samourai.wallet.theme.samouraiWindow | |
--- | |
> import com.samourai.wallet.theme.* | |
108c58 | |
< import java.util.Locale | |
--- | |
> import java.util.* | |
198c148 | |
< Icon(painter = painterResource(id = R.drawable.qrcode_scan), contentDescription = "") | |
--- | |
> Icon(painter = painterResource(id = R.drawable.ic_crop_free_white_24dp), contentDescription = "") | |
259c209 | |
< text = stringResource(id = R.string.estimated_confirmation_time), | |
--- | |
> text = stringResource(id = R.string.estimated_wait_time), | |
689c639 | |
< pcode = pcode!! | |
--- | |
> url = "${WebUtil.PAYNYM_API}${pcode}/avatar" | |
766,769c716 | |
< val feeRange by vm.getFeeRange().observeAsState() | |
< vm.setFeeRange(feeRange!!) | |
< val feeSliderValue by vm.feeSliderValue.observeAsState(feeRange!!) | |
< | |
--- | |
> val feeSliderValue by vm.feeSliderValue.observeAsState(0.5f) | |
845c792 | |
< Text(text = "sat/vB ") | |
--- | |
> Text(text = "sat/b ") | |
874c821 | |
< text = "$satsPerByte sat/vB", | |
--- | |
> text = "$satsPerByte sat/b", | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/collaborate/viewmodels/CahootsTransactionViewModel.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/collaborate/viewmodels/CahootsTransactionViewModel.kt | |
18d17 | |
< import com.samourai.wallet.send.review.ReviewTxModel.findTransactionPriority | |
221,224d219 | |
< fun getFeeRange() : LiveData<Float> { | |
< return feeRange | |
< } | |
< | |
226,228d220 | |
< | |
< FeeUtil.getInstance().normalize() | |
< | |
232,233c224,226 | |
< | |
< | |
--- | |
> if (feeHigh == 1000L && feeLow == 1000L) { | |
> feeHigh = 3000L | |
> } | |
239,269c232,242 | |
< if (FeeUtil.getInstance().feeRepresentation.is1DolFeeEstimator) { | |
< | |
< var transactionPriority = findTransactionPriority(fees.toLong(), feeHigh, feeLow) | |
< var priorityDesc = transactionPriority!!.getDescription( | |
< FeeUtil.getInstance().feeRepresentation, | |
< fees.toLong(), | |
< feeLow, | |
< feeMed, | |
< feeHigh | |
< ) | |
< estBlocks.postValue(priorityDesc) | |
< } else { | |
< //Calculate Block confirm estimation | |
< val pct: Double | |
< var nbBlocks = 6 | |
< if (fees <= feeLow.toDouble()) { | |
< pct = feeLow.toDouble() / fees | |
< nbBlocks = ceil(pct * 24.0).toInt() | |
< } else if (fees >= feeHigh.toDouble()) { | |
< pct = feeHigh.toDouble() / fees | |
< nbBlocks = ceil(pct * 2.0).toInt() | |
< if (nbBlocks < 1) { | |
< nbBlocks = 1 | |
< } | |
< } else { | |
< pct = feeMed.toDouble() / fees | |
< nbBlocks = ceil(pct * 6.0).toInt() | |
< } | |
< var strBlocks = "$nbBlocks blocks" | |
< if (nbBlocks > 50) { | |
< strBlocks = "50+ blocks" | |
--- | |
> //Calculate Block confirm estimation | |
> val pct: Double | |
> var nbBlocks = 6 | |
> if (fees <= feeLow.toDouble()) { | |
> pct = feeLow.toDouble() / fees | |
> nbBlocks = ceil(pct * 24.0).toInt() | |
> } else if (fees >= feeHigh.toDouble()) { | |
> pct = feeHigh.toDouble() / fees | |
> nbBlocks = ceil(pct * 2.0).toInt() | |
> if (nbBlocks < 1) { | |
> nbBlocks = 1 | |
271c244,250 | |
< estBlocks.postValue(strBlocks) | |
--- | |
> } else { | |
> pct = feeMed.toDouble() / fees | |
> nbBlocks = ceil(pct * 6.0).toInt() | |
> } | |
> var strBlocks = "$nbBlocks blocks" | |
> if (nbBlocks > 50) { | |
> strBlocks = "50+ blocks" | |
272a252 | |
> estBlocks.postValue(strBlocks) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/collaborate/viewmodels/CollaborateViewModel.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/collaborate/viewmodels/CollaborateViewModel.kt | |
15d14 | |
< import com.samourai.wallet.collaborate.PaynymChooserType | |
40d38 | |
< private var spendableList = ArrayList<String>() | |
42d39 | |
< private var spendableListLive = MutableLiveData<ArrayList<String>>() | |
50c47 | |
< private var sorobanListenJob: Job? = null | |
--- | |
> private var sorobanListenJob: Job? = null; | |
55,57d51 | |
< val spendable: LiveData<ArrayList<String>> | |
< get() = spendableListLive | |
< | |
80,83c74 | |
< try { | |
< sorobanWalletCounterparty = | |
< androidSorobanWalletService.sorobanWalletCounterparty; | |
< } catch (_: Exception) {} | |
--- | |
> sorobanWalletCounterparty = androidSorobanWalletService.sorobanWalletCounterparty; | |
106d96 | |
< BIP47Meta.getInstance().setName(paynym.code, paynym.nymName) | |
112c102 | |
< BIP47Meta.getInstance().setFollowings(followings) | |
--- | |
> BIP47Meta.getInstance().addFollowings(followings) | |
131,132d120 | |
< spendableList = ArrayList(BIP47Meta.getInstance().getSortedByLabels(false)) | |
< spendableListLive.postValue(ArrayList(spendableList)) | |
151,173c139,148 | |
< fun applySearch(query: String?, paynymChooserType: PaynymChooserType) { | |
< if (paynymChooserType == PaynymChooserType.SPEND) { | |
< if (query == null) { | |
< spendableListLive.postValue(spendableList); | |
< return | |
< } | |
< viewModelScope.launch { | |
< val items = spendableList.filter { | |
< BIP47Meta.getInstance().getDisplayLabel(it).lowercase().indexOf(query.lowercase()) != -1 | |
< }.toList() | |
< spendableListLive.postValue(ArrayList(items)) | |
< } | |
< } else { | |
< if (query == null) { | |
< followingListLive.postValue(followingList); | |
< return | |
< } | |
< viewModelScope.launch { | |
< val items = followingList.filter { | |
< BIP47Meta.getInstance().getDisplayLabel(it).lowercase().indexOf(query.lowercase()) != -1 | |
< }.toList() | |
< followingListLive.postValue(ArrayList(items)) | |
< } | |
--- | |
> fun applySearch(query: String?) { | |
> if (query == null) { | |
> followingListLive.postValue(followingList); | |
> return | |
> } | |
> viewModelScope.launch { | |
> val items = followingList.filter { | |
> BIP47Meta.getInstance().getDisplayLabel(it).lowercase().indexOf(query.lowercase()) != -1 | |
> }.toList() | |
> followingListLive.postValue(ArrayList(items)) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/CreateWalletActivity.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/CreateWalletActivity.java | |
75,76c75 | |
< getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.networking)); | |
< getWindow().setNavigationBarColor(ContextCompat.getColor(this, R.color.networking)); | |
--- | |
> getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.window)); | |
412c411 | |
< PrefsUtil.getInstance(CreateWalletActivity.this).setValue(PrefsUtil.WALLET_SCAN_COMPLETE, false); | |
--- | |
> PrefsUtil.getInstance(CreateWalletActivity.this).setValue(PrefsUtil.FIRST_RUN, true); | |
415c414 | |
< PrefsUtil.getInstance(CreateWalletActivity.this).setValue(PrefsUtil.WALLET_SCAN_COMPLETE, false); | |
--- | |
> PrefsUtil.getInstance(CreateWalletActivity.this).setValue(PrefsUtil.FIRST_RUN, true); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/explorer/ExplorerActivity.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/explorer/ExplorerActivity.kt | |
24d23 | |
< import com.samourai.wallet.util.PrefsUtil | |
26d24 | |
< import com.samourai.wallet.util.network.WebUtil | |
138,140c136 | |
< val blockExplorerURL = PrefsUtil.getInstance(applicationContext).getValue(PrefsUtil.BLOCK_EXPLORER_URL, "") + "/tx/" | |
< | |
< var url = "$blockExplorerURL${txId}" | |
--- | |
> var url = "$blockExplorer${txId}" | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/fragments/PaynymSelectModalFragment.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/fragments/PaynymSelectModalFragment.kt | |
28d27 | |
< import com.squareup.picasso.Callback | |
44a44,45 | |
> private val TAG = "TxAnimUIActivity" | |
> | |
148c149 | |
< throw NetworkErrorException("paynym.rs error"); | |
--- | |
> throw NetworkErrorException("paynym.is error"); | |
152c153 | |
< Toast.makeText(activity, "Network error while loading from paynym.rs", Toast.LENGTH_LONG).show() | |
--- | |
> Toast.makeText(activity, "Network error while loading from paynym.is", Toast.LENGTH_LONG).show() | |
249,251c250,252 | |
< if (code != null) { | |
< setPayNymLogos(code, holder.avatar) | |
< } | |
--- | |
> Picasso.get() | |
> .load("${WebUtil.PAYNYM_API}${code}/avatar") | |
> .into(holder.avatar) | |
260,262d260 | |
< | |
< private val TAG = "PaynymSelectModalFrag" | |
< | |
272,339d269 | |
< } | |
< | |
< fun setPayNymLogos(strPaymentCode: String, avatar: ImageView) { | |
< try { | |
< Picasso.get().load(WebUtil.PAYNYM_API + strPaymentCode + "/avatar") | |
< .into(avatar, createPicassoCallback(strPaymentCode, avatar)) | |
< } catch (t: Throwable) { | |
< /** | |
< * This catch block is useful if ever the onSuccess/onError callback system | |
< * throws a runtime exception. | |
< * It indicates a problem to be fixed, so we log in error. | |
< * This has already been the case through the method LogUtil#error. | |
< */ | |
< Log.e( | |
< TAG, | |
< String.format( | |
< "Throwable with Picasso on /avatar %s : %s", | |
< strPaymentCode, | |
< t.message | |
< ), | |
< t | |
< ) | |
< avatar.setImageResource(R.drawable.paynym) | |
< } | |
< } | |
< | |
< private fun createPicassoCallback( | |
< strPaymentCode: String, | |
< avatar: ImageView | |
< ): Callback { | |
< return object : Callback { | |
< override fun onSuccess() { | |
< } | |
< | |
< override fun onError(e: java.lang.Exception) { | |
< try { | |
< Picasso.get().load(WebUtil.PAYNYM_API + "preview/" + strPaymentCode) | |
< .into(avatar, object : Callback { | |
< override fun onSuccess() {} | |
< | |
< override fun onError(e: java.lang.Exception) { | |
< Log.e( | |
< TAG, | |
< "issue when loading avatar for $strPaymentCode", e | |
< ) | |
< avatar.setImageResource(R.drawable.paynym) | |
< } | |
< }) | |
< } catch (t: Throwable) { | |
< /** | |
< * This catch block is useful if ever the onSuccess/onError callback system | |
< * throws a runtime exception. | |
< * It indicates a problem to be fixed, so we log in error. | |
< * This has already been the case through the method LogUtil#error. | |
< */ | |
< Log.e( | |
< TAG, | |
< String.format( | |
< "Throwable with Picasso on /preview %s : %s", | |
< strPaymentCode, | |
< t.message | |
< ), | |
< t | |
< ) | |
< avatar.setImageResource(R.drawable.paynym) | |
< } | |
< } | |
< } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/home/AccountSelectionActivity.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/home/AccountSelectionActivity.kt | |
53c53,54 | |
< import com.samourai.wallet.theme.samouraiBoxHeaderBackgroundBlack | |
--- | |
> import com.samourai.wallet.theme.samouraiPostmixSpendBlueButton | |
> import com.samourai.wallet.theme.samouraiWindow | |
68,70c69 | |
< window.statusBarColor = resources.getColor(R.color.networking) | |
< window.navigationBarColor = resources.getColor(R.color.networking) | |
< | |
--- | |
> window.statusBarColor = resources.getColor(R.color.samouraiWindow) | |
72,73c71 | |
< window.statusBarColor = getColor(R.color.networking) | |
< window.navigationBarColor = resources.getColor(R.color.networking) | |
--- | |
> window.statusBarColor = getColor(R.color.samouraiWindow) | |
76,80d73 | |
< val isLoadingWallet = AppUtil.getInstance(applicationContext).walletLoading.value | |
< accountSelectionModel.setLoading(isLoadingWallet ?:false) | |
< if ((isLoadingWallet != null) && !isLoadingWallet) { | |
< updateBalanceValues() | |
< } | |
84c77,78 | |
< updateBalanceValues() | |
--- | |
> accountSelectionModel.setDepositBalance(BalanceUtil.getBalance(SamouraiAccountIndex.DEPOSIT, this)); | |
> accountSelectionModel.setPostmixBalance(BalanceUtil.getBalance(SamouraiAccountIndex.POSTMIX, this)); | |
92,106d85 | |
< | |
< private fun updateBalanceValues() { | |
< accountSelectionModel.setDepositBalance( | |
< BalanceUtil.getBalance( | |
< SamouraiAccountIndex.DEPOSIT, | |
< this | |
< ) | |
< ) | |
< accountSelectionModel.setPostmixBalance( | |
< BalanceUtil.getBalance( | |
< SamouraiAccountIndex.POSTMIX, | |
< this | |
< ) | |
< ) | |
< } | |
122,123c101,102 | |
< Triple(SamouraiAccountIndex.DEPOSIT, R.drawable.ic_deposit_account, Color(71, 77, 89)), | |
< Triple(SamouraiAccountIndex.POSTMIX, R.drawable.ic_postmix_account, Color(37, 65, 123))) | |
--- | |
> Triple(SamouraiAccountIndex.DEPOSIT, R.drawable.ic_deposit_account, Color(110, 118, 137)), | |
> Triple(SamouraiAccountIndex.POSTMIX, R.drawable.ic_postmix_account, samouraiPostmixSpendBlueButton)) | |
131c110 | |
< color = samouraiBoxHeaderBackgroundBlack | |
--- | |
> color = samouraiWindow | |
217,219d195 | |
< ) | |
< intent.putExtra("isDonation", | |
< currentIntent.getBooleanExtra("isDonation", false) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/home/BalanceActivity.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/home/BalanceActivity.kt | |
1,1479c1,1356 | |
< package com.samourai.wallet.home | |
< | |
< import android.content.BroadcastReceiver | |
< import android.content.ClipData | |
< import android.content.ClipboardManager | |
< import android.content.Context | |
< import android.content.DialogInterface | |
< import android.content.Intent | |
< import android.content.IntentFilter | |
< import android.content.pm.ActivityInfo | |
< import android.graphics.BitmapFactory | |
< import android.graphics.Typeface | |
< import android.graphics.drawable.BitmapDrawable | |
< import android.net.Uri | |
< import android.os.AsyncTask | |
< import android.os.Bundle | |
< import android.os.Handler | |
< import android.util.Log | |
< import android.util.TypedValue | |
< import android.view.Menu | |
< import android.view.MenuItem | |
< import android.view.View | |
< import android.widget.EditText | |
< import android.widget.ImageView | |
< import android.widget.LinearLayout | |
< import android.widget.TextView | |
< import android.widget.Toast | |
< import androidx.activity.result.contract.ActivityResultContracts | |
< import androidx.activity.viewModels | |
< import androidx.appcompat.app.AlertDialog | |
< import androidx.core.content.ContextCompat | |
< import androidx.core.view.isVisible | |
< import androidx.lifecycle.viewModelScope | |
< import androidx.localbroadcastmanager.content.LocalBroadcastManager | |
< import androidx.recyclerview.widget.LinearLayoutManager | |
< import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener | |
< import androidx.transition.ChangeBounds | |
< import androidx.transition.TransitionManager | |
< import com.dm.zbar.android.scanner.ZBarConstants | |
< import com.google.android.material.dialog.MaterialAlertDialogBuilder | |
< import com.google.android.material.shape.ShapeAppearanceModel | |
< import com.google.common.collect.Lists | |
< import com.google.gson.Gson | |
< import com.samourai.wallet.R | |
< import com.samourai.wallet.ReceiveActivity | |
< import com.samourai.wallet.SamouraiActivity | |
< import com.samourai.wallet.SamouraiWallet | |
< import com.samourai.wallet.access.AccessFactory | |
< import com.samourai.wallet.api.APIFactory | |
< import com.samourai.wallet.api.APIFactory.TxMostRecentDateComparator | |
< import com.samourai.wallet.api.Tx | |
< import com.samourai.wallet.bip47.BIP47Meta | |
< import com.samourai.wallet.bip47.BIP47Util | |
< import com.samourai.wallet.bip47.paynym.WebUtil | |
< import com.samourai.wallet.cahoots.Cahoots | |
< import com.samourai.wallet.cahoots.psbt.PSBTUtil | |
< import com.samourai.wallet.collaborate.CollaborateActivity | |
< import com.samourai.wallet.constants.SamouraiAccountIndex.DEPOSIT | |
< import com.samourai.wallet.constants.SamouraiAccountIndex.POSTMIX | |
< import com.samourai.wallet.crypto.AESUtil | |
< import com.samourai.wallet.crypto.DecryptionException | |
< import com.samourai.wallet.databinding.ActivityBalanceBinding | |
< import com.samourai.wallet.fragments.CameraFragmentBottomSheet | |
< import com.samourai.wallet.fragments.ScanFragment | |
< import com.samourai.wallet.hd.HD_WalletFactory | |
< import com.samourai.wallet.home.adapters.TxAdapter | |
< import com.samourai.wallet.network.NetworkDashboard | |
< import com.samourai.wallet.network.dojo.DojoUtil | |
< import com.samourai.wallet.pairing.PairingMenuActivity | |
< import com.samourai.wallet.payload.ExternalBackupManager.askPermission | |
< import com.samourai.wallet.payload.ExternalBackupManager.hasPermissions | |
< import com.samourai.wallet.payload.ExternalBackupManager.onActivityResult | |
< import com.samourai.wallet.payload.PayloadUtil | |
< import com.samourai.wallet.paynym.PayNymHome | |
< import com.samourai.wallet.paynym.api.PayNymApiService | |
< import com.samourai.wallet.paynym.models.NymResponse | |
< import com.samourai.wallet.ricochet.RicochetMeta | |
< import com.samourai.wallet.segwit.bech32.Bech32Util | |
< import com.samourai.wallet.send.BlockedUTXO | |
< import com.samourai.wallet.send.MyTransactionOutPoint | |
< import com.samourai.wallet.send.SendActivity | |
< import com.samourai.wallet.send.SendActivity.isPSBT | |
< import com.samourai.wallet.send.batch.InputBatchSpendHelper.canParseAsBatchSpend | |
< import com.samourai.wallet.send.cahoots.ManualCahootsActivity | |
< import com.samourai.wallet.settings.SettingsActivity | |
< import com.samourai.wallet.stealth.StealthModeController | |
< import com.samourai.wallet.tools.ToolsBottomSheet | |
< import com.samourai.wallet.tools.viewmodels.Auth47ViewModel | |
< import com.samourai.wallet.tor.EnumTorState | |
< import com.samourai.wallet.tor.SamouraiTorManager | |
< import com.samourai.wallet.tor.TorState | |
< import com.samourai.wallet.tx.TxDetailsActivity | |
< import com.samourai.wallet.util.AppUpdateAvailableBottomSheet | |
< import com.samourai.wallet.util.CharSequenceX | |
< import com.samourai.wallet.util.PrefsUtil | |
< import com.samourai.wallet.util.PrivKeyReader | |
< import com.samourai.wallet.util.TimeOutUtil | |
< import com.samourai.wallet.util.func.FormatsUtil | |
< import com.samourai.wallet.util.func.WalletRefreshUtil | |
< import com.samourai.wallet.util.func.WalletUtil | |
< import com.samourai.wallet.util.func.executeFeaturePayNymUpdate | |
< import com.samourai.wallet.util.network.BlockExplorerUtil | |
< import com.samourai.wallet.util.tech.AppUtil | |
< import com.samourai.wallet.util.tech.LogUtil | |
< import com.samourai.wallet.util.tech.askNotificationPermission | |
< import com.samourai.wallet.utxos.UTXOSActivity | |
< import com.samourai.wallet.whirlpool.WhirlpoolMeta | |
< import com.samourai.wallet.widgets.ItemDividerDecorator | |
< import com.samourai.wallet.widgets.popUpMenu.popupMenu | |
< import com.squareup.picasso.Callback | |
< import com.squareup.picasso.Picasso | |
< import io.reactivex.Observable | |
< import io.reactivex.Single | |
< import io.reactivex.android.schedulers.AndroidSchedulers | |
< import io.reactivex.schedulers.Schedulers | |
< import kotlinx.coroutines.Dispatchers | |
< import kotlinx.coroutines.async | |
< import kotlinx.coroutines.delay | |
< import kotlinx.coroutines.launch | |
< import kotlinx.coroutines.sync.Semaphore | |
< import kotlinx.coroutines.sync.withPermit | |
< import kotlinx.coroutines.withContext | |
< import org.bitcoinj.crypto.MnemonicException.MnemonicLengthException | |
< import org.bitcoinj.script.Script | |
< import org.bouncycastle.util.encoders.Hex | |
< import org.json.JSONException | |
< import org.json.JSONObject | |
< import java.io.IOException | |
< import java.util.Collections | |
< import java.util.Objects.nonNull | |
< | |
< | |
< open class BalanceActivity : SamouraiActivity() { | |
< private var txs: MutableList<Tx>? = null | |
< private var ricochetQueueTask: RicochetQueueTask? = null | |
< private val balanceViewModel: BalanceViewModel by viewModels() | |
< private lateinit var binding: ActivityBalanceBinding | |
< private var menu: Menu? = null | |
< private val menuTorIcon: ImageView? = null | |
< private var executeQuitAppProcessStarted = false | |
< private val uiSemaphore: Semaphore = Semaphore(1) | |
< | |
< private var receiver: BroadcastReceiver = object : BroadcastReceiver() { | |
< override fun onReceive(context: Context, intent: Intent) { | |
< if (ACTION_INTENT == intent.action) { | |
< if (binding.progressBar != null) { | |
< showProgress() | |
< } | |
< val notifTx = intent.getBooleanExtra("notifTx", false) | |
< val fetch = intent.getBooleanExtra("fetch", false) | |
< val rbfHash: String? | |
< val blkHash: String? | |
< rbfHash = if (intent.hasExtra("rbf")) { | |
< intent.getStringExtra("rbf") | |
< } else { | |
< null | |
< } | |
< blkHash = if (intent.hasExtra("hash")) { | |
< intent.getStringExtra("hash") | |
< } else { | |
< null | |
< } | |
< val handler = Handler() | |
< handler.post { | |
< refreshTx(notifTx, false, false) | |
< if (this@BalanceActivity != null) { | |
< if (rbfHash != null) { | |
< MaterialAlertDialogBuilder(this@BalanceActivity) | |
< .setTitle(R.string.app_name) | |
< .setMessage(rbfHash + "\n\n" + getString(R.string.rbf_incoming)) | |
< .setCancelable(true) | |
< .setPositiveButton(R.string.yes, DialogInterface.OnClickListener { dialog, whichButton -> doExplorerView(rbfHash) }) | |
< .setNegativeButton(R.string.no, object : DialogInterface.OnClickListener { | |
< override fun onClick(dialog: DialogInterface, whichButton: Int) { | |
< } | |
< }).show() | |
< } | |
< } | |
< } | |
< } | |
< } | |
< } | |
< private var receiverDisplay: BroadcastReceiver = object : BroadcastReceiver() { | |
< override fun onReceive(context: Context, intent: Intent) { | |
< if (DISPLAY_INTENT == intent.action) { | |
< updateDisplay(true) | |
< checkDust() | |
< } | |
< } | |
< } | |
< | |
< private fun checkDust() { | |
< balanceViewModel.viewModelScope.launch { | |
< withContext(Dispatchers.Default) { | |
< val utxos = APIFactory.getInstance(this@BalanceActivity).getUtxos(false) | |
< val utxoWarnings = arrayListOf<MyTransactionOutPoint>() | |
< for (utxo in utxos) { | |
< val outpoints = utxo.outpoints | |
< for (out in outpoints) { | |
< val scriptBytes = out.scriptBytes | |
< var address: String? = null | |
< try { | |
< address = if (Bech32Util.getInstance().isBech32Script(Hex.toHexString(scriptBytes))) { | |
< Bech32Util.getInstance().getAddressFromScript(Hex.toHexString(scriptBytes)) | |
< } else { | |
< Script(scriptBytes).getToAddress(SamouraiWallet.getInstance().currentNetworkParams).toString() | |
< } | |
< } catch (e: Exception) { | |
< } | |
< val path = APIFactory.getInstance(this@BalanceActivity).unspentPaths[address] | |
< if (path != null && path.startsWith("M/1/")) { | |
< continue | |
< } | |
< val hash = out.hash.toString() | |
< val idx = out.txOutputN | |
< val amount = out.value.longValue() | |
< val contains = BlockedUTXO.getInstance().contains(hash, idx) || BlockedUTXO.getInstance().containsNotDusted(hash, idx) | |
< val containsInPostMix = BlockedUTXO.getInstance().containsPostMix(hash, idx) || BlockedUTXO.getInstance().containsNotDustedPostMix(hash, idx) | |
< if (amount < BlockedUTXO.BLOCKED_UTXO_THRESHOLD && !contains && !containsInPostMix) { | |
< utxoWarnings.add(out); | |
< // BalanceActivity.this.runOnUiThread(new Runnable() { | |
< // @Override | |
< } | |
< } | |
< } | |
< if(! utxoWarnings.isEmpty()) { | |
< withContext(Dispatchers.Main) { | |
< utxoWarnings.forEach { | |
< val hash = it.hash.toString() | |
< val idx = it.txOutputN | |
< val amount = it.value.longValue() | |
< var message: String? = this@BalanceActivity.getString(R.string.dusting_attempt) | |
< message += "\n\n" | |
< message += this@BalanceActivity.getString(R.string.dusting_attempt_amount) | |
< message += " " | |
< message += FormatsUtil.formatBTC(amount) | |
< message += this@BalanceActivity.getString(R.string.dusting_attempt_id) | |
< message += " " | |
< message += "$hash-$idx" | |
< val dlg = MaterialAlertDialogBuilder(this@BalanceActivity) | |
< .setTitle(R.string.dusting_tx) | |
< .setMessage(message) | |
< .setCancelable(false) | |
< .setPositiveButton(R.string.dusting_attempt_mark_unspendable) { dialog, whichButton -> | |
< if (account == WhirlpoolMeta.getInstance(this@BalanceActivity).whirlpoolPostmix) { | |
< BlockedUTXO.getInstance().addPostMix(hash, idx, amount) | |
< } else { | |
< BlockedUTXO.getInstance().add(hash, idx, amount) | |
< } | |
< saveState() | |
< }.setNegativeButton(R.string.dusting_attempt_ignore) { dialog, whichButton -> | |
< if (account == WhirlpoolMeta.getInstance(this@BalanceActivity).whirlpoolPostmix) { | |
< BlockedUTXO.getInstance().addNotDustedPostMix(hash, idx) | |
< } else { | |
< BlockedUTXO.getInstance().addNotDusted(hash, idx) | |
< } | |
< saveState() | |
< } | |
< if (!isFinishing) { | |
< dlg.show() | |
< } | |
< } | |
< } | |
< } | |
< } | |
< } | |
< } | |
< | |
< override fun onCreate(savedInstanceState: Bundle?) { | |
< //Switch themes based on accounts (blue theme for whirlpool account) | |
< setSwitchThemes(true) | |
< super.onCreate(savedInstanceState) | |
< val comeFromPostmix = isFromPostmix() | |
< binding = ActivityBalanceBinding.inflate(layoutInflater) | |
< setContentView(binding.root) | |
< balanceViewModel.setAccount(account) | |
< if (account == DEPOSIT) { | |
< val biP47Util = BIP47Util.getInstance(applicationContext) | |
< biP47Util.payNymLogoLive.observe(this@BalanceActivity) { | |
< binding.toolbarIcon.setImageBitmap(it) | |
< } | |
< } | |
< makePaynymAvatarCache() | |
< requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT | |
< setSupportActionBar(binding.toolbar) | |
< binding.rvTxes.layoutManager = LinearLayoutManager(this) | |
< val drawable = ContextCompat.getDrawable(this, R.drawable.divider_grey) | |
< binding.rvTxes.addItemDecoration(ItemDividerDecorator(drawable)) | |
< txs = ArrayList() | |
< /* | |
< findViewById<View>(R.id.whirlpool_fab).setOnClickListener { view: View? -> | |
< val intent = Intent(this@BalanceActivity, WhirlpoolHome::class.java) | |
< startActivity(intent) | |
< binding.fabMenu.toggle(true) | |
< } | |
< */ | |
< binding.sendFab.setOnClickListener(View.OnClickListener { view: View? -> | |
< | |
< val isPostmixAccount = account == POSTMIX | |
< | |
< val activityType = | |
< if (isPostmixAccount) SendActivity::class.java | |
< else AccountSelectionActivity::class.java | |
< | |
< val intent = Intent(this@BalanceActivity, activityType) | |
< intent.putExtra("via_menu", true) | |
< if (isPostmixAccount) { | |
< intent.putExtra("_account", account) | |
< } | |
< startActivity(intent) | |
< binding.fabMenu.toggle(true) | |
< }) | |
< if (!comeFromPostmix) { | |
< loadBalance() | |
< } | |
< binding.receiveFab.setOnClickListener { view: View? -> | |
< binding.fabMenu.toggle(true) | |
< val hdw = HD_WalletFactory.getInstance(this@BalanceActivity).get() | |
< if (hdw != null) { | |
< val intent = Intent(this@BalanceActivity, ReceiveActivity::class.java) | |
< startActivity(intent) | |
< } | |
< } | |
< binding.paynymFab.setOnClickListener { view: View? -> | |
< binding.fabMenu.toggle(true) | |
< val intent = Intent(this@BalanceActivity, PayNymHome::class.java) | |
< startActivity(intent) | |
< } | |
< binding.txSwipeContainer.setOnRefreshListener(OnRefreshListener { | |
< doClipboardCheck() | |
< refreshTx(false, true, false) | |
< binding.txSwipeContainer.isRefreshing = false | |
< showProgress() | |
< }) | |
< | |
< binding.appBar.addOnOffsetChangedListener { appBarLayout, verticalOffset -> | |
< if (Math.abs(verticalOffset) == appBarLayout.totalScrollRange) { | |
< binding.utxoIcon.visibility = View.GONE | |
< } else if (verticalOffset == 0) { | |
< binding.utxoIcon.visibility = View.VISIBLE | |
< } else { | |
< binding.utxoIcon.visibility = View.GONE | |
< } | |
< } | |
< | |
< val filter = IntentFilter(ACTION_INTENT) | |
< LocalBroadcastManager.getInstance(this@BalanceActivity).registerReceiver(receiver, filter) | |
< val filterDisplay = IntentFilter(DISPLAY_INTENT) | |
< LocalBroadcastManager.getInstance(this@BalanceActivity).registerReceiver(receiverDisplay, filterDisplay) | |
< | |
< balanceViewModel.viewModelScope.launch(Dispatchers.IO) { | |
< if (PrefsUtil.getInstance(applicationContext).getValue(PrefsUtil.AUTO_BACKUP, true)) { | |
< if (!hasPermissions()) askPermission(this@BalanceActivity) | |
< } | |
< } | |
< | |
< if (!comeFromPostmix) { | |
< doFeaturePayNymUpdate() | |
< } | |
< | |
< if (RicochetMeta.getInstance(this@BalanceActivity).queue.size > 0) { | |
< if (ricochetQueueTask == null || ricochetQueueTask!!.status == AsyncTask.Status.FINISHED) { | |
< ricochetQueueTask = RicochetQueueTask() | |
< ricochetQueueTask!!.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR) | |
< } | |
< } | |
< if (!AppUtil.getInstance(this@BalanceActivity).isClipboardSeen) { | |
< doClipboardCheck() | |
< } | |
< setUpTor() | |
< initViewModel() | |
< if (account == DEPOSIT) { | |
< binding.toolbarIcon.setOnClickListener { | |
< showToolOptions(it) | |
< } | |
< if (! comeFromPostmix) { | |
< val delayedHandler = Handler() | |
< delayedHandler.postDelayed({ | |
< var notifTx = intent.getBooleanExtra("notifTx", false) | |
< refreshTx(notifTx, false, true) | |
< updateDisplay(false) | |
< }, 100L) | |
< } | |
< } else { | |
< binding.toolbarIcon.visibility = View.GONE | |
< binding.toolbar.setTitleMargin(0, 0, 0, 0) | |
< binding.toolbar.titleMarginEnd = -50 | |
< binding.toolbar.setNavigationIcon(R.drawable.ic_piggy_bank ) | |
< binding.toolbar.setNavigationOnClickListener { | |
< val intent = Intent(this, BalanceActivity::class.java) | |
< intent.putExtra("_account", DEPOSIT) | |
< intent.putExtra("come_from_postmix", true) | |
< intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) | |
< finish() | |
< startActivity(intent) | |
< } | |
< binding.receiveFab.visibility = View.GONE | |
< //binding.whirlpoolFab.visibility = View.GONE | |
< binding.paynymFab.visibility = View.GONE | |
< Handler().postDelayed({ updateDisplay(true) }, 600L) | |
< } | |
< balanceViewModel.loadOfflineData() | |
< | |
< updateDisplay(false) | |
< checkDeepLinks() | |
< doExternalBackUp() | |
< | |
< balanceViewModel.viewModelScope.launch { | |
< withContext(Dispatchers.Main) { | |
< askNotificationPermission(this@BalanceActivity) | |
< } | |
< } | |
< } | |
< | |
< private fun showAppUpdate(show: Boolean) { | |
< if (appUpdateShowed) return | |
< if (show && nonNull(SamouraiWallet.getInstance().releaseNotes)) { | |
< AppUtil.getInstance(this).setHasUpdateBeenShown(true) | |
< appUpdateShowed = true | |
< val bottomSheetFragment = AppUpdateAvailableBottomSheet(SamouraiWallet.getInstance().releaseNotes.getString("version")) | |
< bottomSheetFragment.show(supportFragmentManager, bottomSheetFragment.tag) | |
< return | |
< } | |
< } | |
< | |
< private fun loadBalance() { | |
< balanceViewModel.viewModelScope.launch(Dispatchers.IO) { | |
< val is_sat_prefs = PrefsUtil.getInstance(this@BalanceActivity) | |
< .getValue(PrefsUtil.IS_SAT, false) | |
< | |
< val payloadWrapper : MutableList<JSONObject> = Lists.newArrayList(); | |
< val job = balanceViewModel.viewModelScope.launch(Dispatchers.IO) { | |
< payloadWrapper.add(PayloadUtil.getInstance(this@BalanceActivity).payload) | |
< } | |
< | |
< balanceViewModel.viewModelScope.launch(Dispatchers.Main) { | |
< job.invokeOnCompletion { it -> | |
< if (it != null) { | |
< AppUtil.getInstance(applicationContext).restartApp() | |
< Log.e(TAG, "issue on payload loading") | |
< it.printStackTrace() | |
< } else { | |
< val payload = if (payloadWrapper.size == 1) payloadWrapper[0] else null | |
< if (account == DEPOSIT && | |
< payload != null && | |
< payload.has("meta") && | |
< payload.getJSONObject("meta").has("prev_balance")) { | |
< | |
< try { | |
< setBalance(payload.getJSONObject("meta").getLong("prev_balance"), is_sat_prefs) | |
< } catch (e: Exception) { | |
< Log.e(TAG, "issue on setBalance()", e) | |
< setBalance(0L, is_sat_prefs) | |
< } | |
< | |
< } else { | |
< if (account == DEPOSIT) { | |
< Log.e(TAG, "issue on payload loading") | |
< } | |
< setBalance(0L, is_sat_prefs) | |
< } | |
< } | |
< } | |
< } | |
< } | |
< } | |
< | |
< private fun showToolOptions(it: View) { | |
< | |
< balanceViewModel.viewModelScope.launch(Dispatchers.IO) { | |
< | |
< val bitmapImage = BIP47Util.getInstance(applicationContext).payNymLogoLive.value | |
< var drawable = ContextCompat.getDrawable(this@BalanceActivity, R.drawable.ic_ashigaru_logo) | |
< var nym = PrefsUtil.getInstance(applicationContext) | |
< .getValue(PrefsUtil.PAYNYM_BOT_NAME, BIP47Meta.getInstance().getDisplayLabel(BIP47Util.getInstance(applicationContext).paymentCode.toString())) | |
< if (bitmapImage != null) { | |
< drawable = BitmapDrawable(resources, bitmapImage) | |
< } | |
< if (nym.isNullOrEmpty()) { | |
< nym = BIP47Meta.getInstance().getDisplayLabel(BIP47Util.getInstance(applicationContext).paymentCode.toString()) | |
< } | |
< | |
< withContext(Dispatchers.Main) { | |
< val toolWindowSize = applicationContext.resources.displayMetrics.density * 220; | |
< val popupMenu = popupMenu { | |
< fixedContentWidthInPx = toolWindowSize.toInt() | |
< style = R.style.Theme_Samourai_Widget_MPM_Menu_Dark | |
< section { | |
< item { | |
< label = nym | |
< iconDrawable = drawable | |
< iconSize = 34 | |
< labelColor = ContextCompat.getColor(applicationContext, R.color.white) | |
< disableTint = true | |
< iconShapeAppearanceModel = ShapeAppearanceModel().toBuilder() | |
< .setAllCornerSizes(resources.getDimension(R.dimen.qr_image_corner_radius)) | |
< .build() | |
< callback = { | |
< val intent = Intent(this@BalanceActivity, PayNymHome::class.java) | |
< startActivity(intent) | |
< } | |
< } | |
< item { | |
< label = "Collaborate" | |
< iconSize = 18 | |
< callback = { | |
< val intent = Intent(this@BalanceActivity, CollaborateActivity::class.java) | |
< startActivity(intent) | |
< } | |
< icon = R.drawable.ic_connect_without_contact | |
< } | |
< item { | |
< label = "Tools" | |
< icon = R.drawable.ic_tools | |
< iconSize = 18 | |
< hasNestedItems | |
< callback = { | |
< ToolsBottomSheet.showTools(supportFragmentManager) | |
< } | |
< } | |
< } | |
< section { | |
< | |
< item { | |
< label = "Pairing" | |
< icon = R.drawable.pairing_icon | |
< iconSize = 18 | |
< hasNestedItems | |
< callback = { | |
< val intent = Intent(this@BalanceActivity, PairingMenuActivity::class.java) | |
< startActivity(intent) | |
< } | |
< } | |
< | |
< item { | |
< label = getString(R.string.action_settings) | |
< icon = R.drawable.ic_cog | |
< iconSize = 18 | |
< callback = { | |
< TimeOutUtil.getInstance().updatePin() | |
< val intent = Intent(this@BalanceActivity, SettingsActivity::class.java) | |
< startActivity(intent) | |
< } | |
< } | |
< item { | |
< label = "Exit Wallet" | |
< iconSize = 18 | |
< iconColor = ContextCompat.getColor(this@BalanceActivity, R.color.mpm_red) | |
< labelColor = ContextCompat.getColor(this@BalanceActivity, R.color.mpm_red) | |
< icon = R.drawable.ic_baseline_power_settings_new_24 | |
< callback = { | |
< this@BalanceActivity.onBackPressed() | |
< } | |
< } | |
< } | |
< } | |
< popupMenu.show(this@BalanceActivity, it) | |
< } | |
< } | |
< } | |
< | |
< private fun hideProgress() { | |
< balanceViewModel.viewModelScope.launch(Dispatchers.IO) { | |
< delay(150L) | |
< withContext(Dispatchers.Main) { | |
< uiSemaphore.withPermit { | |
< val loading = AppUtil.getInstance(applicationContext).walletLoading.value?:false | |
< if (!loading) { | |
< val progressIndicator = binding.progressBar | |
< if (progressIndicator.isVisible) { | |
< progressIndicator.apply { | |
< hide() | |
< } | |
< } | |
< } | |
< } | |
< } | |
< } | |
< } | |
< | |
< private fun showProgress() { | |
< balanceViewModel.viewModelScope.launch(Dispatchers.IO) { | |
< delay(150L) | |
< withContext(Dispatchers.Main) { | |
< uiSemaphore.withPermit { | |
< val loading = AppUtil.getInstance(applicationContext).walletLoading.value?:false | |
< if (loading) { | |
< val progressIndicator = binding.progressBar | |
< if (!progressIndicator.isVisible) { | |
< progressIndicator.apply { | |
< isIndeterminate = true | |
< show() | |
< } | |
< } | |
< } | |
< } | |
< } | |
< } | |
< } | |
< | |
< private fun checkDeepLinks() { | |
< val bundle = intent.extras ?: return | |
< if (bundle.containsKey("pcode") || bundle.containsKey("uri") || bundle.containsKey("amount")) { | |
< if (bundle.containsKey("uri")) { | |
< if (bundle.getString("uri")?.startsWith("auth47") == true) { | |
< ToolsBottomSheet.showTools(supportFragmentManager, ToolsBottomSheet.ToolType.AUTH47, | |
< bundle = Bundle().apply { | |
< putString("KEY", bundle.getString("uri")) | |
< }) | |
< return; | |
< } | |
< } | |
< if (balanceViewModel.balance.value != null) bundle.putLong("balance", balanceViewModel.balance.value!!) | |
< val intent = Intent(this, AccountSelectionActivity::class.java) | |
< intent.putExtra("_account", account) | |
< intent.putExtras(bundle) | |
< startActivity(intent) | |
< } | |
< } | |
< | |
< override fun onNewIntent(intent: Intent) { | |
< super.onNewIntent(intent) | |
< setIntent(intent) | |
< } | |
< | |
< private fun initViewModel() { | |
< val adapter = TxAdapter(applicationContext, ArrayList(), account) | |
< adapter.setClickListener { position: Int, tx: Tx -> txDetails(tx) } | |
< binding.rvTxes.adapter = adapter | |
< val is_sat_prefs = PrefsUtil.getInstance(this@BalanceActivity).getValue(PrefsUtil.IS_SAT, false) | |
< balanceViewModel.balance.observe(this) { balance: Long? -> | |
< if (balance == null) { | |
< return@observe | |
< } | |
< if (balance < 0) { | |
< return@observe | |
< } | |
< if (binding.progressBar.visibility == View.VISIBLE && balance <= 0) { | |
< return@observe | |
< } | |
< setBalance(balance, is_sat_prefs) | |
< } | |
< adapter.setTxes(balanceViewModel.txs.value) | |
< setBalance(balanceViewModel.balance.value, is_sat_prefs) | |
< balanceViewModel.satState.observe(this) { state: Boolean? -> | |
< var isSats = false | |
< if (state != null) { | |
< isSats = state | |
< } | |
< setBalance(balanceViewModel.balance.value, isSats) | |
< adapter.notifyDataSetChanged() | |
< } | |
< balanceViewModel.txs.observe(this) { list -> adapter.setTxes(list) } | |
< binding.toolbarLayout.setOnClickListener { v: View? -> | |
< val is_sat = balanceViewModel.toggleSat() | |
< PrefsUtil.getInstance(this@BalanceActivity).setValue(PrefsUtil.IS_SAT, is_sat) | |
< } | |
< binding.toolbarLayout.setOnLongClickListener { | |
< val intent = Intent(this@BalanceActivity, UTXOSActivity::class.java) | |
< intent.putExtra("_account", account) | |
< startActivityForResult(intent, UTXO_REQUESTCODE) | |
< false | |
< } | |
< | |
< binding.utxoIcon.setOnClickListener { | |
< val intent = Intent(this@BalanceActivity, UTXOSActivity::class.java) | |
< intent.putExtra("_account", account) | |
< startActivityForResult(intent, UTXO_REQUESTCODE) | |
< } | |
< | |
< binding.utxoIcon.setOnLongClickListener { | |
< if (SamouraiWallet.getInstance().isTestNet) { | |
< SamouraiWallet.MOCK_FEE = !SamouraiWallet.MOCK_FEE | |
< refreshTx(false, true, false) | |
< binding.txSwipeContainer.isRefreshing = false | |
< showProgress() | |
< } | |
< false | |
< } | |
< } | |
< | |
< private fun setBalance(balance: Long?, isSat: Boolean) { | |
< if (balance == null) { | |
< return | |
< } | |
< balanceViewModel.viewModelScope.launch(Dispatchers.Main) { | |
< if (supportActionBar != null) { | |
< TransitionManager.beginDelayedTransition(binding.toolbarLayout, ChangeBounds()) | |
< val displayAmount = if (isSat) FormatsUtil.formatSats(balance) else FormatsUtil.formatBTC(balance) | |
< binding.toolbar.title = displayAmount | |
< title = displayAmount | |
< binding.toolbarLayout.title = displayAmount | |
< } | |
< } | |
< } | |
< | |
< public override fun onResume() { | |
< super.onResume() | |
< executeQuitAppProcessStarted = false; | |
< | |
< showProgress() | |
< AppUtil.getInstance(applicationContext).walletLoading.observe(this) { | |
< if (it) { | |
< showProgress() | |
< } else { | |
< hideProgress() | |
< } | |
< } | |
< if (! isFromPostmix() && intent.getBooleanExtra("refresh", false)) { | |
< balanceViewModel.viewModelScope.launch { | |
< withContext(Dispatchers.IO) { | |
< async { | |
< WalletRefreshUtil.refreshWallet( | |
< notifTx = false, | |
< launch = false, | |
< context = applicationContext) | |
< } | |
< } | |
< } | |
< } | |
< | |
< AppUtil.getInstance(applicationContext).hasUpdateBeenShown.observe(this) { | |
< showAppUpdate(!it) | |
< } | |
< | |
< AppUtil.getInstance(this@BalanceActivity).checkTimeOut() | |
< try { | |
< val isSatPrefs = PrefsUtil.getInstance(applicationContext).getValue(PrefsUtil.IS_SAT, false) | |
< if (isSatPrefs != balanceViewModel.satState.value) { | |
< balanceViewModel.toggleSat() | |
< } | |
< } catch (e: Exception) { | |
< LogUtil.error(TAG, e) | |
< } | |
< } | |
< | |
< fun createTag(text: String?): View { | |
< val scale = resources.displayMetrics.density | |
< val lparams = LinearLayout.LayoutParams( | |
< LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT | |
< ) | |
< val textView = TextView(applicationContext) | |
< textView.text = text | |
< textView.setTextColor(ContextCompat.getColor(applicationContext, R.color.white)) | |
< textView.layoutParams = lparams | |
< textView.setBackgroundResource(R.drawable.tag_round_shape) | |
< textView.setPadding((8 * scale + 0.5f).toInt(), (6 * scale + 0.5f).toInt(), (8 * scale + 0.5f).toInt(), (6 * scale + 0.5f).toInt()) | |
< textView.typeface = Typeface.DEFAULT_BOLD | |
< textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 11f) | |
< return textView | |
< } | |
< | |
< private fun makePaynymAvatarCache() { | |
< try { | |
< balanceViewModel.viewModelScope.launch(Dispatchers.IO) { | |
< | |
< if (PrefsUtil.getInstance(applicationContext).getValue(PrefsUtil.PAYNYM_BOT_NAME, "").isNullOrEmpty() | |
< && PrefsUtil.getInstance(applicationContext).getValue(PrefsUtil.PAYNYM_CLAIMED,false)) { | |
< val strPaymentCode = BIP47Util.getInstance(application).paymentCode.toString() | |
< val apiService = PayNymApiService.getInstance(strPaymentCode, getApplication()); | |
< balanceViewModel.viewModelScope.launch(Dispatchers.IO) { | |
< try { | |
< val response = apiService.getNymInfo() | |
< if (response.isSuccessful) { | |
< val responseJson = response.body?.string() | |
< if (responseJson != null) { | |
< val jsonObject = JSONObject(responseJson) | |
< val nym = Gson().fromJson(jsonObject.toString(), NymResponse::class.java); | |
< PrefsUtil.getInstance(applicationContext).setValue(PrefsUtil.PAYNYM_BOT_NAME, nym.nymName) | |
< | |
< } else | |
< throw Exception("Invalid response ") | |
< } | |
< } catch (_: Exception) { | |
< | |
< } | |
< } | |
< } | |
< | |
< if (!BIP47Util.getInstance(applicationContext).avatarImage().exists()) { | |
< loadAvatar() | |
< } else { | |
< balanceViewModel.viewModelScope.launch(Dispatchers.IO) { | |
< val bitmap = BitmapFactory.decodeFile(BIP47Util.getInstance(applicationContext).avatarImage().path) | |
< if (bitmap != null) { | |
< BIP47Util.getInstance(applicationContext).setAvatar(bitmap) | |
< } else { | |
< loadAvatar() | |
< } | |
< } | |
< } | |
< | |
< val paymentCodes = ArrayList(BIP47Meta.getInstance().getSortedByLabels(false, true)) | |
< for (code in paymentCodes) { | |
< Picasso.get() | |
< .load(WebUtil.PAYNYM_API + code + "/avatar").fetch(object : Callback { | |
< override fun onSuccess() { | |
< /*NO OP*/ | |
< } | |
< | |
< override fun onError(e: Exception) { | |
< /*NO OP*/ | |
< } | |
< }) | |
< } | |
< } | |
< | |
< } catch (ignored: Exception) { | |
< } | |
< } | |
< | |
< private fun loadAvatar() { | |
< BIP47Util.getInstance(applicationContext).fetchBotImage() | |
< .subscribe() | |
< .apply { | |
< registerDisposable(this) | |
< } | |
< } | |
< | |
< public override fun onDestroy() { | |
< LocalBroadcastManager.getInstance(this@BalanceActivity).unregisterReceiver(receiver) | |
< LocalBroadcastManager.getInstance(this@BalanceActivity).unregisterReceiver(receiverDisplay) | |
< | |
< if (PrefsUtil.getInstance(this.application).getValue(StealthModeController.PREF_ENABLED, false)) { | |
< StealthModeController.enableStealth(applicationContext) | |
< } | |
< super.onDestroy() | |
< } | |
< | |
< override fun onCreateOptionsMenu(menu: Menu): Boolean { | |
< menuInflater.inflate(R.menu.main, menu) | |
< menu.findItem(R.id.action_mock_fees).isVisible = false | |
< menu.findItem(R.id.action_refresh).isVisible = false | |
< menu.findItem(R.id.action_share_receive).isVisible = false | |
< menu.findItem(R.id.action_ricochet).isVisible = false | |
< menu.findItem(R.id.action_empty_ricochet).isVisible = false | |
< menu.findItem(R.id.action_sign).isVisible = false | |
< menu.findItem(R.id.action_fees).isVisible = false | |
< menu.findItem(R.id.action_batch).isVisible = false | |
< menu.findItem(R.id.action_backup).isVisible = false | |
< menu.findItem(R.id.action_utxo).isVisible = false | |
< WhirlpoolMeta.getInstance(applicationContext) | |
< if (account == POSTMIX) { | |
< menu.findItem(R.id.action_network_dashboard).isVisible = false | |
< menu.findItem(R.id.action_postmix_balance).isVisible = false | |
< val item = menu.findItem(R.id.action_menu_account) | |
< item.actionView = createTag(" POST-MIX ") | |
< item.isVisible = true | |
< item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS) | |
< } | |
< this.menu = menu | |
< return super.onCreateOptionsMenu(menu) | |
< } | |
< | |
< override fun onOptionsItemSelected(item: MenuItem): Boolean { | |
< // Handle action bar item clicks here. The action bar will | |
< // automatically handle clicks on the Home/Up button, so long | |
< // as you specify a parent activity in AndroidManifest.xml. | |
< val id = item.itemId | |
< if (id == android.R.id.home) { | |
< finish() | |
< return super.onOptionsItemSelected(item) | |
< } | |
< if (id == R.id.action_mock_fees) { | |
< SamouraiWallet.MOCK_FEE = !SamouraiWallet.MOCK_FEE | |
< refreshTx(false, true, false) | |
< binding.txSwipeContainer.isRefreshing = false | |
< showProgress() | |
< return super.onOptionsItemSelected(item) | |
< } | |
< if (id == R.id.action_postmix_balance) { | |
< val intent = Intent(this, BalanceActivity::class.java) | |
< intent.putExtra("_account", POSTMIX) | |
< intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) | |
< finish() | |
< startActivity(intent) | |
< return super.onOptionsItemSelected(item) | |
< } | |
< | |
< // noinspection SimplifiableIfStatement | |
< if (id == R.id.action_network_dashboard) { | |
< startActivity(Intent(this, NetworkDashboard::class.java)) | |
< } // noinspection SimplifiableIfStatement | |
< /* | |
< if (id == R.id.action_support) { | |
< ActivityHelper.launchSupportPageInBrowser(this, SamouraiTorManager.isConnected()) | |
< } else */ | |
< if (id == R.id.action_utxo) { | |
< doUTXO() | |
< } else if (id == R.id.action_backup) { | |
< if (SamouraiWallet.getInstance().hasPassphrase(this@BalanceActivity)) { | |
< if (HD_WalletFactory.getInstance(this@BalanceActivity).get() != null && SamouraiWallet.getInstance().hasPassphrase(this@BalanceActivity)) { | |
< doBackup(HD_WalletFactory.getInstance(this@BalanceActivity).get().passphrase) | |
< } | |
< } else { | |
< val builder = MaterialAlertDialogBuilder(this) | |
< builder.setTitle(R.string.enter_backup_password) | |
< val view = layoutInflater.inflate(R.layout.password_input_dialog_layout, null) | |
< val password = view.findViewById<EditText>(R.id.restore_dialog_password_edittext) | |
< val message = view.findViewById<TextView>(R.id.dialogMessage) | |
< message.setText(R.string.backup_password) | |
< builder.setPositiveButton(R.string.confirm) { dialog: DialogInterface, which: Int -> | |
< val pw = password.text.toString() | |
< if (pw.length >= AppUtil.MIN_BACKUP_PW_LENGTH && pw.length <= AppUtil.MAX_BACKUP_PW_LENGTH) { | |
< doBackup(pw) | |
< } else { | |
< Toast.makeText(applicationContext, R.string.password_error, Toast.LENGTH_SHORT).show() | |
< } | |
< dialog.dismiss() | |
< } | |
< builder.setNegativeButton(R.string.cancel) { dialog: DialogInterface, which: Int -> dialog.dismiss() } | |
< builder.setView(view) | |
< builder.show() | |
< } | |
< } else if (id == R.id.action_scan_qr) { | |
< doScan() | |
< } else { | |
< } | |
< return super.onOptionsItemSelected(item) | |
< } | |
< | |
< private fun setUpTor() { | |
< SamouraiTorManager.getTorStateLiveData().observe(this) { torState: TorState -> | |
< | |
< if (torState.state == EnumTorState.ON) { | |
< balanceViewModel.viewModelScope.launch(Dispatchers.IO) { | |
< PrefsUtil.getInstance(this@BalanceActivity).setValue(PrefsUtil.ENABLE_TOR, true) | |
< balanceViewModel.viewModelScope.launch(Dispatchers.Main) { | |
< binding.progressBar.visibility = View.INVISIBLE | |
< menuTorIcon?.setImageResource(R.drawable.tor_on) | |
< } | |
< } | |
< | |
< } else if (torState.state == EnumTorState.STARTING) { | |
< binding.progressBar.visibility = View.VISIBLE | |
< menuTorIcon?.setImageResource(R.drawable.tor_on) | |
< | |
< } else { | |
< balanceViewModel.viewModelScope.launch(Dispatchers.IO) { | |
< if (torState.state == EnumTorState.OFF && !executeQuitAppProcessStarted) { | |
< PrefsUtil.getInstance(this@BalanceActivity).setValue(PrefsUtil.ENABLE_TOR, false) | |
< } | |
< balanceViewModel.viewModelScope.launch(Dispatchers.Main) { | |
< binding.progressBar.visibility = View.INVISIBLE | |
< menuTorIcon?.setImageResource(R.drawable.tor_off) | |
< } | |
< } | |
< } | |
< } | |
< } | |
< | |
< public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | |
< super.onActivityResult(requestCode, resultCode, data) | |
< onActivityResult(requestCode, resultCode, data, application) | |
< if (resultCode == RESULT_OK && requestCode == SCAN_COLD_STORAGE) { | |
< if (data?.getStringExtra(ZBarConstants.SCAN_RESULT) != null) { | |
< val strResult = data.getStringExtra(ZBarConstants.SCAN_RESULT) | |
< doPrivKey(strResult) | |
< } | |
< } else if (resultCode == RESULT_CANCELED && requestCode == SCAN_COLD_STORAGE) { | |
< } else if (resultCode == RESULT_OK && requestCode == SCAN_QR) { | |
< | |
< if (data?.getStringExtra(ZBarConstants.SCAN_RESULT) != null) { | |
< val strResult = data.getStringExtra(ZBarConstants.SCAN_RESULT) | |
< val params = SamouraiWallet.getInstance().currentNetworkParams | |
< val privKeyReader = PrivKeyReader(strResult, params) | |
< try { | |
< if (privKeyReader.format != null) { | |
< doPrivKey(strResult!!.trim { it <= ' ' }) | |
< } else if (strResult?.lowercase()?.startsWith(Auth47ViewModel.AUTH_SCHEME.lowercase()) == true) { | |
< ToolsBottomSheet.showTools(supportFragmentManager, ToolsBottomSheet.ToolType.AUTH47, | |
< bundle = Bundle().apply { | |
< putString("KEY", strResult) | |
< }) | |
< } else if (Cahoots.isCahoots(strResult!!.trim { it <= ' ' })) { | |
< val cahootIntent = ManualCahootsActivity.createIntentResume(this, account, strResult.trim { it <= ' ' }) | |
< startActivity(cahootIntent) | |
< } else if (isPSBT(strResult.trim { it <= ' ' })) { | |
< PSBTUtil.getInstance(this@BalanceActivity).doPSBT(strResult.trim { it <= ' ' }) | |
< } else if (DojoUtil.getInstance(this@BalanceActivity).isValidPairingPayload(strResult.trim { it <= ' ' })) { | |
< val intent = Intent(this@BalanceActivity, NetworkDashboard::class.java) | |
< intent.putExtra("params", strResult.trim { it <= ' ' }) | |
< startActivity(intent) | |
< } else { | |
< val intent = Intent(this@BalanceActivity, AccountSelectionActivity::class.java) | |
< intent.putExtra("uri", strResult.trim { it <= ' ' }) | |
< intent.putExtra("_account", account) | |
< startActivity(intent) | |
< } | |
< } catch (e: Exception) { | |
< } | |
< } | |
< } | |
< if (resultCode == RESULT_OK && requestCode == UTXO_REQUESTCODE) { | |
< refreshTx(false, false, false) | |
< showProgress() | |
< } else { | |
< } | |
< } | |
< | |
< override fun onBackPressed() { | |
< if (account == DEPOSIT || account == POSTMIX) { | |
< val builder = MaterialAlertDialogBuilder(this) | |
< builder.setMessage(R.string.ask_you_sure_exit) | |
< val alert = builder.create() | |
< alert.setButton(AlertDialog.BUTTON_POSITIVE, getString(R.string.yes)) { dialog: DialogInterface?, id: Int -> | |
< executeQuitAppProcesses() | |
< } | |
< alert.setButton(AlertDialog.BUTTON_NEGATIVE, getString(R.string.no)) { dialog: DialogInterface, id: Int -> dialog.dismiss() } | |
< alert.show() | |
< } else { | |
< super.onBackPressed() | |
< } | |
< } | |
< | |
< private fun doExternalBackUp() { | |
< balanceViewModel.viewModelScope.launch(Dispatchers.IO) { | |
< try { | |
< if (hasPermissions() && PrefsUtil.getInstance(application).getValue(PrefsUtil.AUTO_BACKUP, false)) { | |
< val disposable = Observable.fromCallable { | |
< PayloadUtil.getInstance(this@BalanceActivity).saveWalletToJSON(CharSequenceX(AccessFactory.getInstance(this@BalanceActivity).guid + AccessFactory.getInstance(this@BalanceActivity).pin)) | |
< true | |
< }.subscribeOn(Schedulers.io()) | |
< .observeOn(AndroidSchedulers.mainThread()).subscribe({ t: Boolean? -> }) { throwable: Throwable? -> LogUtil.error(TAG, throwable) } | |
< registerDisposable(disposable) | |
< } | |
< } catch (exception: Exception) { | |
< LogUtil.error(TAG, exception) | |
< } | |
< } | |
< } | |
< | |
< private fun executeQuitAppProcesses() { | |
< | |
< executeQuitAppProcessStarted = true; | |
< appUpdateShowed = false; | |
< | |
< try { | |
< if (hasPermissions() && | |
< PrefsUtil.getInstance(application).getValue(PrefsUtil.AUTO_BACKUP, false)) { | |
< | |
< val disposable = Observable.fromCallable { | |
< PayloadUtil.getInstance(this@BalanceActivity) | |
< .saveWalletToJSON(CharSequenceX( | |
< AccessFactory.getInstance(this@BalanceActivity).guid + | |
< AccessFactory.getInstance(this@BalanceActivity).pin)) | |
< true | |
< }.subscribeOn(Schedulers.io()) | |
< .observeOn(AndroidSchedulers.mainThread()) | |
< .subscribe({ t: Boolean? -> | |
< stopingServices() | |
< }) { throwable: Throwable? -> | |
< LogUtil.error(TAG, throwable) | |
< stopingServices() | |
< } | |
< registerDisposable(disposable) | |
< } else { | |
< stopingServices() | |
< } | |
< } catch (exception: Exception) { | |
< LogUtil.error(TAG, exception) | |
< stopingServices() | |
< } | |
< } | |
< | |
< private fun stopingServices() { | |
< WalletUtil.stop(this); | |
< super.onBackPressed() | |
< } | |
< | |
< private fun updateDisplay(fromRefreshService: Boolean) { | |
< val txDisposable = getTxes(account) | |
< .subscribeOn(Schedulers.io()) | |
< .observeOn(AndroidSchedulers.mainThread()) | |
< .subscribe { txes: List<Tx>?, throwable: Throwable? -> | |
< throwable?.printStackTrace() | |
< if (txes != null) { | |
< if (txes.isNotEmpty()) { | |
< balanceViewModel.setTx(txes) | |
< } else { | |
< if (balanceViewModel.txs.value != null && balanceViewModel.txs.value!!.size == 0) { | |
< balanceViewModel.setTx(txes) | |
< } | |
< } | |
< Collections.sort(txes, TxMostRecentDateComparator()) | |
< txs!!.clear() | |
< txs!!.addAll(txes) | |
< } | |
< if (binding.progressBar.visibility == View.VISIBLE && | |
< fromRefreshService && | |
< !(AppUtil.getInstance(applicationContext).walletLoading.value?:false)) { | |
< | |
< hideProgress() | |
< } | |
< } | |
< val balanceDisposable = getBalance(account) | |
< .subscribeOn(Schedulers.io()) | |
< .observeOn(AndroidSchedulers.mainThread()) | |
< .subscribe { balance: Long?, throwable: Throwable? -> | |
< throwable?.printStackTrace() | |
< balanceViewModel.postNewBalance(balance) | |
< } | |
< registerDisposable(balanceDisposable) | |
< registerDisposable(txDisposable) | |
< // displayBalance(); | |
< // txAdapter.notifyDataSetChanged(); | |
< } | |
< | |
< private fun getTxes(account: Int): Single<List<Tx>> { | |
< return Single.fromCallable { | |
< var loadedTxes: List<Tx> = ArrayList() | |
< if (account == 0) { | |
< loadedTxes = APIFactory.getInstance(this@BalanceActivity).allXpubTxs | |
< } else if (account == WhirlpoolMeta.getInstance(applicationContext).whirlpoolPostmix) { | |
< loadedTxes = APIFactory.getInstance(this@BalanceActivity).allPostMixTxs | |
< } | |
< loadedTxes | |
< } | |
< } | |
< | |
< private fun getBalance(account: Int): Single<Long> { | |
< return Single.fromCallable { | |
< var loadedBalance = 0L | |
< if (account == 0) { | |
< loadedBalance = APIFactory.getInstance(this@BalanceActivity).xpubBalance | |
< } else if (account == WhirlpoolMeta.getInstance(applicationContext).whirlpoolPostmix) { | |
< loadedBalance = APIFactory.getInstance(this@BalanceActivity).xpubPostMixBalance | |
< } | |
< loadedBalance | |
< } | |
< } | |
< | |
< private fun doSettings() { | |
< TimeOutUtil.getInstance().updatePin() | |
< val intent = Intent(this@BalanceActivity, SettingsActivity::class.java) | |
< startActivity(intent) | |
< } | |
< | |
< var utxoListResult = registerForActivityResult( | |
< ActivityResultContracts.StartActivityForResult() | |
< ) { | |
< run { | |
< showProgress() | |
< refreshTx(false, false, false) | |
< } | |
< } | |
< | |
< private fun doUTXO() { | |
< val intent = Intent(this@BalanceActivity, UTXOSActivity::class.java) | |
< intent.putExtra("_account", account) | |
< utxoListResult.launch(intent) | |
< } | |
< | |
< private fun doScan() { | |
< val cameraFragmentBottomSheet = ScanFragment() | |
< cameraFragmentBottomSheet.show(supportFragmentManager, cameraFragmentBottomSheet.tag) | |
< cameraFragmentBottomSheet.setOnScanListener { code -> | |
< cameraFragmentBottomSheet.dismissAllowingStateLoss() | |
< val params = SamouraiWallet.getInstance().currentNetworkParams | |
< val privKeyReader = PrivKeyReader(code, params) | |
< try { | |
< when { | |
< canParseAsBatchSpend(code) -> { | |
< launchBatchSpend(code) | |
< } | |
< privKeyReader.format != null -> { | |
< doPrivKey(code.trim { it <= ' ' }) | |
< } | |
< code.lowercase().startsWith(Auth47ViewModel.AUTH_SCHEME) -> { | |
< ToolsBottomSheet.showTools(supportFragmentManager, ToolsBottomSheet.ToolType.AUTH47, | |
< bundle = Bundle().apply { | |
< putString("KEY", code) | |
< }) | |
< } | |
< Cahoots.isCahoots(code.trim { it <= ' ' }) -> { | |
< val cahootIntent = ManualCahootsActivity.createIntentResume(this, account, code.trim { it <= ' ' }) | |
< startActivity(cahootIntent) | |
< } | |
< isPSBT(code.trim { it <= ' ' }) -> { | |
< ToolsBottomSheet.showTools(supportFragmentManager, ToolsBottomSheet.ToolType.PSBT, | |
< bundle = Bundle().apply { | |
< putString("KEY", code) | |
< }) | |
< } | |
< DojoUtil.getInstance(this@BalanceActivity).isValidPairingPayload(code.trim { it <= ' ' }) -> { | |
< val intent = Intent(this@BalanceActivity, NetworkDashboard::class.java) | |
< intent.putExtra("params", code.trim { it <= ' ' }) | |
< startActivity(intent) | |
< } | |
< else -> { | |
< | |
< val isPostmixAccount = account == POSTMIX | |
< | |
< val activityType = | |
< if (isPostmixAccount) SendActivity::class.java | |
< else AccountSelectionActivity::class.java | |
< | |
< val intent = Intent(this@BalanceActivity, activityType) | |
< intent.putExtra("uri", code.trim { it <= ' ' }) | |
< if (isPostmixAccount) { | |
< intent.putExtra("_account", account) | |
< } | |
< startActivity(intent) | |
< } | |
< } | |
< } catch (e: Exception) { | |
< } | |
< } | |
< } | |
< | |
< private fun launchBatchSpend(inputBatchSpendAsJson: String) { | |
< val intent = Intent(this@BalanceActivity, AccountSelectionActivity::class.java) | |
< intent.putExtra("inputBatchSpend", inputBatchSpendAsJson) | |
< startActivity(intent) | |
< } | |
< | |
< private fun doSweepViaScan() { | |
< val cameraFragmentBottomSheet = CameraFragmentBottomSheet() | |
< cameraFragmentBottomSheet.show(supportFragmentManager, cameraFragmentBottomSheet.tag) | |
< cameraFragmentBottomSheet.setQrCodeScanListener { code: String -> | |
< cameraFragmentBottomSheet.dismissAllowingStateLoss() | |
< val params = SamouraiWallet.getInstance().currentNetworkParams | |
< val privKeyReader = PrivKeyReader(code, params) | |
< try { | |
< when { | |
< privKeyReader.format != null -> { | |
< doPrivKey(code.trim { it <= ' ' }) | |
< } | |
< Cahoots.isCahoots(code.trim { it <= ' ' }) -> { | |
< val cahootIntent = ManualCahootsActivity.createIntentResume(this, account, code.trim { it <= ' ' }) | |
< startActivity(cahootIntent) | |
< } | |
< isPSBT(code.trim { it <= ' ' }) -> { | |
< PSBTUtil.getInstance(this@BalanceActivity).doPSBT(code.trim { it <= ' ' }) | |
< } | |
< DojoUtil.getInstance(this@BalanceActivity).isValidPairingPayload(code.trim { it <= ' ' }) -> { | |
< Toast.makeText(this@BalanceActivity, "Samourai Dojo full node coming soon.", Toast.LENGTH_SHORT).show() | |
< } | |
< else -> { | |
< val intent = Intent(this@BalanceActivity, AccountSelectionActivity::class.java) | |
< intent.putExtra("uri", code.trim { it <= ' ' }) | |
< intent.putExtra("_account", account) | |
< startActivity(intent) | |
< } | |
< } | |
< } catch (e: Exception) { | |
< } | |
< } | |
< } | |
< | |
< private fun doPrivKey(data: String?) { | |
< | |
< val params = SamouraiWallet.getInstance().currentNetworkParams | |
< var privKeyReader: PrivKeyReader? = null | |
< var format: String? = null | |
< try { | |
< privKeyReader = PrivKeyReader(data, params) | |
< format = privKeyReader.format | |
< } catch (e: Exception) { | |
< Toast.makeText(this@BalanceActivity, e.message, Toast.LENGTH_SHORT).show() | |
< return | |
< } | |
< if (format != null) { | |
< ToolsBottomSheet.showTools(supportFragmentManager, ToolsBottomSheet.ToolType.SWEEP, | |
< bundle = Bundle().apply { | |
< putString("KEY", data) | |
< }) | |
< } else { | |
< Toast.makeText(this@BalanceActivity, R.string.cannot_recognize_privkey, Toast.LENGTH_SHORT).show() | |
< } | |
< } | |
< | |
< private fun doBackup(passphrase: String) { | |
< val export_methods = arrayOfNulls<String>(2) | |
< export_methods[0] = getString(R.string.export_to_clipboard) | |
< export_methods[1] = getString(R.string.export_to_email) | |
< MaterialAlertDialogBuilder(this@BalanceActivity) | |
< .setTitle(R.string.options_export) | |
< .setSingleChoiceItems(export_methods, 0, DialogInterface.OnClickListener { dialog, which -> | |
< try { | |
< PayloadUtil.getInstance(this@BalanceActivity).saveWalletToJSON(CharSequenceX(AccessFactory.getInstance(this@BalanceActivity).guid + AccessFactory.getInstance(this@BalanceActivity).pin)) | |
< } catch (ioe: IOException) { | |
< } catch (je: JSONException) { | |
< } catch (de: DecryptionException) { | |
< } catch (mle: MnemonicLengthException) { | |
< } | |
< var encrypted: String? = null | |
< try { | |
< encrypted = AESUtil.encryptSHA256(PayloadUtil.getInstance(this@BalanceActivity).payload.toString(), CharSequenceX(passphrase)) | |
< } catch (e: Exception) { | |
< Toast.makeText(this@BalanceActivity, e.message, Toast.LENGTH_SHORT).show() | |
< } finally { | |
< if (encrypted == null) { | |
< Toast.makeText(this@BalanceActivity, R.string.encryption_error, Toast.LENGTH_SHORT).show() | |
< return@OnClickListener | |
< } | |
< } | |
< val obj = PayloadUtil.getInstance(this@BalanceActivity).putPayload(encrypted, true) | |
< if (which == 0) { | |
< val clipboard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager | |
< var clip: ClipData? = null | |
< clip = ClipData.newPlainText("Wallet backup", obj.toString()) | |
< clipboard.setPrimaryClip(clip) | |
< Toast.makeText(this@BalanceActivity, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show() | |
< } else { | |
< val email = Intent(Intent.ACTION_SEND) | |
< email.putExtra(Intent.EXTRA_SUBJECT, "Ashigaru backup") | |
< email.putExtra(Intent.EXTRA_TEXT, obj.toString()) | |
< email.type = "message/rfc822" | |
< startActivity(Intent.createChooser(email, getText(R.string.choose_email_client))) | |
< } | |
< dialog.dismiss() | |
< } | |
< ).show() | |
< } | |
< | |
< private fun doClipboardCheck() { | |
< val clipboard = this@BalanceActivity.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager | |
< if (clipboard.hasPrimaryClip()) { | |
< val clip = clipboard.primaryClip | |
< val item = clip!!.getItemAt(0) | |
< if (item.text != null) { | |
< val text = item.text.toString() | |
< val s = text.split("\\s+").toTypedArray() | |
< try { | |
< for (i in s.indices) { | |
< val params = SamouraiWallet.getInstance().currentNetworkParams | |
< val privKeyReader = PrivKeyReader(s[i], params) | |
< if (privKeyReader.format != null && | |
< (privKeyReader.format == PrivKeyReader.WIF_COMPRESSED || privKeyReader.format == PrivKeyReader.WIF_UNCOMPRESSED || privKeyReader.format == PrivKeyReader.BIP38 || | |
< FormatsUtil.getInstance().isValidXprv(s[i])) | |
< ) { | |
< MaterialAlertDialogBuilder(this@BalanceActivity) | |
< .setTitle(R.string.app_name) | |
< .setMessage(R.string.privkey_clipboard) | |
< .setCancelable(false) | |
< .setPositiveButton(R.string.yes) { _, _ -> clipboard.setPrimaryClip(ClipData.newPlainText("", "")) }.setNegativeButton(R.string.no) { _, _ -> }.show() | |
< } | |
< } | |
< } catch (e: Exception) { | |
< } | |
< } | |
< } | |
< } | |
< | |
< private fun refreshTx(notifTx: Boolean, dragged: Boolean, launch: Boolean) { | |
< if (AppUtil.getInstance(this@BalanceActivity).isOfflineMode) { | |
< Toast.makeText(this@BalanceActivity, R.string.in_offline_mode, Toast.LENGTH_SHORT).show() | |
< /* | |
< CoordinatorLayout coordinatorLayout = new CoordinatorLayout(BalanceActivity.this); | |
< Snackbar snackbar = Snackbar.make(coordinatorLayout, R.string.in_offline_mode, Snackbar.LENGTH_LONG); | |
< snackbar.show(); | |
< */ | |
< } | |
< | |
< balanceViewModel.viewModelScope.launch { | |
< withContext(Dispatchers.IO) { | |
< async { | |
< WalletRefreshUtil.refreshWallet( | |
< notifTx = notifTx, | |
< launch = launch, | |
< context = applicationContext) | |
< } | |
< } | |
< } | |
< // | |
< // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | |
< // startForegroundService(intent); | |
< // } else { | |
< // startService(intent); | |
< // } | |
< } | |
< | |
< private fun doExplorerView(strHash: String?) { | |
< if (strHash != null) { | |
< val blockExplorer = BlockExplorerUtil.getInstance().getUri(true) | |
< val blockExplorerURL = PrefsUtil.getInstance(applicationContext).getValue(PrefsUtil.BLOCK_EXPLORER_URL, "") + "/tx/" | |
< val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(blockExplorerURL + strHash)) | |
< startActivity(browserIntent) | |
< } | |
< } | |
< | |
< private fun txDetails(tx: Tx) { | |
< if (account == WhirlpoolMeta.getInstance(applicationContext).whirlpoolPostmix && tx.amount == 0.0) { | |
< return | |
< } | |
< val txIntent = Intent(this, TxDetailsActivity::class.java) | |
< txIntent.putExtra("TX", tx.toJSON().toString()) | |
< txIntent.putExtra("_account", account) | |
< startActivity(txIntent) | |
< } | |
< | |
< private inner class RicochetQueueTask : AsyncTask<String?, Void?, String>() { | |
< | |
< override fun onPostExecute(result: String) { | |
< } | |
< | |
< override fun onPreExecute() { | |
< } | |
< | |
< override fun doInBackground(vararg params: String?): String { | |
< if (RicochetMeta.getInstance(this@BalanceActivity).queue.size > 0) { | |
< var count = 0 | |
< val itr = RicochetMeta.getInstance(this@BalanceActivity).iterator | |
< while (itr.hasNext()) { | |
< if (count == 3) { | |
< break | |
< } | |
< try { | |
< val jObj = itr.next() | |
< val jHops = jObj.getJSONArray("hops") | |
< if (jHops.length() > 0) { | |
< val jHop = jHops.getJSONObject(jHops.length() - 1) | |
< val txHash = jHop.getString("hash") | |
< val txObj = APIFactory.getInstance(this@BalanceActivity).getTxInfo(txHash) | |
< if (txObj != null && txObj.has("block_height") && txObj.getInt("block_height") != -1) { | |
< itr.remove() | |
< count++ | |
< } | |
< } | |
< } catch (je: JSONException) { | |
< } | |
< } | |
< } | |
< if (RicochetMeta.getInstance(this@BalanceActivity).staggered.size > 0) { | |
< var count = 0 | |
< val staggered = RicochetMeta.getInstance(this@BalanceActivity).staggered | |
< val _staggered: MutableList<JSONObject> = ArrayList() | |
< for (jObj in staggered) { | |
< if (count == 3) { | |
< break | |
< } | |
< try { | |
< val jHops = jObj.getJSONArray("script") | |
< if (jHops.length() > 0) { | |
< val jHop = jHops.getJSONObject(jHops.length() - 1) | |
< val txHash = jHop.getString("tx") | |
< val txObj = APIFactory.getInstance(this@BalanceActivity).getTxInfo(txHash) | |
< if (txObj != null && txObj.has("block_height") && txObj.getInt("block_height") != -1) { | |
< count++ | |
< } else { | |
< _staggered.add(jObj) | |
< } | |
< } | |
< } catch (je: JSONException) { | |
< } catch (cme: ConcurrentModificationException) { | |
< } | |
< } | |
< } | |
< return "OK" | |
< } | |
< } | |
< | |
< private fun doFeaturePayNymUpdate() { | |
< balanceViewModel.viewModelScope.launch(Dispatchers.IO) { | |
< if (PrefsUtil.getInstance(this@BalanceActivity).getValue(PrefsUtil.PAYNYM_CLAIMED, false) && | |
< !PrefsUtil.getInstance(this@BalanceActivity).getValue(PrefsUtil.PAYNYM_FEATURED_SEGWIT, false)) { | |
< try { | |
< executeFeaturePayNymUpdate(this@BalanceActivity) | |
< Log.i(TAG, "executeFeaturePayNymUpdate: Feature update complete") | |
< } catch (e : Exception) { | |
< Log.i(TAG, "executeFeaturePayNymUpdate: Feature update Fail") | |
< } | |
< } | |
< } | |
< } | |
< | |
< private fun isFromPostmix() = intent.getBooleanExtra("come_from_postmix", false) | |
< | |
< companion object { | |
< private const val SCAN_COLD_STORAGE = 2011 | |
< private const val SCAN_QR = 2012 | |
< private const val UTXO_REQUESTCODE = 2012 | |
< private const val TAG = "BalanceActivity" | |
< const val ACTION_INTENT = "com.samourai.wallet.BalanceFragment.REFRESH" | |
< const val DISPLAY_INTENT = "com.samourai.wallet.BalanceFragment.DISPLAY" | |
< | |
< public var appUpdateShowed : Boolean = false | |
< } | |
--- | |
> package com.samourai.wallet.home | |
> | |
> import android.content.BroadcastReceiver | |
> import android.content.ClipData | |
> import android.content.ClipboardManager | |
> import android.content.Context | |
> import android.content.DialogInterface | |
> import android.content.Intent | |
> import android.content.IntentFilter | |
> import android.content.pm.ActivityInfo | |
> import android.graphics.BitmapFactory | |
> import android.graphics.Typeface | |
> import android.graphics.drawable.BitmapDrawable | |
> import android.net.Uri | |
> import android.os.AsyncTask | |
> import android.os.Bundle | |
> import android.os.Handler | |
> import android.util.Log | |
> import android.util.TypedValue | |
> import android.view.Menu | |
> import android.view.MenuItem | |
> import android.view.View | |
> import android.widget.EditText | |
> import android.widget.ImageView | |
> import android.widget.LinearLayout | |
> import android.widget.TextView | |
> import android.widget.Toast | |
> import androidx.activity.result.contract.ActivityResultContracts | |
> import androidx.activity.viewModels | |
> import androidx.appcompat.app.AlertDialog | |
> import androidx.core.content.ContextCompat | |
> import androidx.lifecycle.viewModelScope | |
> import androidx.localbroadcastmanager.content.LocalBroadcastManager | |
> import androidx.recyclerview.widget.LinearLayoutManager | |
> import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener | |
> import androidx.transition.ChangeBounds | |
> import androidx.transition.TransitionManager | |
> import com.dm.zbar.android.scanner.ZBarConstants | |
> import com.google.android.material.dialog.MaterialAlertDialogBuilder | |
> import com.google.android.material.shape.ShapeAppearanceModel | |
> import com.google.gson.Gson | |
> import com.samourai.wallet.BuildConfig | |
> import com.samourai.wallet.R | |
> import com.samourai.wallet.ReceiveActivity | |
> import com.samourai.wallet.SamouraiActivity | |
> import com.samourai.wallet.SamouraiWallet | |
> import com.samourai.wallet.access.AccessFactory | |
> import com.samourai.wallet.api.APIFactory | |
> import com.samourai.wallet.api.APIFactory.TxMostRecentDateComparator | |
> import com.samourai.wallet.api.Tx | |
> import com.samourai.wallet.bip47.BIP47Meta | |
> import com.samourai.wallet.bip47.BIP47Util | |
> import com.samourai.wallet.bip47.paynym.WebUtil | |
> import com.samourai.wallet.cahoots.Cahoots | |
> import com.samourai.wallet.cahoots.psbt.PSBTUtil | |
> import com.samourai.wallet.collaborate.CollaborateActivity | |
> import com.samourai.wallet.constants.SamouraiAccountIndex.POSTMIX | |
> import com.samourai.wallet.crypto.AESUtil | |
> import com.samourai.wallet.crypto.DecryptionException | |
> import com.samourai.wallet.databinding.ActivityBalanceBinding | |
> import com.samourai.wallet.fragments.CameraFragmentBottomSheet | |
> import com.samourai.wallet.fragments.ScanFragment | |
> import com.samourai.wallet.hd.HD_WalletFactory | |
> import com.samourai.wallet.home.adapters.TxAdapter | |
> import com.samourai.wallet.network.NetworkDashboard | |
> import com.samourai.wallet.network.dojo.DojoUtil | |
> import com.samourai.wallet.pairing.PairingMenuActivity | |
> import com.samourai.wallet.payload.ExternalBackupManager.askPermission | |
> import com.samourai.wallet.payload.ExternalBackupManager.hasPermissions | |
> import com.samourai.wallet.payload.ExternalBackupManager.onActivityResult | |
> import com.samourai.wallet.payload.PayloadUtil | |
> import com.samourai.wallet.paynym.PayNymHome | |
> import com.samourai.wallet.paynym.api.PayNymApiService | |
> import com.samourai.wallet.paynym.fragments.PayNymOnBoardBottomSheet | |
> import com.samourai.wallet.paynym.models.NymResponse | |
> import com.samourai.wallet.ricochet.RicochetMeta | |
> import com.samourai.wallet.segwit.bech32.Bech32Util | |
> import com.samourai.wallet.send.BlockedUTXO | |
> import com.samourai.wallet.send.MyTransactionOutPoint | |
> import com.samourai.wallet.send.SendActivity | |
> import com.samourai.wallet.send.SendActivity.isPSBT | |
> import com.samourai.wallet.send.batch.BatchSpendActivity | |
> import com.samourai.wallet.send.batch.InputBatchSpendHelper.canParseAsBatchSpend | |
> import com.samourai.wallet.send.batch.InputBatchSpendHelper.canParseAsBatchSpend | |
> import com.samourai.wallet.send.cahoots.ManualCahootsActivity | |
> import com.samourai.wallet.service.WalletRefreshWorker | |
> import com.samourai.wallet.settings.SettingsActivity | |
> import com.samourai.wallet.stealth.StealthModeController | |
> import com.samourai.wallet.tools.ToolsBottomSheet | |
> import com.samourai.wallet.tools.viewmodels.Auth47ViewModel | |
> import com.samourai.wallet.tor.EnumTorState | |
> import com.samourai.wallet.tor.SamouraiTorManager | |
> import com.samourai.wallet.tor.TorState | |
> import com.samourai.wallet.tx.TxDetailsActivity | |
> import com.samourai.wallet.util.CharSequenceX | |
> import com.samourai.wallet.util.PrefsUtil | |
> import com.samourai.wallet.util.PrivKeyReader | |
> import com.samourai.wallet.util.TimeOutUtil | |
> import com.samourai.wallet.util.activity.ActivityHelper | |
> import com.samourai.wallet.util.func.FormatsUtil | |
> import com.samourai.wallet.util.func.MessageSignUtil | |
> import com.samourai.wallet.util.network.BlockExplorerUtil | |
> import com.samourai.wallet.util.tech.AppUtil | |
> import com.samourai.wallet.util.tech.LogUtil | |
> import com.samourai.wallet.util.tech.askNotificationPermission | |
> import com.samourai.wallet.utxos.UTXOSActivity | |
> import com.samourai.wallet.whirlpool.WhirlpoolHome | |
> import com.samourai.wallet.whirlpool.WhirlpoolMeta | |
> import com.samourai.wallet.whirlpool.service.WhirlpoolNotificationService | |
> import com.samourai.wallet.widgets.ItemDividerDecorator | |
> import com.samourai.wallet.widgets.popUpMenu.popupMenu | |
> import com.squareup.picasso.Callback | |
> import com.squareup.picasso.Picasso | |
> import io.reactivex.Observable | |
> import io.reactivex.Single | |
> import io.reactivex.android.schedulers.AndroidSchedulers | |
> import io.reactivex.schedulers.Schedulers | |
> import kotlinx.coroutines.Dispatchers | |
> import kotlinx.coroutines.delay | |
> import kotlinx.coroutines.launch | |
> import kotlinx.coroutines.withContext | |
> import org.bitcoinj.crypto.MnemonicException.MnemonicLengthException | |
> import org.bitcoinj.script.Script | |
> import org.bouncycastle.util.encoders.Hex | |
> import org.json.JSONException | |
> import org.json.JSONObject | |
> import java.io.IOException | |
> import java.util.Collections | |
> | |
> | |
> open class BalanceActivity : SamouraiActivity() { | |
> private var txs: MutableList<Tx>? = null | |
> private var ricochetQueueTask: RicochetQueueTask? = null | |
> private val balanceViewModel: BalanceViewModel by viewModels() | |
> private lateinit var binding: ActivityBalanceBinding | |
> private var menu: Menu? = null | |
> private val menuTorIcon: ImageView? = null | |
> private var executeQuitAppProcessStarted = false; | |
> | |
> private var receiver: BroadcastReceiver = object : BroadcastReceiver() { | |
> override fun onReceive(context: Context, intent: Intent) { | |
> if (ACTION_INTENT == intent.action) { | |
> if (binding.progressBar != null) { | |
> showProgress() | |
> } | |
> val notifTx = intent.getBooleanExtra("notifTx", false) | |
> val fetch = intent.getBooleanExtra("fetch", false) | |
> val rbfHash: String? | |
> val blkHash: String? | |
> rbfHash = if (intent.hasExtra("rbf")) { | |
> intent.getStringExtra("rbf") | |
> } else { | |
> null | |
> } | |
> blkHash = if (intent.hasExtra("hash")) { | |
> intent.getStringExtra("hash") | |
> } else { | |
> null | |
> } | |
> val handler = Handler() | |
> handler.post { | |
> refreshTx(notifTx, false, false) | |
> if (this@BalanceActivity != null) { | |
> if (rbfHash != null) { | |
> MaterialAlertDialogBuilder(this@BalanceActivity) | |
> .setTitle(R.string.app_name) | |
> .setMessage(rbfHash + "\n\n" + getString(R.string.rbf_incoming)) | |
> .setCancelable(true) | |
> .setPositiveButton(R.string.yes, DialogInterface.OnClickListener { dialog, whichButton -> doExplorerView(rbfHash) }) | |
> .setNegativeButton(R.string.no, object : DialogInterface.OnClickListener { | |
> override fun onClick(dialog: DialogInterface, whichButton: Int) { | |
> } | |
> }).show() | |
> } | |
> } | |
> } | |
> } | |
> } | |
> } | |
> private var receiverDisplay: BroadcastReceiver = object : BroadcastReceiver() { | |
> override fun onReceive(context: Context, intent: Intent) { | |
> if (DISPLAY_INTENT == intent.action) { | |
> updateDisplay(true) | |
> checkDust() | |
> } | |
> } | |
> } | |
> | |
> private fun checkDust() { | |
> balanceViewModel.viewModelScope.launch { | |
> withContext(Dispatchers.Default) { | |
> val utxos = APIFactory.getInstance(this@BalanceActivity).getUtxos(false) | |
> val utxoWarnings = arrayListOf<MyTransactionOutPoint>() | |
> for (utxo in utxos) { | |
> val outpoints = utxo.outpoints | |
> for (out in outpoints) { | |
> val scriptBytes = out.scriptBytes | |
> var address: String? = null | |
> try { | |
> address = if (Bech32Util.getInstance().isBech32Script(Hex.toHexString(scriptBytes))) { | |
> Bech32Util.getInstance().getAddressFromScript(Hex.toHexString(scriptBytes)) | |
> } else { | |
> Script(scriptBytes).getToAddress(SamouraiWallet.getInstance().currentNetworkParams).toString() | |
> } | |
> } catch (e: Exception) { | |
> } | |
> val path = APIFactory.getInstance(this@BalanceActivity).unspentPaths[address] | |
> if (path != null && path.startsWith("M/1/")) { | |
> continue | |
> } | |
> val hash = out.hash.toString() | |
> val idx = out.txOutputN | |
> val amount = out.value.longValue() | |
> val contains = BlockedUTXO.getInstance().contains(hash, idx) || BlockedUTXO.getInstance().containsNotDusted(hash, idx) | |
> val containsInPostMix = BlockedUTXO.getInstance().containsPostMix(hash, idx) || BlockedUTXO.getInstance().containsNotDustedPostMix(hash, idx) | |
> if (amount < BlockedUTXO.BLOCKED_UTXO_THRESHOLD && !contains && !containsInPostMix) { | |
> utxoWarnings.add(out); | |
> // BalanceActivity.this.runOnUiThread(new Runnable() { | |
> // @Override | |
> } | |
> } | |
> } | |
> if(! utxoWarnings.isEmpty()) { | |
> withContext(Dispatchers.Main) { | |
> utxoWarnings.forEach { | |
> val hash = it.hash.toString() | |
> val idx = it.txOutputN | |
> val amount = it.value.longValue() | |
> var message: String? = this@BalanceActivity.getString(R.string.dusting_attempt) | |
> message += "\n\n" | |
> message += this@BalanceActivity.getString(R.string.dusting_attempt_amount) | |
> message += " " | |
> message += FormatsUtil.formatBTC(amount) | |
> message += this@BalanceActivity.getString(R.string.dusting_attempt_id) | |
> message += " " | |
> message += "$hash-$idx" | |
> val dlg = MaterialAlertDialogBuilder(this@BalanceActivity) | |
> .setTitle(R.string.dusting_tx) | |
> .setMessage(message) | |
> .setCancelable(false) | |
> .setPositiveButton(R.string.dusting_attempt_mark_unspendable) { dialog, whichButton -> | |
> if (account == WhirlpoolMeta.getInstance(this@BalanceActivity).whirlpoolPostmix) { | |
> BlockedUTXO.getInstance().addPostMix(hash, idx, amount) | |
> } else { | |
> BlockedUTXO.getInstance().add(hash, idx, amount) | |
> } | |
> saveState() | |
> }.setNegativeButton(R.string.dusting_attempt_ignore) { dialog, whichButton -> | |
> if (account == WhirlpoolMeta.getInstance(this@BalanceActivity).whirlpoolPostmix) { | |
> BlockedUTXO.getInstance().addNotDustedPostMix(hash, idx) | |
> } else { | |
> BlockedUTXO.getInstance().addNotDusted(hash, idx) | |
> } | |
> saveState() | |
> } | |
> if (!isFinishing) { | |
> dlg.show() | |
> } | |
> } | |
> } | |
> } | |
> } | |
> } | |
> } | |
> | |
> override fun onCreate(savedInstanceState: Bundle?) { | |
> //Switch themes based on accounts (blue theme for whirlpool account) | |
> setSwitchThemes(true) | |
> super.onCreate(savedInstanceState) | |
> binding = ActivityBalanceBinding.inflate(layoutInflater) | |
> setContentView(binding.root) | |
> balanceViewModel.setAccount(account) | |
> makePaynymAvatarCache() | |
> requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT | |
> setSupportActionBar(binding.toolbar) | |
> binding.rvTxes.layoutManager = LinearLayoutManager(this) | |
> val drawable = ContextCompat.getDrawable(this, R.drawable.divider_grey) | |
> binding.rvTxes.addItemDecoration(ItemDividerDecorator(drawable)) | |
> txs = ArrayList() | |
> val is_sat_prefs = PrefsUtil.getInstance(this@BalanceActivity).getValue(PrefsUtil.IS_SAT, false) | |
> findViewById<View>(R.id.whirlpool_fab).setOnClickListener { view: View? -> | |
> val intent = Intent(this@BalanceActivity, WhirlpoolHome::class.java) | |
> startActivity(intent) | |
> binding.fabMenu.toggle(true) | |
> } | |
> binding.sendFab.setOnClickListener(View.OnClickListener { view: View? -> | |
> | |
> val isPostmixAccount = account == POSTMIX | |
> | |
> val activityType = | |
> if (isPostmixAccount) SendActivity::class.java | |
> else AccountSelectionActivity::class.java | |
> | |
> val intent = Intent(this@BalanceActivity, activityType) | |
> intent.putExtra("via_menu", true) | |
> if (isPostmixAccount) { | |
> intent.putExtra("_account", account) | |
> } | |
> startActivity(intent) | |
> binding.fabMenu.toggle(true) | |
> }) | |
> var payload: JSONObject? = null | |
> payload = try { | |
> PayloadUtil.getInstance(this@BalanceActivity).payload | |
> } catch (e: Exception) { | |
> AppUtil.getInstance(applicationContext).restartApp() | |
> e.printStackTrace() | |
> return | |
> } | |
> if (account == 0 && payload != null && payload.has("prev_balance")) { | |
> try { | |
> setBalance(payload.getLong("prev_balance"), is_sat_prefs) | |
> } catch (e: Exception) { | |
> setBalance(0L, is_sat_prefs) | |
> } | |
> } else { | |
> setBalance(0L, is_sat_prefs) | |
> } | |
> binding.receiveFab.setOnClickListener { view: View? -> | |
> binding.fabMenu.toggle(true) | |
> val hdw = HD_WalletFactory.getInstance(this@BalanceActivity).get() | |
> if (hdw != null) { | |
> val intent = Intent(this@BalanceActivity, ReceiveActivity::class.java) | |
> startActivity(intent) | |
> } | |
> } | |
> binding.paynymFab.setOnClickListener { view: View? -> | |
> binding.fabMenu.toggle(true) | |
> val intent = Intent(this@BalanceActivity, PayNymHome::class.java) | |
> startActivity(intent) | |
> } | |
> binding.txSwipeContainer.setOnRefreshListener(OnRefreshListener { | |
> doClipboardCheck() | |
> refreshTx(false, true, false) | |
> binding.txSwipeContainer.isRefreshing = false | |
> showProgress() | |
> }) | |
> val filter = IntentFilter(ACTION_INTENT) | |
> LocalBroadcastManager.getInstance(this@BalanceActivity).registerReceiver(receiver, filter) | |
> val filterDisplay = IntentFilter(DISPLAY_INTENT) | |
> LocalBroadcastManager.getInstance(this@BalanceActivity).registerReceiver(receiverDisplay, filterDisplay) | |
> if (PrefsUtil.getInstance(applicationContext).getValue(PrefsUtil.AUTO_BACKUP, true)) { | |
> if (!hasPermissions()) askPermission(this) | |
> } | |
> if (PrefsUtil.getInstance(this@BalanceActivity).getValue(PrefsUtil.PAYNYM_CLAIMED, false) && !PrefsUtil.getInstance(this@BalanceActivity).getValue(PrefsUtil.PAYNYM_FEATURED_SEGWIT, false)) { | |
> doFeaturePayNymUpdate() | |
> } else if (!PrefsUtil.getInstance(this@BalanceActivity).getValue(PrefsUtil.PAYNYM_CLAIMED, false) && | |
> !PrefsUtil.getInstance(this@BalanceActivity).getValue(PrefsUtil.PAYNYM_REFUSED, false) | |
> ) { | |
> val payNymOnBoardBottomSheet = PayNymOnBoardBottomSheet() | |
> payNymOnBoardBottomSheet.show(supportFragmentManager, payNymOnBoardBottomSheet.tag) | |
> } | |
> if (RicochetMeta.getInstance(this@BalanceActivity).queue.size > 0) { | |
> if (ricochetQueueTask == null || ricochetQueueTask!!.status == AsyncTask.Status.FINISHED) { | |
> ricochetQueueTask = RicochetQueueTask() | |
> ricochetQueueTask!!.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR) | |
> } | |
> } | |
> if (!AppUtil.getInstance(this@BalanceActivity).isClipboardSeen) { | |
> doClipboardCheck() | |
> } | |
> setUpTor() | |
> initViewModel() | |
> showProgress() | |
> if (account == 0) { | |
> BIP47Util.getInstance(applicationContext) | |
> .payNymLogoLive.observe(this) { | |
> binding.toolbarIcon.setImageBitmap(it) | |
> } | |
> binding.toolbarIcon.setOnClickListener { | |
> showToolOptions(it) | |
> } | |
> val delayedHandler = Handler() | |
> delayedHandler.postDelayed({ | |
> var notifTx = false | |
> val extras = intent.extras | |
> if (extras != null && extras.containsKey("notifTx")) { | |
> notifTx = extras.getBoolean("notifTx") | |
> } | |
> refreshTx(notifTx, false, true) | |
> updateDisplay(false) | |
> }, 100L) | |
> } else { | |
> binding.toolbarIcon.visibility = View.GONE | |
> binding.toolbar.setTitleMargin(0, 0, 0, 0) | |
> binding.toolbar.titleMarginEnd = -50 | |
> binding.toolbar.setNavigationIcon(R.drawable.ic_baseline_arrow_back_24) | |
> binding.toolbar.setNavigationOnClickListener { | |
> super.onBackPressed() | |
> } | |
> binding.receiveFab.visibility = View.GONE | |
> binding.whirlpoolFab.visibility = View.GONE | |
> binding.paynymFab.visibility = View.GONE | |
> Handler().postDelayed({ updateDisplay(true) }, 600L) | |
> } | |
> balanceViewModel.loadOfflineData() | |
> | |
> updateDisplay(false) | |
> checkDeepLinks() | |
> doExternalBackUp() | |
> AppUtil.getInstance(applicationContext).walletLoading.observe(this) { | |
> if (it) { | |
> showProgress() | |
> } else { | |
> hideProgress() | |
> } | |
> } | |
> if (intent.getBooleanExtra("refresh", false)) { | |
> balanceViewModel.viewModelScope.launch { | |
> withContext(Dispatchers.Default) { | |
> delay(800) | |
> WalletRefreshWorker.enqueue(applicationContext, notifTx = false, launched = false) | |
> } | |
> } | |
> } | |
> | |
> balanceViewModel.viewModelScope.launch { | |
> withContext(Dispatchers.Main) { | |
> askNotificationPermission(this@BalanceActivity) | |
> } | |
> } | |
> } | |
> | |
> private fun showToolOptions(it: View) { | |
> val bitmapImage = BIP47Util.getInstance(applicationContext).payNymLogoLive.value | |
> var drawable = ContextCompat.getDrawable(this, R.drawable.ic_samourai_logo) | |
> var nym = PrefsUtil.getInstance(applicationContext) | |
> .getValue(PrefsUtil.PAYNYM_BOT_NAME, BIP47Meta.getInstance().getDisplayLabel(BIP47Util.getInstance(applicationContext).paymentCode.toString())) | |
> if (bitmapImage != null) { | |
> drawable = BitmapDrawable(resources, bitmapImage) | |
> } | |
> if (nym.isNullOrEmpty()) { | |
> nym = BIP47Meta.getInstance().getDisplayLabel(BIP47Util.getInstance(applicationContext).paymentCode.toString()) | |
> } | |
> val toolWindowSize = applicationContext.resources.displayMetrics.density * 220; | |
> val popupMenu = popupMenu { | |
> fixedContentWidthInPx = toolWindowSize.toInt() | |
> style = R.style.Theme_Samourai_Widget_MPM_Menu_Dark | |
> section { | |
> item { | |
> label = nym | |
> iconDrawable = drawable | |
> iconSize = 34 | |
> labelColor = ContextCompat.getColor(applicationContext, R.color.white) | |
> disableTint = true | |
> iconShapeAppearanceModel = ShapeAppearanceModel().toBuilder() | |
> .setAllCornerSizes(resources.getDimension(R.dimen.qr_image_corner_radius)) | |
> .build() | |
> callback = { | |
> val intent = Intent(this@BalanceActivity, PayNymHome::class.java) | |
> startActivity(intent) | |
> } | |
> } | |
> item { | |
> label = "Collaborate" | |
> iconSize = 18 | |
> callback = { | |
> val intent = Intent(this@BalanceActivity, CollaborateActivity::class.java) | |
> startActivity(intent) | |
> } | |
> icon = R.drawable.ic_connect_without_contact | |
> } | |
> item { | |
> label = "Tools" | |
> icon = R.drawable.ic_tools | |
> iconSize = 18 | |
> hasNestedItems | |
> callback = { | |
> ToolsBottomSheet.showTools(supportFragmentManager) | |
> } | |
> } | |
> } | |
> section { | |
> item { | |
> label = "Pairing" | |
> icon = R.drawable.pairing_icon | |
> iconSize = 18 | |
> hasNestedItems | |
> callback = { | |
> val intent = Intent(this@BalanceActivity, PairingMenuActivity::class.java) | |
> startActivity(intent) | |
> } | |
> } | |
> item { | |
> label = getString(R.string.action_settings) | |
> icon = R.drawable.ic_cog | |
> iconSize = 18 | |
> callback = { | |
> TimeOutUtil.getInstance().updatePin() | |
> val intent = Intent(this@BalanceActivity, SettingsActivity::class.java) | |
> startActivity(intent) | |
> } | |
> } | |
> item { | |
> label = "Exit Wallet" | |
> iconSize = 18 | |
> iconColor = ContextCompat.getColor(this@BalanceActivity, R.color.mpm_red) | |
> labelColor = ContextCompat.getColor(this@BalanceActivity, R.color.mpm_red) | |
> icon = R.drawable.ic_baseline_power_settings_new_24 | |
> callback = { | |
> this@BalanceActivity.onBackPressed() | |
> } | |
> } | |
> } | |
> } | |
> popupMenu.show(this@BalanceActivity, it) | |
> } | |
> | |
> private fun hideProgress() { | |
> binding.progressBar.hide() | |
> } | |
> | |
> private fun showProgress() { | |
> binding.progressBar.isIndeterminate = true | |
> binding.progressBar.show() | |
> } | |
> | |
> private fun checkDeepLinks() { | |
> val bundle = intent.extras ?: return | |
> if (bundle.containsKey("pcode") || bundle.containsKey("uri") || bundle.containsKey("amount")) { | |
> if (bundle.containsKey("uri")) { | |
> if (bundle.getString("uri")?.startsWith("auth47") == true) { | |
> ToolsBottomSheet.showTools(supportFragmentManager, ToolsBottomSheet.ToolType.AUTH47, | |
> bundle = Bundle().apply { | |
> putString("KEY", bundle.getString("uri")) | |
> }) | |
> return; | |
> } | |
> } | |
> if (balanceViewModel.balance.value != null) bundle.putLong("balance", balanceViewModel.balance.value!!) | |
> val intent = Intent(this, AccountSelectionActivity::class.java) | |
> intent.putExtra("_account", account) | |
> intent.putExtras(bundle) | |
> startActivity(intent) | |
> } | |
> } | |
> | |
> override fun onNewIntent(intent: Intent) { | |
> super.onNewIntent(intent) | |
> setIntent(intent) | |
> } | |
> | |
> private fun initViewModel() { | |
> val adapter = TxAdapter(applicationContext, ArrayList(), account) | |
> adapter.setClickListener { position: Int, tx: Tx -> txDetails(tx) } | |
> binding.rvTxes.adapter = adapter | |
> val is_sat_prefs = PrefsUtil.getInstance(this@BalanceActivity).getValue(PrefsUtil.IS_SAT, false) | |
> balanceViewModel.balance.observe(this) { balance: Long? -> | |
> if (balance == null) { | |
> return@observe | |
> } | |
> if (balance < 0) { | |
> return@observe | |
> } | |
> if (binding.progressBar.visibility == View.VISIBLE && balance <= 0) { | |
> return@observe | |
> } | |
> setBalance(balance, is_sat_prefs) | |
> } | |
> adapter.setTxes(balanceViewModel.txs.value) | |
> setBalance(balanceViewModel.balance.value, is_sat_prefs) | |
> balanceViewModel.satState.observe(this) { state: Boolean? -> | |
> var isSats = false | |
> if (state != null) { | |
> isSats = state | |
> } | |
> setBalance(balanceViewModel.balance.value, isSats) | |
> adapter.notifyDataSetChanged() | |
> } | |
> balanceViewModel.txs.observe(this) { list -> adapter.setTxes(list) } | |
> binding.toolbarLayout.setOnClickListener { v: View? -> | |
> val is_sat = balanceViewModel!!.toggleSat() | |
> PrefsUtil.getInstance(this@BalanceActivity).setValue(PrefsUtil.IS_SAT, is_sat) | |
> } | |
> binding.toolbarLayout.setOnLongClickListener { | |
> val intent = Intent(this@BalanceActivity, UTXOSActivity::class.java) | |
> intent.putExtra("_account", account) | |
> startActivityForResult(intent, UTXO_REQUESTCODE) | |
> false | |
> } | |
> } | |
> | |
> private fun setBalance(balance: Long?, isSat: Boolean) { | |
> if (balance == null) { | |
> return | |
> } | |
> if (supportActionBar != null) { | |
> TransitionManager.beginDelayedTransition(binding.toolbarLayout, ChangeBounds()) | |
> val displayAmount = if (isSat) FormatsUtil.formatSats(balance) else FormatsUtil.formatBTC(balance) | |
> binding.toolbar.title = displayAmount | |
> title = displayAmount | |
> binding.toolbarLayout.title = displayAmount | |
> } | |
> } | |
> | |
> public override fun onResume() { | |
> super.onResume() | |
> executeQuitAppProcessStarted = false; | |
> | |
> // IntentFilter filter = new IntentFilter(ACTION_INTENT); | |
> // LocalBroadcastManager.getInstance(BalanceActivity.this).registerReceiver(receiver, filter); | |
> AppUtil.getInstance(this@BalanceActivity).checkTimeOut() | |
> try { | |
> val isSatPrefs = PrefsUtil.getInstance(applicationContext).getValue(PrefsUtil.IS_SAT, false) | |
> if (isSatPrefs != balanceViewModel.satState.value) { | |
> balanceViewModel.toggleSat() | |
> } | |
> } catch (e: Exception) { | |
> LogUtil.error(TAG, e) | |
> } | |
> // | |
> // Intent intent = new Intent("com.samourai.wallet.MainActivity2.RESTART_SERVICE"); | |
> // LocalBroadcastManager.getInstance(BalanceActivity.this).sendBroadcast(intent); | |
> } | |
> | |
> fun createTag(text: String?): View { | |
> val scale = resources.displayMetrics.density | |
> val lparams = LinearLayout.LayoutParams( | |
> LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT | |
> ) | |
> val textView = TextView(applicationContext) | |
> textView.text = text | |
> textView.setTextColor(ContextCompat.getColor(applicationContext, R.color.white)) | |
> textView.layoutParams = lparams | |
> textView.setBackgroundResource(R.drawable.tag_round_shape) | |
> textView.setPadding((8 * scale + 0.5f).toInt(), (6 * scale + 0.5f).toInt(), (8 * scale + 0.5f).toInt(), (6 * scale + 0.5f).toInt()) | |
> textView.typeface = Typeface.DEFAULT_BOLD | |
> textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 11f) | |
> return textView | |
> } | |
> | |
> private fun makePaynymAvatarCache() { | |
> try { | |
> val paymentCodes = ArrayList(BIP47Meta.getInstance().getSortedByLabels(false, true)) | |
> if (PrefsUtil.getInstance(applicationContext).getValue(PrefsUtil.PAYNYM_BOT_NAME, "").isNullOrEmpty() | |
> && PrefsUtil.getInstance(applicationContext).getValue(PrefsUtil.PAYNYM_CLAIMED,false)) { | |
> val strPaymentCode = BIP47Util.getInstance(application).paymentCode.toString() | |
> val apiService = PayNymApiService.getInstance(strPaymentCode, getApplication()); | |
> balanceViewModel.viewModelScope.launch { | |
> withContext(Dispatchers.IO) { | |
> try { | |
> val response = apiService.getNymInfo() | |
> if (response.isSuccessful) { | |
> val responseJson = response.body?.string() | |
> if (responseJson != null) { | |
> val jsonObject = JSONObject(responseJson) | |
> val nym = Gson().fromJson(jsonObject.toString(), NymResponse::class.java); | |
> PrefsUtil.getInstance(applicationContext).setValue(PrefsUtil.PAYNYM_BOT_NAME, nym.nymName) | |
> | |
> } else | |
> throw Exception("Invalid response ") | |
> } | |
> } catch (_: Exception) { | |
> | |
> } | |
> } | |
> } | |
> } | |
> if (!BIP47Util.getInstance(applicationContext).avatarImage().exists()) { | |
> BIP47Util.getInstance(applicationContext).fetchBotImage() | |
> .subscribe() | |
> .apply { | |
> registerDisposable(this) | |
> balanceViewModel.viewModelScope.launch { | |
> withContext(Dispatchers.Default) { | |
> val bitmap = BitmapFactory.decodeFile(BIP47Util.getInstance(applicationContext).avatarImage().path) | |
> BIP47Util.getInstance(applicationContext) | |
> .setAvatar(bitmap) | |
> } | |
> } | |
> } | |
> } | |
> balanceViewModel.viewModelScope.launch { | |
> withContext(Dispatchers.Default) { | |
> if (BIP47Util.getInstance(applicationContext).avatarImage().exists()) { | |
> val bitmap = BitmapFactory.decodeFile(BIP47Util.getInstance(applicationContext).avatarImage().path) | |
> BIP47Util.getInstance(applicationContext) | |
> .setAvatar(bitmap) | |
> } | |
> } | |
> } | |
> for (code in paymentCodes) { | |
> Picasso.get() | |
> .load(WebUtil.PAYNYM_API + code + "/avatar").fetch(object : Callback { | |
> override fun onSuccess() { | |
> /*NO OP*/ | |
> } | |
> | |
> override fun onError(e: Exception) { | |
> /*NO OP*/ | |
> } | |
> }) | |
> } | |
> } catch (ignored: Exception) { | |
> } | |
> } | |
> | |
> public override fun onDestroy() { | |
> LocalBroadcastManager.getInstance(this@BalanceActivity).unregisterReceiver(receiver) | |
> LocalBroadcastManager.getInstance(this@BalanceActivity).unregisterReceiver(receiverDisplay) | |
> | |
> if (PrefsUtil.getInstance(this.application).getValue(StealthModeController.PREF_ENABLED, false)) { | |
> StealthModeController.enableStealth(applicationContext) | |
> } | |
> super.onDestroy() | |
> } | |
> | |
> override fun onCreateOptionsMenu(menu: Menu): Boolean { | |
> menuInflater.inflate(R.menu.main, menu) | |
> if (BuildConfig.FLAVOR == "staging") menu.findItem(R.id.action_mock_fees).isVisible = true | |
> menu.findItem(R.id.action_refresh).isVisible = false | |
> menu.findItem(R.id.action_share_receive).isVisible = false | |
> menu.findItem(R.id.action_ricochet).isVisible = false | |
> menu.findItem(R.id.action_empty_ricochet).isVisible = false | |
> menu.findItem(R.id.action_sign).isVisible = false | |
> menu.findItem(R.id.action_fees).isVisible = false | |
> menu.findItem(R.id.action_batch).isVisible = false | |
> WhirlpoolMeta.getInstance(applicationContext) | |
> if (account == WhirlpoolMeta.getInstance(applicationContext).whirlpoolPostmix) { | |
> menu.findItem(R.id.action_backup).isVisible = false | |
> menu.findItem(R.id.action_network_dashboard).isVisible = false | |
> menu.findItem(R.id.action_postmix_balance).isVisible = false | |
> val item = menu.findItem(R.id.action_menu_account) | |
> item.actionView = createTag(" POST-MIX ") | |
> item.isVisible = true | |
> item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS) | |
> } | |
> this.menu = menu | |
> return super.onCreateOptionsMenu(menu) | |
> } | |
> | |
> override fun onOptionsItemSelected(item: MenuItem): Boolean { | |
> // Handle action bar item clicks here. The action bar will | |
> // automatically handle clicks on the Home/Up button, so long | |
> // as you specify a parent activity in AndroidManifest.xml. | |
> val id = item.itemId | |
> if (id == android.R.id.home) { | |
> finish() | |
> return super.onOptionsItemSelected(item) | |
> } | |
> if (id == R.id.action_mock_fees) { | |
> SamouraiWallet.MOCK_FEE = !SamouraiWallet.MOCK_FEE | |
> refreshTx(false, true, false) | |
> binding.txSwipeContainer.isRefreshing = false | |
> showProgress() | |
> return super.onOptionsItemSelected(item) | |
> } | |
> if (id == R.id.action_postmix_balance) { | |
> startActivity(Intent(this, BalanceActivity::class.java).apply { | |
> putExtra("_account", POSTMIX) | |
> }) | |
> return super.onOptionsItemSelected(item) | |
> } | |
> | |
> // noinspection SimplifiableIfStatement | |
> if (id == R.id.action_network_dashboard) { | |
> startActivity(Intent(this, NetworkDashboard::class.java)) | |
> } // noinspection SimplifiableIfStatement | |
> if (id == R.id.action_support) { | |
> ActivityHelper.launchSupportPageInBrowser(this, SamouraiTorManager.isConnected()) | |
> } else if (id == R.id.action_utxo) { | |
> doUTXO() | |
> } else if (id == R.id.action_backup) { | |
> if (SamouraiWallet.getInstance().hasPassphrase(this@BalanceActivity)) { | |
> if (HD_WalletFactory.getInstance(this@BalanceActivity).get() != null && SamouraiWallet.getInstance().hasPassphrase(this@BalanceActivity)) { | |
> doBackup(HD_WalletFactory.getInstance(this@BalanceActivity).get().passphrase) | |
> } | |
> } else { | |
> val builder = MaterialAlertDialogBuilder(this) | |
> builder.setTitle(R.string.enter_backup_password) | |
> val view = layoutInflater.inflate(R.layout.password_input_dialog_layout, null) | |
> val password = view.findViewById<EditText>(R.id.restore_dialog_password_edittext) | |
> val message = view.findViewById<TextView>(R.id.dialogMessage) | |
> message.setText(R.string.backup_password) | |
> builder.setPositiveButton(R.string.confirm) { dialog: DialogInterface, which: Int -> | |
> val pw = password.text.toString() | |
> if (pw.length >= AppUtil.MIN_BACKUP_PW_LENGTH && pw.length <= AppUtil.MAX_BACKUP_PW_LENGTH) { | |
> doBackup(pw) | |
> } else { | |
> Toast.makeText(applicationContext, R.string.password_error, Toast.LENGTH_SHORT).show() | |
> } | |
> dialog.dismiss() | |
> } | |
> builder.setNegativeButton(R.string.cancel) { dialog: DialogInterface, which: Int -> dialog.dismiss() } | |
> builder.setView(view) | |
> builder.show() | |
> } | |
> } else if (id == R.id.action_scan_qr) { | |
> doScan() | |
> } else { | |
> } | |
> return super.onOptionsItemSelected(item) | |
> } | |
> | |
> private fun setUpTor() { | |
> SamouraiTorManager.getTorStateLiveData().observe(this) { torState: TorState -> | |
> if (torState.state == EnumTorState.ON) { | |
> PrefsUtil.getInstance(this).setValue(PrefsUtil.ENABLE_TOR, true) | |
> binding.progressBar.visibility = View.INVISIBLE | |
> menuTorIcon?.setImageResource(R.drawable.tor_on) | |
> } else if (torState.state == EnumTorState.STARTING) { | |
> binding.progressBar.visibility = View.VISIBLE | |
> menuTorIcon?.setImageResource(R.drawable.tor_on) | |
> } else { | |
> if (torState.state == EnumTorState.OFF && !executeQuitAppProcessStarted) { | |
> PrefsUtil.getInstance(this).setValue(PrefsUtil.ENABLE_TOR, false) | |
> } | |
> binding.progressBar.visibility = View.INVISIBLE | |
> menuTorIcon?.setImageResource(R.drawable.tor_off) | |
> } | |
> } | |
> } | |
> | |
> public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | |
> super.onActivityResult(requestCode, resultCode, data) | |
> onActivityResult(requestCode, resultCode, data, application) | |
> if (resultCode == RESULT_OK && requestCode == SCAN_COLD_STORAGE) { | |
> if (data?.getStringExtra(ZBarConstants.SCAN_RESULT) != null) { | |
> val strResult = data.getStringExtra(ZBarConstants.SCAN_RESULT) | |
> doPrivKey(strResult) | |
> } | |
> } else if (resultCode == RESULT_CANCELED && requestCode == SCAN_COLD_STORAGE) { | |
> } else if (resultCode == RESULT_OK && requestCode == SCAN_QR) { | |
> | |
> if (data?.getStringExtra(ZBarConstants.SCAN_RESULT) != null) { | |
> val strResult = data.getStringExtra(ZBarConstants.SCAN_RESULT) | |
> val params = SamouraiWallet.getInstance().currentNetworkParams | |
> val privKeyReader = PrivKeyReader(strResult, params) | |
> try { | |
> if (privKeyReader.format != null) { | |
> doPrivKey(strResult!!.trim { it <= ' ' }) | |
> } else if (strResult?.lowercase()?.startsWith(Auth47ViewModel.AUTH_SCHEME.lowercase()) == true) { | |
> ToolsBottomSheet.showTools(supportFragmentManager, ToolsBottomSheet.ToolType.AUTH47, | |
> bundle = Bundle().apply { | |
> putString("KEY", strResult) | |
> }) | |
> } else if (Cahoots.isCahoots(strResult!!.trim { it <= ' ' })) { | |
> val cahootIntent = ManualCahootsActivity.createIntentResume(this, account, strResult.trim { it <= ' ' }) | |
> startActivity(cahootIntent) | |
> } else if (isPSBT(strResult.trim { it <= ' ' })) { | |
> PSBTUtil.getInstance(this@BalanceActivity).doPSBT(strResult.trim { it <= ' ' }) | |
> } else if (DojoUtil.getInstance(this@BalanceActivity).isValidPairingPayload(strResult.trim { it <= ' ' })) { | |
> val intent = Intent(this@BalanceActivity, NetworkDashboard::class.java) | |
> intent.putExtra("params", strResult.trim { it <= ' ' }) | |
> startActivity(intent) | |
> } else { | |
> val intent = Intent(this@BalanceActivity, AccountSelectionActivity::class.java) | |
> intent.putExtra("uri", strResult.trim { it <= ' ' }) | |
> intent.putExtra("_account", account) | |
> startActivity(intent) | |
> } | |
> } catch (e: Exception) { | |
> } | |
> } | |
> } | |
> if (resultCode == RESULT_OK && requestCode == UTXO_REQUESTCODE) { | |
> refreshTx(false, false, false) | |
> showProgress() | |
> } else { | |
> } | |
> } | |
> | |
> override fun onBackPressed() { | |
> if (account == 0) { | |
> val builder = MaterialAlertDialogBuilder(this) | |
> builder.setMessage(R.string.ask_you_sure_exit) | |
> val alert = builder.create() | |
> alert.setButton(AlertDialog.BUTTON_POSITIVE, getString(R.string.yes)) { dialog: DialogInterface?, id: Int -> | |
> executeQuitAppProcesses() | |
> } | |
> alert.setButton(AlertDialog.BUTTON_NEGATIVE, getString(R.string.no)) { dialog: DialogInterface, id: Int -> dialog.dismiss() } | |
> alert.show() | |
> } else { | |
> super.onBackPressed() | |
> } | |
> } | |
> | |
> private fun doExternalBackUp() { | |
> try { | |
> if (hasPermissions() && PrefsUtil.getInstance(application).getValue(PrefsUtil.AUTO_BACKUP, false)) { | |
> val disposable = Observable.fromCallable { | |
> PayloadUtil.getInstance(this@BalanceActivity).saveWalletToJSON(CharSequenceX(AccessFactory.getInstance(this@BalanceActivity).guid + AccessFactory.getInstance(this@BalanceActivity).pin)) | |
> true | |
> }.subscribeOn(Schedulers.io()) | |
> .observeOn(AndroidSchedulers.mainThread()).subscribe({ t: Boolean? -> }) { throwable: Throwable? -> LogUtil.error(TAG, throwable) } | |
> registerDisposable(disposable) | |
> } | |
> } catch (exception: Exception) { | |
> LogUtil.error(TAG, exception) | |
> } | |
> } | |
> | |
> private fun executeQuitAppProcesses() { | |
> | |
> executeQuitAppProcessStarted = true; | |
> | |
> try { | |
> if (hasPermissions() && | |
> PrefsUtil.getInstance(application).getValue(PrefsUtil.AUTO_BACKUP, false)) { | |
> | |
> val disposable = Observable.fromCallable { | |
> PayloadUtil.getInstance(this@BalanceActivity) | |
> .saveWalletToJSON(CharSequenceX( | |
> AccessFactory.getInstance(this@BalanceActivity).guid + | |
> AccessFactory.getInstance(this@BalanceActivity).pin)) | |
> true | |
> }.subscribeOn(Schedulers.io()) | |
> .observeOn(AndroidSchedulers.mainThread()) | |
> .subscribe({ t: Boolean? -> | |
> stopingServices() | |
> }) { throwable: Throwable? -> | |
> LogUtil.error(TAG, throwable) | |
> stopingServices() | |
> } | |
> registerDisposable(disposable) | |
> } else { | |
> stopingServices() | |
> } | |
> } catch (exception: Exception) { | |
> LogUtil.error(TAG, exception) | |
> stopingServices() | |
> } | |
> } | |
> | |
> private fun stopingServices() { | |
> if (SamouraiTorManager.isConnected()) { | |
> SamouraiTorManager.stop() | |
> } | |
> if (WhirlpoolNotificationService.isRunning(applicationContext)) { | |
> WhirlpoolNotificationService.stopService(applicationContext) | |
> } | |
> TimeOutUtil.getInstance().reset() | |
> if (StealthModeController.isStealthEnabled(applicationContext)) { | |
> StealthModeController.enableStealth(applicationContext) | |
> } | |
> // disconnect Whirlpool on app back key exit | |
> finishAffinity() | |
> finish() | |
> super.onBackPressed() | |
> } | |
> | |
> private fun updateDisplay(fromRefreshService: Boolean) { | |
> val txDisposable = loadTxes(account) | |
> .subscribeOn(Schedulers.io()) | |
> .observeOn(AndroidSchedulers.mainThread()) | |
> .subscribe { txes: List<Tx>?, throwable: Throwable? -> | |
> throwable?.printStackTrace() | |
> if (txes != null) { | |
> if (txes.isNotEmpty()) { | |
> balanceViewModel.setTx(txes) | |
> } else { | |
> if (balanceViewModel.txs.value != null && balanceViewModel.txs.value!!.size == 0) { | |
> balanceViewModel.setTx(txes) | |
> } | |
> } | |
> Collections.sort(txes, TxMostRecentDateComparator()) | |
> txs!!.clear() | |
> txs!!.addAll(txes) | |
> } | |
> if (binding.progressBar.visibility == View.VISIBLE && fromRefreshService) { | |
> hideProgress() | |
> } | |
> } | |
> val balanceDisposable = loadBalance(account) | |
> .subscribeOn(Schedulers.io()) | |
> .observeOn(AndroidSchedulers.mainThread()) | |
> .subscribe { balance: Long?, throwable: Throwable? -> | |
> throwable?.printStackTrace() | |
> if (balanceViewModel.balance.value != null) { | |
> balanceViewModel.setBalance(balance) | |
> } else { | |
> balanceViewModel.setBalance(balance) | |
> } | |
> } | |
> registerDisposable(balanceDisposable) | |
> registerDisposable(txDisposable) | |
> // displayBalance(); | |
> // txAdapter.notifyDataSetChanged(); | |
> } | |
> | |
> private fun loadTxes(account: Int): Single<List<Tx>> { | |
> return Single.fromCallable { | |
> var loadedTxes: List<Tx> = ArrayList() | |
> if (account == 0) { | |
> loadedTxes = APIFactory.getInstance(this@BalanceActivity).allXpubTxs | |
> } else if (account == WhirlpoolMeta.getInstance(applicationContext).whirlpoolPostmix) { | |
> loadedTxes = APIFactory.getInstance(this@BalanceActivity).allPostMixTxs | |
> } | |
> loadedTxes | |
> } | |
> } | |
> | |
> private fun loadBalance(account: Int): Single<Long> { | |
> return Single.fromCallable { | |
> var loadedBalance = 0L | |
> if (account == 0) { | |
> loadedBalance = APIFactory.getInstance(this@BalanceActivity).xpubBalance | |
> } else if (account == WhirlpoolMeta.getInstance(applicationContext).whirlpoolPostmix) { | |
> loadedBalance = APIFactory.getInstance(this@BalanceActivity).xpubPostMixBalance | |
> } | |
> loadedBalance | |
> } | |
> } | |
> | |
> private fun doSettings() { | |
> TimeOutUtil.getInstance().updatePin() | |
> val intent = Intent(this@BalanceActivity, SettingsActivity::class.java) | |
> startActivity(intent) | |
> } | |
> | |
> var utxoListResult = registerForActivityResult( | |
> ActivityResultContracts.StartActivityForResult() | |
> ) { | |
> run { | |
> refreshTx(false, false, false) | |
> showProgress() | |
> } | |
> } | |
> | |
> private fun doUTXO() { | |
> val intent = Intent(this@BalanceActivity, UTXOSActivity::class.java) | |
> intent.putExtra("_account", account) | |
> utxoListResult.launch(intent) | |
> } | |
> | |
> private fun doScan() { | |
> val cameraFragmentBottomSheet = ScanFragment() | |
> cameraFragmentBottomSheet.show(supportFragmentManager, cameraFragmentBottomSheet.tag) | |
> cameraFragmentBottomSheet.setOnScanListener { code -> | |
> cameraFragmentBottomSheet.dismissAllowingStateLoss() | |
> val params = SamouraiWallet.getInstance().currentNetworkParams | |
> val privKeyReader = PrivKeyReader(code, params) | |
> try { | |
> when { | |
> canParseAsBatchSpend(code) -> { | |
> launchBatchSpend(code) | |
> } | |
> privKeyReader.format != null -> { | |
> doPrivKey(code.trim { it <= ' ' }) | |
> } | |
> code.lowercase().startsWith(Auth47ViewModel.AUTH_SCHEME) -> { | |
> ToolsBottomSheet.showTools(supportFragmentManager, ToolsBottomSheet.ToolType.AUTH47, | |
> bundle = Bundle().apply { | |
> putString("KEY", code) | |
> }) | |
> } | |
> Cahoots.isCahoots(code.trim { it <= ' ' }) -> { | |
> val cahootIntent = ManualCahootsActivity.createIntentResume(this, account, code.trim { it <= ' ' }) | |
> startActivity(cahootIntent) | |
> } | |
> isPSBT(code.trim { it <= ' ' }) -> { | |
> ToolsBottomSheet.showTools(supportFragmentManager, ToolsBottomSheet.ToolType.PSBT, | |
> bundle = Bundle().apply { | |
> putString("KEY", code) | |
> }) | |
> } | |
> DojoUtil.getInstance(this@BalanceActivity).isValidPairingPayload(code.trim { it <= ' ' }) -> { | |
> val intent = Intent(this@BalanceActivity, NetworkDashboard::class.java) | |
> intent.putExtra("params", code.trim { it <= ' ' }) | |
> startActivity(intent) | |
> } | |
> else -> { | |
> | |
> val isPostmixAccount = account == POSTMIX | |
> | |
> val activityType = | |
> if (isPostmixAccount) SendActivity::class.java | |
> else AccountSelectionActivity::class.java | |
> | |
> val intent = Intent(this@BalanceActivity, activityType) | |
> intent.putExtra("uri", code.trim { it <= ' ' }) | |
> if (isPostmixAccount) { | |
> intent.putExtra("_account", account) | |
> } | |
> startActivity(intent) | |
> } | |
> } | |
> } catch (e: Exception) { | |
> } | |
> } | |
> } | |
> | |
> private fun launchBatchSpend(inputBatchSpendAsJson: String) { | |
> val intent = Intent(this@BalanceActivity, AccountSelectionActivity::class.java) | |
> intent.putExtra("inputBatchSpend", inputBatchSpendAsJson) | |
> startActivity(intent) | |
> } | |
> | |
> private fun doSweepViaScan() { | |
> val cameraFragmentBottomSheet = CameraFragmentBottomSheet() | |
> cameraFragmentBottomSheet.show(supportFragmentManager, cameraFragmentBottomSheet.tag) | |
> cameraFragmentBottomSheet.setQrCodeScanListener { code: String -> | |
> cameraFragmentBottomSheet.dismissAllowingStateLoss() | |
> val params = SamouraiWallet.getInstance().currentNetworkParams | |
> val privKeyReader = PrivKeyReader(code, params) | |
> try { | |
> when { | |
> privKeyReader.format != null -> { | |
> doPrivKey(code.trim { it <= ' ' }) | |
> } | |
> Cahoots.isCahoots(code.trim { it <= ' ' }) -> { | |
> val cahootIntent = ManualCahootsActivity.createIntentResume(this, account, code.trim { it <= ' ' }) | |
> startActivity(cahootIntent) | |
> } | |
> isPSBT(code.trim { it <= ' ' }) -> { | |
> PSBTUtil.getInstance(this@BalanceActivity).doPSBT(code.trim { it <= ' ' }) | |
> } | |
> DojoUtil.getInstance(this@BalanceActivity).isValidPairingPayload(code.trim { it <= ' ' }) -> { | |
> Toast.makeText(this@BalanceActivity, "Samourai Dojo full node coming soon.", Toast.LENGTH_SHORT).show() | |
> } | |
> else -> { | |
> val intent = Intent(this@BalanceActivity, AccountSelectionActivity::class.java) | |
> intent.putExtra("uri", code.trim { it <= ' ' }) | |
> intent.putExtra("_account", account) | |
> startActivity(intent) | |
> } | |
> } | |
> } catch (e: Exception) { | |
> } | |
> } | |
> } | |
> | |
> private fun doPrivKey(data: String?) { | |
> | |
> val params = SamouraiWallet.getInstance().currentNetworkParams | |
> var privKeyReader: PrivKeyReader? = null | |
> var format: String? = null | |
> try { | |
> privKeyReader = PrivKeyReader(data, params) | |
> format = privKeyReader.format | |
> } catch (e: Exception) { | |
> Toast.makeText(this@BalanceActivity, e.message, Toast.LENGTH_SHORT).show() | |
> return | |
> } | |
> if (format != null) { | |
> ToolsBottomSheet.showTools(supportFragmentManager, ToolsBottomSheet.ToolType.SWEEP, | |
> bundle = Bundle().apply { | |
> putString("KEY", data) | |
> }) | |
> } else { | |
> Toast.makeText(this@BalanceActivity, R.string.cannot_recognize_privkey, Toast.LENGTH_SHORT).show() | |
> } | |
> } | |
> | |
> private fun doBackup(passphrase: String) { | |
> val export_methods = arrayOfNulls<String>(2) | |
> export_methods[0] = getString(R.string.export_to_clipboard) | |
> export_methods[1] = getString(R.string.export_to_email) | |
> MaterialAlertDialogBuilder(this@BalanceActivity) | |
> .setTitle(R.string.options_export) | |
> .setSingleChoiceItems(export_methods, 0, DialogInterface.OnClickListener { dialog, which -> | |
> try { | |
> PayloadUtil.getInstance(this@BalanceActivity).saveWalletToJSON(CharSequenceX(AccessFactory.getInstance(this@BalanceActivity).guid + AccessFactory.getInstance(this@BalanceActivity).pin)) | |
> } catch (ioe: IOException) { | |
> } catch (je: JSONException) { | |
> } catch (de: DecryptionException) { | |
> } catch (mle: MnemonicLengthException) { | |
> } | |
> var encrypted: String? = null | |
> try { | |
> encrypted = AESUtil.encryptSHA256(PayloadUtil.getInstance(this@BalanceActivity).payload.toString(), CharSequenceX(passphrase)) | |
> } catch (e: Exception) { | |
> Toast.makeText(this@BalanceActivity, e.message, Toast.LENGTH_SHORT).show() | |
> } finally { | |
> if (encrypted == null) { | |
> Toast.makeText(this@BalanceActivity, R.string.encryption_error, Toast.LENGTH_SHORT).show() | |
> return@OnClickListener | |
> } | |
> } | |
> val obj = PayloadUtil.getInstance(this@BalanceActivity).putPayload(encrypted, true) | |
> if (which == 0) { | |
> val clipboard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager | |
> var clip: ClipData? = null | |
> clip = ClipData.newPlainText("Wallet backup", obj.toString()) | |
> clipboard.setPrimaryClip(clip) | |
> Toast.makeText(this@BalanceActivity, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show() | |
> } else { | |
> val email = Intent(Intent.ACTION_SEND) | |
> email.putExtra(Intent.EXTRA_SUBJECT, "Samourai Wallet backup") | |
> email.putExtra(Intent.EXTRA_TEXT, obj.toString()) | |
> email.type = "message/rfc822" | |
> startActivity(Intent.createChooser(email, getText(R.string.choose_email_client))) | |
> } | |
> dialog.dismiss() | |
> } | |
> ).show() | |
> } | |
> | |
> private fun doClipboardCheck() { | |
> val clipboard = this@BalanceActivity.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager | |
> if (clipboard.hasPrimaryClip()) { | |
> val clip = clipboard.primaryClip | |
> val item = clip!!.getItemAt(0) | |
> if (item.text != null) { | |
> val text = item.text.toString() | |
> val s = text.split("\\s+").toTypedArray() | |
> try { | |
> for (i in s.indices) { | |
> val params = SamouraiWallet.getInstance().currentNetworkParams | |
> val privKeyReader = PrivKeyReader(s[i], params) | |
> if (privKeyReader.format != null && | |
> (privKeyReader.format == PrivKeyReader.WIF_COMPRESSED || privKeyReader.format == PrivKeyReader.WIF_UNCOMPRESSED || privKeyReader.format == PrivKeyReader.BIP38 || | |
> FormatsUtil.getInstance().isValidXprv(s[i])) | |
> ) { | |
> MaterialAlertDialogBuilder(this@BalanceActivity) | |
> .setTitle(R.string.app_name) | |
> .setMessage(R.string.privkey_clipboard) | |
> .setCancelable(false) | |
> .setPositiveButton(R.string.yes) { _, _ -> clipboard.setPrimaryClip(ClipData.newPlainText("", "")) }.setNegativeButton(R.string.no) { _, _ -> }.show() | |
> } | |
> } | |
> } catch (e: Exception) { | |
> } | |
> } | |
> } | |
> } | |
> | |
> private fun refreshTx(notifTx: Boolean, dragged: Boolean, launch: Boolean) { | |
> if (AppUtil.getInstance(this@BalanceActivity).isOfflineMode) { | |
> Toast.makeText(this@BalanceActivity, R.string.in_offline_mode, Toast.LENGTH_SHORT).show() | |
> /* | |
> CoordinatorLayout coordinatorLayout = new CoordinatorLayout(BalanceActivity.this); | |
> Snackbar snackbar = Snackbar.make(coordinatorLayout, R.string.in_offline_mode, Snackbar.LENGTH_LONG); | |
> snackbar.show(); | |
> */ | |
> } | |
> WalletRefreshWorker.enqueue(applicationContext, launched = launch, notifTx = notifTx) | |
> // | |
> // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | |
> // startForegroundService(intent); | |
> // } else { | |
> // startService(intent); | |
> // } | |
> } | |
> | |
> private fun doExplorerView(strHash: String?) { | |
> if (strHash != null) { | |
> val blockExplorer = BlockExplorerUtil.getInstance().getUri(true) | |
> val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(blockExplorer + strHash)) | |
> startActivity(browserIntent) | |
> } | |
> } | |
> | |
> private fun txDetails(tx: Tx) { | |
> if (account == WhirlpoolMeta.getInstance(applicationContext).whirlpoolPostmix && tx.amount == 0.0) { | |
> return | |
> } | |
> val txIntent = Intent(this, TxDetailsActivity::class.java) | |
> txIntent.putExtra("TX", tx.toJSON().toString()) | |
> txIntent.putExtra("_account", account) | |
> startActivity(txIntent) | |
> } | |
> | |
> private inner class RicochetQueueTask : AsyncTask<String?, Void?, String>() { | |
> | |
> override fun onPostExecute(result: String) { | |
> } | |
> | |
> override fun onPreExecute() { | |
> } | |
> | |
> override fun doInBackground(vararg params: String?): String { | |
> if (RicochetMeta.getInstance(this@BalanceActivity).queue.size > 0) { | |
> var count = 0 | |
> val itr = RicochetMeta.getInstance(this@BalanceActivity).iterator | |
> while (itr.hasNext()) { | |
> if (count == 3) { | |
> break | |
> } | |
> try { | |
> val jObj = itr.next() | |
> val jHops = jObj.getJSONArray("hops") | |
> if (jHops.length() > 0) { | |
> val jHop = jHops.getJSONObject(jHops.length() - 1) | |
> val txHash = jHop.getString("hash") | |
> val txObj = APIFactory.getInstance(this@BalanceActivity).getTxInfo(txHash) | |
> if (txObj != null && txObj.has("block_height") && txObj.getInt("block_height") != -1) { | |
> itr.remove() | |
> count++ | |
> } | |
> } | |
> } catch (je: JSONException) { | |
> } | |
> } | |
> } | |
> if (RicochetMeta.getInstance(this@BalanceActivity).staggered.size > 0) { | |
> var count = 0 | |
> val staggered = RicochetMeta.getInstance(this@BalanceActivity).staggered | |
> val _staggered: MutableList<JSONObject> = ArrayList() | |
> for (jObj in staggered) { | |
> if (count == 3) { | |
> break | |
> } | |
> try { | |
> val jHops = jObj.getJSONArray("script") | |
> if (jHops.length() > 0) { | |
> val jHop = jHops.getJSONObject(jHops.length() - 1) | |
> val txHash = jHop.getString("tx") | |
> val txObj = APIFactory.getInstance(this@BalanceActivity).getTxInfo(txHash) | |
> if (txObj != null && txObj.has("block_height") && txObj.getInt("block_height") != -1) { | |
> count++ | |
> } else { | |
> _staggered.add(jObj) | |
> } | |
> } | |
> } catch (je: JSONException) { | |
> } catch (cme: ConcurrentModificationException) { | |
> } | |
> } | |
> } | |
> return "OK" | |
> } | |
> } | |
> | |
> private fun doFeaturePayNymUpdate() { | |
> val disposable = Observable.fromCallable { | |
> var obj = JSONObject() | |
> obj.put("code", BIP47Util.getInstance(this@BalanceActivity).paymentCode.toString()) | |
> // Log.d("BalanceActivity", obj.toString()); | |
> var res = WebUtil.getInstance(this@BalanceActivity).postURL("application/json", null, WebUtil.PAYNYM_API + "api/v1/token", obj.toString()) | |
> // Log.d("BalanceActivity", res); | |
> var responseObj = JSONObject(res) | |
> if (responseObj.has("token")) { | |
> val token = responseObj.getString("token") | |
> val sig = MessageSignUtil.getInstance(this@BalanceActivity).signMessage(BIP47Util.getInstance(this@BalanceActivity).notificationAddress.ecKey, token) | |
> // Log.d("BalanceActivity", sig); | |
> obj = JSONObject() | |
> obj.put("nym", BIP47Util.getInstance(this@BalanceActivity).paymentCode.toString()) | |
> obj.put("code", BIP47Util.getInstance(this@BalanceActivity).featurePaymentCode.toString()) | |
> obj.put("signature", sig) | |
> | |
> // Log.d("BalanceActivity", "nym/add:" + obj.toString()); | |
> res = WebUtil.getInstance(this@BalanceActivity).postURL("application/json", token, WebUtil.PAYNYM_API + "api/v1/nym/add", obj.toString()) | |
> // Log.d("BalanceActivity", res); | |
> responseObj = JSONObject(res) | |
> if (responseObj.has("segwit") && responseObj.has("token")) { | |
> PrefsUtil.getInstance(this@BalanceActivity).setValue(PrefsUtil.PAYNYM_FEATURED_SEGWIT, true) | |
> } else if (responseObj.has("claimed") && responseObj.getBoolean("claimed") == true) { | |
> PrefsUtil.getInstance(this@BalanceActivity).setValue(PrefsUtil.PAYNYM_FEATURED_SEGWIT, true) | |
> } | |
> } | |
> true | |
> }.subscribeOn(Schedulers.newThread()) | |
> .observeOn(AndroidSchedulers.mainThread()) | |
> .subscribe({ aBoolean: Boolean? -> Log.i(TAG, "doFeaturePayNymUpdate: Feature update complete") }) { error: Throwable? -> Log.i(TAG, "doFeaturePayNymUpdate: Feature update Fail") } | |
> registerDisposable(disposable) | |
> } | |
> | |
> companion object { | |
> private const val SCAN_COLD_STORAGE = 2011 | |
> private const val SCAN_QR = 2012 | |
> private const val UTXO_REQUESTCODE = 2012 | |
> private const val TAG = "BalanceActivity" | |
> const val ACTION_INTENT = "com.samourai.wallet.BalanceFragment.REFRESH" | |
> const val DISPLAY_INTENT = "com.samourai.wallet.BalanceFragment.DISPLAY" | |
> } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/home/BalanceViewModel.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/home/BalanceViewModel.java | |
3a4,8 | |
> | |
> import androidx.lifecycle.AndroidViewModel; | |
> import androidx.lifecycle.LiveData; | |
> import androidx.lifecycle.MutableLiveData; | |
> | |
9,11d13 | |
< import androidx.lifecycle.AndroidViewModel; | |
< import androidx.lifecycle.LiveData; | |
< import androidx.lifecycle.MutableLiveData; | |
17d18 | |
< import com.samourai.wallet.util.PrefsUtil; | |
18a20 | |
> import com.samourai.wallet.util.PrefsUtil; | |
20a23 | |
> import org.json.JSONException; | |
22a26 | |
> import java.io.IOException; | |
58a63,65 | |
> boolean is_sat_prefs = PrefsUtil.getInstance(this.mContext).getValue(PrefsUtil.IS_SAT, true); | |
> try { | |
> JSONObject response = new JSONObject("{}"); | |
60c67,68 | |
< final boolean is_sat_prefs = PrefsUtil.getInstance(this.mContext).getValue(PrefsUtil.IS_SAT, true); | |
--- | |
> if (account == 0) { | |
> response = PayloadUtil.getInstance(getApplication()).deserializeMultiAddr(); | |
62,114c70,111 | |
< final Disposable disposableJson = Observable.fromCallable(() -> { | |
< if (account == 0) { | |
< return PayloadUtil.getInstance(getApplication()).deserializeMultiAddr(); | |
< } else if (account == WhirlpoolMeta.getInstance(getApplication()).getWhirlpoolPostmix()) { | |
< return PayloadUtil.getInstance(getApplication()).deserializeMultiAddrMix(); | |
< } else { | |
< return null; | |
< } | |
< }) | |
< .subscribeOn(Schedulers.io()) | |
< .observeOn(AndroidSchedulers.mainThread()) | |
< .subscribe(response -> { | |
< if (response == null) { | |
< return; | |
< } | |
< | |
< Observable<Pair<List<Tx>, Long>> parser = account == 0 | |
< ? APIFactory.getInstance(getApplication()).parseXPUBObservable(new JSONObject(response.toString())) | |
< : APIFactory.getInstance(getApplication()).parseMixXPUBObservable(new JSONObject(response.toString())); | |
< Disposable disposable = parser | |
< .subscribeOn(Schedulers.computation()) | |
< .observeOn(AndroidSchedulers.mainThread()) | |
< .subscribe(pairValues -> { | |
< List<Tx> txes = pairValues.first; | |
< Long xpub_balance = pairValues.second; | |
< Collections.sort(txes, new APIFactory.TxMostRecentDateComparator()); | |
< txs.postValue(txes); | |
< toggleSat.setValue(is_sat_prefs); | |
< if (account == 0) { | |
< balance.postValue(xpub_balance - BlockedUTXO.getInstance().getTotalValueBlocked0()); | |
< } | |
< if (account == WhirlpoolMeta.getInstance(getApplication()).getWhirlpoolPostmix()) { | |
< balance.postValue(xpub_balance - BlockedUTXO.getInstance().getTotalValuePostMix()); | |
< } | |
< if (account == WhirlpoolMeta.getInstance(getApplication()).getWhirlpoolBadBank()) { | |
< balance.postValue(xpub_balance - BlockedUTXO.getInstance().getTotalValueBadBank()); | |
< } | |
< }, error -> { | |
< LogUtil.info(TAG,error.getMessage()); | |
< txs.postValue(new ArrayList<>()); | |
< toggleSat.setValue(is_sat_prefs); | |
< balance.postValue(0L); | |
< }); | |
< | |
< compositeDisposables.add(disposable); | |
< | |
< }, error -> { | |
< LogUtil.info(TAG,error.getMessage()); | |
< txs.postValue(new ArrayList<>()); | |
< toggleSat.setValue(is_sat_prefs); | |
< balance.postValue(0L); | |
< }); | |
< compositeDisposables.add(disposableJson); | |
--- | |
> } | |
> if (account == WhirlpoolMeta.getInstance(getApplication()).getWhirlpoolPostmix()) { | |
> response = PayloadUtil.getInstance(getApplication()).deserializeMultiAddrMix(); | |
> } | |
> | |
> if (response != null) { | |
> | |
> Observable<Pair<List<Tx>, Long>> parser = account == 0 ? APIFactory.getInstance(getApplication()).parseXPUBObservable(new JSONObject(response.toString())) : APIFactory.getInstance(getApplication()).parseMixXPUBObservable(new JSONObject(response.toString())); | |
> Disposable disposable = parser | |
> .subscribeOn(Schedulers.computation()) | |
> .observeOn(AndroidSchedulers.mainThread()).subscribe(pairValues -> { | |
> List<Tx> txes = pairValues.first; | |
> Long xpub_balance = pairValues.second; | |
> Collections.sort(txes, new APIFactory.TxMostRecentDateComparator()); | |
> txs.postValue(txes); | |
> toggleSat.setValue(is_sat_prefs); | |
> if (account == 0) { | |
> balance.postValue(xpub_balance - BlockedUTXO.getInstance().getTotalValueBlocked0()); | |
> } | |
> if (account == WhirlpoolMeta.getInstance(getApplication()).getWhirlpoolPostmix()) { | |
> balance.postValue(xpub_balance - BlockedUTXO.getInstance().getTotalValuePostMix()); | |
> } | |
> if (account == WhirlpoolMeta.getInstance(getApplication()).getWhirlpoolBadBank()) { | |
> balance.postValue(xpub_balance - BlockedUTXO.getInstance().getTotalValueBadBank()); | |
> } | |
> }, error -> { | |
> LogUtil.info(TAG,error.getMessage()); | |
> txs.postValue(new ArrayList<>()); | |
> toggleSat.setValue(is_sat_prefs); | |
> balance.postValue(0L); | |
> }); | |
> | |
> compositeDisposables.add(disposable); | |
> | |
> } | |
> | |
> } catch (IOException | JSONException e) { | |
> e.printStackTrace(); | |
> txs.setValue(new ArrayList<>()); | |
> toggleSat.setValue(is_sat_prefs); | |
> balance.setValue(0L); | |
> } | |
152c149 | |
< public void postNewBalance(Long balance) { | |
--- | |
> public void setBalance(Long balance) { | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/MainActivity2.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/MainActivity2.java | |
3,10d2 | |
< import static com.samourai.wallet.payload.ExternalBackupManager.backupAvailable; | |
< import static com.samourai.wallet.payload.ExternalBackupManager.hasBackUpURI; | |
< import static com.samourai.wallet.util.func.WalletUtil.ASHIGARU_PUB_KEY; | |
< import static org.apache.commons.lang3.StringUtils.defaultString; | |
< import static org.apache.commons.lang3.StringUtils.isNotBlank; | |
< import static org.apache.commons.lang3.StringUtils.strip; | |
< import static org.apache.commons.lang3.StringUtils.stripStart; | |
< import static org.apache.commons.lang3.StringUtils.substringBetween; | |
11a4 | |
> import static java.util.Objects.isNull; | |
24d16 | |
< import android.util.Log; | |
29a22 | |
> import androidx.appcompat.app.AppCompatActivity; | |
31d23 | |
< import androidx.core.content.ContextCompat; | |
46d37 | |
< import com.samourai.wallet.sync.SyncWalletActivity; | |
53,54d43 | |
< import com.samourai.wallet.util.Util; | |
< import com.samourai.wallet.util.func.WalletUtil; | |
56d44 | |
< import com.samourai.wallet.util.network.WebUtil; | |
62d49 | |
< import com.samourai.wallet.util.tech.VerifyPGPSignedClearMessageUtil; | |
66d52 | |
< import org.apache.commons.lang3.StringUtils; | |
70d55 | |
< import org.json.JSONObject; | |
74,76d58 | |
< import java.util.concurrent.ExecutorService; | |
< import java.util.concurrent.Executors; | |
< import java.util.concurrent.atomic.AtomicBoolean; | |
79d60 | |
< import io.reactivex.Observable; | |
85c66 | |
< public class MainActivity2 extends SamouraiActivity { | |
--- | |
> public class MainActivity2 extends AppCompatActivity { | |
89a71 | |
> private boolean pinEntryActivityLaunched = false; | |
97d78 | |
< private AtomicBoolean torStateObserverInitialized = new AtomicBoolean(false); | |
151,165d131 | |
< | |
< // if (BuildConfig.DEBUG) { // useful to detect bad usage of main thread for developers | |
< // StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() | |
< // .detectCustomSlowCalls() | |
< // .detectNetwork() | |
< // .detectDiskReads() | |
< // .penaltyLog() | |
< // .build()); | |
< // StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() | |
< // .detectLeakedSqlLiteObjects() | |
< // .detectLeakedClosableObjects() | |
< // .penaltyLog() | |
< // .build()); | |
< // } | |
< | |
168,169d133 | |
< getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.window)); | |
< | |
177,178d140 | |
< BalanceActivity.Companion.setAppUpdateShowed(false); | |
< SamouraiWallet.getInstance().releaseNotes = null; | |
180,192c142,151 | |
< final Disposable disposable = Observable.fromCallable(() -> { | |
< return PrefsUtil.getInstance(MainActivity2.this).getValue(PrefsUtil.TESTNET, false); | |
< }) | |
< .subscribeOn(Schedulers.io()) | |
< .observeOn(AndroidSchedulers.mainThread()) | |
< .subscribe(isTestNet -> { | |
< if (isTestNet) { | |
< SamouraiWallet.getInstance().setCurrentNetworkParams(TestNet3Params.get()); | |
< } | |
< BackgroundManager.get(MainActivity2.this).addListener(bgListener); | |
< startApp(); | |
< }); | |
< compositeDisposables.add(disposable); | |
--- | |
> | |
> if (PrefsUtil.getInstance(MainActivity2.this).getValue(PrefsUtil.TESTNET, false) == true) { | |
> SamouraiWallet.getInstance().setCurrentNetworkParams(TestNet3Params.get()); | |
> } | |
> | |
> // if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { | |
> BackgroundManager.get(MainActivity2.this).addListener(bgListener); | |
> // } | |
> | |
> startApp(); | |
195c154,155 | |
< private void startApp() { | |
--- | |
> @Override | |
> protected void onResume() { | |
197,199c157,158 | |
< if (SamouraiTorManager.INSTANCE.isRequired() && | |
< !AppUtil.getInstance(getApplicationContext()).isOfflineMode() && | |
< ConnectivityStatus.hasConnectivity(getApplicationContext()) && | |
--- | |
> if (PrefsUtil.getInstance(this).getValue(PrefsUtil.ENABLE_TOR, false) && | |
> !PrefsUtil.getInstance(this).getValue(PrefsUtil.OFFLINE,false) && | |
201a161 | |
> progressIndicator.setIndeterminate(true); | |
203c163 | |
< loaderTxView.setText(getText(R.string.initializing_tor)); | |
--- | |
> SamouraiTorManager.INSTANCE.start(); | |
206c166 | |
< initAppOnCreate(); | |
--- | |
> initAppOnResume(); | |
207a168,169 | |
> super.onResume(); | |
> | |
210,211c172 | |
< @Override | |
< protected void onResume() { | |
--- | |
> private void startApp() { | |
218d178 | |
< progressIndicator.setIndeterminate(true); | |
220c180 | |
< SamouraiTorManager.INSTANCE.start(); | |
--- | |
> loaderTxView.setText(getText(R.string.initializing_tor)); | |
223c183 | |
< initAppOnResume(); | |
--- | |
> initAppOnCreate(); | |
225,226d184 | |
< super.onResume(); | |
< | |
233c191 | |
< doAppInit0(false, null); | |
--- | |
> doAppInit0(false, null, null); | |
242a201 | |
> String strPCode = null; | |
252a212,214 | |
> if (extras != null && extras.containsKey("pcode")) { | |
> strPCode = extras.getString("pcode"); | |
> } | |
258c220,221 | |
< doAppInit0(isDial, strUri); | |
--- | |
> doAppInit0(isDial, strUri, strPCode); | |
> | |
264,268c227,243 | |
< if (torStateObserverInitialized.compareAndSet(false, true)) { | |
< if (torStateObserver == null) { | |
< torStateObserver = new Observer<TorState>() { | |
< @Override | |
< public void onChanged(TorState torState) { | |
--- | |
> if (isNull(torStateObserver)) { | |
> torStateObserver = new Observer<TorState>() { | |
> @Override | |
> public void onChanged(TorState torState) { | |
> | |
> SimpleTaskRunner.create().executeAsync(new Callable<Integer>() { | |
> @Override | |
> public Integer call() throws Exception { | |
> final int progressIndicatorValue = torState.getProgressIndicator(); | |
> final int newProgressIndicatorValue = max( | |
> progressIndicatorValue, | |
> progressIndicator.getProgress()); | |
> return newProgressIndicatorValue; | |
> } | |
> }, new SimpleCallback<Integer>() { | |
> @Override | |
> public void onComplete(final Integer newProgressIndicatorValue) { | |
270,283c245,247 | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< new Callable<Integer>() { | |
< @Override | |
< public Integer call() throws Exception { | |
< final int progressIndicatorValue = torState.getProgressIndicator(); | |
< final int newProgressIndicatorValue = max( | |
< progressIndicatorValue, | |
< progressIndicator.getProgress()); | |
< return newProgressIndicatorValue; | |
< } | |
< }, new SimpleCallback<Integer>() { | |
< @Override | |
< public void onComplete(final Integer newProgressIndicatorValue) { | |
--- | |
> if (newProgressIndicatorValue > 0 && progressIndicator.isIndeterminate()) { | |
> progressIndicator.setIndeterminate(false); | |
> } | |
285,286c249,254 | |
< if (newProgressIndicatorValue > 0 && progressIndicator.isIndeterminate()) { | |
< progressIndicator.setIndeterminate(false); | |
--- | |
> SimpleTaskRunner.create().executeAsync(new Callable<Boolean>() { | |
> @Override | |
> public Boolean call() throws Exception { | |
> if (progressIndicator.getProgress() <= 0 && newProgressIndicatorValue > 0) { | |
> ThreadHelper.pauseMillis(100L); | |
> return true; | |
288,302c256,270 | |
< | |
< SimpleTaskRunner.create().executeAsync(true, new Callable<Boolean>() { | |
< @Override | |
< public Boolean call() throws Exception { | |
< if (progressIndicator.getProgress() <= 0 && newProgressIndicatorValue > 0) { | |
< ThreadHelper.pauseMillis(100L); | |
< return true; | |
< } | |
< return false; | |
< } | |
< }, new SimpleCallback<Boolean>() { | |
< @Override | |
< public void onComplete(final Boolean stateChanged) { | |
< if (newProgressIndicatorValue > 0) { | |
< progressIndicator.setProgressCompat(newProgressIndicatorValue, true); | |
--- | |
> return false; | |
> } | |
> }, new SimpleCallback<Boolean>() { | |
> @Override | |
> public void onComplete(final Boolean stateChanged) { | |
> if (newProgressIndicatorValue > 0) { | |
> progressIndicator.setProgressCompat(newProgressIndicatorValue, true); | |
> } | |
> if (torState.getState() == EnumTorState.ON) { | |
> SimpleTaskRunner.create().executeAsync(new Callable<Object>() { | |
> @Override | |
> public Object call() throws Exception { | |
> // wait for progress bar to reach 100% | |
> ThreadUtils.sleep(Duration.ofMillis(500)); | |
> return null; | |
304,317c272,275 | |
< if (torState.getState() == EnumTorState.ON) { | |
< SimpleTaskRunner.create().executeAsync(true, new Callable<Object>() { | |
< @Override | |
< public Object call() throws Exception { | |
< // wait for progress bar to reach 100% | |
< ThreadUtils.sleep(Duration.ofMillis(500)); | |
< return null; | |
< } | |
< }, new SimpleCallback<Object>() { | |
< @Override | |
< public void onComplete(Object result) { | |
< SimpleTaskRunner.create().executeAsyncAndShutdown(() -> initAppOnCreate()); | |
< } | |
< }); | |
--- | |
> }, new SimpleCallback<Object>() { | |
> @Override | |
> public void onComplete(Object result) { | |
> SimpleTaskRunner.create().executeAsync(() -> initAppOnCreate()); | |
319,326c277,285 | |
< } | |
< }); | |
< } | |
< }); | |
< } | |
< }; | |
< SamouraiTorManager.INSTANCE.getTorStateLiveData().observe(this, torStateObserver); | |
< } | |
--- | |
> }); | |
> } | |
> } | |
> }); | |
> } | |
> }); | |
> } | |
> }; | |
> SamouraiTorManager.INSTANCE.getTorStateLiveData().observe(this, torStateObserver); | |
334,356c293,294 | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< new Callable<Void>() { | |
< @Override | |
< public Void call() throws Exception { | |
< AppUtil.getInstance(MainActivity2.this).deleteQR(); | |
< AppUtil.getInstance(MainActivity2.this).deleteBackup(); | |
< return null; | |
< } | |
< }, | |
< new SimpleCallback<Void>() { | |
< @Override | |
< public void onComplete(Void result) { | |
< IntentFilter filter_restart = new IntentFilter(ACTION_RESTART); | |
< LocalBroadcastManager.getInstance(MainActivity2.this).registerReceiver(receiver_restart, filter_restart); | |
< String strUri = null; | |
< try { | |
< String action = getIntent().getAction(); | |
< String scheme = getIntent().getScheme(); | |
< if (action != null && Intent.ACTION_VIEW.equals(action) && scheme.equals("bitcoin")) { | |
< strUri = getIntent().getData().toString(); | |
< } else { | |
< Bundle extras = getIntent().getExtras(); | |
--- | |
> AppUtil.getInstance(MainActivity2.this).deleteQR(); | |
> AppUtil.getInstance(MainActivity2.this).deleteBackup(); | |
358,361c296,305 | |
< if (extras != null && extras.containsKey("uri")) { | |
< strUri = extras.getString("uri"); | |
< } | |
< } | |
--- | |
> IntentFilter filter_restart = new IntentFilter(ACTION_RESTART); | |
> LocalBroadcastManager.getInstance(MainActivity2.this).registerReceiver(receiver_restart, filter_restart); | |
> String strUri = null; | |
> try { | |
> String action = getIntent().getAction(); | |
> String scheme = getIntent().getScheme(); | |
> if (action != null && Intent.ACTION_VIEW.equals(action) && scheme.equals("bitcoin")) { | |
> strUri = getIntent().getData().toString(); | |
> } else { | |
> Bundle extras = getIntent().getExtras(); | |
363,370c307,318 | |
< if ( scheme !=null && scheme.equals("auth47") && getIntent().getData()!=null) { | |
< strUri = getIntent().getData().toString(); | |
< } | |
< } catch (Exception e) { | |
< e.printStackTrace(); | |
< } | |
< doAppInit0(false, strUri); | |
< } | |
--- | |
> if (extras != null && extras.containsKey("uri")) { | |
> strUri = extras.getString("uri"); | |
> } | |
> } | |
> | |
> if ( scheme !=null && scheme.equals("auth47") && getIntent().getData()!=null) { | |
> strUri = getIntent().getData().toString(); | |
> } | |
> } catch (Exception e) { | |
> e.printStackTrace(); | |
> } | |
> doAppInit0(false, strUri, null); | |
372,376d319 | |
< @Override | |
< public void onException(Throwable t) { | |
< Log.e(TAG, "issue on initAppOnResume()", t); | |
< } | |
< }); | |
390a334,335 | |
> AppUtil.getInstance(MainActivity2.this).deleteQR(); | |
> AppUtil.getInstance(MainActivity2.this).deleteBackup(); | |
392,410c337 | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< () -> { | |
< AppUtil.getInstance(MainActivity2.this).deleteQR(); | |
< AppUtil.getInstance(MainActivity2.this).deleteBackup(); | |
< return null; | |
< }, | |
< new SimpleCallback<Void>() { | |
< @Override | |
< public void onComplete(Void result) { | |
< SimpleCallback.super.onComplete(result); | |
< } | |
< | |
< @Override | |
< public void onException(Throwable t) { | |
< Log.e(TAG, "issue on delete resources", t); | |
< } | |
< }); | |
< | |
--- | |
> // if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { | |
411a339 | |
> // } | |
423,425c351,368 | |
< if (AccessFactory.getInstance(MainActivity2.this).isLoggedIn() && !TimeOutUtil.getInstance().isTimedOut()) { | |
< return; | |
< } | |
--- | |
> if (!pinEntryActivityLaunched) { | |
> | |
> if (AccessFactory.getInstance(MainActivity2.this).isLoggedIn() && !TimeOutUtil.getInstance().isTimedOut()) { | |
> return; | |
> } | |
> | |
> AccessFactory.getInstance(MainActivity2.this).setIsLoggedIn(false); | |
> final Intent intent = new Intent(MainActivity2.this, PinEntryActivity.class); | |
> if (strUri != null) { | |
> intent.putExtra("uri", strUri); | |
> PrefsUtil.getInstance(MainActivity2.this).setValue("SCHEMED_URI", strUri); | |
> } | |
> if (getBundleExtras() != null) { | |
> intent.putExtras(getBundleExtras()); | |
> } | |
> startActivity(intent); | |
> finish(); | |
> pinEntryActivityLaunched = true; | |
427,434d369 | |
< AccessFactory.getInstance(MainActivity2.this).setIsLoggedIn(false); | |
< final Intent intent = new Intent(MainActivity2.this, PinEntryActivity.class); | |
< if (strUri != null) { | |
< intent.putExtra("uri", strUri); | |
< PrefsUtil.getInstance(MainActivity2.this).setValue("SCHEMED_URI", strUri); | |
< } | |
< if (getBundleExtras() != null) { | |
< intent.putExtras(getBundleExtras()); | |
436,437d370 | |
< startActivity(intent); | |
< finish(); | |
478a412 | |
> | |
486c420 | |
< private void doAppInit0(final boolean isDial, final String strUri) { | |
--- | |
> private void doAppInit0(final boolean isDial, final String strUri, final String strPCode) { | |
491c425 | |
< doAppInit1(isDial, strUri); | |
--- | |
> doAppInit1(isDial, strUri, strPCode); | |
494d427 | |
< | |
509c442 | |
< doAppInit1(isDial, strUri); | |
--- | |
> doAppInit1(isDial, strUri, strPCode); | |
514c447 | |
< doAppInit1(isDial, strUri); | |
--- | |
> doAppInit1(isDial, strUri, strPCode); | |
556c489 | |
< synchronized private void doAppInit1(boolean isDial, final String strUri) { | |
--- | |
> private void doAppInit1(boolean isDial, final String strUri, final String strPCode) { | |
572d504 | |
< | |
575,578c507,511 | |
< boolean walletScanComplete = isWalletScanComplete(); | |
< | |
< if (!walletScanComplete && hasBackUpURI() && !backupAvailable()) { | |
< WalletUtil.saveWallet(this); | |
--- | |
> Intent intent = new Intent(MainActivity2.this, BalanceActivity.class); | |
> intent.putExtra("notifTx", true); | |
> intent.putExtra("fetch", true); | |
> if(strUri != null){ | |
> intent.putExtra("uri", strUri); | |
580,587c513,514 | |
< | |
< if(!walletScanComplete && !AppUtil.getInstance(this).isOfflineMode()) { | |
< startSyncWalletActivity(strUri); | |
< } else { | |
< if (!AppUtil.getInstance(this).isOfflineMode()) { | |
< checkForAppUpdates(); | |
< } | |
< startBalanceActivity(strUri); | |
--- | |
> if (getBundleExtras() != null) { | |
> intent.putExtras(getBundleExtras()); | |
589c516 | |
< | |
--- | |
> startActivity(intent); | |
594,611d520 | |
< } | |
< | |
< private boolean isWalletScanComplete() { | |
< return PrefsUtil.getInstance(this).getValue(PrefsUtil.WALLET_SCAN_COMPLETE, false); | |
< } | |
< | |
< private void startSyncWalletActivity(final String strUri) { | |
< final Intent intent = new Intent(MainActivity2.this, SyncWalletActivity.class); | |
< intent.putExtra("notifTx", true); | |
< intent.putExtra("fetch", true); | |
< if(strUri != null) { | |
< intent.putExtra("uri", strUri); | |
< } | |
< if (getBundleExtras() != null) { | |
< intent.putExtras(getBundleExtras()); | |
< } | |
< startActivity(intent); | |
< } | |
613,623d521 | |
< private void startBalanceActivity(final String strUri) { | |
< final Intent intent = new Intent(MainActivity2.this, BalanceActivity.class); | |
< intent.putExtra("notifTx", true); | |
< intent.putExtra("fetch", true); | |
< if(strUri != null){ | |
< intent.putExtra("uri", strUri); | |
< } | |
< if (getBundleExtras() != null) { | |
< intent.putExtras(getBundleExtras()); | |
< } | |
< startActivity(intent); | |
671c569 | |
< .setTitle("Ashigaru") | |
--- | |
> .setTitle("Samourai") | |
684,732d581 | |
< } | |
< | |
< private void checkForAppUpdates() { | |
< ExecutorService executor = Executors.newSingleThreadExecutor(); | |
< executor.execute(() -> { | |
< try { | |
< String latestVersionMessage = WebUtil.getInstance(null).getURL("http://lbpxfhbnfyhxmy3jl6a4q7dzpeobx7cvkghz2vvwygevq3k4ilo2v5ad.onion/Ashigaru/Ashigaru-Mobile/raw/branch/main/accompanying-release-files/ashigaru_mobile_latest.txt"); | |
< // 1. If the message is signed with Ashigaru's Dev public key | |
< // If it's correct, proceed; otherwise, return and don't check anything else | |
< if (!VerifyPGPSignedClearMessageUtil.verifySignedMessage( | |
< defaultString(latestVersionMessage), | |
< ASHIGARU_PUB_KEY)) | |
< return; | |
< final String releaseNotes = WebUtil.getInstance(null).getURL("http://lbpxfhbnfyhxmy3jl6a4q7dzpeobx7cvkghz2vvwygevq3k4ilo2v5ad.onion/Ashigaru/Ashigaru-Mobile/raw/branch/main/accompanying-release-files/ashigaru_mobile_release_notes.txt"); | |
< | |
< final String releaseNotesSha256 = Util.sha256Hex(defaultString(releaseNotes)); | |
< final String releaseNoteSha256ToVerify = substringBetween(latestVersionMessage, "ashigaru_mobile_release_notes.txt_sha256hash=", "\n"); | |
< if (! StringUtils.equals(releaseNotesSha256, releaseNoteSha256ToVerify)) { | |
< return; | |
< } | |
< | |
< JSONObject releaseNotesJSON = null; | |
< if (isNotBlank(releaseNotes)) { | |
< try { | |
< releaseNotesJSON = new JSONObject(releaseNotes); | |
< } catch (final Exception e) { | |
< Log.e(TAG, e.getMessage(), e); | |
< releaseNotesJSON = null; | |
< } | |
< } | |
< if (releaseNotesJSON == null) { | |
< Log.w(TAG, "releaseNotesJSON is null"); | |
< return; | |
< } | |
< SamouraiWallet.getInstance().releaseNotes = releaseNotesJSON; | |
< | |
< final String latestVersion = strip(stripStart(substringBetween(latestVersionMessage, "latest_ashigaru_mobile_version=", "\n"), "v")); | |
< boolean noNeedToShow = latestVersion.equals(stripStart(BuildConfig.VERSION_NAME, "v")); | |
< runOnUiThread(() -> { | |
< AppUtil.getInstance(this).setHasUpdateBeenShown(noNeedToShow); | |
< }); | |
< | |
< } catch (Exception e) { | |
< e.printStackTrace(); | |
< runOnUiThread(() -> { | |
< System.out.println("Failed to fetch app updated"); | |
< }); | |
< } | |
< }); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/network/dojo/DojoUtil.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/network/dojo/DojoUtil.java | |
8d7 | |
< import com.samourai.wallet.util.PrefsUtil; | |
23d21 | |
< private static String dojoName = "My Dojo"; | |
71,73d68 | |
< public String getDojoName() { | |
< return dojoName; | |
< } | |
76,101c71,95 | |
< return Observable.fromCallable(() -> { | |
< | |
< DojoUtil.dojoParams = dojoParams; | |
< Log.i(TAG, "setDojoParams: ".concat(dojoParams)); | |
< String url = getUrl(dojoParams); | |
< | |
< if(url.charAt(url.length() - 1) != '/') { | |
< url = url + "/"; | |
< | |
< JSONObject obj = new JSONObject(dojoParams); | |
< if(obj.has("pairing") && obj.getJSONObject("pairing").has("url")) { | |
< obj.getJSONObject("pairing").put("url", url); | |
< DojoUtil.dojoParams = obj.toString(); | |
< } | |
< } | |
< | |
< if(SamouraiWallet.getInstance().isTestNet()) { | |
< WebUtil.SAMOURAI_API2_TESTNET_TOR = url; | |
< } else { | |
< WebUtil.SAMOURAI_API2_TOR = url; | |
< } | |
< | |
< String apiToken = getApiKey(dojoParams); | |
< APIFactory.getInstance(context).setAppToken(apiToken); | |
< return APIFactory.getInstance(context).getToken(true, false); | |
< }); | |
--- | |
> return Observable.fromCallable(() -> { | |
> DojoUtil.dojoParams = dojoParams; | |
> Log.i(TAG, "setDojoParams: ".concat(dojoParams)); | |
> String url = getUrl(dojoParams); | |
> if(url.charAt(url.length() - 1) != '/') { | |
> url = url + "/"; | |
> | |
> JSONObject obj = new JSONObject(dojoParams); | |
> if(obj.has("pairing") && obj.getJSONObject("pairing").has("url")) { | |
> obj.getJSONObject("pairing").put("url", url); | |
> DojoUtil.dojoParams = obj.toString(); | |
> } | |
> } | |
> if(SamouraiWallet.getInstance().isTestNet()) { | |
> WebUtil.SAMOURAI_API2_TESTNET_TOR = url; | |
> } | |
> else { | |
> WebUtil.SAMOURAI_API2_TOR = url; | |
> } | |
> | |
> String apiToken = getApiKey(dojoParams); | |
> APIFactory.getInstance(context).setAppToken(apiToken); | |
> boolean tokenRetrieved = APIFactory.getInstance(context).getToken(true, false); | |
> return tokenRetrieved; | |
> }); | |
117,141d110 | |
< public synchronized void setDojoParamsOfflineMode(String dojoParams) throws JSONException { | |
< DojoUtil.dojoParams = dojoParams; | |
< Log.i(TAG, "setDojoParams: ".concat(dojoParams)); | |
< String url = getUrl(dojoParams); | |
< | |
< if(url.charAt(url.length() - 1) != '/') { | |
< url = url + "/"; | |
< | |
< JSONObject obj = new JSONObject(dojoParams); | |
< if(obj.has("pairing") && obj.getJSONObject("pairing").has("url")) { | |
< obj.getJSONObject("pairing").put("url", url); | |
< DojoUtil.dojoParams = obj.toString(); | |
< } | |
< } | |
< | |
< if(SamouraiWallet.getInstance().isTestNet()) { | |
< WebUtil.SAMOURAI_API2_TESTNET_TOR = url; | |
< } else { | |
< WebUtil.SAMOURAI_API2_TOR = url; | |
< } | |
< | |
< String apiToken = getApiKey(dojoParams); | |
< APIFactory.getInstance(context).setAppToken(apiToken); | |
< } | |
< | |
157c126,140 | |
< return isGreaterOrEqualThanVersionOneDot(11); | |
--- | |
> String[] s = dojoVersion.split("\\."); | |
> try { | |
> if(s.length >= 1 && Integer.parseInt(s[0]) > 1) { | |
> return true; | |
> } | |
> else if(s.length >= 2 && Integer.parseInt(s[0]) == 1 && Integer.parseInt(s[1]) >= 11){ | |
> return true; | |
> } | |
> else { | |
> return false; | |
> } | |
> } | |
> catch(NumberFormatException nfe) { | |
> return false; | |
> } | |
168c151,165 | |
< return isGreaterOrEqualThanVersionOneDot(13); | |
--- | |
> String[] s = dojoVersion.split("\\."); | |
> try { | |
> if(s.length >= 1 && Integer.parseInt(s[0]) > 1) { | |
> return true; | |
> } | |
> else if(s.length >= 2 && Integer.parseInt(s[0]) == 1 && Integer.parseInt(s[1]) >= 13){ | |
> return true; | |
> } | |
> else { | |
> return false; | |
> } | |
> } | |
> catch(NumberFormatException nfe) { | |
> return false; | |
> } | |
226a224 | |
> | |
228c226,241 | |
< return isGreaterOrEqualThanVersionOneDot(23); | |
--- | |
> String[] s = dojoVersion.split("\\."); | |
> try { | |
> if(s.length >= 1 && Integer.parseInt(s[0]) > 1) { | |
> return true; | |
> } | |
> else if(s.length >= 2 && Integer.parseInt(s[0]) == 1 && Integer.parseInt(s[1]) >= 23){ | |
> return true; | |
> } | |
> else { | |
> return false; | |
> } | |
> } | |
> catch(NumberFormatException nfe) { | |
> return false; | |
> } | |
> | |
238,247c251 | |
< return isGreaterOrEqualThanVersionOneDot(22); | |
< | |
< } | |
< | |
< public String getVersion(String data) { | |
< | |
< if(!isValidPairingPayload(data)) { | |
< return null; | |
< } | |
< | |
--- | |
> String[] s = dojoVersion.split("\\."); | |
249,251c253,261 | |
< JSONObject obj = new JSONObject(data); | |
< JSONObject pObj = obj.getJSONObject("pairing"); | |
< return pObj.getString("version"); | |
--- | |
> if(s.length >= 1 && Integer.parseInt(s[0]) > 1) { | |
> return true; | |
> } | |
> else if(s.length >= 2 && Integer.parseInt(s[0]) == 1 && Integer.parseInt(s[1]) >= 22){ | |
> return true; | |
> } | |
> else { | |
> return false; | |
> } | |
253,254c263,264 | |
< catch(JSONException je) { | |
< return null; | |
--- | |
> catch(NumberFormatException nfe) { | |
> return false; | |
259c269 | |
< public String getExplorerUrl(String data) { | |
--- | |
> public String getVersion(String data) { | |
267,268c277,278 | |
< JSONObject pObj = obj.getJSONObject("explorer"); | |
< return pObj.getString("url"); | |
--- | |
> JSONObject pObj = obj.getJSONObject("pairing"); | |
> return pObj.getString("version"); | |
317,323d326 | |
< String blockExplorer = PrefsUtil.getInstance(context).getValue(PrefsUtil.BLOCK_EXPLORER_URL, ""); | |
< if (blockExplorer != null && !blockExplorer.isEmpty()) { | |
< JSONObject explorerJSON = new JSONObject(); | |
< explorerJSON.put("type", "explorer.btc_rpc_explorer"); | |
< explorerJSON.put("url", blockExplorer); | |
< obj.put("explorer", explorerJSON); | |
< } | |
342,346c345 | |
< if (SamouraiWallet.getInstance().isTestNet()) { | |
< WebUtil.SAMOURAI_API2_TESTNET_TOR = getUrl(dojoParams); | |
< } else { | |
< WebUtil.SAMOURAI_API2_TOR = getUrl(dojoParams); | |
< } | |
--- | |
> if (dojoParams != null) { | |
348,349c347,351 | |
< String apiToken = getApiKey(dojoParams); | |
< APIFactory.getInstance(context).setAppToken(apiToken); | |
--- | |
> if (SamouraiWallet.getInstance().isTestNet()) { | |
> WebUtil.SAMOURAI_API2_TESTNET_TOR = getUrl(dojoParams); | |
> } else { | |
> WebUtil.SAMOURAI_API2_TOR = getUrl(dojoParams); | |
> } | |
351,352c353,354 | |
< } | |
< } | |
--- | |
> String apiToken = getApiKey(dojoParams); | |
> APIFactory.getInstance(context).setAppToken(apiToken); | |
354,362d355 | |
< private static boolean isGreaterOrEqualThanVersionOneDot(final int middle) { | |
< String[] s = dojoVersion.split("\\."); | |
< try { | |
< if (s.length >= 1 && Integer.parseInt(s[0]) > 1) { | |
< return true; | |
< } else if (s.length >= 2 && Integer.parseInt(s[0]) == 1 && Integer.parseInt(s[1]) >= middle) { | |
< return true; | |
< } else { | |
< return false; | |
364,365c357 | |
< } catch (NumberFormatException nfe) { | |
< return false; | |
--- | |
> | |
366a359 | |
> | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/network/NetworkDashboard.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/network/NetworkDashboard.java | |
29d28 | |
< import com.samourai.wallet.network.dojo.DojoDetailsActivity; | |
31a31 | |
> import com.samourai.wallet.service.WebSocketService; | |
39d38 | |
< import com.samourai.wallet.util.tech.LogUtil; | |
42d40 | |
< | |
45d42 | |
< import io.reactivex.android.schedulers.AndroidSchedulers; | |
47,48d43 | |
< import io.reactivex.disposables.Disposable; | |
< import io.reactivex.schedulers.Schedulers; | |
56c51 | |
< //Button torButton; | |
--- | |
> Button torButton; | |
58,59c53,57 | |
< TextView dojoName; | |
< ImageView dojoDetailsButton; | |
--- | |
> Button dojoBtn; | |
> TextView dataConnectionStatus; | |
> TextView torRenewBtn; | |
> TextView torConnectionStatus; | |
> TextView dojoConnectionStatus; | |
79,80d76 | |
< getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.window)); | |
< getWindow().setNavigationBarColor(ContextCompat.getColor(this, R.color.networking)); | |
90,93c86,92 | |
< dojoName = findViewById(R.id.dojoName); | |
< dojoDetailsButton = findViewById(R.id.dojoRightBtn); | |
< //torButton = findViewById(R.id.networking_tor_btn); | |
< | |
--- | |
> torButton = findViewById(R.id.networking_tor_btn); | |
> dojoBtn = findViewById(R.id.networking_dojo_btn); | |
> torRenewBtn = findViewById(R.id.networking_tor_renew); | |
> | |
> dataConnectionStatus = findViewById(R.id.network_data_status); | |
> torConnectionStatus = findViewById(R.id.network_tor_status); | |
> dojoConnectionStatus = findViewById(R.id.network_dojo_status); | |
107,113c106,109 | |
< if (!PrefsUtil.getInstance(getApplicationContext()).getValue(PrefsUtil.DOJO_NAME, "").isEmpty()) | |
< dojoName.setText(PrefsUtil.getInstance(getApplicationContext()).getValue(PrefsUtil.DOJO_NAME, "")); | |
< | |
< dojoLayout = findViewById(R.id.network_dojo_layout); | |
< | |
< dojoLayout.setOnClickListener(v -> { | |
< startActivity(new Intent(this, DojoDetailsActivity.class)); | |
--- | |
> torRenewBtn.setOnClickListener(view -> { | |
> if (SamouraiTorManager.INSTANCE.isConnected()) { | |
> SamouraiTorManager.newIdentity(); | |
> } | |
115,116d110 | |
< | |
< /* | |
136,137c130 | |
< */ | |
< /* | |
--- | |
> | |
163c156 | |
< */ | |
--- | |
> | |
168a162 | |
> dojoLayout = findViewById(R.id.network_dojo_layout); | |
174c168 | |
< resetApiConfig(); | |
--- | |
> resetAPI(); | |
189,195d182 | |
< @Override | |
< protected void onResume() { | |
< super.onResume(); | |
< if (!PrefsUtil.getInstance(getApplicationContext()).getValue(PrefsUtil.DOJO_NAME, "").isEmpty()) | |
< dojoName.setText(PrefsUtil.getInstance(getApplicationContext()).getValue(PrefsUtil.DOJO_NAME, "")); | |
< } | |
< | |
197c184 | |
< SimpleTaskRunner.create().executeAsyncAndShutdown(() -> { | |
--- | |
> SimpleTaskRunner.create().executeAsync(() -> { | |
257c244 | |
< //if (SamouraiTorManager.INSTANCE.isRequired() && !SamouraiTorManager.INSTANCE.isConnected()) { | |
--- | |
> if (SamouraiTorManager.INSTANCE.isRequired() && !SamouraiTorManager.INSTANCE.isConnected()) { | |
259c246 | |
< //} | |
--- | |
> } | |
266c253 | |
< Snackbar.make(dojoDetailsButton.getRootView(), "No data connection", Snackbar.LENGTH_SHORT).show(); | |
--- | |
> Snackbar.make(torButton.getRootView(), "No data connection", Snackbar.LENGTH_SHORT).show(); | |
289a277 | |
> dataConnectionStatus.setText("Enabled"); | |
293a282 | |
> dataConnectionStatus.setText("Disabled"); | |
303c292 | |
< //dojoBtn.setText("Disable"); | |
--- | |
> dojoBtn.setText("Disable"); | |
304a294 | |
> dojoConnectionStatus.setText("Enabled"); | |
306c296 | |
< //dojoBtn.setText("configure"); | |
--- | |
> dojoBtn.setText("configure"); | |
307a298 | |
> dojoConnectionStatus.setText("Not configured"); | |
309c300 | |
< //dojoBtn.setText("Enable"); | |
--- | |
> dojoBtn.setText("Enable"); | |
310a302 | |
> dojoConnectionStatus.setText("Disabled"); | |
319,320c311,312 | |
< //torButton.setText("Disable"); | |
< //torButton.setEnabled(true); | |
--- | |
> torButton.setText("Disable"); | |
> torButton.setEnabled(true); | |
321a314,315 | |
> torConnectionStatus.setText("Enabled"); | |
> torRenewBtn.setVisibility(View.VISIBLE); | |
324c318,324 | |
< initDojoWithPairingParams(); | |
--- | |
> | |
> if (strPairingParams != null) { | |
> DojoUtil.getInstance(NetworkDashboard.this).setDojoParams(strPairingParams); | |
> Toast.makeText(NetworkDashboard.this, "Tor enabled for Dojo pairing:" + DojoUtil.getInstance(NetworkDashboard.this).getDojoParams(), Toast.LENGTH_SHORT).show(); | |
> initDojo(); | |
> } | |
> | |
328,329c328,330 | |
< // torButton.setText("loading..."); | |
< // torButton.setEnabled(false); | |
--- | |
> torRenewBtn.setVisibility(View.INVISIBLE); | |
> torButton.setText("loading..."); | |
> torButton.setEnabled(false); | |
330a332 | |
> torConnectionStatus.setText("Tor initializing"); | |
332,333c334,336 | |
< // torButton.setText("Enable"); | |
< // torButton.setEnabled(true); | |
--- | |
> torRenewBtn.setVisibility(View.INVISIBLE); | |
> torButton.setText("Enable"); | |
> torButton.setEnabled(true); | |
334a338 | |
> torConnectionStatus.setText("Disabled"); | |
347c351 | |
< Snackbar.make(dojoDetailsButton.getRootView(), R.string.in_offline_mode, Snackbar.LENGTH_LONG) | |
--- | |
> Snackbar.make(torButton.getRootView(), R.string.in_offline_mode, Snackbar.LENGTH_LONG) | |
369,397c373,375 | |
< | |
< | |
< if (! SamouraiTorManager.INSTANCE.isConnected() && | |
< ! SamouraiTorManager.INSTANCE.isStarting()) { | |
< | |
< waitingForPairing = true; | |
< startTor(); | |
< PrefsUtil.getInstance(getApplicationContext()).setValue(PrefsUtil.ENABLE_TOR, true); | |
< } else { | |
< waitingForPairing = false; | |
< initDojoWithPairingParams(); | |
< } | |
< } | |
< | |
< private void initDojoWithPairingParams() { | |
< if (strPairingParams != null) { | |
< final Disposable disposable = DojoUtil.getInstance(NetworkDashboard.this) | |
< .setDojoParams(strPairingParams) | |
< .subscribeOn(Schedulers.io()) | |
< .observeOn(AndroidSchedulers.mainThread()).subscribe((aBoolean) -> { | |
< initDojo(); | |
< Toast.makeText( | |
< NetworkDashboard.this, | |
< "Tor enabled for Dojo pairing:" | |
< + DojoUtil.getInstance(NetworkDashboard.this).getDojoParams(), | |
< Toast.LENGTH_SHORT).show(); | |
< }, throwable -> LogUtil.error(TAG, throwable)); | |
< disposables.add(disposable); | |
< } | |
--- | |
> waitingForPairing = true; | |
> startTor(); | |
> PrefsUtil.getInstance(getApplicationContext()).setValue(PrefsUtil.ENABLE_TOR, true); | |
420,422c398,400 | |
< if (Objects.nonNull(WebUtil.SAMOURAI_API2_TESTNET_TOR)) { | |
< Log.d("NetworkDashboard", WebUtil.SAMOURAI_API2_TESTNET_TOR); | |
< } | |
--- | |
> Log.d("NetworkDashboard", WebUtil.SAMOURAI_API2_TESTNET_TOR); | |
> | |
> resetAPI(); | |
445,468c423,458 | |
< private void resetApiConfig() { | |
< // PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUB44REG, false); | |
< PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUB49REG, false); | |
< PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUB84REG, false); | |
< PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBPREREG, false); | |
< PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBPOSTREG, false); | |
< PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBBADBANKREG, false); | |
< PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBRICOCHETREG, false); | |
< PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUB44LOCK, false); | |
< PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUB49LOCK, false); | |
< PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUB84LOCK, false); | |
< PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBPRELOCK, false); | |
< PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBPOSTLOCK, false); | |
< PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBBADBANKLOCK, false); | |
< PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBRICOCHETLOCK, false); | |
< | |
< DojoUtil.getInstance(NetworkDashboard.this).clear(); | |
< APIFactory.getInstance(NetworkDashboard.this).setAccessToken(null); | |
< APIFactory.getInstance(NetworkDashboard.this).setAppToken(null); | |
< try { | |
< APIFactory.getInstance(NetworkDashboard.this).getToken(true, false); | |
< } catch (Exception e) { | |
< e.printStackTrace(); | |
< } | |
--- | |
> private void resetAPI() { | |
> | |
> new Thread(new Runnable() { | |
> @Override | |
> public void run() { | |
> Looper.prepare(); | |
> | |
> // PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUB44REG, false); | |
> PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUB49REG, false); | |
> PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUB84REG, false); | |
> PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBPREREG, false); | |
> PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBPOSTREG, false); | |
> PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBBADBANKREG, false); | |
> PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBRICOCHETREG, false); | |
> PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUB44LOCK, false); | |
> PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUB49LOCK, false); | |
> PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUB84LOCK, false); | |
> PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBPRELOCK, false); | |
> PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBPOSTLOCK, false); | |
> PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBBADBANKLOCK, false); | |
> PrefsUtil.getInstance(NetworkDashboard.this).setValue(PrefsUtil.XPUBRICOCHETLOCK, false); | |
> | |
> DojoUtil.getInstance(NetworkDashboard.this).clear(); | |
> APIFactory.getInstance(NetworkDashboard.this).setAccessToken(null); | |
> APIFactory.getInstance(NetworkDashboard.this).setAppToken(null); | |
> try { | |
> APIFactory.getInstance(NetworkDashboard.this).getToken(true, false); | |
> } catch (Exception e) { | |
> e.printStackTrace(); | |
> } | |
> | |
> Looper.loop(); | |
> | |
> } | |
> }).start(); | |
> | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard/OnBoardSlidesActivity.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/onboard/OnBoardSlidesActivity.kt | |
28d27 | |
< window.navigationBarColor = ContextCompat.getColor(this, R.color.window); | |
31c30 | |
< startActivity(Intent(this, CreateOrRestoreActivity::class.java)) | |
--- | |
> startActivity(Intent(this, SetUpWalletActivity::class.java)) | |
35c34 | |
< override fun getItemCount(): Int = 3 | |
--- | |
> override fun getItemCount(): Int = 4 | |
44a44 | |
> R.drawable.ic_offline_slider, | |
49a50 | |
> R.string.offline_mode_allows, | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard/RestoreOptionActivity.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/onboard/RestoreOptionActivity.kt | |
213a214,218 | |
> | |
> override fun onCreateOptionsMenu(menu: Menu): Boolean { | |
> menuInflater.inflate(R.menu.landing_activity_menu, menu) | |
> return true | |
> } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard/SetUpWalletActivity.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/onboard/SetUpWalletActivity.kt | |
3,4d2 | |
< import android.content.ClipboardManager | |
< import android.content.Context | |
12d9 | |
< import android.widget.Toast | |
34d30 | |
< import com.samourai.wallet.util.tech.AppUtil | |
154,178c150 | |
< val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager | |
< val string = if (clipboard.hasPrimaryClip()) { | |
< val item = clipboard.primaryClip?.getItemAt(0) | |
< item?.text.toString() | |
< } else { | |
< "" | |
< } | |
< if (DojoUtil.getInstance(applicationContext).isValidPairingPayload(string)) { | |
< binding.jsonDojoTextField.text = string | |
< try { | |
< setUpWalletViewModel.viewModelScope.launch(Dispatchers.Default) { | |
< withContext(Dispatchers.Main) { | |
< setUpWalletViewModel.setDojoParams(string, applicationContext) | |
< } | |
< delay(600) | |
< withContext(Dispatchers.Main) { | |
< connectDojo() | |
< } | |
< } | |
< } catch (e: Exception) { | |
< } | |
< } | |
< else | |
< Toast.makeText(applicationContext, "Clipboard doesn't contain a valid Dojo pairing payload", Toast.LENGTH_LONG).show() | |
< | |
--- | |
> connectDojo() | |
181,191c153,154 | |
< if (DojoUtil.getInstance(this@SetUpWalletActivity).dojoParams != null || AppUtil.getInstance(this@SetUpWalletActivity).isOfflineMode) { | |
< val intent = Intent(this, CreateWalletActivity::class.java) | |
< startActivity(intent) | |
< } | |
< else { | |
< Toast.makeText( | |
< this@SetUpWalletActivity, | |
< "No Dojo credentials. Enter these to create a wallet. Or go offline.", | |
< Toast.LENGTH_LONG | |
< ).show() | |
< } | |
--- | |
> val intent = Intent(this, CreateWalletActivity::class.java) | |
> startActivity(intent) | |
194,204c157,158 | |
< if (DojoUtil.getInstance(this@SetUpWalletActivity).dojoParams != null || AppUtil.getInstance(this@SetUpWalletActivity).isOfflineMode) { | |
< val intent = Intent(this, RestoreOptionActivity::class.java) | |
< startActivity(intent) | |
< } | |
< else { | |
< Toast.makeText( | |
< this@SetUpWalletActivity, | |
< "No Dojo credentials. Enter these to restore a wallet. Or go offline.", | |
< Toast.LENGTH_LONG | |
< ).show() | |
< } | |
--- | |
> val intent = Intent(this, RestoreOptionActivity::class.java) | |
> startActivity(intent) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/onboard/SetUpWalletViewModel.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/onboard/SetUpWalletViewModel.kt | |
11d10 | |
< import com.samourai.wallet.util.network.WebUtil | |
33d31 | |
< private val _explorer = MutableLiveData("") | |
39d36 | |
< val explorer: LiveData<String> get() = _explorer | |
49,52d45 | |
< val explorerPayload = JSONObject(code).getJSONObject("explorer"); | |
< if (explorerPayload.has("url")) { | |
< _explorer.postValue(explorerPayload.getString("url")) | |
< } | |
61,64d53 | |
< } | |
< val dojoExplorer = JSONObject(code).getJSONObject("explorer"); | |
< if (dojoExplorer.has("url")) { | |
< PrefsUtil.getInstance(applicationContext).setValue(PrefsUtil.BLOCK_EXPLORER_URL, dojoExplorer.getString("url")); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/pairing/PairingMenu.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/pairing/PairingMenu.kt | |
27d26 | |
< window.statusBarColor = resources.getColor(R.color.grey_accent) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/payload/ExternalBackupManager.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/payload/ExternalBackupManager.kt | |
39c39 | |
< private const val strBackupFilename = "ashigaru.txt" | |
--- | |
> private const val strBackupFilename = "samourai.txt" | |
87c87,90 | |
< }.setCancelable(false).show() | |
--- | |
> }.setNegativeButton(R.string.cancel) { dialog, _ -> | |
> dialog.dismiss() | |
> Toast.makeText(appContext, "Read and write permissions are needed to save backup file", Toast.LENGTH_LONG).show() | |
> }.show() | |
245,249d247 | |
< } | |
< | |
< @JvmStatic | |
< fun hasBackUpURI(): Boolean { | |
< return getBackUpURI() != null; | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/payload/PayloadUtil.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/payload/PayloadUtil.java | |
3,4d2 | |
< import static com.samourai.wallet.send.SendActivity.SPEND_BOLTZMANN; | |
< | |
12d9 | |
< import com.samourai.wallet.BuildConfig; | |
20d16 | |
< import com.samourai.wallet.constants.WALLET_INDEX; | |
24a21 | |
> import com.samourai.wallet.constants.WALLET_INDEX; | |
32a30,32 | |
> import com.samourai.wallet.util.func.AddressFactory; | |
> import com.samourai.wallet.util.tech.AppUtil; | |
> import com.samourai.wallet.util.func.BatchSendUtil; | |
36,37c36 | |
< import com.samourai.wallet.util.func.AddressFactory; | |
< import com.samourai.wallet.util.func.BatchSendUtil; | |
--- | |
> import com.samourai.wallet.util.network.SIMUtil; | |
40,41d38 | |
< import com.samourai.wallet.util.network.SIMUtil; | |
< import com.samourai.wallet.util.tech.AppUtil; | |
73a71,72 | |
> import static com.samourai.wallet.send.SendActivity.SPEND_BOLTZMANN; | |
> | |
82c81 | |
< private final static String strPayNymFilename = "ashigaru.paynyms"; | |
--- | |
> private final static String strPayNymFilename = "samourai.paynyms"; | |
84c83 | |
< private final static String strOptionalFilename = "ashigaru.rs.txt"; | |
--- | |
> private final static String strOptionalFilename = "samourai.support.txt"; | |
227c226 | |
< final JSONObject wallet = new JSONObject(); | |
--- | |
> JSONObject wallet = new JSONObject(); | |
231,235c230,232 | |
< final HD_Wallet hdWallet = HD_WalletFactory.getInstance(context).get(); | |
< if (hdWallet != null) { | |
< if(hdWallet.getSeedHex() != null) { | |
< wallet.put("seed", hdWallet.getSeedHex()); | |
< wallet.put("passphrase", hdWallet.getPassphrase()); | |
--- | |
> if(HD_WalletFactory.getInstance(context).get().getSeedHex() != null) { | |
> wallet.put("seed", HD_WalletFactory.getInstance(context).get().getSeedHex()); | |
> wallet.put("passphrase", HD_WalletFactory.getInstance(context).get().getPassphrase()); | |
237,241c234 | |
< wallet.put("fingerprint", Hex.toHexString(HD_WalletFactory.getInstance(context).getFingerprint())); | |
< } | |
< final JSONArray accts = new JSONArray(); | |
< accts.put(hdWallet.getAccount(0).toJSON(44)); | |
< wallet.put("accounts", accts); | |
--- | |
> wallet.put("fingerprint", Hex.toHexString(HD_WalletFactory.getInstance(context).getFingerprint())); | |
243a237,239 | |
> JSONArray accts = new JSONArray(); | |
> accts.put(HD_WalletFactory.getInstance(context).get().getAccount(0).toJSON(44)); | |
> wallet.put("accounts", accts); | |
289c285 | |
< meta.put("version_name", BuildConfig.VERSION_NAME); | |
--- | |
> meta.put("version_name", context.getText(R.string.version_name)); | |
350,353d345 | |
< meta.put("explorer_url", PrefsUtil.getInstance(context).getValue(PrefsUtil.BLOCK_EXPLORER_URL, "")); | |
< if (PrefsUtil.getInstance(context).getValue(PrefsUtil.WALLET_SCAN_COMPLETE, false)) { | |
< meta.put("wallet_scan_complete", true); | |
< } | |
431,434c423 | |
< synchronized public HD_Wallet restoreWalletfromJSON( | |
< final JSONObject obj, | |
< final boolean skipDojo | |
< ) throws DecoderException, MnemonicException.MnemonicLengthException { | |
--- | |
> synchronized public HD_Wallet restoreWalletfromJSON(JSONObject obj,boolean skipDojo) throws DecoderException, MnemonicException.MnemonicLengthException { | |
468c457,458 | |
< if (wallet.has("testnet")) { | |
--- | |
> | |
> if(wallet.has("testnet")) { | |
471c461,462 | |
< } else { | |
--- | |
> } | |
> else { | |
475,482d465 | |
< } | |
< | |
< if (meta != null) { | |
< // dojo should be set before set hdwallet which will start webservice | |
< if(!skipDojo && meta.has("dojo")) { | |
< DojoUtil.getInstance(context).fromJSON(meta.getJSONObject("dojo")); | |
< } | |
< } | |
484d466 | |
< if(wallet != null) { | |
501a484 | |
> | |
695a679,682 | |
> if(!skipDojo) | |
> if (meta.has("dojo")) { | |
> DojoUtil.getInstance(context).fromJSON(meta.getJSONObject("dojo")); | |
> } | |
708,713d694 | |
< if (meta.has("explorer_url") && PrefsUtil.getInstance(context).getValue(PrefsUtil.BLOCK_EXPLORER_URL, "").isEmpty()) { | |
< PrefsUtil.getInstance(context).setValue(PrefsUtil.BLOCK_EXPLORER_URL, meta.getString("explorer_url")); | |
< } | |
< if (meta.has("wallet_scan_complete")) { | |
< PrefsUtil.getInstance(context).setValue(PrefsUtil.WALLET_SCAN_COMPLETE, meta.getBoolean("wallet_scan_complete")); | |
< } | |
1042,1054c1023,1033 | |
< final List<String> pcodes = Lists.newArrayList(); | |
< try { | |
< String backupData = ExternalBackupManager.read(); | |
< if (backupData != null) { | |
< try { | |
< String passphrase = HD_WalletFactory.getInstance(context).get().getPassphrase(); | |
< String decrypted = getDecryptedBackupPayload(backupData, new CharSequenceX(passphrase)); | |
< JSONObject json = new JSONObject(decrypted); | |
< JSONArray pCodes = json.getJSONObject("meta").getJSONObject("bip47").getJSONArray("pcodes"); | |
< for (int i = 0; i < pCodes.length(); i++) { | |
< if (pCodes.getJSONObject(i).has("following")) { | |
< pcodes.add(String.valueOf(pCodes.getJSONObject(i).get("payment_code"))); | |
< } | |
--- | |
> String backupData = ExternalBackupManager.read(); | |
> List<String> pcodes = Lists.newArrayList(); | |
> if (backupData != null) { | |
> try { | |
> String passphrase = HD_WalletFactory.getInstance(context).get().getPassphrase(); | |
> String decrypted = getDecryptedBackupPayload(backupData, new CharSequenceX(passphrase)); | |
> JSONObject json = new JSONObject(decrypted); | |
> JSONArray pCodes = json.getJSONObject("meta").getJSONObject("bip47").getJSONArray("pcodes"); | |
> for (int i = 0; i < pCodes.length(); i++) { | |
> if (pCodes.getJSONObject(i).has("following")) { | |
> pcodes.add(String.valueOf(pCodes.getJSONObject(i).get("payment_code"))); | |
1056,1057d1034 | |
< } catch (Exception e) { | |
< System.out.println("Something went wrong: " + e); | |
1058a1036,1037 | |
> } catch (Exception e) { | |
> System.out.println("Something went wrong: "+ e); | |
1060,1061d1038 | |
< } catch (final Exception e1) { | |
< System.out.println("No backup file found for Paynyms: "+ e1); | |
1063d1039 | |
< | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/addPaynym/AddPaynymActivity.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/addPaynym/AddPaynymActivity.java | |
56d55 | |
< getWindow().setStatusBarColor(getResources().getColor(R.color.grey_accent)); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/api/PayNymApiService.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/api/PayNymApiService.kt | |
4c4,5 | |
< import android.util.Log | |
--- | |
> import com.samourai.wallet.access.AccessFactory | |
> import com.samourai.wallet.api.APIFactory | |
5a7 | |
> import com.samourai.wallet.bip47.BIP47Meta | |
7c9,13 | |
< import com.samourai.wallet.sync.SyncWalletModel | |
--- | |
> import com.samourai.wallet.bip47.rpc.NotSecp256k1Exception | |
> import com.samourai.wallet.bip47.rpc.PaymentCode | |
> import com.samourai.wallet.crypto.DecryptionException | |
> import com.samourai.wallet.payload.PayloadUtil | |
> import com.samourai.wallet.util.CharSequenceX | |
9d14 | |
< import com.samourai.wallet.util.func.synPayNym | |
11,14c16 | |
< import okhttp3.HttpUrl | |
< import okhttp3.OkHttpClient | |
< import okhttp3.Request | |
< import okhttp3.RequestBody | |
--- | |
> import okhttp3.* | |
16c18,19 | |
< import okhttp3.Response | |
--- | |
> import org.bitcoinj.crypto.MnemonicException | |
> import org.json.JSONException | |
18a22,25 | |
> import java.security.InvalidKeyException | |
> import java.security.NoSuchAlgorithmException | |
> import java.security.NoSuchProviderException | |
> import java.security.spec.InvalidKeySpecException | |
27,28d33 | |
< private val TAG = PayNymApiService::class.java.simpleName | |
< | |
181c186 | |
< suspend fun unfollow(pcode: String): Response { | |
--- | |
> public suspend fun unfollow(pcode: String): Response { | |
199,207d203 | |
< fun syncPcode(pcode: String): Boolean { | |
< try { | |
< synPayNym(pcode, context) | |
< return true | |
< } catch (ex: Exception) { | |
< Log.e(TAG, "Exception on synPayNym") | |
< } | |
< return false | |
< } | |
209c205 | |
< suspend fun retrievePayNymConnections(): Boolean { | |
--- | |
> fun syncPcode(pcode: String) { | |
211c207,259 | |
< return SyncWalletModel.retrievePayNymConnections(context) | |
--- | |
> val payment_code = PaymentCode(pcode) | |
> var idx = 0 | |
> var loop = true | |
> val addrs = ArrayList<String>() | |
> while (loop) { | |
> addrs.clear() | |
> for (i in idx until idx + 20) { | |
> // Log.i("BIP47Activity", "sync receive from " + i + ":" + BIP47Util.getInstance(BIP47Activity.this).getReceivePubKey(payment_code, i)); | |
> BIP47Meta.getInstance().idx4AddrLookup[BIP47Util.getInstance(context).getReceivePubKey(payment_code, i)] = i | |
> BIP47Meta.getInstance().pCode4AddrLookup[BIP47Util.getInstance(context).getReceivePubKey(payment_code, i)] = payment_code.toString() | |
> addrs.add(BIP47Util.getInstance(context).getReceivePubKey(payment_code, i)) | |
> // Log.i("BIP47Activity", "p2pkh " + i + ":" + BIP47Util.getInstance(BIP47Activity.this).getReceiveAddress(payment_code, i).getReceiveECKey().toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString()); | |
> } | |
> val s = addrs.toTypedArray() | |
> val nb = APIFactory.getInstance(context).syncBIP47Incoming(s) | |
> // Log.i("BIP47Activity", "sync receive idx:" + idx + ", nb == " + nb); | |
> if (nb == 0) { | |
> loop = false | |
> } | |
> idx += 20 | |
> } | |
> idx = 0 | |
> loop = true | |
> BIP47Meta.getInstance().setOutgoingIdx(pcode, 0) | |
> while (loop) { | |
> addrs.clear() | |
> for (i in idx until idx + 20) { | |
> val sendAddress = BIP47Util.getInstance(context).getSendAddress(payment_code, i) | |
> // Log.i("BIP47Activity", "sync send to " + i + ":" + sendAddress.getSendECKey().toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString()); | |
> // BIP47Meta.getInstance().setOutgoingIdx(payment_code.toString(), i); | |
> BIP47Meta.getInstance().idx4AddrLookup[BIP47Util.getInstance(context).getSendPubKey(payment_code, i)] = i | |
> BIP47Meta.getInstance().pCode4AddrLookup[BIP47Util.getInstance(context).getSendPubKey(payment_code, i)] = payment_code.toString() | |
> addrs.add(BIP47Util.getInstance(context).getSendPubKey(payment_code, i)) | |
> } | |
> val s = addrs.toTypedArray() | |
> val nb = APIFactory.getInstance(context).syncBIP47Outgoing(s) | |
> // Log.i("BIP47Activity", "sync send idx:" + idx + ", nb == " + nb); | |
> if (nb == 0) { | |
> loop = false | |
> } | |
> idx += 20 | |
> } | |
> BIP47Meta.getInstance().pruneIncoming() | |
> PayloadUtil.getInstance(context.applicationContext).saveWalletToJSON(CharSequenceX(AccessFactory.getInstance(context.applicationContext).guid + AccessFactory.getInstance(context.applicationContext).pin)) | |
> } catch (ioe: IOException) { | |
> } catch (je: JSONException) { | |
> } catch (de: DecryptionException) { | |
> } catch (nse: NotSecp256k1Exception) { | |
> } catch (ikse: InvalidKeySpecException) { | |
> } catch (ike: InvalidKeyException) { | |
> } catch (nsae: NoSuchAlgorithmException) { | |
> } catch (nspe: NoSuchProviderException) { | |
> } catch (mle: MnemonicException.MnemonicLengthException) { | |
213d260 | |
< Log.e(TAG, "Exception on synPayNym") | |
215d261 | |
< return false | |
225c271 | |
< const val PAYNYM_API = "https://paynym.rs/"; | |
--- | |
> const val PAYNYM_API = "https://paynym.is/"; | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/fragments/EditPaynymBottomSheet.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/fragments/EditPaynymBottomSheet.java | |
28c28 | |
< private TextInputEditText labelEdt; | |
--- | |
> private TextInputEditText labelEdt, pcodeEdt; | |
30d29 | |
< private MaterialButton removeNickBtn; | |
47a47 | |
> pcodeEdt = view.findViewById(R.id.paynym_pcode); | |
49d48 | |
< removeNickBtn = view.findViewById(R.id.remove_nickname_button); | |
51a51 | |
> pcodeEdt.setText(pcode); | |
53,55d52 | |
< removeNickBtn.setText("Delete nickname and save"); | |
< if (getArguments().getString("nymName").equals(label)) | |
< removeNickBtn.setVisibility(View.GONE); | |
62,69d58 | |
< | |
< removeNickBtn.setOnClickListener(button -> { | |
< labelEdt.setText(getArguments().getString("nymName")); | |
< this.dismiss(); | |
< if (onClickListener != null) { | |
< onClickListener.onClick(button); | |
< } | |
< }); | |
73,75d61 | |
< public String getPcode() { | |
< return pcode; | |
< } | |
78a65,68 | |
> } | |
> | |
> public String getPcode() { | |
> return pcodeEdt.getText().toString(); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/fragments/PaynymListFragment.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/fragments/PaynymListFragment.java | |
3,5d2 | |
< import static android.view.View.GONE; | |
< import static java.lang.String.format; | |
< | |
30,31d26 | |
< import org.apache.commons.lang3.StringUtils; | |
< | |
105c100 | |
< | |
--- | |
> final String strPaymentCode = pcodes.get(position); | |
109d103 | |
< final TextView paynymLabel = holder.paynymLabel; | |
111,116c105,139 | |
< final String strPaymentCode = pcodes.get(position); | |
< if (strPaymentCode == null) { | |
< paynymCode.setText(""); | |
< paynymLabel.setText(""); | |
< avatar.setImageResource(R.drawable.paynym); | |
< return; | |
--- | |
> try { | |
> Picasso.get().load(WebUtil.PAYNYM_API + strPaymentCode + "/avatar") | |
> .into(avatar, new Callback() { | |
> @Override | |
> public void onSuccess() { | |
> paynymCode.setText(BIP47Meta.getInstance().getDisplayLabel(strPaymentCode)); | |
> itemView.setOnClickListener(view -> onPayNymItemClick(strPaymentCode, avatar, true)); | |
> } | |
> | |
> @Override | |
> public void onError(Exception e) { | |
> | |
> Picasso.get().load(WebUtil.PAYNYM_API + "preview/" + strPaymentCode) | |
> .into(avatar, new Callback() { | |
> @Override | |
> public void onSuccess() { | |
> paynymCode.setText(BIP47Meta.getInstance().getDisplayLabel(strPaymentCode)); | |
> itemView.setOnClickListener(view -> onPayNymItemClick(strPaymentCode, avatar, false)); | |
> } | |
> | |
> @Override | |
> public void onError(final Exception e) { | |
> Log.e(TAG, "issue when loading avatar for " + strPaymentCode, e); | |
> } | |
> }); | |
> } | |
> }); | |
> } catch (final Throwable t) { | |
> /** | |
> * This catch block is useful if ever the onSuccess/onError callback system | |
> * throws a runtime exception. | |
> * It indicates a problem to be fixed, so we log in error. | |
> * This has already been the case through the method LogUtil#error. | |
> */ | |
> Log.e(TAG, "error with Picasso: " + t.getMessage(), t); | |
118,121d140 | |
< | |
< setPayNymLabels(strPaymentCode, paynymCode, paynymLabel); | |
< setPayNymLogos(strPaymentCode, avatar, itemView); | |
< | |
139d157 | |
< TextView paynymLabel; | |
145d162 | |
< paynymLabel = itemView.findViewById(R.id.paynym_label); | |
148,227d164 | |
< } | |
< | |
< private static void setPayNymLabels( | |
< final String strPaymentCode, | |
< final TextView paynymCode, | |
< final TextView paynymLabel) { | |
< | |
< if (!StringUtils.equals( | |
< BIP47Meta.getInstance().getName(strPaymentCode), | |
< BIP47Meta.getInstance().getDisplayLabel(strPaymentCode))) { | |
< | |
< paynymCode.setText(BIP47Meta.getInstance().getName(strPaymentCode)); | |
< paynymLabel.setText(BIP47Meta.getInstance().getDisplayLabel(strPaymentCode)); | |
< paynymLabel.setVisibility(View.VISIBLE); | |
< } else { | |
< paynymCode.setText(BIP47Meta.getInstance().getName(strPaymentCode)); | |
< paynymLabel.setText(""); | |
< paynymLabel.setVisibility(GONE); | |
< } | |
< } | |
< | |
< private void setPayNymLogos(String strPaymentCode, CircleImageView avatar, View itemView) { | |
< try { | |
< Picasso.get().load(WebUtil.PAYNYM_API + strPaymentCode + "/avatar") | |
< .into(avatar, createPicassoCallback(itemView, strPaymentCode, avatar)); | |
< } catch (final Throwable t) { | |
< /** | |
< * This catch block is useful if ever the onSuccess/onError callback system | |
< * throws a runtime exception. | |
< * It indicates a problem to be fixed, so we log in error. | |
< * This has already been the case through the method LogUtil#error. | |
< */ | |
< Log.e(TAG, format("Throwable with Picasso on /avatar %s : %s", strPaymentCode, t.getMessage()), t); | |
< avatar.setImageResource(R.drawable.paynym); | |
< itemView.setOnClickListener(view -> onPayNymItemClick(strPaymentCode, avatar, false)); | |
< } | |
< } | |
< | |
< @NonNull | |
< private Callback createPicassoCallback( | |
< final View itemView, | |
< final String strPaymentCode, | |
< final CircleImageView avatar) { | |
< return new Callback() { | |
< @Override | |
< public void onSuccess() { | |
< itemView.setOnClickListener(view -> onPayNymItemClick(strPaymentCode, avatar, true)); | |
< } | |
< | |
< @Override | |
< public void onError(Exception e) { | |
< | |
< try { | |
< Picasso.get().load(WebUtil.PAYNYM_API + "preview/" + strPaymentCode) | |
< .into(avatar, new Callback() { | |
< @Override | |
< public void onSuccess() { | |
< itemView.setOnClickListener(view -> onPayNymItemClick(strPaymentCode, avatar, false)); | |
< } | |
< | |
< @Override | |
< public void onError(final Exception e) { | |
< Log.e(TAG, "issue when loading avatar for " + strPaymentCode, e); | |
< avatar.setImageResource(R.drawable.paynym); | |
< itemView.setOnClickListener(view -> onPayNymItemClick(strPaymentCode, avatar, false)); | |
< } | |
< }); | |
< } catch (final Throwable t) { | |
< /** | |
< * This catch block is useful if ever the onSuccess/onError callback system | |
< * throws a runtime exception. | |
< * It indicates a problem to be fixed, so we log in error. | |
< * This has already been the case through the method LogUtil#error. | |
< */ | |
< Log.e(TAG, format("Throwable with Picasso on /preview %s : %s", strPaymentCode, t.getMessage()), t); | |
< avatar.setImageResource(R.drawable.paynym); | |
< itemView.setOnClickListener(view -> onPayNymItemClick(strPaymentCode, avatar, false)); | |
< } | |
< } | |
< }; | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/paynymDetails/PayNymDetailsActivity.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/paynymDetails/PayNymDetailsActivity.kt | |
6a7 | |
> import android.net.Uri | |
7a9 | |
> import android.os.Looper | |
28d29 | |
< import com.samourai.wallet.SamouraiWalletConst | |
59a61 | |
> import com.samourai.wallet.tor.SamouraiTorManager | |
65a68 | |
> import com.samourai.wallet.util.func.RBFFactory.updateRBFSpendForBroadcastTxAndRegister | |
69a73,74 | |
> import com.samourai.wallet.xmanagerClient.XManagerClient | |
> import com.samourai.xmanager.protocol.XManagerService | |
79d83 | |
< import kotlinx.coroutines.async | |
81,83d84 | |
< import kotlinx.coroutines.runBlocking | |
< import kotlinx.coroutines.withContext | |
< import org.apache.commons.lang3.StringUtils.isNotBlank | |
122d122 | |
< window.statusBarColor = resources.getColor(R.color.grey_accent) | |
168,189d167 | |
< if (isNotBlank(pcode) && !BIP47Meta.getInstance().isFollowing(pcode)) { | |
< val disposable = Observable.fromCallable<Boolean> { | |
< | |
< runBlocking { | |
< withContext(Dispatchers.IO) { | |
< async { | |
< payNymViewModel.doFollow(pcode!!) | |
< }.await() | |
< async { | |
< payNymViewModel.getPayNymData() | |
< }.await() | |
< } | |
< } | |
< true | |
< }.subscribeOn(Schedulers.io()) | |
< .observeOn(AndroidSchedulers.mainThread()) | |
< .subscribe { status: Boolean -> | |
< Log.i(TAG, "auto follow an already connected PayNym") | |
< } | |
< disposables.add(disposable) | |
< return | |
< } | |
211c189 | |
< binding.txtviewPaynym.text = getName() | |
--- | |
> title = getLabel() | |
350,369c328 | |
< pcode?.let { | |
< | |
< val disposable = Observable.fromCallable<Boolean> { | |
< | |
< runBlocking { | |
< withContext(Dispatchers.IO) { | |
< async { | |
< payNymViewModel.doFollow(it) | |
< }.await() | |
< } | |
< } | |
< true | |
< }.subscribeOn(Schedulers.io()) | |
< .observeOn(AndroidSchedulers.mainThread()) | |
< .subscribe { status: Boolean -> | |
< Log.i(TAG, "follow a PayNym") | |
< } | |
< disposables.add(disposable) | |
< | |
< } | |
--- | |
> pcode?.let { payNymViewModel.doFollow(it) }; | |
382,387d340 | |
< private fun getName(): String { | |
< if (pcode == BIP47Meta.strSamouraiDonationPCode && SamouraiWallet.getInstance().isTestNet) return "+ashigarutest" | |
< if (pcode == BIP47Meta.strSamouraiDonationPCode && !SamouraiWallet.getInstance().isTestNet) return "+ashigaru" | |
< return BIP47Meta.getInstance().getName(pcode) | |
< } | |
< | |
449c402 | |
< Snackbar.make(findViewById(android.R.id.content), "Follow transaction is still pending", Snackbar.LENGTH_SHORT).show() | |
--- | |
> Snackbar.make(binding.historyLayout.rootView, "Follow transaction is still pending", Snackbar.LENGTH_SHORT).show() | |
456d408 | |
< bundle.putString("nymName", getName()) | |
510c462 | |
< Snackbar.make(findViewById(android.R.id.content), R.string.invalid_payment_code, Snackbar.LENGTH_SHORT).show() | |
--- | |
> Snackbar.make(binding.userAvatar.rootView, R.string.invalid_payment_code, Snackbar.LENGTH_SHORT).show() | |
512c464 | |
< Snackbar.make(findViewById(android.R.id.content), R.string.bip47_no_label_error, Snackbar.LENGTH_SHORT).show() | |
--- | |
> Snackbar.make(binding.userAvatar.rootView, R.string.bip47_no_label_error, Snackbar.LENGTH_SHORT).show() | |
515c467,468 | |
< scope.launch(Dispatchers.IO) { | |
--- | |
> Thread { | |
> Looper.prepare() | |
535a489 | |
> } finally { | |
537,540c491,493 | |
< scope.launch(Dispatchers.Main) { | |
< doUpdatePayNymInfo(pcode) | |
< } | |
< } | |
--- | |
> Looper.loop() | |
> doUpdatePayNymInfo(pcode) | |
> }.start() | |
560a514 | |
> | |
564,571c518,538 | |
< try { | |
< doNotifyTxAsync() | |
< } catch (t : Throwable) { | |
< manageException(t) | |
< } | |
< } | |
< return | |
< } | |
--- | |
> val httpClient: IHttpClient = AndroidHttpClient(com.samourai.wallet.util.network.WebUtil.getInstance(applicationContext)) | |
> val xManagerClient = XManagerClient(httpClient, SamouraiWallet.getInstance().isTestNet, SamouraiTorManager.isConnected()) | |
> val address = xManagerClient.getAddressOrDefault(XManagerService.BIP47) | |
> SendNotifTxFactory.getInstance().setAddress(address) | |
> // | |
> // get wallet balance | |
> // | |
> var balance = 0L | |
> balance = try { | |
> APIFactory.getInstance(this@PayNymDetailsActivity).xpubAmounts[HD_WalletFactory.getInstance(this@PayNymDetailsActivity).get().getAccount(0).xpubstr()]!! | |
> } catch (npe: NullPointerException) { | |
> 0L | |
> } | |
> val selectedUTXO: MutableList<UTXO?> = ArrayList() | |
> var totalValueSelected = 0L | |
> // long change = 0L; | |
> var fee: BigInteger? = null | |
> // | |
> // spend dust threshold amount to notification address | |
> // | |
> var amount = SendNotifTxFactory._bNotifTxValue.toLong() | |
573c540,543 | |
< private fun doNotifyTxAsync() { | |
--- | |
> // | |
> // add Samourai Wallet fee to total amount | |
> // | |
> amount += SendNotifTxFactory._bSWFee.toLong() | |
575,596c545,554 | |
< val selectedUTXO: MutableList<UTXO?> = ArrayList() | |
< var totalValueSelected = 0L | |
< val fee: BigInteger? | |
< | |
< // spend dust threshold amount to notification address | |
< val amount = SendNotifTxFactory._bNotifTxValue.toLong() | |
< | |
< // add Ashigaru fee to total amount | |
< //amount += SendNotifTxFactory._bSWFee.toLong() | |
< | |
< // get unspents | |
< var utxos: MutableList<UTXO?>? | |
< if (UTXOFactory.getInstance().totalP2SH_P2WPKH > amount + FeeUtil.getInstance() | |
< .estimatedFeeSegwit(0, 1, 0, 4).toLong() | |
< ) { | |
< utxos = ArrayList() | |
< utxos.addAll( | |
< APIFactory.getInstance(this@PayNymDetailsActivity).getUtxosP2SH_P2WPKH(true) | |
< ) | |
< } else { | |
< utxos = APIFactory.getInstance(this@PayNymDetailsActivity).getUtxos(true) | |
< } | |
--- | |
> // | |
> // get unspents | |
> // | |
> var utxos: MutableList<UTXO?>? = null | |
> if (UTXOFactory.getInstance().totalP2SH_P2WPKH > amount + FeeUtil.getInstance().estimatedFeeSegwit(0, 1, 0, 4).toLong()) { | |
> utxos = ArrayList() | |
> utxos.addAll(APIFactory.getInstance(this@PayNymDetailsActivity).getUtxosP2SH_P2WPKH(true)) | |
> } else { | |
> utxos = APIFactory.getInstance(this@PayNymDetailsActivity).getUtxos(true) | |
> } | |
598,601c556,559 | |
< // sort in ascending order by value | |
< val _utxos: List<UTXO?>? = utxos | |
< Collections.sort(_utxos, UTXOComparator()) | |
< Collections.reverse(_utxos) | |
--- | |
> // sort in ascending order by value | |
> val _utxos: List<UTXO?>? = utxos | |
> Collections.sort(_utxos, UTXOComparator()) | |
> Collections.reverse(_utxos) | |
603,607c561,566 | |
< // get smallest 1 UTXO > than spend + fee + sw fee + dust | |
< for (u in _utxos!!) { | |
< if (u!!.value >= amount + SamouraiWallet.bDust.toLong() + FeeUtil.getInstance() | |
< .estimatedFee(1, 4).toLong() | |
< ) { | |
--- | |
> // | |
> // get smallest 1 UTXO > than spend + fee + sw fee + dust | |
> // | |
> for (u in _utxos!!) { | |
> if (u!!.value >= amount + SamouraiWallet.bDust.toLong() + FeeUtil.getInstance() | |
> .estimatedFee(1, 4).toLong()) { | |
609,614c568,574 | |
< selectedUTXO.add(u) | |
< totalValueSelected += u.value | |
< Log.d("PayNymDetailsActivity", "value selected:" + u.value) | |
< Log.d("PayNymDetailsActivity", "total value selected:$totalValueSelected") | |
< Log.d("PayNymDetailsActivity", "nb inputs:" + u.outpoints.size) | |
< break | |
--- | |
> selectedUTXO.add(u) | |
> totalValueSelected += u.value | |
> Log.d("PayNymDetailsActivity", "value selected:" + u.value) | |
> Log.d("PayNymDetailsActivity", "total value selected:$totalValueSelected") | |
> Log.d("PayNymDetailsActivity", "nb inputs:" + u.outpoints.size) | |
> break | |
> } | |
616d575 | |
< } | |
618,620c577,581 | |
< val outputCountForFeeEstimation = | |
< if (FeeUtil.getInstance().feeRepresentation === EnumFeeRepresentation.BLOCK_COUNT) 6 | |
< else 3 | |
--- | |
> val keepCurrentSuggestedFee = FeeUtil.getInstance().suggestedFee | |
> try { | |
> if (FeeUtil.getInstance().feeRepresentation === EnumFeeRepresentation.NEXT_BLOCK_RATE) { | |
> FeeUtil.getInstance().suggestedFee = FeeUtil.getInstance().highFee | |
> } else { | |
622,626c583,595 | |
< val keepCurrentSuggestedFee = FeeUtil.getInstance().suggestedFee | |
< try { | |
< if (FeeUtil.getInstance().feeRepresentation === EnumFeeRepresentation.NEXT_BLOCK_RATE) { | |
< FeeUtil.getInstance().suggestedFee = FeeUtil.getInstance().highFee | |
< } else { | |
--- | |
> val lo = FeeUtil.getInstance().lowFee.defaultPerKB.toLong() / 1000L | |
> val mi = FeeUtil.getInstance().normalFee.defaultPerKB.toLong() / 1000L | |
> val hi = FeeUtil.getInstance().highFee.defaultPerKB.toLong() / 1000L | |
> if (lo == mi && mi == hi) { | |
> val hi_sf = SuggestedFee() | |
> hi_sf.defaultPerKB = BigInteger.valueOf((hi * 1000.0 * 1.15).toLong()) | |
> FeeUtil.getInstance().suggestedFee = hi_sf | |
> } else if (lo == mi) { | |
> FeeUtil.getInstance().suggestedFee = FeeUtil.getInstance().highFee | |
> } else { | |
> FeeUtil.getInstance().suggestedFee = FeeUtil.getInstance().normalFee | |
> } | |
> } | |
628,636c597,616 | |
< val lo = FeeUtil.getInstance().lowFee.defaultPerKB.toLong() / 1000L | |
< val mi = FeeUtil.getInstance().normalFee.defaultPerKB.toLong() / 1000L | |
< val hi = FeeUtil.getInstance().highFee.defaultPerKB.toLong() / 1000L | |
< if (lo == mi && mi == hi) { | |
< val hi_sf = SuggestedFee() | |
< hi_sf.defaultPerKB = BigInteger.valueOf((hi * 1000.0 * 1.15).toLong()) | |
< FeeUtil.getInstance().suggestedFee = hi_sf | |
< } else if (lo == mi) { | |
< FeeUtil.getInstance().suggestedFee = FeeUtil.getInstance().highFee | |
--- | |
> | |
> if (selectedUTXO.size == 0) { | |
> // sort in descending order by value | |
> Collections.sort(_utxos, UTXOComparator()) | |
> var selected = 0 | |
> | |
> // get largest UTXOs > than spend + fee + dust | |
> for (u in _utxos) { | |
> selectedUTXO.add(u) | |
> totalValueSelected += u!!.value | |
> selected += u.outpoints.size | |
> if (totalValueSelected >= amount + SamouraiWallet.bDust.toLong() + FeeUtil.getInstance().estimatedFee(selected, 4).toLong()) { | |
> Log.d("PayNymDetailsActivity", "multiple outputs") | |
> Log.d("PayNymDetailsActivity", "total value selected:$totalValueSelected") | |
> Log.d("PayNymDetailsActivity", "nb inputs:" + u.outpoints.size) | |
> break | |
> } | |
> } | |
> | |
> fee = FeeUtil.getInstance().estimatedFee(selected, 7) | |
638c618 | |
< FeeUtil.getInstance().suggestedFee = FeeUtil.getInstance().normalFee | |
--- | |
> fee = FeeUtil.getInstance().estimatedFee(1, 7) | |
639a620,623 | |
> } catch(e : Exception) { | |
> return@launch | |
> } finally { | |
> FeeUtil.getInstance().suggestedFee = keepCurrentSuggestedFee | |
641,644d624 | |
< if (selectedUTXO.size == 0) { | |
< // sort in descending order by value | |
< Collections.sort(_utxos, UTXOComparator()) | |
< var selected = 0 | |
646,657c626,647 | |
< // get largest UTXOs > than spend + fee + dust | |
< for (u in _utxos) { | |
< selectedUTXO.add(u) | |
< totalValueSelected += u!!.value | |
< selected += u.outpoints.size | |
< if (totalValueSelected >= amount + SamouraiWallet.bDust.toLong() + FeeUtil.getInstance() | |
< .estimatedFee(selected, 4).toLong() | |
< ) { | |
< Log.d("PayNymDetailsActivity", "multiple outputs") | |
< Log.d("PayNymDetailsActivity", "total value selected:$totalValueSelected") | |
< Log.d("PayNymDetailsActivity", "nb inputs:" + u.outpoints.size) | |
< break | |
--- | |
> // | |
> // total amount to spend including fee | |
> // | |
> if (amount + fee!!.toLong() >= balance) { | |
> scope.launch(Dispatchers.Main) { | |
> binding.progressBar.visibility = View.INVISIBLE | |
> var message: String? = getText(R.string.bip47_notif_tx_insufficient_funds_1).toString() + " " | |
> val biAmount = SendNotifTxFactory._bSWFee.add(SendNotifTxFactory._bNotifTxValue.add(FeeUtil.getInstance().estimatedFee(1, 4, FeeUtil.getInstance().lowFee.defaultPerKB))) | |
> val strAmount = FormatsUtil.formatBTC(biAmount.toLong()); | |
> message += strAmount | |
> message += " " + getText(R.string.bip47_notif_tx_insufficient_funds_2) | |
> val dlg = MaterialAlertDialogBuilder(this@PayNymDetailsActivity) | |
> .setTitle(R.string.app_name) | |
> .setMessage(message) | |
> .setCancelable(false) | |
> .setPositiveButton(R.string.help) { _, _ -> | |
> val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://docs.samourai.io/wallet/usage#follow-paynyms")) | |
> startActivity(browserIntent) | |
> } | |
> .setNegativeButton(R.string.close) { _, _ -> } | |
> if (!isFinishing) { | |
> dlg.show() | |
659a650,651 | |
> return@launch | |
> } | |
661,663c653,663 | |
< fee = FeeUtil.getInstance().estimatedFee(selected, outputCountForFeeEstimation) | |
< } else { | |
< fee = FeeUtil.getInstance().estimatedFee(1, outputCountForFeeEstimation) | |
--- | |
> // | |
> // payment code to be notified | |
> // | |
> val payment_code: PaymentCode? | |
> payment_code = try { | |
> PaymentCode(pcode) | |
> } catch (afe: AddressFormatException) { | |
> null | |
> } | |
> if (payment_code == null) { | |
> return@launch | |
665,669d664 | |
< } catch (e: Exception) { | |
< return | |
< } finally { | |
< FeeUtil.getInstance().suggestedFee = keepCurrentSuggestedFee | |
< } | |
671,691c666,681 | |
< // | |
< // total amount to spend including fee | |
< // | |
< val toSpent = amount + fee!!.toLong() | |
< val balance = APIFactory.getInstance(this@PayNymDetailsActivity).xpubBalance | |
< if (toSpent >= balance || toSpent >= totalValueSelected) { | |
< scope.launch(Dispatchers.Main) { | |
< binding.progressBar.visibility = View.INVISIBLE | |
< var message: String? = | |
< getText(R.string.bip47_notif_tx_insufficient_funds_1).toString() + " " | |
< val biAmount = BigInteger.valueOf(toSpent) | |
< val strAmount = FormatsUtil.formatBTC(biAmount.toLong()); | |
< message += strAmount | |
< message += " " + getText(R.string.bip47_notif_tx_insufficient_funds_2) | |
< val dlg = MaterialAlertDialogBuilder(this@PayNymDetailsActivity) | |
< .setTitle(R.string.app_name) | |
< .setMessage(message) | |
< .setCancelable(false) | |
< .setPositiveButton(R.string.close) { _, _ -> } | |
< if (!isFinishing) { | |
< dlg.show() | |
--- | |
> // | |
> // create outpoints for spend later | |
> // | |
> val outpoints: MutableList<MyTransactionOutPoint> = ArrayList() | |
> for (u in selectedUTXO) { | |
> outpoints.addAll(u!!.outpoints) | |
> } | |
> // | |
> // create inputs from outpoints | |
> // | |
> val inputs: MutableList<MyTransactionInput> = ArrayList() | |
> val currentNetworkParams = SamouraiWallet.getInstance().currentNetworkParams | |
> for (o in outpoints) { | |
> val script = Script(o.scriptBytes) | |
> if (script.scriptType == Script.ScriptType.NO_TYPE) { | |
> continue | |
692a683,684 | |
> val input = MyTransactionInput(currentNetworkParams, null, ByteArray(0), o, o.txHash.toString(), o.txOutputN) | |
> inputs.add(input) | |
694,765c686,698 | |
< return | |
< } | |
< | |
< // | |
< // payment code to be notified | |
< // | |
< val payment_code: PaymentCode? | |
< payment_code = try { | |
< PaymentCode(pcode) | |
< } catch (afe: AddressFormatException) { | |
< null | |
< } | |
< if (payment_code == null) { | |
< return | |
< } | |
< | |
< // | |
< // create outpoints for spend later | |
< // | |
< val outpoints: MutableList<MyTransactionOutPoint> = ArrayList() | |
< for (u in selectedUTXO) { | |
< outpoints.addAll(u!!.outpoints) | |
< } | |
< // | |
< // create inputs from outpoints | |
< // | |
< val inputs: MutableList<MyTransactionInput> = ArrayList() | |
< val currentNetworkParams = SamouraiWallet.getInstance().currentNetworkParams | |
< for (o in outpoints) { | |
< val script = Script(o.scriptBytes) | |
< if (script.scriptType == Script.ScriptType.NO_TYPE) { | |
< continue | |
< } | |
< val input = MyTransactionInput( | |
< currentNetworkParams, | |
< null, | |
< ByteArray(0), | |
< o, | |
< o.txHash.toString(), | |
< o.txOutputN | |
< ) | |
< inputs.add(input) | |
< } | |
< // | |
< // sort inputs | |
< // | |
< Collections.sort(inputs, SendFactory.BIP69InputComparator()) | |
< // | |
< // find outpoint that corresponds to 0th input | |
< // | |
< var outPoint: MyTransactionOutPoint? = null | |
< for (o in outpoints) { | |
< if (o.txHash.toString() == inputs[0].getTxHash() && o.txOutputN == inputs[0].getTxPos()) { | |
< outPoint = o | |
< break | |
< } | |
< } | |
< if (outPoint == null) { | |
< throw Exception(getString(R.string.bip47_cannot_identify_outpoint)) | |
< } | |
< var op_return: ByteArray? = null | |
< // | |
< // get private key corresponding to outpoint | |
< // | |
< try { | |
< // Script inputScript = new Script(outPoint.getConnectedPubKeyScript()); | |
< val scriptBytes = outPoint?.connectedPubKeyScript | |
< var address: String? | |
< address = if (Bech32Util.getInstance().isBech32Script(Hex.toHexString(scriptBytes))) { | |
< Bech32Util.getInstance().getAddressFromScript(Hex.toHexString(scriptBytes)) | |
< } else { | |
< Script(scriptBytes).getToAddress(currentNetworkParams).toString() | |
--- | |
> // | |
> // sort inputs | |
> // | |
> Collections.sort(inputs, SendFactory.BIP69InputComparator()) | |
> // | |
> // find outpoint that corresponds to 0th input | |
> // | |
> var outPoint: MyTransactionOutPoint? = null | |
> for (o in outpoints) { | |
> if (o.txHash.toString() == inputs[0].getTxHash() && o.txOutputN == inputs[0].getTxPos()) { | |
> outPoint = o | |
> break | |
> } | |
767,770c700,701 | |
< // String address = inputScript.getToAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString(); | |
< val ecKey = SendFactory.getPrivKey(address, 0) | |
< if (ecKey == null || !ecKey.hasPrivKey()) { | |
< throw Exception(getString(R.string.bip47_cannot_compose_notif_tx)) | |
--- | |
> if (outPoint == null) { | |
> throw Exception(getString(R.string.bip47_cannot_identify_outpoint)) | |
772c703 | |
< | |
--- | |
> var op_return: ByteArray? = null | |
774c705 | |
< // use outpoint for payload masking | |
--- | |
> // get private key corresponding to outpoint | |
776,803c707,748 | |
< val privkey = ecKey.privKeyBytes | |
< val pubkey = payment_code.notificationAddress(currentNetworkParams).pubKey | |
< val outpoint = outPoint?.bitcoinSerialize() | |
< // Log.i("PayNymDetailsActivity", "outpoint:" + Hex.toHexString(outpoint)); | |
< // Log.i("PayNymDetailsActivity", "payer shared secret:" + Hex.toHexString(new SecretPoint(privkey, pubkey).ECDHSecretAsBytes())); | |
< val mask = | |
< PaymentCode.getMask(SecretPoint(privkey, pubkey).ECDHSecretAsBytes(), outpoint) | |
< // Log.i("PayNymDetailsActivity", "mask:" + Hex.toHexString(mask)); | |
< // Log.i("PayNymDetailsActivity", "mask length:" + mask.length); | |
< // Log.i("PayNymDetailsActivity", "payload0:" + Hex.toHexString(BIP47Util.getInstance(context).getPaymentCode().getPayload())); | |
< op_return = PaymentCode.blind( | |
< BIP47Util.getInstance(this@PayNymDetailsActivity).paymentCode.payload, | |
< mask | |
< ) | |
< // Log.i("PayNymDetailsActivity", "payload1:" + Hex.toHexString(op_return)); | |
< } catch (ike: InvalidKeyException) { | |
< throw ike | |
< } catch (ikse: InvalidKeySpecException) { | |
< throw ikse | |
< } catch (nsae: NoSuchAlgorithmException) { | |
< throw nsae | |
< } catch (nspe: NoSuchProviderException) { | |
< throw nspe | |
< } catch (e: Exception) { | |
< throw e | |
< } | |
< val receivers = HashMap<String, BigInteger>() | |
< receivers[Hex.toHexString(op_return)] = BigInteger.ZERO | |
--- | |
> try { | |
> // Script inputScript = new Script(outPoint.getConnectedPubKeyScript()); | |
> val scriptBytes = outPoint?.connectedPubKeyScript | |
> var address: String? | |
> address = if (Bech32Util.getInstance().isBech32Script(Hex.toHexString(scriptBytes))) { | |
> Bech32Util.getInstance().getAddressFromScript(Hex.toHexString(scriptBytes)) | |
> } else { | |
> Script(scriptBytes).getToAddress(currentNetworkParams).toString() | |
> } | |
> // String address = inputScript.getToAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString(); | |
> val ecKey = SendFactory.getPrivKey(address, 0) | |
> if (ecKey == null || !ecKey.hasPrivKey()) { | |
> throw Exception(getString(R.string.bip47_cannot_compose_notif_tx)) | |
> } | |
> | |
> // | |
> // use outpoint for payload masking | |
> // | |
> val privkey = ecKey.privKeyBytes | |
> val pubkey = payment_code.notificationAddress(currentNetworkParams).pubKey | |
> val outpoint = outPoint?.bitcoinSerialize() | |
> // Log.i("PayNymDetailsActivity", "outpoint:" + Hex.toHexString(outpoint)); | |
> // Log.i("PayNymDetailsActivity", "payer shared secret:" + Hex.toHexString(new SecretPoint(privkey, pubkey).ECDHSecretAsBytes())); | |
> val mask = PaymentCode.getMask(SecretPoint(privkey, pubkey).ECDHSecretAsBytes(), outpoint) | |
> // Log.i("PayNymDetailsActivity", "mask:" + Hex.toHexString(mask)); | |
> // Log.i("PayNymDetailsActivity", "mask length:" + mask.length); | |
> // Log.i("PayNymDetailsActivity", "payload0:" + Hex.toHexString(BIP47Util.getInstance(context).getPaymentCode().getPayload())); | |
> op_return = PaymentCode.blind(BIP47Util.getInstance(this@PayNymDetailsActivity).paymentCode.payload, mask) | |
> // Log.i("PayNymDetailsActivity", "payload1:" + Hex.toHexString(op_return)); | |
> } catch (ike: InvalidKeyException) { | |
> throw ike | |
> } catch (ikse: InvalidKeySpecException) { | |
> throw ikse | |
> } catch (nsae: NoSuchAlgorithmException) { | |
> throw nsae | |
> } catch (nspe: NoSuchProviderException) { | |
> throw nspe | |
> } catch (e: Exception) { | |
> throw e | |
> } | |
> val receivers = HashMap<String, BigInteger>() | |
> receivers[Hex.toHexString(op_return)] = BigInteger.ZERO | |
805,806c750 | |
< val notificationAddr = payment_code.notificationAddress(currentNetworkParams).addressString | |
< /* | |
--- | |
> val notificationAddr = payment_code.notificationAddress(currentNetworkParams).addressString | |
810d753 | |
< */ | |
812,813c755,756 | |
< receivers[notificationAddr] = SendNotifTxFactory._bNotifTxValue | |
< //receivers[samFeeAddress] = SendNotifTxFactory._bSWFee | |
--- | |
> receivers[notificationAddr] = SendNotifTxFactory._bNotifTxValue | |
> receivers[samFeeAddress] = SendNotifTxFactory._bSWFee | |
815,839c758,776 | |
< val change = totalValueSelected - (amount + fee.toLong()) | |
< if (change > 0L) { | |
< val change_address = BIP84Util.getInstance(this@PayNymDetailsActivity).getAddressAt( | |
< AddressFactory.CHANGE_CHAIN, | |
< BIP84Util.getInstance(this@PayNymDetailsActivity).wallet.getAccount(0).change.addrIdx | |
< ).bech32AsString | |
< receivers[change_address] = BigInteger.valueOf(change) | |
< } | |
< Log.d("PayNymDetailsActivity", "outpoints:" + outpoints.size) | |
< Log.d( | |
< "PayNymDetailsActivity", | |
< "totalValueSelected:" + BigInteger.valueOf(totalValueSelected).toString() | |
< ) | |
< Log.d("PayNymDetailsActivity", "amount:" + BigInteger.valueOf(amount).toString()) | |
< Log.d("PayNymDetailsActivity", "change:" + BigInteger.valueOf(change).toString()) | |
< Log.d("PayNymDetailsActivity", "fee:$fee") | |
< if (change < 0L) { | |
< throw Exception(getString(R.string.bip47_cannot_compose_notif_tx)) | |
< } | |
< val _outPoint: MyTransactionOutPoint = outPoint!! | |
< var strNotifTxMsg = getText(R.string.bip47_setup4_text1).toString() + " " | |
< val notifAmount = amount | |
< val strAmount = | |
< MonetaryUtil.getInstance().btcFormat.format((notifAmount.toDouble() + fee.toLong()) / 1e8) + " BTC " | |
< strNotifTxMsg += strAmount + getText(R.string.bip47_setup4_text2) | |
--- | |
> val change = totalValueSelected - (amount + fee.toLong()) | |
> if (change > 0L) { | |
> val change_address = BIP84Util.getInstance(this@PayNymDetailsActivity).getAddressAt( | |
> AddressFactory.CHANGE_CHAIN, BIP84Util.getInstance(this@PayNymDetailsActivity).wallet.getAccount(0).change.addrIdx).bech32AsString | |
> receivers[change_address] = BigInteger.valueOf(change) | |
> } | |
> Log.d("PayNymDetailsActivity", "outpoints:" + outpoints.size) | |
> Log.d("PayNymDetailsActivity", "totalValueSelected:" + BigInteger.valueOf(totalValueSelected).toString()) | |
> Log.d("PayNymDetailsActivity", "amount:" + BigInteger.valueOf(amount).toString()) | |
> Log.d("PayNymDetailsActivity", "change:" + BigInteger.valueOf(change).toString()) | |
> Log.d("PayNymDetailsActivity", "fee:$fee") | |
> if (change < 0L) { | |
> throw Exception(getString(R.string.bip47_cannot_compose_notif_tx)) | |
> } | |
> val _outPoint: MyTransactionOutPoint = outPoint!! | |
> var strNotifTxMsg = getText(R.string.bip47_setup4_text1).toString() + " " | |
> val notifAmount = amount | |
> val strAmount = MonetaryUtil.getInstance().btcFormat.format((notifAmount.toDouble() + fee.toLong()) / 1e8) + " BTC " | |
> strNotifTxMsg += strAmount + getText(R.string.bip47_setup4_text2) | |
841,842c778 | |
< scope.launch(Dispatchers.Main) { | |
< try { | |
--- | |
> scope.launch(Dispatchers.Main) { | |
848,868c784,800 | |
< scope.launch(Dispatchers.IO) { | |
< try { | |
< var tx = SendFactory.getInstance(this@PayNymDetailsActivity) | |
< .makeTransaction(outpoints, receivers) | |
< if (tx != null) { | |
< val input0hash = tx.getInput(0L).outpoint.hash.toString() | |
< val input0index = tx.getInput(0L).outpoint.index.toInt() | |
< if (input0hash != _outPoint.txHash.toString() || input0index != _outPoint.txOutputN) { | |
< throw Exception(getString(R.string.bip47_cannot_compose_notif_tx)) | |
< } | |
< tx = SendFactory.getInstance(this@PayNymDetailsActivity) | |
< .signTransaction(tx, 0) | |
< val hexTx = String(Hex.encode(tx.bitcoinSerialize())) | |
< | |
< var hashTx = tx.hashAsString | |
< var changeIdx = 0 | |
< for (i in 0 until tx.outputs.size) { | |
< if (tx.getOutput(i.toLong()).value.value == change) { | |
< changeIdx = i | |
< break | |
< } | |
--- | |
> val job = scope.launch(Dispatchers.IO) { | |
> var tx = SendFactory.getInstance(this@PayNymDetailsActivity).makeTransaction(outpoints, receivers) | |
> if (tx != null) { | |
> val input0hash = tx.getInput(0L).outpoint.hash.toString() | |
> val input0index = tx.getInput(0L).outpoint.index.toInt() | |
> if (input0hash != _outPoint.txHash.toString() || input0index != _outPoint.txOutputN) { | |
> throw Exception(getString(R.string.bip47_cannot_compose_notif_tx)) | |
> } | |
> tx = SendFactory.getInstance(this@PayNymDetailsActivity).signTransaction(tx, 0) | |
> val hexTx = String(Hex.encode(tx.bitcoinSerialize())) | |
> | |
> var hashTx = tx.hashAsString | |
> var changeIdx = 0 | |
> for (i in 0 until tx.outputs.size) { | |
> if (tx.getOutput(i.toLong()).value.value == change) { | |
> changeIdx = i | |
> break | |
869a802 | |
> } | |
871,885c804,815 | |
< var isOK = false | |
< var response: String? | |
< try { | |
< val rbf = createRBFSpendFromTx(tx, this@PayNymDetailsActivity) | |
< response = | |
< PushTx.getInstance(this@PayNymDetailsActivity).samourai(hexTx, null) | |
< Log.d("SendActivity", "pushTx:$response") | |
< if (response != null) { | |
< val jsonObject = JSONObject(response) | |
< if (jsonObject.has("status")) { | |
< if ((jsonObject.getString("status") == "ok")) { | |
< isOK = true | |
< APIFactory.getInstance(this@PayNymDetailsActivity) | |
< .initWallet() | |
< } | |
--- | |
> var isOK = false | |
> var response: String? | |
> try { | |
> val rbf = createRBFSpendFromTx(tx, this@PayNymDetailsActivity) | |
> response = PushTx.getInstance(this@PayNymDetailsActivity).samourai(hexTx, null) | |
> Log.d("SendActivity", "pushTx:$response") | |
> if (response != null) { | |
> val jsonObject = JSONObject(response) | |
> if (jsonObject.has("status")) { | |
> if ((jsonObject.getString("status") == "ok")) { | |
> isOK = true | |
> APIFactory.getInstance(this@PayNymDetailsActivity).initWallet() | |
887,888d816 | |
< } else { | |
< throw Exception(getString(R.string.pushtx_returns_null)) | |
890,891c818,822 | |
< scope.launch(Dispatchers.Main) { | |
< binding.progressBar.visibility = View.INVISIBLE | |
--- | |
> } else { | |
> throw Exception(getString(R.string.pushtx_returns_null)) | |
> } | |
> scope.launch(Dispatchers.Main) { | |
> binding.progressBar.visibility = View.INVISIBLE | |
893c824 | |
< if (isOK) { | |
--- | |
> if (isOK) { | |
895,896c826 | |
< UTXOUtil.getInstance() | |
< .add(hashTx, changeIdx, "\u2623 notif tx change\u2623") | |
--- | |
> UTXOUtil.getInstance().add(hashTx, changeIdx, "\u2623 notif tx change\u2623") | |
898,939c828,846 | |
< Toast.makeText( | |
< this@PayNymDetailsActivity, | |
< R.string.payment_channel_init, | |
< Toast.LENGTH_SHORT | |
< ).show() | |
< // | |
< // set outgoing index for payment code to 0 | |
< // | |
< BIP47Meta.getInstance().setOutgoingIdx(pcode, 0) | |
< // Log.i("SendNotifTxFactory", "tx hash:" + tx.getHashAsString()); | |
< // | |
< // status to NO_CFM | |
< // | |
< BIP47Meta.getInstance().setOutgoingStatus( | |
< pcode, | |
< tx.hashAsString, | |
< BIP47Meta.STATUS_SENT_NO_CFM | |
< ) | |
< | |
< //updateRBFSpendForBroadcastTxAndRegister(rbf, tx, samFeeAddress, 84, this@PayNymDetailsActivity) | |
< | |
< // | |
< // increment change index | |
< // | |
< if (change > 0L) { | |
< BIP49Util.getInstance(this@PayNymDetailsActivity) | |
< .wallet.getAccount(0).change.incAddrIdx() | |
< } | |
< if (!BIP47Meta.getInstance().exists(pcode, false)) { | |
< BIP47Meta.getInstance().setLabel( | |
< pcode, | |
< BIP47Meta.getInstance().getAbbreviatedPcode(pcode) | |
< ); | |
< BIP47Meta.getInstance().setFollowing(pcode, true); | |
< } | |
< savePayLoad() | |
< } else { | |
< Toast.makeText( | |
< this@PayNymDetailsActivity, | |
< R.string.tx_failed, | |
< Toast.LENGTH_SHORT | |
< ).show() | |
--- | |
> Toast.makeText(this@PayNymDetailsActivity, R.string.payment_channel_init, Toast.LENGTH_SHORT).show() | |
> // | |
> // set outgoing index for payment code to 0 | |
> // | |
> BIP47Meta.getInstance().setOutgoingIdx(pcode, 0) | |
> // Log.i("SendNotifTxFactory", "tx hash:" + tx.getHashAsString()); | |
> // | |
> // status to NO_CFM | |
> // | |
> BIP47Meta.getInstance().setOutgoingStatus(pcode, tx.hashAsString, BIP47Meta.STATUS_SENT_NO_CFM) | |
> | |
> updateRBFSpendForBroadcastTxAndRegister(rbf, tx, samFeeAddress, 84, this@PayNymDetailsActivity) | |
> | |
> // | |
> // increment change index | |
> // | |
> if (change > 0L) { | |
> BIP49Util.getInstance(this@PayNymDetailsActivity) | |
> .wallet.getAccount(0).change.incAddrIdx() | |
941,942c848,850 | |
< scope.launch(Dispatchers.Main) { | |
< setPayNym() | |
--- | |
> if (!BIP47Meta.getInstance().exists(pcode, false)) { | |
> BIP47Meta.getInstance().setLabel(pcode, BIP47Meta.getInstance().getAbbreviatedPcode(pcode)); | |
> BIP47Meta.getInstance().setRole(pcode, true); | |
943a852,857 | |
> savePayLoad() | |
> } else { | |
> Toast.makeText(this@PayNymDetailsActivity, R.string.tx_failed, Toast.LENGTH_SHORT).show() | |
> } | |
> scope.launch(Dispatchers.Main) { | |
> setPayNym() | |
945,946d858 | |
< } catch (e: Exception) { | |
< manageException(e) | |
947a860,861 | |
> } catch (e: Exception) { | |
> manageException(e) | |
949,950c863,868 | |
< } catch (t: Throwable) { | |
< manageException(t) | |
--- | |
> } | |
> } | |
> | |
> job.invokeOnCompletion { | |
> if (nonNull(it)) { | |
> manageException(it!!) | |
954,955c872,879 | |
< } catch (t: Throwable) { | |
< manageException(t) | |
--- | |
> }.invokeOnCompletion { | |
> if (nonNull(it)) { | |
> manageException(it!!) | |
> } | |
> } | |
> }.invokeOnCompletion { | |
> if (nonNull(it)) { | |
> manageException(it!!) | |
957a882 | |
> return | |
983d907 | |
< BIP47Meta.getInstance().setName(pcode, strNymName) | |
1030c954 | |
< } | |
--- | |
> } | |
\ No newline at end of file | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/PayNymHome.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/PayNymHome.kt | |
81,83d80 | |
< | |
< window.statusBarColor = resources.getColor(R.color.grey_accent) | |
< | |
143a141,143 | |
> if (!PrefsUtil.getInstance(this).getValue(PrefsUtil.PAYNYM_CLAIMED, false)) { | |
> doClaimPayNym() | |
> } | |
182a183,190 | |
> private fun doClaimPayNym() { | |
> val payNymOnBoardBottomSheet = PayNymOnBoardBottomSheet() | |
> payNymOnBoardBottomSheet.show(supportFragmentManager, payNymOnBoardBottomSheet.tag) | |
> payNymOnBoardBottomSheet.setOnClaimCallBack { | |
> payNymViewModel.refreshPayNym() | |
> } | |
> } | |
> | |
207d214 | |
< /* | |
211d217 | |
< */ | |
260c266 | |
< var url = "null"; //"https://samouraiwallet.com/support" | |
--- | |
> var url = "https://samouraiwallet.com/support" | |
262,265c268,271 | |
< url = "null"; // "http://72typmu5edrjmcdkzuzmv2i4zqru7rjlrcxwtod4nu6qtfsqegngzead.onion/support" | |
< val intent = Intent(this, ExplorerActivity::class.java) | |
< intent.putExtra(ExplorerActivity.SUPPORT, url) | |
< startActivity(intent) | |
--- | |
> url = "http://72typmu5edrjmcdkzuzmv2i4zqru7rjlrcxwtod4nu6qtfsqegngzead.onion/support" | |
> val explorerIntent = Intent(this, ExplorerActivity::class.java) | |
> explorerIntent.putExtra(ExplorerActivity.SUPPORT, url) | |
> startActivity(explorerIntent) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/paynym/PayNymViewModel.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/paynym/PayNymViewModel.kt | |
4d3 | |
< import android.util.Log | |
17,18d15 | |
< import com.samourai.wallet.util.PrefsUtil | |
< import com.samourai.wallet.util.func.isClaimedPayNym | |
19a17 | |
> import com.samourai.wallet.util.PrefsUtil | |
20a19 | |
> import kotlinx.coroutines.Deferred | |
27,28d25 | |
< import kotlinx.coroutines.sync.Semaphore | |
< import kotlinx.coroutines.sync.withPermit | |
33d29 | |
< import java.util.concurrent.atomic.AtomicInteger | |
69c65 | |
< BIP47Meta.getInstance().setFollowings(backupFilePaynyms as java.util.ArrayList<String>?) | |
--- | |
> BIP47Meta.getInstance().addFollowings(backupFilePaynyms as java.util.ArrayList<String>?) | |
77,78c73,77 | |
< val pcode = BIP47Util.getInstance(getApplication()).paymentCode.toString() | |
< if (isClaimedPayNym(pcode, jsonObject)) { | |
--- | |
> val nym = Gson().fromJson(jsonObject.toString(), NymResponse::class.java); | |
> val backupFilePaynyms = PayloadUtil.getInstance(getApplication<Application>().applicationContext).paynymsFromBackupFile | |
> | |
> var array = jsonObject.getJSONArray("codes") | |
> if (array.getJSONObject(0).has("claimed") && array.getJSONObject(0).getBoolean("claimed")) { | |
85,87d83 | |
< val backupFilePaynyms = PayloadUtil.getInstance(getApplication<Application>().applicationContext).paynymsFromBackupFile | |
< | |
< val nym = Gson().fromJson(jsonObject.toString(), NymResponse::class.java) | |
91d86 | |
< BIP47Meta.getInstance().setName(paynym.code, paynym.nymName) | |
101c96 | |
< BIP47Meta.getInstance().setFollowings(followings) | |
--- | |
> BIP47Meta.getInstance().addFollowings(followings) | |
110d104 | |
< BIP47Meta.getInstance().setName(paynym.code, paynym.nymName) | |
116c110 | |
< sortByLabel(followers); | |
--- | |
> sortByLabel(followers); | |
137c131 | |
< suspend fun getPayNymData() { | |
--- | |
> private suspend fun getPayNymData() { | |
204,208c198,205 | |
< | |
< try { | |
< if (_pcodes.contains(BIP47Util.getInstance(getApplication()).paymentCode.toString())) { | |
< _pcodes.remove(BIP47Util.getInstance(getApplication()).paymentCode.toString()) | |
< BIP47Meta.getInstance().remove(BIP47Util.getInstance(getApplication()).paymentCode.toString()) | |
--- | |
> refreshJob = viewModelScope.launch(Dispatchers.IO) { | |
> try { | |
> if (_pcodes.contains(BIP47Util.getInstance(getApplication()).paymentCode.toString())) { | |
> _pcodes.remove(BIP47Util.getInstance(getApplication()).paymentCode.toString()) | |
> BIP47Meta.getInstance().remove(BIP47Util.getInstance(getApplication()).paymentCode.toString()) | |
> } | |
> } catch (afe: AddressFormatException) { | |
> afe.printStackTrace() | |
210,217c207,208 | |
< } catch (afe: AddressFormatException) { | |
< afe.printStackTrace() | |
< } | |
< | |
< refreshJob = viewModelScope.launch(Dispatchers.Main) { | |
< | |
< var progress = AtomicInteger(0) | |
< | |
--- | |
> var progress = 0; | |
> val jobs = arrayListOf<Deferred<Unit>>() | |
219,250c210,217 | |
< refreshTaskProgress.postValue(Pair(progress.get(), _pcodes.size)) | |
< | |
< viewModelScope.launch(Dispatchers.IO) { | |
< BIP47Util.getInstance(getApplication()).fetchBotImage().subscribe() | |
< } | |
< | |
< withContext(Dispatchers.IO) { | |
< val semaphore = Semaphore(6) | |
< val tasks = _pcodes.map { pcode -> | |
< async(Dispatchers.IO) { | |
< semaphore.withPermit { | |
< try { | |
< apiService.syncPcode(pcode) | |
< val progress = progress.incrementAndGet() | |
< if (!silentSync) { | |
< if(progress < _pcodes.size) { | |
< refreshTaskProgress.postValue(Pair(progress, _pcodes.size)) | |
< } | |
< } | |
< true | |
< } catch (te : Throwable) { | |
< Log.e(TAG, "issue on syncPcode " + pcode, te) | |
< } | |
< } | |
< } | |
< } | |
< tasks.awaitAll() | |
< async(Dispatchers.IO) { | |
< try { | |
< apiService.retrievePayNymConnections() | |
< val progress = progress.incrementAndGet() | |
< if (!silentSync) { | |
--- | |
> refreshTaskProgress.postValue(Pair(0, _pcodes.size)) | |
> _pcodes.forEachIndexed { _, pcode -> | |
> val job = async(Dispatchers.IO) { apiService.syncPcode(pcode) } | |
> jobs.add(job) | |
> job.invokeOnCompletion { | |
> if (it == null) { | |
> progress++ | |
> if (!silentSync) | |
252,254c219,220 | |
< } | |
< } catch (te : Throwable) { | |
< Log.e(TAG, "issue on retrievePayNymConnections", te) | |
--- | |
> } else { | |
> it.printStackTrace() | |
256,257c222 | |
< true | |
< }.await() | |
--- | |
> } | |
258a224,226 | |
> BIP47Util.getInstance(getApplication()).fetchBotImage() | |
> .subscribe() | |
> jobs.awaitAll() | |
266,267c234,235 | |
< suspend fun doFollow(pcode: String) { | |
< val job = viewModelScope.launch { | |
--- | |
> fun doFollow(pcode: String) { | |
> viewModelScope.launch { | |
284,285c252 | |
< } | |
< job.invokeOnCompletion { | |
--- | |
> }.invokeOnCompletion { | |
293d259 | |
< job.join() | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/pin/PinEntryActivity.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/pin/PinEntryActivity.java | |
3,5d2 | |
< import static com.samourai.wallet.payload.ExternalBackupManager.askPermission; | |
< import static com.samourai.wallet.payload.ExternalBackupManager.hasPermissions; | |
< | |
17d13 | |
< import com.samourai.wallet.util.PrefsUtil; | |
37,42d32 | |
< | |
< if (! PrefsUtil.getInstance(this).getValue(PrefsUtil.WALLET_SCAN_COMPLETE, false)) { | |
< if (PrefsUtil.getInstance(this).getValue(PrefsUtil.AUTO_BACKUP, true)) { | |
< if (!hasPermissions()) askPermission(this); | |
< } | |
< } | |
48c38 | |
< AppUtil.getInstance(this).restartAppFromActivity(getIntent().getExtras(), this); | |
--- | |
> AppUtil.getInstance(this).restartApp(getIntent().getExtras()); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/pin/PinEntryManager.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/pin/PinEntryManager.java | |
15d14 | |
< import android.util.Log; | |
41a41,42 | |
> import com.samourai.wallet.util.func.AddressFactory; | |
> import com.samourai.wallet.util.tech.AppUtil; | |
45,48d45 | |
< import com.samourai.wallet.util.func.AddressFactory; | |
< import com.samourai.wallet.util.tech.AppUtil; | |
< import com.samourai.wallet.util.tech.SimpleCallback; | |
< import com.samourai.wallet.util.tech.SimpleTaskRunner; | |
52d48 | |
< import org.apache.commons.lang3.StringUtils; | |
68d63 | |
< private final static String TAG = "PinEntryManager"; | |
154,206c149 | |
< final View theView = getView(); | |
< | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< () -> { | |
< if (attemptToLog && PrefsUtil.getInstance(activity).getValue(PrefsUtil.ATTEMPTS, 0) > 0) { | |
< failures = PrefsUtil.getInstance(activity).getValue(PrefsUtil.ATTEMPTS, 0); | |
< } | |
< return null; | |
< }, new SimpleCallback<Void>() { | |
< @Override | |
< public void onComplete(Void result) { | |
< userInput = new StringBuilder(); | |
< pinEntryView = theView.findViewById(R.id.pinentry_view); | |
< walletStatusTextView = theView.findViewById(R.id.pin_entry_wallet_status); | |
< restoreLayout = theView.findViewById(R.id.pin_entry_restore); | |
< MaterialButton restoreBtn = theView.findViewById(R.id.pin_entry_restore_btn); | |
< pinEntryMaskLayout = theView.findViewById(R.id.pin_entry_mask_layout); | |
< progressBar = theView.findViewById(R.id.progress_pin_entry); | |
< activity.getWindow().setStatusBarColor(ContextCompat.getColor(activity, R.color.window)); | |
< activity.getWindow().setNavigationBarColor(ContextCompat.getColor(activity, R.color.window)); | |
< restoreLayout.setVisibility(View.GONE); | |
< pinEntryView.setEntryListener((key, view) -> { | |
< if (userInput.length() <= (AccessFactory.MAX_PIN_LENGTH - 1)) { | |
< userInput = userInput.append(key); | |
< if (userInput.length() >= AccessFactory.MIN_PIN_LENGTH) { | |
< pinEntryView.showCheckButton(); | |
< } else { | |
< pinEntryView.hideCheckButton(); | |
< } | |
< setPinMaskView(); | |
< } | |
< }); | |
< restoreBtn.setOnClickListener(v -> doBackupRestore()); | |
< pinEntryView.setClearListener(clearType -> { | |
< if (clearType == PinEntryView.KeyClearTypes.CLEAR) { | |
< if (userInput.length() != 0) | |
< userInput = new StringBuilder(userInput.substring(0, (userInput.length() - 1))); | |
< if (userInput.length() >= AccessFactory.MIN_PIN_LENGTH) { | |
< pinEntryView.showCheckButton(); | |
< } else { | |
< pinEntryView.hideCheckButton(); | |
< } | |
< } else { | |
< strPassphrase = ""; | |
< userInput = new StringBuilder(); | |
< pinEntryMaskLayout.removeAllViews(); | |
< pinEntryView.hideCheckButton(); | |
< } | |
< setPinMaskView(); | |
< }); | |
< | |
< boolean scramble = PrefsUtil.getInstance(activity).getValue(PrefsUtil.SCRAMBLE_PIN, false); | |
--- | |
> final View viewBuilt = getView(); | |
208,210c151,167 | |
< strUri = PrefsUtil.getInstance(activity).getValue("SCHEMED_URI", ""); | |
< if (strUri.length() > 0) { | |
< PrefsUtil.getInstance(activity).setValue("SCHEMED_URI", ""); | |
--- | |
> if (attemptToLog && PrefsUtil.getInstance(activity).getValue(PrefsUtil.ATTEMPTS, 0) > 0) { | |
> failures = PrefsUtil.getInstance(activity).getValue(PrefsUtil.ATTEMPTS, 0); | |
> } | |
> userInput = new StringBuilder(); | |
> pinEntryView = viewBuilt.findViewById(R.id.pinentry_view); | |
> walletStatusTextView = viewBuilt.findViewById(R.id.pin_entry_wallet_status); | |
> restoreLayout = viewBuilt.findViewById(R.id.pin_entry_restore); | |
> MaterialButton restoreBtn = viewBuilt.findViewById(R.id.pin_entry_restore_btn); | |
> pinEntryMaskLayout = viewBuilt.findViewById(R.id.pin_entry_mask_layout); | |
> progressBar = viewBuilt.findViewById(R.id.progress_pin_entry); | |
> activity.getWindow().setStatusBarColor(ContextCompat.getColor(activity, R.color.window)); | |
> restoreLayout.setVisibility(View.GONE); | |
> pinEntryView.setEntryListener((key, view) -> { | |
> if (userInput.length() <= (AccessFactory.MAX_PIN_LENGTH - 1)) { | |
> userInput = userInput.append(key); | |
> if (userInput.length() >= AccessFactory.MIN_PIN_LENGTH) { | |
> pinEntryView.showCheckButton(); | |
212c169 | |
< strUri = null; | |
--- | |
> pinEntryView.hideCheckButton(); | |
214,215c171,182 | |
< if (scramble) { | |
< pinEntryView.setScramble(true); | |
--- | |
> setPinMaskView(); | |
> } | |
> }); | |
> restoreBtn.setOnClickListener(v -> doBackupRestore()); | |
> pinEntryView.setClearListener(clearType -> { | |
> if (clearType == PinEntryView.KeyClearTypes.CLEAR) { | |
> if (userInput.length() != 0) | |
> userInput = new StringBuilder(userInput.substring(0, (userInput.length() - 1))); | |
> if (userInput.length() >= AccessFactory.MIN_PIN_LENGTH) { | |
> pinEntryView.showCheckButton(); | |
> } else { | |
> pinEntryView.hideCheckButton(); | |
216a184,191 | |
> } else { | |
> strPassphrase = ""; | |
> userInput = new StringBuilder(); | |
> pinEntryMaskLayout.removeAllViews(); | |
> pinEntryView.hideCheckButton(); | |
> } | |
> setPinMaskView(); | |
> }); | |
218c193 | |
< Bundle extras = activity.getIntent().getExtras(); | |
--- | |
> boolean scramble = PrefsUtil.getInstance(activity).getValue(PrefsUtil.SCRAMBLE_PIN, false); | |
220,239c195,203 | |
< if (extras != null && extras.containsKey("create") && extras.getBoolean("create")) { | |
< scramble = false; | |
< create = true; | |
< confirm = false; | |
< strSeed = extras.getString("seed"); | |
< strPassphrase = extras.getString("passphrase"); | |
< Toast.makeText(activity, R.string.pin_5_8, Toast.LENGTH_LONG).show(); | |
< } else if (extras != null && extras.containsKey("confirm") && extras.getBoolean("confirm")) { | |
< scramble = false; | |
< create = false; | |
< confirm = true; | |
< strConfirm = extras.getString("first"); | |
< strSeed = extras.getString("seed"); | |
< strPassphrase = extras.getString("passphrase"); | |
< Toast.makeText(activity, R.string.pin_5_8_confirm, Toast.LENGTH_LONG).show(); | |
< } else { | |
< if (isLocked()) { | |
< lockWallet(); | |
< } | |
< } | |
--- | |
> strUri = PrefsUtil.getInstance(activity).getValue("SCHEMED_URI", ""); | |
> if (strUri.length() > 0) { | |
> PrefsUtil.getInstance(activity).setValue("SCHEMED_URI", ""); | |
> } else { | |
> strUri = null; | |
> } | |
> if (scramble) { | |
> pinEntryView.setScramble(true); | |
> } | |
241,243c205 | |
< if (strSeed != null && strSeed.length() < 1) { | |
< strSeed = null; | |
< } | |
--- | |
> Bundle extras = activity.getIntent().getExtras(); | |
245,251c207,226 | |
< if (strPassphrase == null) { | |
< strPassphrase = ""; | |
< } | |
< if (!PrefsUtil.getInstance(activity).getValue(PrefsUtil.HAPTIC_PIN, true)) { | |
< pinEntryView.disableHapticFeedBack(); | |
< } | |
< pinEntryView.setConfirmClickListener(view -> { | |
--- | |
> if (extras != null && extras.containsKey("create") && extras.getBoolean("create")) { | |
> scramble = false; | |
> create = true; | |
> confirm = false; | |
> strSeed = extras.getString("seed"); | |
> strPassphrase = extras.getString("passphrase"); | |
> Toast.makeText(activity, R.string.pin_5_8, Toast.LENGTH_LONG).show(); | |
> } else if (extras != null && extras.containsKey("confirm") && extras.getBoolean("confirm")) { | |
> scramble = false; | |
> create = false; | |
> confirm = true; | |
> strConfirm = extras.getString("first"); | |
> strSeed = extras.getString("seed"); | |
> strPassphrase = extras.getString("passphrase"); | |
> Toast.makeText(activity, R.string.pin_5_8_confirm, Toast.LENGTH_LONG).show(); | |
> } else { | |
> if (isLocked()) { | |
> lockWallet(); | |
> } | |
> } | |
253,262c228,230 | |
< if (create && strPassphrase.length() >= AccessFactory.MIN_PIN_LENGTH && userInput.toString().length() <= AccessFactory.MAX_PIN_LENGTH) { | |
< Intent intent = new Intent(activity, PinEntryActivity.class); | |
< intent.putExtra("confirm", true); | |
< intent.putExtra("create", false); | |
< intent.putExtra("first", userInput.toString()); | |
< intent.putExtra("seed", strSeed); | |
< intent.putExtra("passphrase", strPassphrase); | |
< activity.startActivity(intent); | |
< activity.finish(); | |
< } else if (confirm && strPassphrase.length() >= AccessFactory.MIN_PIN_LENGTH && userInput.toString().length() <= AccessFactory.MAX_PIN_LENGTH) { | |
--- | |
> if (strSeed != null && strSeed.length() < 1) { | |
> strSeed = null; | |
> } | |
264c232,238 | |
< if (userInput.toString().equals(strConfirm)) { | |
--- | |
> if (strPassphrase == null) { | |
> strPassphrase = ""; | |
> } | |
> if (!PrefsUtil.getInstance(activity).getValue(PrefsUtil.HAPTIC_PIN, true)) { | |
> pinEntryView.disableHapticFeedBack(); | |
> } | |
> pinEntryView.setConfirmClickListener(view -> { | |
266c240,249 | |
< progressBar.setVisibility(View.VISIBLE); | |
--- | |
> if (create && strPassphrase.length() >= AccessFactory.MIN_PIN_LENGTH && userInput.toString().length() <= AccessFactory.MAX_PIN_LENGTH) { | |
> Intent intent = new Intent(activity, PinEntryActivity.class); | |
> intent.putExtra("confirm", true); | |
> intent.putExtra("create", false); | |
> intent.putExtra("first", userInput.toString()); | |
> intent.putExtra("seed", strSeed); | |
> intent.putExtra("passphrase", strPassphrase); | |
> activity.startActivity(intent); | |
> activity.finish(); | |
> } else if (confirm && strPassphrase.length() >= AccessFactory.MIN_PIN_LENGTH && userInput.toString().length() <= AccessFactory.MAX_PIN_LENGTH) { | |
268c251 | |
< initThread(strSeed == null, userInput.toString(), strPassphrase, strSeed == null ? null : strSeed); | |
--- | |
> if (userInput.toString().equals(strConfirm)) { | |
270,277c253 | |
< } else { | |
< Intent intent = new Intent(activity, PinEntryActivity.class); | |
< intent.putExtra("create", true); | |
< intent.putExtra("seed", strSeed); | |
< intent.putExtra("passphrase", strPassphrase); | |
< activity.startActivity(intent); | |
< activity.finish(); | |
< } | |
--- | |
> progressBar.setVisibility(View.VISIBLE); | |
279,283c255,264 | |
< } else { | |
< validateThread(userInput.toString(), strUri); | |
< } | |
< }); | |
< } | |
--- | |
> initThread(strSeed == null, userInput.toString(), strPassphrase, strSeed == null ? null : strSeed); | |
> | |
> } else { | |
> Intent intent = new Intent(activity, PinEntryActivity.class); | |
> intent.putExtra("create", true); | |
> intent.putExtra("seed", strSeed); | |
> intent.putExtra("passphrase", strPassphrase); | |
> activity.startActivity(intent); | |
> activity.finish(); | |
> } | |
285,287c266,267 | |
< @Override | |
< public void onException(Throwable t) { | |
< Log.e(TAG, "issue on install view", t); | |
--- | |
> } else { | |
> validateThread(userInput.toString(), strUri); | |
350c330 | |
< AppUtil.getInstance(activity).restartAppFromActivity(activity.getIntent().getExtras(), activity); | |
--- | |
> AppUtil.getInstance(activity).restartApp(activity.getIntent().getExtras()); | |
362c342 | |
< AppUtil.getInstance(activity).restartAppFromActivity(activity.getIntent().getExtras(), activity); | |
--- | |
> AppUtil.getInstance(activity).restartApp(activity.getIntent().getExtras()); | |
415c395 | |
< AppUtil.getInstance(activity).restartAppFromActivity(activity.getIntent().getExtras(), activity); | |
--- | |
> AppUtil.getInstance(activity).restartApp(activity.getIntent().getExtras()); | |
466,473c446 | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< () -> { | |
< | |
< String guid = AccessFactory.getInstance(activity).createGUID(); | |
< String hash = AccessFactory.getInstance(activity).getHash(guid, new CharSequenceX(pin), AESUtil.DefaultPBKDF2Iterations); | |
< PrefsUtil.getInstance(activity).setValue(PrefsUtil.ACCESS_HASH, hash); | |
< PrefsUtil.getInstance(activity).setValue(PrefsUtil.ACCESS_HASH2, hash); | |
--- | |
> new Thread(() -> { | |
475c448 | |
< if (create) { | |
--- | |
> Looper.prepare(); | |
477,485c450,465 | |
< try { | |
< HD_WalletFactory.getInstance(activity).newWallet(12, passphrase); | |
< } catch (IOException ioe) { | |
< ioe.printStackTrace(); | |
< } catch (MnemonicException.MnemonicLengthException mle) { | |
< mle.printStackTrace(); | |
< } finally { | |
< ; | |
< } | |
--- | |
> String guid = AccessFactory.getInstance(activity).createGUID(); | |
> String hash = AccessFactory.getInstance(activity).getHash(guid, new CharSequenceX(pin), AESUtil.DefaultPBKDF2Iterations); | |
> PrefsUtil.getInstance(activity).setValue(PrefsUtil.ACCESS_HASH, hash); | |
> PrefsUtil.getInstance(activity).setValue(PrefsUtil.ACCESS_HASH2, hash); | |
> | |
> if (create) { | |
> | |
> try { | |
> HD_WalletFactory.getInstance(activity).newWallet(12, passphrase); | |
> } catch (IOException ioe) { | |
> ioe.printStackTrace(); | |
> } catch (MnemonicException.MnemonicLengthException mle) { | |
> mle.printStackTrace(); | |
> } finally { | |
> ; | |
> } | |
487,489c467,469 | |
< } else if (seed == null) { | |
< ; | |
< } else { | |
--- | |
> } else if (seed == null) { | |
> ; | |
> } else { | |
491,507c471,487 | |
< try { | |
< HD_WalletFactory.getInstance(activity).restoreWallet(seed, passphrase); | |
< } catch (IOException ioe) { | |
< ioe.printStackTrace(); | |
< } catch (DecoderException de) { | |
< de.printStackTrace(); | |
< } catch (AddressFormatException afe) { | |
< afe.printStackTrace(); | |
< } catch (MnemonicException.MnemonicLengthException mle) { | |
< mle.printStackTrace(); | |
< } catch (MnemonicException.MnemonicChecksumException mce) { | |
< mce.printStackTrace(); | |
< } catch (MnemonicException.MnemonicWordException mwe) { | |
< mwe.printStackTrace(); | |
< } finally { | |
< ; | |
< } | |
--- | |
> try { | |
> HD_WalletFactory.getInstance(activity).restoreWallet(seed, passphrase); | |
> } catch (IOException ioe) { | |
> ioe.printStackTrace(); | |
> } catch (DecoderException de) { | |
> de.printStackTrace(); | |
> } catch (AddressFormatException afe) { | |
> afe.printStackTrace(); | |
> } catch (MnemonicException.MnemonicLengthException mle) { | |
> mle.printStackTrace(); | |
> } catch (MnemonicException.MnemonicChecksumException mce) { | |
> mce.printStackTrace(); | |
> } catch (MnemonicException.MnemonicWordException mwe) { | |
> mwe.printStackTrace(); | |
> } finally { | |
> ; | |
> } | |
509c489,491 | |
< } | |
--- | |
> } | |
> | |
> PrefsUtil.getInstance(activity).setValue(PrefsUtil.SCRAMBLE_PIN, true); | |
511c493 | |
< PrefsUtil.getInstance(activity).setValue(PrefsUtil.SCRAMBLE_PIN, true); | |
--- | |
> try { | |
513c495 | |
< String msg; | |
--- | |
> String msg = null; | |
515c497,507 | |
< if (HD_WalletFactory.getInstance(activity).get() != null) { | |
--- | |
> if (HD_WalletFactory.getInstance(activity).get() != null) { | |
> | |
> if (create) { | |
> msg = activity.getString(R.string.wallet_created_ok); | |
> } else { | |
> msg = activity.getString(R.string.wallet_restored_ok); | |
> } | |
> | |
> try { | |
> AccessFactory.getInstance(activity).setPIN(pin); | |
> PayloadUtil.getInstance(activity).saveWalletToJSON(new CharSequenceX(AccessFactory.getInstance(activity).getGUID() + pin)); | |
518c510,511 | |
< msg = activity.getString(R.string.wallet_created_ok); | |
--- | |
> PrefsUtil.getInstance(activity).setValue(PrefsUtil.WALLET_ORIGIN, "new"); | |
> PrefsUtil.getInstance(activity).setValue(PrefsUtil.FIRST_RUN, true); | |
520c513,514 | |
< msg = activity.getString(R.string.wallet_restored_ok); | |
--- | |
> PrefsUtil.getInstance(activity).setValue(PrefsUtil.WALLET_ORIGIN, "restored"); | |
> PrefsUtil.getInstance(activity).setValue(PrefsUtil.FIRST_RUN, true); | |
523,537c517,519 | |
< try { | |
< AccessFactory.getInstance(activity).setPIN(pin); | |
< PayloadUtil.getInstance(activity).saveWalletToJSON(new CharSequenceX(AccessFactory.getInstance(activity).getGUID() + pin)); | |
< | |
< if (create) { | |
< PrefsUtil.getInstance(activity).setValue(PrefsUtil.WALLET_ORIGIN, "new"); | |
< PrefsUtil.getInstance(activity).setValue(PrefsUtil.WALLET_SCAN_COMPLETE, false); | |
< } else { | |
< PrefsUtil.getInstance(activity).setValue(PrefsUtil.WALLET_ORIGIN, "restored"); | |
< PrefsUtil.getInstance(activity).setValue(PrefsUtil.WALLET_SCAN_COMPLETE, false); | |
< } | |
< | |
< } catch (JSONException | IOException | DecryptionException je) { | |
< je.printStackTrace(); | |
< } | |
--- | |
> } catch (JSONException | IOException | DecryptionException je) { | |
> je.printStackTrace(); | |
> } | |
539,542c521,524 | |
< for (int i = 0; i < 2; i++) { | |
< AddressFactory.getInstance().account2xpub().put(i, HD_WalletFactory.getInstance(activity).get().getAccount(i).xpubstr()); | |
< AddressFactory.getInstance().xpub2account().put(HD_WalletFactory.getInstance(activity).get().getAccount(i).xpubstr(), i); | |
< } | |
--- | |
> for (int i = 0; i < 2; i++) { | |
> AddressFactory.getInstance().account2xpub().put(i, HD_WalletFactory.getInstance(activity).get().getAccount(i).xpubstr()); | |
> AddressFactory.getInstance().xpub2account().put(HD_WalletFactory.getInstance(activity).get().getAccount(i).xpubstr(), i); | |
> } | |
544,547c526,529 | |
< // | |
< // backup wallet for alpha | |
< // | |
< if (create) { | |
--- | |
> // | |
> // backup wallet for alpha | |
> // | |
> if (create) { | |
549,562c531 | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< () -> HD_WalletFactory.getInstance(activity).get().getMnemonic(), | |
< new SimpleCallback<String>() { | |
< @Override | |
< public void onComplete(String seed1) { | |
< final Intent intent = new Intent(activity, RecoveryWordsActivity.class); | |
< intent.putExtra(RecoveryWordsActivity.WORD_LIST, seed1); | |
< intent.putExtra(RecoveryWordsActivity.PASSPHRASE, passphrase); | |
< activity.startActivity(intent); | |
< activity.finish(); | |
< } | |
< } | |
< ); | |
--- | |
> String seed1 = HD_WalletFactory.getInstance(activity).get().getMnemonic(); | |
564,580c533,537 | |
< } else { | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< () -> { | |
< AccessFactory.getInstance(activity).setIsLoggedIn(true); | |
< TimeOutUtil.getInstance().updatePin(); | |
< return null; | |
< }, | |
< new SimpleCallback<Void>() { | |
< @Override | |
< public void onComplete(Void result) { | |
< AppUtil.getInstance(activity).restartAppFromActivity(activity.getIntent().getExtras(), activity); | |
< activity.finish(); | |
< } | |
< } | |
< ); | |
< } | |
--- | |
> Intent intent = new Intent(activity, RecoveryWordsActivity.class); | |
> intent.putExtra(RecoveryWordsActivity.WORD_LIST, seed1); | |
> intent.putExtra(RecoveryWordsActivity.PASSPHRASE, passphrase); | |
> activity.startActivity(intent); | |
> activity.finish(); | |
583,596c540,543 | |
< if (create) { | |
< msg = activity.getString(R.string.wallet_created_ko); | |
< } else { | |
< msg = activity.getString(R.string.wallet_restored_ko); | |
< } | |
< } | |
< | |
< return msg; | |
< }, | |
< new SimpleCallback<String>() { | |
< @Override | |
< public void onComplete(String msg) { | |
< Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show(); | |
< progressBar.setVisibility(View.INVISIBLE); | |
--- | |
> AccessFactory.getInstance(activity).setIsLoggedIn(true); | |
> TimeOutUtil.getInstance().updatePin(); | |
> AppUtil.getInstance(activity).restartApp(activity.getIntent().getExtras()); | |
> activity.finish(); | |
599,601c546,550 | |
< @Override | |
< public void onException(Throwable t) { | |
< Log.e(TAG, "issue on initThread()", t); | |
--- | |
> } else { | |
> if (create) { | |
> msg = activity.getString(R.string.wallet_created_ko); | |
> } else { | |
> msg = activity.getString(R.string.wallet_restored_ko); | |
604c553,565 | |
< ); | |
--- | |
> | |
> Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show(); | |
> | |
> } catch (final Exception e) { | |
> e.printStackTrace(); | |
> } | |
> | |
> progressBar.setVisibility(View.INVISIBLE); | |
> | |
> Looper.loop(); | |
> | |
> }).start(); | |
> | |
611,612c572,573 | |
< SimpleTaskRunner.create().executeAsyncAndShutdown( | |
< () -> { | |
--- | |
> new Thread(() -> { | |
> Looper.prepare(); | |
614,622c575,583 | |
< if (pin.length() < AccessFactory.MIN_PIN_LENGTH || pin.length() > AccessFactory.MAX_PIN_LENGTH) { | |
< activity.runOnUiThread(() -> { | |
< progressBar.setVisibility(View.INVISIBLE); | |
< pinEntryView.resetPinLen(); | |
< Toast.makeText(activity, R.string.pin_error, Toast.LENGTH_SHORT).show(); | |
< AppUtil.getInstance(activity).restartAppFromActivity(activity.getIntent().getExtras(), activity); | |
< activity.finish(); | |
< }); | |
< } | |
--- | |
> if (pin.length() < AccessFactory.MIN_PIN_LENGTH || pin.length() > AccessFactory.MAX_PIN_LENGTH) { | |
> activity.runOnUiThread(() -> { | |
> progressBar.setVisibility(View.INVISIBLE); | |
> pinEntryView.resetPinLen(); | |
> }); | |
> Toast.makeText(activity, R.string.pin_error, Toast.LENGTH_SHORT).show(); | |
> AppUtil.getInstance(activity).restartApp(activity.getIntent().getExtras()); | |
> activity.finish(); | |
> } | |
624,633c585,594 | |
< String randomKey = AccessFactory.getInstance(activity).getGUID(); | |
< if (StringUtils.isEmpty(randomKey)) { | |
< activity.runOnUiThread(() -> { | |
< progressBar.setVisibility(View.INVISIBLE); | |
< pinEntryView.resetPinLen(); | |
< Toast.makeText(activity, R.string.random_key_error, Toast.LENGTH_SHORT).show(); | |
< AppUtil.getInstance(activity).restartAppFromActivity(activity.getIntent().getExtras(), activity); | |
< activity.finish(); | |
< }); | |
< } | |
--- | |
> String randomKey = AccessFactory.getInstance(activity).getGUID(); | |
> if (randomKey.length() < 1) { | |
> activity.runOnUiThread(() -> { | |
> progressBar.setVisibility(View.INVISIBLE); | |
> pinEntryView.resetPinLen(); | |
> }); | |
> Toast.makeText(activity, R.string.random_key_error, Toast.LENGTH_SHORT).show(); | |
> AppUtil.getInstance(activity).restartApp(activity.getIntent().getExtras()); | |
> activity.finish(); | |
> } | |
635,636c596,597 | |
< String hash = PrefsUtil.getInstance(activity).getValue(PrefsUtil.ACCESS_HASH, ""); | |
< if (AccessFactory.getInstance(activity).validateHash(hash, randomKey, new CharSequenceX(pin), AESUtil.DefaultPBKDF2Iterations)) { | |
--- | |
> String hash = PrefsUtil.getInstance(activity).getValue(PrefsUtil.ACCESS_HASH, ""); | |
> if (AccessFactory.getInstance(activity).validateHash(hash, randomKey, new CharSequenceX(pin), AESUtil.DefaultPBKDF2Iterations)) { | |
638c599 | |
< AccessFactory.getInstance(activity).setPIN(pin); | |
--- | |
> AccessFactory.getInstance(activity).setPIN(pin); | |
640c601 | |
< try { | |
--- | |
> try { | |
642,656c603,604 | |
< if (attemptToLog) { | |
< HD_Wallet hdw = PayloadUtil.getInstance(activity) | |
< .restoreWalletfromJSON(new CharSequenceX(AccessFactory.getInstance(activity).getGUID() + pin)); | |
< | |
< if (isNull(hdw)) { | |
< | |
< activity.runOnUiThread(() -> { | |
< incFailures(); | |
< PrefsUtil.getInstance(activity).setValue(PrefsUtil.ATTEMPTS, failures); | |
< pinEntryMaskLayout.removeAllViews(); | |
< pinEntryView.hideCheckButton(); | |
< pinEntryView.resetPinLen(); | |
< setPinMaskView(); | |
< managePinFailureCount(); | |
< }); | |
--- | |
> if (attemptToLog) { | |
> HD_Wallet hdw = PayloadUtil.getInstance(activity).restoreWalletfromJSON(new CharSequenceX(AccessFactory.getInstance(activity).getGUID() + pin)); | |
658,661c606 | |
< } else { | |
< PrefsUtil.getInstance(activity).setValue(PrefsUtil.ATTEMPTS, 0); | |
< } | |
< } | |
--- | |
> if (isNull(hdw)) { | |
664c609,615 | |
< fireOnSuccessMessage(); | |
--- | |
> incFailures(); | |
> PrefsUtil.getInstance(activity).setValue(PrefsUtil.ATTEMPTS, failures); | |
> pinEntryMaskLayout.removeAllViews(); | |
> pinEntryView.hideCheckButton(); | |
> pinEntryView.resetPinLen(); | |
> setPinMaskView(); | |
> managePinFailureCount(); | |
667,672c618,619 | |
< } catch (final Exception e) { | |
< e.printStackTrace(); | |
< } finally { | |
< activity.runOnUiThread(() -> { | |
< progressBar.setVisibility(View.INVISIBLE); | |
< }); | |
--- | |
> } else { | |
> PrefsUtil.getInstance(activity).setValue(PrefsUtil.ATTEMPTS, 0); | |
674,686d620 | |
< | |
< } else { | |
< activity.runOnUiThread(() -> { | |
< progressBar.setVisibility(View.INVISIBLE); | |
< incFailures(); | |
< PrefsUtil.getInstance(activity).setValue(PrefsUtil.ATTEMPTS, failures); | |
< userInput = new StringBuilder(); | |
< pinEntryMaskLayout.removeAllViews(); | |
< pinEntryView.hideCheckButton(); | |
< pinEntryView.resetPinLen(); | |
< managePinFailureCount(); | |
< }); | |
< | |
688a623,627 | |
> fireOnSuccessMessage(); | |
> | |
> } catch (final Exception e) { | |
> e.printStackTrace(); | |
> } finally { | |
691d629 | |
< | |
694c632,653 | |
< ); | |
--- | |
> | |
> } else { | |
> activity.runOnUiThread(() -> { | |
> progressBar.setVisibility(View.INVISIBLE); | |
> incFailures(); | |
> PrefsUtil.getInstance(activity).setValue(PrefsUtil.ATTEMPTS, failures); | |
> userInput = new StringBuilder(); | |
> pinEntryMaskLayout.removeAllViews(); | |
> pinEntryView.hideCheckButton(); | |
> pinEntryView.resetPinLen(); | |
> managePinFailureCount(); | |
> }); | |
> | |
> } | |
> | |
> activity.runOnUiThread(() -> { | |
> progressBar.setVisibility(View.INVISIBLE); | |
> | |
> }); | |
> | |
> }).start(); | |
> | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/ReceiveActivity.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/ReceiveActivity.java | |
5,6d4 | |
< import android.content.ClipData; | |
< import android.content.ClipboardManager; | |
16d13 | |
< import android.os.Build; | |
22d18 | |
< import android.util.Log; | |
38,39d33 | |
< import com.google.common.collect.ImmutableListMultimap; | |
< import com.google.common.collect.ListMultimap; | |
50d43 | |
< import com.samourai.wallet.util.func.EnumAddressType; | |
55,56d47 | |
< import com.samourai.wallet.util.tech.SimpleCallback; | |
< import com.samourai.wallet.util.tech.SimpleTaskRunner; | |
58d48 | |
< import org.apache.commons.lang3.StringUtils; | |
74d63 | |
< import java.util.concurrent.Callable; | |
87,88d75 | |
< | |
< private static final String TAG = "ReceiveActivity"; | |
159d145 | |
< getWindow().setStatusBarColor(getResources().getColor(R.color.grey_accent)); | |
184a171,172 | |
> useSegwit = PrefsUtil.getInstance(ReceiveActivity.this).getValue(PrefsUtil.USE_SEGWIT, true); | |
> | |
194,219c182,221 | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< new Callable<Void>() { | |
< @Override | |
< public Void call() throws Exception { | |
< | |
< Pair<Integer, String> pair84 = AddressFactory.getInstance(ReceiveActivity.this).getAddress(WALLET_INDEX.BIP84_RECEIVE); | |
< addr84 = pair84.getRight(); | |
< idx84 = pair84.getLeft(); | |
< Pair<Integer, String> pair49 = AddressFactory.getInstance(ReceiveActivity.this).getAddress(WALLET_INDEX.BIP49_RECEIVE); | |
< addr49 = pair49.getRight(); | |
< idx49 = pair49.getLeft(); | |
< Pair<Integer, String> pair44 = AddressFactory.getInstance(ReceiveActivity.this).getAddress(WALLET_INDEX.BIP44_RECEIVE); | |
< addr44 = pair44.getRight(); | |
< idx44 = pair44.getLeft(); | |
< | |
< useSegwit = PrefsUtil.getInstance(ReceiveActivity.this).getValue(PrefsUtil.USE_SEGWIT, true); | |
< | |
< if (useSegwit && isBIP84Selected()) { | |
< addr = addr84; | |
< idx = idx84; | |
< AddressFactory.getInstance(ReceiveActivity.this).increment(WALLET_INDEX.BIP84_RECEIVE); | |
< inc84 = true; | |
< } else if (useSegwit && !isBIP84Selected()) { | |
< addr = addr49; | |
< idx = idx49; | |
--- | |
> Pair<Integer, String> pair84 = AddressFactory.getInstance(ReceiveActivity.this).getAddress(WALLET_INDEX.BIP84_RECEIVE); | |
> addr84 = pair84.getRight(); | |
> idx84 = pair84.getLeft(); | |
> Pair<Integer, String> pair49 = AddressFactory.getInstance(ReceiveActivity.this).getAddress(WALLET_INDEX.BIP49_RECEIVE); | |
> addr49 = pair49.getRight(); | |
> idx49 = pair49.getLeft(); | |
> Pair<Integer, String> pair44 = AddressFactory.getInstance(ReceiveActivity.this).getAddress(WALLET_INDEX.BIP44_RECEIVE); | |
> addr44 = pair44.getRight(); | |
> idx44 = pair44.getLeft(); | |
> | |
> if (!useSegwit) { | |
> addressTypesSpinner.setSelection(2); | |
> } | |
> | |
> if (useSegwit && isBIP84Selected()) { | |
> addr = addr84; | |
> idx = idx84; | |
> AddressFactory.getInstance(ReceiveActivity.this).increment(WALLET_INDEX.BIP84_RECEIVE); | |
> inc84 = true; | |
> } | |
> else if (useSegwit && !isBIP84Selected()) { | |
> addr = addr49; | |
> idx = idx49; | |
> AddressFactory.getInstance(ReceiveActivity.this).increment(WALLET_INDEX.BIP49_RECEIVE); | |
> inc49 = true; | |
> } | |
> else { | |
> addr = addr44; | |
> idx = idx44; | |
> AddressFactory.getInstance(ReceiveActivity.this).increment(WALLET_INDEX.BIP44_RECEIVE); | |
> inc44 = true; | |
> } | |
> addressTypesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { | |
> @Override | |
> public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { | |
> switch (position) { | |
> case 1: { | |
> addr = addr49; | |
> idx = idx49; | |
> if(!inc49) { | |
222,224c224,230 | |
< } else { | |
< addr = addr44; | |
< idx = idx44; | |
--- | |
> } | |
> break; | |
> } | |
> case 2: { | |
> addr = addr44; | |
> idx = idx44; | |
> if(!inc44) { | |
228c234 | |
< return null; | |
--- | |
> break; | |
230,235c236,241 | |
< }, | |
< new SimpleCallback<Void>() { | |
< @Override | |
< public void onComplete(Void result) { | |
< if (!useSegwit) { | |
< addressTypesSpinner.setSelection(2); | |
--- | |
> default: { | |
> addr = addr84; | |
> idx = idx84; | |
> if(!inc84) { | |
> AddressFactory.getInstance(ReceiveActivity.this).increment(WALLET_INDEX.BIP84_RECEIVE); | |
> inc84 = true; | |
237d242 | |
< displayQRCode(); | |
239,291c244,245 | |
< | |
< @Override | |
< public void onException(Throwable t) { | |
< Log.e(TAG, "issue on computing addresses"); | |
< } | |
< }); | |
< | |
< addressTypesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { | |
< @Override | |
< public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< new Callable<Void>() { | |
< @Override | |
< public Void call() throws Exception { | |
< switch (position) { | |
< case 1: { | |
< addr = addr49; | |
< idx = idx49; | |
< if(!inc49) { | |
< AddressFactory.getInstance(ReceiveActivity.this).increment(WALLET_INDEX.BIP49_RECEIVE); | |
< inc49 = true; | |
< } | |
< break; | |
< } | |
< case 2: { | |
< addr = addr44; | |
< idx = idx44; | |
< if(!inc44) { | |
< AddressFactory.getInstance(ReceiveActivity.this).increment(WALLET_INDEX.BIP44_RECEIVE); | |
< inc44 = true; | |
< } | |
< break; | |
< } | |
< default: { | |
< addr = addr84; | |
< idx = idx84; | |
< if(!inc84) { | |
< AddressFactory.getInstance(ReceiveActivity.this).increment(WALLET_INDEX.BIP84_RECEIVE); | |
< inc84 = true; | |
< } | |
< } | |
< } | |
< return null; | |
< } | |
< }, | |
< new SimpleCallback<Void>() { | |
< @Override | |
< public void onComplete(Void result) { | |
< displayQRCode(); | |
< } | |
< } | |
< ); | |
--- | |
> } | |
> displayQRCode(); | |
311,329c265,269 | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< new Callable<Void>() { | |
< @Override | |
< public Void call() throws Exception { | |
< final ClipboardManager clipboard = (ClipboardManager) ReceiveActivity.this.getSystemService(Context.CLIPBOARD_SERVICE); | |
< ClipData clip = null; | |
< clip = ClipData.newPlainText("Receive address", addr); | |
< clipboard.setPrimaryClip(clip); | |
< return null; | |
< } | |
< }, | |
< new SimpleCallback<Void>() { | |
< @Override | |
< public void onComplete(Void result) { | |
< Toast.makeText(ReceiveActivity.this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show(); | |
< } | |
< } | |
< ); | |
--- | |
> android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ReceiveActivity.this.getSystemService(android.content.Context.CLIPBOARD_SERVICE); | |
> android.content.ClipData clip = null; | |
> clip = android.content.ClipData.newPlainText("Receive address", addr); | |
> clipboard.setPrimaryClip(clip); | |
> Toast.makeText(ReceiveActivity.this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show(); | |
380a321,322 | |
> | |
> displayQRCode(); | |
539,598c481,528 | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< new Callable<File>() { | |
< @Override | |
< public File call() throws Exception { | |
< final String strFileName = AppUtil.getInstance(ReceiveActivity.this).getReceiveQRFilename(); | |
< File file = new File(strFileName); | |
< if (!file.exists()) { | |
< try { | |
< file.createNewFile(); | |
< } catch (Exception e) { | |
< Toast.makeText(ReceiveActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show(); | |
< return null; | |
< } | |
< } | |
< file.setReadable(true, false); | |
< | |
< final ClipboardManager clipboard = (ClipboardManager) ReceiveActivity.this.getSystemService(Context.CLIPBOARD_SERVICE); | |
< clipboard.setPrimaryClip(ClipData.newPlainText("Receive address", addr)); | |
< | |
< try (FileOutputStream fos = new FileOutputStream(file)) { | |
< Bitmap bitmap = ((BitmapDrawable) ivQR.getDrawable()).getBitmap(); | |
< bitmap.compress(Bitmap.CompressFormat.PNG, 0, fos); | |
< return file; | |
< } catch (FileNotFoundException fnfe) { | |
< ; | |
< } | |
< | |
< return null; | |
< } | |
< }, | |
< new SimpleCallback<File>() { | |
< @Override | |
< public void onComplete(File file) { | |
< | |
< final Intent intent = new Intent(); | |
< intent.setAction(Intent.ACTION_SEND); | |
< Uri uri; | |
< if (Build.VERSION.SDK_INT >= 24) { | |
< uri = FileProvider.getUriForFile( | |
< ReceiveActivity.this, | |
< getApplicationContext() | |
< .getPackageName() + ".provider", file); | |
< } else { | |
< uri = Uri.fromFile(file); | |
< } | |
< intent.setDataAndType(uri, "image/png"); | |
< intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); | |
< final Intent chooser = Intent.createChooser( | |
< intent, | |
< ReceiveActivity.this.getText(R.string.send_payment_code)); | |
< startActivity(chooser); | |
< } | |
< | |
< @Override | |
< public void onException(Throwable t) { | |
< SimpleCallback.super.onException(t); | |
< } | |
< } | |
< ); | |
--- | |
> String strFileName = AppUtil.getInstance(ReceiveActivity.this).getReceiveQRFilename(); | |
> File file = new File(strFileName); | |
> if (!file.exists()) { | |
> try { | |
> file.createNewFile(); | |
> } catch (Exception e) { | |
> Toast.makeText(ReceiveActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show(); | |
> } | |
> } | |
> file.setReadable(true, false); | |
> | |
> FileOutputStream fos = null; | |
> try { | |
> fos = new FileOutputStream(file); | |
> } catch (FileNotFoundException fnfe) { | |
> ; | |
> } | |
> | |
> android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ReceiveActivity.this.getSystemService(android.content.Context.CLIPBOARD_SERVICE); | |
> android.content.ClipData clip = null; | |
> clip = android.content.ClipData.newPlainText("Receive address", addr); | |
> clipboard.setPrimaryClip(clip); | |
> | |
> if (file != null && fos != null) { | |
> Bitmap bitmap = ((BitmapDrawable) ivQR.getDrawable()).getBitmap(); | |
> bitmap.compress(Bitmap.CompressFormat.PNG, 0, fos); | |
> | |
> try { | |
> fos.close(); | |
> } catch (IOException ioe) { | |
> ; | |
> } | |
> | |
> Intent intent = new Intent(); | |
> intent.setAction(Intent.ACTION_SEND); | |
> intent.setType("image/png"); | |
> if (android.os.Build.VERSION.SDK_INT >= 24) { | |
> //From API 24 sending FIle on intent ,require custom file provider | |
> intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile( | |
> ReceiveActivity.this, | |
> getApplicationContext() | |
> .getPackageName() + ".provider", file)); | |
> } else { | |
> intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); | |
> } | |
> startActivity(Intent.createChooser(intent, ReceiveActivity.this.getText(R.string.send_payment_code))); | |
> } | |
> | |
647d576 | |
< /* | |
652d580 | |
< */ | |
666c594 | |
< String url = null; //"https://samouraiwallet.com/support"; | |
--- | |
> String url = "https://samouraiwallet.com/support"; | |
668c596 | |
< url = null; //"http://72typmu5edrjmcdkzuzmv2i4zqru7rjlrcxwtod4nu6qtfsqegngzead.onion/support"; | |
--- | |
> url = "http://72typmu5edrjmcdkzuzmv2i4zqru7rjlrcxwtod4nu6qtfsqegngzead.onion/support"; | |
748,749c676 | |
< final JSONObject jsonObject = APIFactory.getInstance(ReceiveActivity.this) | |
< .getAddressInfo(new android.util.Pair<>(EnumAddressType.BIP44_LEGACY, addr)); | |
--- | |
> final JSONObject jsonObject = APIFactory.getInstance(ReceiveActivity.this).getAddressInfo(addr); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/RecoveryWordsActivity.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/RecoveryWordsActivity.kt | |
19,21d18 | |
< import com.samourai.wallet.onboard.CreateOrRestoreActivity | |
< import com.samourai.wallet.onboard.OfflineDojoActivityScreen | |
< import com.samourai.wallet.onboard.SetDojoActivity | |
34,35c31 | |
< window.statusBarColor = ContextCompat.getColor(this, R.color.networking) | |
< window.navigationBarColor = ContextCompat.getColor(this, R.color.networking) | |
--- | |
> window.statusBarColor = ContextCompat.getColor(this, R.color.window) | |
58,62c54,57 | |
< if (step >= 2) { | |
< if (AppUtil.getInstance(applicationContext).isOfflineMode()) | |
< startActivity(Intent(this, OfflineDojoActivityScreen::class.java)) | |
< else | |
< startActivity(Intent(this, SetDojoActivity::class.java)) | |
--- | |
> if (step >= 3) { | |
> AccessFactory.getInstance(applicationContext).setIsLoggedIn(true) | |
> TimeOutUtil.getInstance().updatePin() | |
> AppUtil.getInstance(applicationContext).restartApp() | |
66,68c61,64 | |
< 0 -> RecoveryWords.newInstance(ArrayList(wordList)) | |
< 1 -> PassphraseFragment.newInstance(passphrase) | |
< else -> RecoveryWords.newInstance(ArrayList(wordList)) | |
--- | |
> 0 -> RecoveryTemplateDownload() | |
> 1 -> RecoveryWords.newInstance(ArrayList(wordList)) | |
> 2 -> PassphraseFragment.newInstance(passphrase) | |
> else -> RecoveryTemplateDownload() | |
86d81 | |
< /* | |
110c105 | |
< */ | |
--- | |
> | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/RestoreSeedWalletActivity.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/RestoreSeedWalletActivity.java | |
28,29d27 | |
< import com.samourai.wallet.onboard.OfflineDojoActivityScreen; | |
< import com.samourai.wallet.onboard.SetDojoActivity; | |
51d48 | |
< import java.util.HashMap; | |
55d51 | |
< import static com.samourai.wallet.R.id.start; | |
103c99 | |
< getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.networking)); | |
--- | |
> getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.window)); | |
132a129 | |
> ((TextView) forwardButton.getChildAt(0)).setText(R.string.finish); | |
386c383 | |
< synchronized private void toggleLoading() { | |
--- | |
> private void toggleLoading() { | |
410c407 | |
< PayloadUtil.getInstance(RestoreSeedWalletActivity.this).restoreWalletfromJSON(json, skipDojo); | |
--- | |
> PayloadUtil.getInstance(RestoreSeedWalletActivity.this).restoreWalletfromJSON(json,skipDojo); | |
415d411 | |
< PrefsUtil.getInstance(RestoreSeedWalletActivity.this).setValue(PrefsUtil.WALLET_SCAN_COMPLETE, false); | |
442,457c438 | |
< HashMap<String, String> dojoCredsMap = getDojoCredentialsFromBackup(decrypted); | |
< | |
< Intent intent; | |
< | |
< if (AppUtil.getInstance(getApplicationContext()).isOfflineMode()) | |
< intent = new Intent(getApplicationContext(), OfflineDojoActivityScreen.class); | |
< else | |
< intent = new Intent(getApplicationContext(), SetDojoActivity.class); | |
< | |
< if (dojoCredsMap != null) { | |
< intent.putExtra("dojoURL", dojoCredsMap.get("dojoURL")); | |
< intent.putExtra("explorerURL", dojoCredsMap.get("explorerURL")); | |
< intent.putExtra("apikey", dojoCredsMap.get("apikey")); | |
< } | |
< | |
< startActivity(intent); | |
--- | |
> AppUtil.getInstance(RestoreSeedWalletActivity.this).restartApp(); | |
467,484d447 | |
< private HashMap<String, String> getDojoCredentialsFromBackup (String decryptedString) { | |
< HashMap<String, String> dojoCredsMap = new HashMap<>(); | |
< try { | |
< JSONObject decryptedJson = new JSONObject(decryptedString); | |
< JSONObject dojoJson = decryptedJson.getJSONObject("meta").getJSONObject("dojo").getJSONObject("pairing"); | |
< String explorerURL = decryptedJson.getJSONObject("meta").has("explorer_url") | |
< ? decryptedJson.getJSONObject("meta").getString("explorer_url") | |
< : ""; | |
< | |
< dojoCredsMap.put("dojoURL", dojoJson.getString("url")); | |
< dojoCredsMap.put("apikey", dojoJson.getString("apikey")); | |
< dojoCredsMap.put("explorerURL", explorerURL); | |
< } catch (JSONException e) { | |
< return null; | |
< } | |
< return dojoCredsMap; | |
< } | |
< | |
552c515 | |
< PrefsUtil.getInstance(RestoreSeedWalletActivity.this).setValue(PrefsUtil.WALLET_SCAN_COMPLETE, false); | |
--- | |
> PrefsUtil.getInstance(RestoreSeedWalletActivity.this).setValue(PrefsUtil.FIRST_RUN, true); | |
555c518 | |
< PrefsUtil.getInstance(RestoreSeedWalletActivity.this).setValue(PrefsUtil.WALLET_SCAN_COMPLETE, false); | |
--- | |
> PrefsUtil.getInstance(RestoreSeedWalletActivity.this).setValue(PrefsUtil.FIRST_RUN, true); | |
583,588d545 | |
< if (AppUtil.getInstance(getApplicationContext()).isOfflineMode()) | |
< startActivity(new Intent(getApplicationContext(), OfflineDojoActivityScreen.class)); | |
< else | |
< startActivity(new Intent(getApplicationContext(), SetDojoActivity.class)); | |
< | |
< /* | |
592d548 | |
< */ | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/ricochet/RicochetMeta.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/ricochet/RicochetMeta.java | |
60,61c60,61 | |
< private String SAMOURAI_RICOCHET_TX_FEE_ADDRESS = "bc1qsc887pxce0r3qed50e8he49a3amenemgptakg2"; | |
< private String TESTNET_SAMOURAI_RICOCHET_TX_FEE_ADDRESS = "tb1q6qkv397xf3j48mz4sdh9r3a38r22df5ddct587"; | |
--- | |
> private String SAMOURAI_RICOCHET_TX_FEE_ADDRESS = "bc1q52fzmcdqu07j845q7jnwzw9q68s924wdva3lfz"; | |
> private String TESTNET_SAMOURAI_RICOCHET_TX_FEE_ADDRESS = "tb1qkymumss6zj0rxy9l3v5vqxqwwffy8jjsyhrkrg"; | |
562c562 | |
< public static Pair<List<UTXO>, BigInteger> getHop0UTXO( | |
--- | |
> private Pair<List<UTXO>, BigInteger> getHop0UTXO( | |
586a587 | |
> Collections.reverse(utxos); | |
730,751d730 | |
< } | |
< | |
< public static long getFeesFor1Inputs() { | |
< return SamouraiWallet.bDust.longValue() + | |
< RicochetMeta.samouraiFeeAmountV1.longValue() + computeHopFee() + | |
< FeeUtil.getInstance().estimatedFee(1, 3).longValue(); | |
< } | |
< | |
< public static long computeHopFee() { | |
< return computeFeePerHop() * defaultNbHops; | |
< } | |
< | |
< public static long computeFeePerHop() { | |
< final boolean samouraiFeeViaBIP47 = BIP47Meta.getInstance() | |
< .getOutgoingStatus(BIP47Meta.strSamouraiDonationPCode) == BIP47Meta.STATUS_SENT_CFM; | |
< final int hopSz = samouraiFeeViaBIP47 | |
< ? FeeUtil.getInstance().estimatedSize(1, 2) | |
< : FeeUtil.getInstance().estimatedSize(1, 1); | |
< | |
< final long biFeePerKB = FeeUtil.getInstance().getSuggestedFee().getDefaultPerKB().longValue(); | |
< final BigInteger biFeePerHop = FeeUtil.getInstance().calculateFee(hopSz, BigInteger.valueOf(biFeePerKB)); | |
< return biFeePerHop.longValue(); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/SamouraiActivity.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/SamouraiActivity.java | |
3,5d2 | |
< import static com.samourai.wallet.constants.SamouraiAccountIndex.POSTMIX; | |
< import static com.samourai.wallet.util.func.WalletUtil.ASHIGARU_PUB_KEY; | |
< | |
16,18d12 | |
< import androidx.annotation.Nullable; | |
< import androidx.appcompat.app.AppCompatActivity; | |
< | |
19a14 | |
> import com.samourai.wallet.constants.SamouraiAccountIndex; | |
24d18 | |
< import com.samourai.wallet.util.network.WebUtil; | |
26,31c20 | |
< import com.samourai.wallet.util.tech.VerifyPGPSignedClearMessageUtil; | |
< | |
< import org.json.JSONObject; | |
< | |
< import java.util.concurrent.ExecutorService; | |
< import java.util.concurrent.Executors; | |
--- | |
> import com.samourai.wallet.whirlpool.WhirlpoolMeta; | |
32a22,23 | |
> import androidx.annotation.Nullable; | |
> import androidx.appcompat.app.AppCompatActivity; | |
47d37 | |
< | |
57,58c47,48 | |
< if (getIntent().getExtras().getInt("_account") == POSTMIX) { | |
< account = POSTMIX; | |
--- | |
> if (getIntent().getExtras().getInt("_account") == WhirlpoolMeta.getInstance(getApplicationContext()).getWhirlpoolPostmix()) { | |
> account = WhirlpoolMeta.getInstance(getApplicationContext()).getWhirlpoolPostmix(); | |
67c57 | |
< if (account == POSTMIX) { | |
--- | |
> if (account == WhirlpoolMeta.getInstance(getApplication()).getWhirlpoolPostmix()) { | |
132c122 | |
< if (account == POSTMIX) { | |
--- | |
> if (account == SamouraiAccountIndex.POSTMIX) { | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/SamouraiApplication.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/SamouraiApplication.java | |
29d28 | |
< import com.samourai.wallet.util.tech.SimpleCallback; | |
79d77 | |
< /* | |
88d85 | |
< */ | |
100c97 | |
< "Ashigaru Service", | |
--- | |
> "Samourai Service", | |
108d104 | |
< /* | |
114,117c110 | |
< */ | |
< | |
< | |
< //whirlpoolChannel.enableLights(true); | |
--- | |
> whirlpoolChannel.enableLights(true); | |
122,123c115,116 | |
< //manager.createNotificationChannel(whirlpoolChannel); | |
< //manager.createNotificationChannel(whirlpoolNotifications); | |
--- | |
> manager.createNotificationChannel(whirlpoolChannel); | |
> manager.createNotificationChannel(whirlpoolNotifications); | |
170,207c163,171 | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< () -> { | |
< if (tryCount == 1) { | |
< SamouraiTorManager.INSTANCE.newIdentity(); | |
< } else { | |
< SamouraiTorManager.INSTANCE.start(); | |
< } | |
< for (int i = 0; i < 3; ++i) { | |
< pauseMillis(2_000L); | |
< if (SamouraiTorManager.INSTANCE.isConnected()) { | |
< return null; | |
< } | |
< } | |
< pauseMillis(4_000L); | |
< return null; | |
< }, | |
< new SimpleCallback<Object>() { | |
< @Override | |
< public void onComplete(Object result) { | |
< if (! SamouraiTorManager.INSTANCE.isConnected()) { | |
< tryStart(tryCount-1); | |
< } else { | |
< Log.i(TAG, "Tor is started"); | |
< } | |
< } | |
< | |
< @Override | |
< public void onException(Throwable t) { | |
< if (! SamouraiTorManager.INSTANCE.isConnected()) { | |
< tryStart(tryCount-1); | |
< } else { | |
< Log.i(TAG, "Tor is started"); | |
< } | |
< } | |
< } | |
< | |
< ); | |
--- | |
> SimpleTaskRunner.create().executeAsync(() -> { | |
> SamouraiTorManager.INSTANCE.start(); | |
> pauseMillis(3_000L); | |
> if (! SamouraiTorManager.INSTANCE.isConnected()) { | |
> tryStart(tryCount-1); | |
> } else { | |
> Log.i(TAG, "Tor is started"); | |
> } | |
> }); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/SamouraiWallet.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/SamouraiWallet.java | |
11d10 | |
< import org.json.JSONObject; | |
18d16 | |
< public JSONObject releaseNotes = null; | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/batch/BatchSpendActivity.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/batch/BatchSpendActivity.kt | |
52d51 | |
< import com.samourai.wallet.send.SendActivity.isPSBT | |
55a55 | |
> import com.samourai.wallet.send.SendActivity.isPSBT | |
88d87 | |
< import java.text.DecimalFormatSymbols | |
385d383 | |
< | |
387,392d384 | |
< .replace( | |
< java.lang.String.valueOf(DecimalFormatSymbols(Locale.getDefault()).getGroupingSeparator()), | |
< "" | |
< ) | |
< | |
< | |
448d439 | |
< /* | |
452d442 | |
< */ | |
637c627 | |
< var url = "null"; // "https://samouraiwallet.com/support" | |
--- | |
> var url = "https://samouraiwallet.com/support" | |
639c629 | |
< url = "null"; // "http://72typmu5edrjmcdkzuzmv2i4zqru7rjlrcxwtod4nu6qtfsqegngzead.onion/support" | |
--- | |
> url = "http://72typmu5edrjmcdkzuzmv2i4zqru7rjlrcxwtod4nu6qtfsqegngzead.onion/support" | |
647c637,654 | |
< SendActivity.doFees(this@BatchSpendActivity) | |
--- | |
> val highFee = FeeUtil.getInstance().highFee | |
> val normalFee = FeeUtil.getInstance().normalFee | |
> val lowFee = FeeUtil.getInstance().lowFee | |
> var message = getText(R.string.current_fee_selection).toString() + " " + FeeUtil.getInstance().suggestedFee.defaultPerKB.toLong() / 1000L + " " + getText(R.string.slash_sat) | |
> message += "\n" | |
> message += getText(R.string.current_hi_fee_value).toString() + " " + highFee.defaultPerKB.toLong() / 1000L + " " + getText(R.string.slash_sat) | |
> message += "\n" | |
> message += getText(R.string.current_mid_fee_value).toString() + " " + normalFee.defaultPerKB.toLong() / 1000L + " " + getText(R.string.slash_sat) | |
> message += "\n" | |
> message += getText(R.string.current_lo_fee_value).toString() + " " + lowFee.defaultPerKB.toLong() / 1000L + " " + getText(R.string.slash_sat) | |
> val dlg = MaterialAlertDialogBuilder(this@BatchSpendActivity) | |
> .setTitle(R.string.app_name) | |
> .setMessage(message) | |
> .setCancelable(false) | |
> .setPositiveButton(R.string.ok) { _, _ -> } | |
> if (!isFinishing) { | |
> dlg.show() | |
> } | |
782c789 | |
< .getSendAddressString(pcode) | |
--- | |
> .getDestinationAddrFromPcode(pcode) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/cahoots/SelectCahootsType.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/cahoots/SelectCahootsType.java | |
17a18 | |
> import com.samourai.wallet.SamouraiWalletConst; | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/FeeUtil.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/FeeUtil.java | |
3d2 | |
< import static java.lang.Math.max; | |
65,72d63 | |
< public RawFees getRawFees() { | |
< return getRawFees(feeRepresentation); | |
< } | |
< | |
< public RawFees getRawFees(final EnumFeeRepresentation feeRepresentation) { | |
< return rawFeesMap.get(feeRepresentation); | |
< } | |
< | |
217,281d207 | |
< } | |
< | |
< public void normalize() { | |
< | |
< long feeLow = FeeUtil.getInstance().getLowFee().getDefaultPerKB().longValue(); | |
< long feeMed = FeeUtil.getInstance().getNormalFee().getDefaultPerKB().longValue(); | |
< long feeHigh = FeeUtil.getInstance().getHighFee().getDefaultPerKB().longValue(); | |
< | |
< /** | |
< * Finally we don't want to adjust the fees from 1$fee estimator. | |
< * So this condition is added to avoid that. | |
< */ | |
< if (!FeeUtil.getInstance().getFeeRepresentation().is1DolFeeEstimator()) { | |
< if (feeLow == feeMed && feeMed == feeHigh) { | |
< // offset of low and high | |
< feeLow = max(1, feeMed * 85L / 100L); | |
< feeHigh = feeMed * 115L / 100L; | |
< final SuggestedFee lo_sf = new SuggestedFee(); | |
< lo_sf.setDefaultPerKB(BigInteger.valueOf(feeLow / 1000L * 1000L)); | |
< FeeUtil.getInstance().setLowFee(lo_sf); | |
< final SuggestedFee hi_sf = new SuggestedFee(); | |
< hi_sf.setDefaultPerKB(BigInteger.valueOf(feeHigh / 1000L * 1000L)); | |
< FeeUtil.getInstance().setHighFee(hi_sf); | |
< } else if (feeLow == feeMed || feeMed == feeHigh) { | |
< if (FeeUtil.getInstance().getFeeRepresentation().isBitcoindFeeEstimator()) { | |
< // offset of mid | |
< feeMed = (feeLow + feeHigh) / 2L; | |
< final SuggestedFee mi_sf = new SuggestedFee(); | |
< mi_sf.setDefaultPerKB(BigInteger.valueOf(feeMed / 1000L * 1000L)); | |
< FeeUtil.getInstance().setNormalFee(mi_sf); | |
< } else if (feeLow == feeMed) { | |
< feeLow = max(1, feeMed * 85L / 100L); | |
< final SuggestedFee lo_sf = new SuggestedFee(); | |
< lo_sf.setDefaultPerKB(BigInteger.valueOf(feeLow / 1000L * 1000L)); | |
< FeeUtil.getInstance().setLowFee(lo_sf); | |
< } else { | |
< feeHigh = feeMed * 115L / 100L; | |
< final SuggestedFee hi_sf = new SuggestedFee(); | |
< hi_sf.setDefaultPerKB(BigInteger.valueOf(feeHigh / 1000L * 1000L)); | |
< FeeUtil.getInstance().setHighFee(hi_sf); | |
< } | |
< } | |
< } | |
< | |
< /** | |
< * just for security, avoid inconsistent value | |
< */ | |
< if (feeLow < 1000L) { | |
< feeLow = 1000L; | |
< final SuggestedFee lo_sf = new SuggestedFee(); | |
< lo_sf.setDefaultPerKB(BigInteger.valueOf(feeLow)); | |
< FeeUtil.getInstance().setLowFee(lo_sf); | |
< } | |
< if (feeMed < 1000L) { | |
< feeMed = 1000L; | |
< final SuggestedFee mi_sf = new SuggestedFee(); | |
< mi_sf.setDefaultPerKB(BigInteger.valueOf(feeMed)); | |
< FeeUtil.getInstance().setNormalFee(mi_sf); | |
< } | |
< if (feeHigh < 1000L) { | |
< feeHigh = 1000L; | |
< final SuggestedFee hi_sf = new SuggestedFee(); | |
< hi_sf.setDefaultPerKB(BigInteger.valueOf(feeHigh)); | |
< FeeUtil.getInstance().setHighFee(hi_sf); | |
< } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/broadcast/SpendRicochetTxBroadcaster.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/broadcast/SpendRicochetTxBroadcaster.java | |
21d20 | |
< import com.samourai.wallet.util.network.BackendApiAndroid; | |
111c110,111 | |
< final String apiService = BackendApiAndroid.getApiServiceUrl("pushtx/schedule"); | |
--- | |
> String url = WebUtil.getAPIUrl(activity); | |
> url += "pushtx/schedule"; | |
114c114,120 | |
< result = WebUtil.getInstance(activity).tor_postURL(apiService, nLockTimeObj, null); | |
--- | |
> if (SamouraiTorManager.INSTANCE.isRequired()) { | |
> result = WebUtil.getInstance(activity).tor_postURL(url, nLockTimeObj, null); | |
> | |
> } else { | |
> result = WebUtil.getInstance(activity).postURL("application/json", url, nLockTimeObj.toString()); | |
> | |
> } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/CoinSelectionManagerBottomSheet.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/CoinSelectionManagerBottomSheet.kt | |
76,82c76 | |
< val stonewallPossible by model.isStonewallPossible.observeAsState() | |
< | |
< val txData by model.txData.observeAsState() | |
< val destinationAmount by model.impliedAmount.observeAsState() | |
< val feeAggregated by model.feeAggregated.observeAsState() | |
< val amountToLeaveWallet = (destinationAmount ?: 0L) + (feeAggregated ?: 0L) | |
< val isMissingAmount = amountToLeaveWallet > txData!!.totalAmountInTxInput | |
--- | |
> val stonewallPossible by model.isStonewallPossible.observeAsState(); | |
94d87 | |
< | |
96d88 | |
< | |
98,101d89 | |
< enable = false | |
< } | |
< | |
< if (selectionType == CUSTOM && isMissingAmount) { | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/preview/BatchPreviewTx.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/preview/BatchPreviewTx.kt | |
119c119 | |
< .background(Color(0xFF313131), RoundedCornerShape(6.dp)) | |
--- | |
> .background(samouraiLightGreyAccent, RoundedCornerShape(6.dp)) | |
184,185c184,209 | |
< if (txData!!.change > 0L) { | |
< Row ( | |
--- | |
> Row ( | |
> modifier = Modifier | |
> .padding(top = 6.dp, bottom = 6.dp) | |
> .fillMaxWidth(), | |
> horizontalArrangement = Arrangement.spacedBy(12.dp) | |
> ) { | |
> Column { | |
> Icon( | |
> painter = painterResource(id = R.drawable.ic_arrow_left_bottom), | |
> contentDescription = null, | |
> modifier = Modifier.size(18.dp), | |
> tint = Color.White | |
> ) | |
> } | |
> Column ( | |
> modifier = Modifier, | |
> horizontalAlignment = Alignment.Start, | |
> ) { | |
> Text( | |
> text = "Returned to wallet", | |
> color = samouraiTextLightGrey, | |
> fontSize = 12.sp, | |
> fontFamily = robotoMonoBoldFont | |
> ) | |
> } | |
> Column ( | |
187d210 | |
< .padding(top = 6.dp, bottom = 6.dp) | |
189c212 | |
< horizontalArrangement = Arrangement.spacedBy(12.dp) | |
--- | |
> horizontalAlignment = Alignment.End, | |
191,221c214,219 | |
< Column { | |
< Icon( | |
< painter = painterResource(id = R.drawable.ic_arrow_left_bottom), | |
< contentDescription = null, | |
< modifier = Modifier.size(18.dp), | |
< tint = Color.White | |
< ) | |
< } | |
< Column ( | |
< modifier = Modifier, | |
< horizontalAlignment = Alignment.Start, | |
< ) { | |
< Text( | |
< text = "Returned to wallet", | |
< color = samouraiTextLightGrey, | |
< fontSize = 12.sp, | |
< fontFamily = robotoMonoBoldFont | |
< ) | |
< } | |
< Column ( | |
< modifier = Modifier | |
< .fillMaxWidth(), | |
< horizontalAlignment = Alignment.End, | |
< ) { | |
< Text( | |
< text = FormatsUtil.formatBTC(txData!!.change.coerceAtLeast(0L)), | |
< color = Color.White, | |
< fontSize = 12.sp, | |
< fontFamily = robotoMediumNormalFont | |
< ) | |
< } | |
--- | |
> Text( | |
> text = FormatsUtil.formatBTC(txData!!.change.coerceAtLeast(0L)), | |
> color = Color.White, | |
> fontSize = 12.sp, | |
> fontFamily = robotoMediumNormalFont | |
> ) | |
224d221 | |
< | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/preview/CustomPreviewTx.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/preview/CustomPreviewTx.kt | |
135d134 | |
< // security to ensure max 1 utxo for custom postmix, should be never used | |
143c142 | |
< .background(Color(0xFF313131), RoundedCornerShape(6.dp)) | |
--- | |
> .background(samouraiLightGreyAccent, RoundedCornerShape(6.dp)) | |
316c315 | |
< if (!model.isPostmixAccount || CollectionUtils.isEmpty(customSelectionUtxos)) { | |
--- | |
> if (!model.isPostmixAccount || customSelectionUtxos!!.isEmpty()) { | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/preview/RicochetCustomPreviewTx.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/preview/RicochetCustomPreviewTx.kt | |
44,47d43 | |
< import com.samourai.wallet.SamouraiWallet | |
< import com.samourai.wallet.ricochet.RicochetMeta | |
< import com.samourai.wallet.ricochet.RicochetMeta.computeHopFee | |
< import com.samourai.wallet.send.FeeUtil | |
58a55,56 | |
> import com.samourai.wallet.util.func.TransactionOutPointHelper.retrievesAggregatedAmount | |
> import com.samourai.wallet.util.func.TransactionOutPointHelper.toTxOutPoints | |
126a125,129 | |
> val customSelectionUtxos by model.customSelectionUtxos.observeAsState() | |
> if (model.isPostmixAccount && CollectionUtils.size(customSelectionUtxos) > 1) { | |
> model.autoLoadCustomSelectionUtxos(1_000_000L) | |
> model.refreshModel() | |
> } | |
131c134 | |
< .background(Color(0xFF313131), RoundedCornerShape(6.dp)) | |
--- | |
> .background(samouraiLightGreyAccent, RoundedCornerShape(6.dp)) | |
181a185 | |
> val sendType by model.impliedSendType.observeAsState() | |
182a187,190 | |
> val customSelectionAggrAmount = retrievesAggregatedAmount(toTxOutPoints(customSelectionUtxos)) | |
> val isSmallSelectionAmountForRicochet = sendType!!.isRicochet && | |
> sendType!!.isCustomSelection && | |
> customSelectionAggrAmount < 1_000_000L | |
188,198c196 | |
< | |
< val necessaryAmount = | |
< if (CollectionUtils.isEmpty(customSelectionUtxos)) { | |
< destinationAmount!! + SamouraiWallet.bDust.toLong() + | |
< RicochetMeta.samouraiFeeAmountV1.toLong() + computeHopFee() + | |
< FeeUtil.getInstance().estimatedFee(1, 3).toLong() | |
< } else { | |
< amountToLeaveWallet + SamouraiWallet.bDust.toLong() | |
< } | |
< | |
< val isMissingAmount = necessaryAmount > txData!!.totalAmountInTxInput | |
--- | |
> val isMissingAmount = amountToLeaveWallet > txData!!.totalAmountInTxInput | |
256c254,280 | |
< text = FormatsUtil.formatBTC(necessaryAmount - txData!!.totalAmountInTxInput), | |
--- | |
> text = FormatsUtil.formatBTC(amountToLeaveWallet - txData!!.totalAmountInTxInput), | |
> maxLines = 1, | |
> color = samouraiAlerts, | |
> fontSize = 12.sp, | |
> fontFamily = robotoMediumItalicBoldFont | |
> ) | |
> } | |
> } | |
> } | |
> if (isSmallSelectionAmountForRicochet) { | |
> Row ( | |
> horizontalArrangement = Arrangement.spacedBy(12.dp), | |
> verticalAlignment = Alignment.CenterVertically | |
> ) { | |
> Text( | |
> text = "Sum of inputs must be greater than 0.01 BTC", | |
> color = samouraiAlerts, | |
> fontSize = 14.sp, | |
> fontFamily = robotoMediumItalicBoldFont | |
> ) | |
> Column( | |
> modifier = Modifier | |
> .weight(0.35f), | |
> horizontalAlignment = Alignment.End, | |
> ) { | |
> Text( | |
> text = FormatsUtil.formatBTC(amountToLeaveWallet - txData!!.totalAmountInTxInput), | |
326c350 | |
< if (!model.isPostmixAccount || CollectionUtils.isEmpty(customSelectionUtxos)) { | |
--- | |
> if (!model.isPostmixAccount || customSelectionUtxos!!.isEmpty()) { | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/preview/RicochetPreviewTx.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/preview/RicochetPreviewTx.kt | |
111c111 | |
< .background(Color(0xFF313131), RoundedCornerShape(6.dp)) | |
--- | |
> .background(samouraiLightGreyAccent, RoundedCornerShape(6.dp)) | |
133c133 | |
< for (utxoPoint in txData!!.selectedUTXOPoints.sortedWith(MyTransactionOutPointAmountComparator(true))) { | |
--- | |
> for (utxoPoint in txData!!.selectedUTXOPoints.sortedWith(MyTransactionOutPointAmountComparator(false))) { | |
168c168 | |
< .background(Color(0xFF313131), RoundedCornerShape(6.dp)) | |
--- | |
> .background(samouraiLightGreyAccent, RoundedCornerShape(6.dp)) | |
229,230c229,254 | |
< if (txData!!.change > 0L) { | |
< Row ( | |
--- | |
> Row ( | |
> modifier = Modifier | |
> .padding(top = 6.dp, bottom = 6.dp) | |
> .fillMaxWidth(), | |
> horizontalArrangement = Arrangement.spacedBy(12.dp) | |
> ) { | |
> Column { | |
> Icon( | |
> painter = painterResource(id = R.drawable.ic_arrow_left_bottom), | |
> contentDescription = null, | |
> modifier = Modifier.size(18.dp), | |
> tint = Color.White | |
> ) | |
> } | |
> Column ( | |
> modifier = Modifier, | |
> horizontalAlignment = Alignment.Start, | |
> ) { | |
> Text( | |
> text = "Returned to wallet", | |
> color = samouraiTextLightGrey, | |
> fontSize = 12.sp, | |
> fontFamily = robotoMonoBoldFont | |
> ) | |
> } | |
> Column ( | |
232d255 | |
< .padding(top = 6.dp, bottom = 6.dp) | |
234c257 | |
< horizontalArrangement = Arrangement.spacedBy(12.dp) | |
--- | |
> horizontalAlignment = Alignment.End, | |
236,266c259,264 | |
< Column { | |
< Icon( | |
< painter = painterResource(id = R.drawable.ic_arrow_left_bottom), | |
< contentDescription = null, | |
< modifier = Modifier.size(18.dp), | |
< tint = Color.White | |
< ) | |
< } | |
< Column ( | |
< modifier = Modifier, | |
< horizontalAlignment = Alignment.Start, | |
< ) { | |
< Text( | |
< text = "Returned to wallet", | |
< color = samouraiTextLightGrey, | |
< fontSize = 12.sp, | |
< fontFamily = robotoMonoBoldFont | |
< ) | |
< } | |
< Column ( | |
< modifier = Modifier | |
< .fillMaxWidth(), | |
< horizontalAlignment = Alignment.End, | |
< ) { | |
< Text( | |
< text = FormatsUtil.formatBTC(txData!!.change.coerceAtLeast(0L)), | |
< color = Color.White, | |
< fontSize = 12.sp, | |
< fontFamily = robotoMediumNormalFont | |
< ) | |
< } | |
--- | |
> Text( | |
> text = FormatsUtil.formatBTC(txData!!.change.coerceAtLeast(0L)), | |
> color = Color.White, | |
> fontSize = 12.sp, | |
> fontFamily = robotoMediumNormalFont | |
> ) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/preview/SimplePreviewTx.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/preview/SimplePreviewTx.kt | |
110c110 | |
< .background(Color(0xFF313131), RoundedCornerShape(6.dp)) | |
--- | |
> .background(samouraiLightGreyAccent, RoundedCornerShape(6.dp)) | |
167c167 | |
< .background(Color(0xFF313131), RoundedCornerShape(6.dp)) | |
--- | |
> .background(samouraiLightGreyAccent, RoundedCornerShape(6.dp)) | |
228,229c228,253 | |
< if (txData!!.change > 0L) { | |
< Row ( | |
--- | |
> Row ( | |
> modifier = Modifier | |
> .padding(top = 6.dp, bottom = 6.dp) | |
> .fillMaxWidth(), | |
> horizontalArrangement = Arrangement.spacedBy(12.dp) | |
> ) { | |
> Column { | |
> Icon( | |
> painter = painterResource(id = R.drawable.ic_arrow_left_bottom), | |
> contentDescription = null, | |
> modifier = Modifier.size(18.dp), | |
> tint = Color.White | |
> ) | |
> } | |
> Column ( | |
> modifier = Modifier, | |
> horizontalAlignment = Alignment.Start, | |
> ) { | |
> Text( | |
> text = "Returned to wallet", | |
> color = samouraiTextLightGrey, | |
> fontSize = 12.sp, | |
> fontFamily = robotoMonoBoldFont | |
> ) | |
> } | |
> Column ( | |
231d254 | |
< .padding(top = 6.dp, bottom = 6.dp) | |
233c256 | |
< horizontalArrangement = Arrangement.spacedBy(12.dp) | |
--- | |
> horizontalAlignment = Alignment.End, | |
235,265c258,263 | |
< Column { | |
< Icon( | |
< painter = painterResource(id = R.drawable.ic_arrow_left_bottom), | |
< contentDescription = null, | |
< modifier = Modifier.size(18.dp), | |
< tint = Color.White | |
< ) | |
< } | |
< Column ( | |
< modifier = Modifier, | |
< horizontalAlignment = Alignment.Start, | |
< ) { | |
< Text( | |
< text = "Returned to wallet", | |
< color = samouraiTextLightGrey, | |
< fontSize = 12.sp, | |
< fontFamily = robotoMonoBoldFont | |
< ) | |
< } | |
< Column ( | |
< modifier = Modifier | |
< .fillMaxWidth(), | |
< horizontalAlignment = Alignment.End, | |
< ) { | |
< Text( | |
< text = FormatsUtil.formatBTC(txData!!.change.coerceAtLeast(0L)), | |
< color = Color.White, | |
< fontSize = 12.sp, | |
< fontFamily = robotoMediumNormalFont | |
< ) | |
< } | |
--- | |
> Text( | |
> text = FormatsUtil.formatBTC(txData!!.change.coerceAtLeast(0L)), | |
> color = Color.White, | |
> fontSize = 12.sp, | |
> fontFamily = robotoMediumNormalFont | |
> ) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/preview/StonewallPreviewTx.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/preview/StonewallPreviewTx.kt | |
115c115 | |
< .background(Color(0xFF313131), RoundedCornerShape(6.dp)) | |
--- | |
> .background(samouraiLightGreyAccent, RoundedCornerShape(6.dp)) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/ref/EnumTransactionPriority.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/ref/EnumTransactionPriority.java | |
122c122 | |
< case VERY_LOW: | |
--- | |
> case LOW: | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/ref/EnumTxAlert.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/ref/EnumTxAlert.java | |
3,4c3 | |
< import static com.samourai.wallet.constants.SamouraiAccountIndex.DEPOSIT; | |
< import static com.samourai.wallet.util.func.AddressHelper.isMyDepositOrPostmixAddress; | |
--- | |
> import static com.samourai.wallet.util.func.AddressHelper.sendToMyDepositAddress; | |
23d21 | |
< import com.samourai.wallet.send.SendActivity; | |
28d25 | |
< import com.samourai.wallet.util.func.AddressHelper; | |
38d34 | |
< import java.util.Objects; | |
43,60d38 | |
< SENDING_TO_LEGAL_FUND_DONATION_ADDRESS { | |
< @Override | |
< public TxAlertReview createAlert(final ReviewTxModel reviewTxModel) { | |
< return TxAlertReview.create( | |
< R.string.tx_alert_title_send_to_donation_address, | |
< R.string.tx_alert_desc_send_to_donation_address, | |
< null); | |
< } | |
< | |
< @Override | |
< public TxAlertReview checkForAlert(final ReviewTxModel reviewTxModel, boolean forInit) { | |
< if (reviewTxModel.getAddress().equals(SendActivity.DONATION_ADDRESS_MAINNET) | |
< || reviewTxModel.getAddress().equals(SendActivity.DONATION_ADDRESS_TESTNET)) { | |
< return createAlert(reviewTxModel); | |
< } | |
< return null; | |
< } | |
< }, | |
78,82d55 | |
< if (reviewTxModel.getAddress().equals(SendActivity.DONATION_ADDRESS_MAINNET) | |
< || reviewTxModel.getAddress().equals(SendActivity.DONATION_ADDRESS_TESTNET)) { | |
< return null; | |
< } | |
< | |
127,131d99 | |
< if (reviewTxModel.getAddress().equals(SendActivity.DONATION_ADDRESS_MAINNET) | |
< || reviewTxModel.getAddress().equals(SendActivity.DONATION_ADDRESS_TESTNET)) { | |
< return null; | |
< } | |
< | |
328,340c296,300 | |
< | |
< if (reviewTxModel.isPostmixAccount()) { | |
< | |
< final AddressHelper.AddressInfo myDepositOrPostmixAddress = isMyDepositOrPostmixAddress( | |
< reviewTxModel.getApplication(), | |
< reviewTxModel.getAddress(), | |
< 256); | |
< | |
< if (myDepositOrPostmixAddress.isFound() && | |
< Objects.equals(myDepositOrPostmixAddress.getAccountIdx(), DEPOSIT) ) { | |
< return createAlert(reviewTxModel); | |
< } | |
< | |
--- | |
> if (reviewTxModel.isPostmixAccount() && | |
> sendToMyDepositAddress( | |
> reviewTxModel.getApplication(), | |
> reviewTxModel.getAddress())) { | |
> return createAlert(reviewTxModel); | |
344c304,305 | |
< }; | |
--- | |
> } | |
> ; | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/ReviewTxActivity.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/ReviewTxActivity.kt | |
96a97,98 | |
> import com.samourai.wallet.util.func.TransactionOutPointHelper.retrievesAggregatedAmount | |
> import com.samourai.wallet.util.func.TransactionOutPointHelper.toTxOutPoints | |
172,173d173 | |
< val sendType = reviewTxModel.impliedSendType.value | |
< val screen = reviewTxModel.currentScreen.value | |
174a175,180 | |
> val sendType = reviewTxModel.impliedSendType.value | |
> val customSelectionUtxos = reviewTxModel.customSelectionUtxos.value | |
> val customSelectionAggrAmount = retrievesAggregatedAmount(toTxOutPoints(customSelectionUtxos)) | |
> val isSmallSingleUtxoForCustomRicochet = sendType!!.isRicochet && | |
> sendType!!.isCustomSelection && | |
> customSelectionAggrAmount < 1_000_000L | |
176,177c182,183 | |
< if (!isMissingAmount || !sendType!!.isCustomSelection || sendType!!.isJoinbot || screen != EnumReviewScreen.TX_PREVIEW) { | |
< when (screen) { | |
--- | |
> if ((! isSmallSingleUtxoForCustomRicochet && !isMissingAmount) || sendType.isJoinbot) { | |
> when (reviewTxModel.currentScreen.value) { | |
183,186d188 | |
< } else { | |
< if (isMissingAmount && sendType.isCustomSelection) { | |
< Toast.makeText(this, "missing amount!", Toast.LENGTH_LONG).show() | |
< } | |
200,201c202,203 | |
< UpdateStatusBarColorBasedOnDragState(isDraggable = isOnSwipeValidation.value, whiteAlpha = whiteAlpha) | |
< UpdateNavigationBarColorBasedOnDragState(isDraggable = isOnSwipeValidation.value, whiteAlpha = whiteAlpha) | |
--- | |
> UpdateStatusBarColorBasedOnDragState(isDraggable = isOnSwipeValidation, whiteAlpha = whiteAlpha) | |
> UpdateNavigationBarColorBasedOnDragState(isDraggable = isOnSwipeValidation, whiteAlpha = whiteAlpha) | |
363d364 | |
< val sendType by model.impliedSendType.observeAsState() | |
364a366,371 | |
> val sendType by model.impliedSendType.observeAsState() | |
> val customSelectionUtxos by model.customSelectionUtxos.observeAsState() | |
> val customSelectionAggrAmount = retrievesAggregatedAmount(toTxOutPoints(customSelectionUtxos)) | |
> val isSmallSelectionAmountForRicochet = sendType!!.isRicochet && | |
> sendType!!.isCustomSelection && | |
> customSelectionAggrAmount < 1_000_000L | |
367c374 | |
< val backgroundColor = if (account == SamouraiAccountIndex.POSTMIX) Color(0xFF25417b) else Color(0xFF474d59) | |
--- | |
> val backgroundColor = if (account == SamouraiAccountIndex.POSTMIX) samouraiPostmixSpendBlueButton else samouraiSlateGreyAccent | |
374c381 | |
< if (!isMissingAmount || !sendType!!.isCustomSelection || sendType!!.isJoinbot || screen != EnumReviewScreen.TX_PREVIEW) { | |
--- | |
> if ((! isSmallSelectionAmountForRicochet && !isMissingAmount) || sendType!!.isJoinbot) { | |
449a457,459 | |
> val robotoMonoNormalFont = FontFamily( | |
> Font(R.font.roboto_mono, FontWeight.Normal) | |
> ) | |
459c469 | |
< .background(lightenColor(Color(0xFF313131), whiteAlpha), RoundedCornerShape(6.dp)) | |
--- | |
> .background(lightenColor(samouraiLightGreyAccent, whiteAlpha), RoundedCornerShape(6.dp)) | |
554a565,577 | |
> | |
> val alertReusedGlobal = alertReviews.value!!.get(EnumTxAlert.REUSED_SENDING_ADDRESS_GLOBAL) | |
> val isReusedAddrGlobal = if (nonNull(alertReusedGlobal)) | |
> alertReusedGlobal!!.isReusedAddress(model.address) | |
> else false | |
> | |
> val alertReusedLocal = alertReviews.value!!.get(EnumTxAlert.REUSED_SENDING_ADDRESS_LOCAL) | |
> val isReusedAddrLocal = if (nonNull(alertReusedLocal)) | |
> alertReusedLocal!!.isReusedAddress(model.address) | |
> else false | |
> | |
> val isReusedAddr = isReusedAddrGlobal || isReusedAddrLocal | |
> | |
556c579,582 | |
< DisplayAddress(address = model.addressLabel) | |
--- | |
> DisplayAddress( | |
> address = model.addressLabel, | |
> addressReused = isReusedAddr | |
> ) | |
620c646 | |
< addressReused: Boolean = false) { | |
--- | |
> addressReused: Boolean) { | |
703c729 | |
< .background(lightenColor(Color(0xFF313131), whiteAlpha), RoundedCornerShape(6.dp)) | |
--- | |
> .background(lightenColor(samouraiLightGreyAccent, whiteAlpha), RoundedCornerShape(6.dp)) | |
975c1001 | |
< .background(lightenColor( Color(0xFF313131), whiteAlpha), RoundedCornerShape(6.dp)) | |
--- | |
> .background(lightenColor(samouraiLightGreyAccent, whiteAlpha), RoundedCornerShape(6.dp)) | |
1245c1271 | |
< Color(0xFF313131).copy(alphaBackground), | |
--- | |
> samouraiLightGreyAccent.copy(alphaBackground), | |
1293c1319 | |
< isDraggable: Boolean, | |
--- | |
> isDraggable: MutableState<Boolean>, | |
1299c1325 | |
< LaunchedEffect(isDraggable) { | |
--- | |
> LaunchedEffect(isDraggable.value) { | |
1307c1333 | |
< isDraggable: Boolean, | |
--- | |
> isDraggable: MutableState<Boolean>, | |
1313c1339 | |
< LaunchedEffect(isDraggable) { | |
--- | |
> LaunchedEffect(isDraggable.value) { | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/ReviewTxAlert.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/ReviewTxAlert.kt | |
100c100 | |
< .background(Color(0xFF313131), RoundedCornerShape(6.dp)) | |
--- | |
> .background(samouraiLightGreyAccent, RoundedCornerShape(6.dp)) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/ReviewTxFeeManagerBottomSheet.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/ReviewTxFeeManagerBottomSheet.kt | |
28d27 | |
< import androidx.compose.ui.res.stringResource | |
137c136 | |
< model.setTransactionPriorityRequested(EnumTransactionPriority.VERY_LOW) | |
--- | |
> model.setTransactionPriorityRequested(EnumTransactionPriority.LOW) | |
147c146 | |
< Text(text = EnumTransactionPriority.VERY_LOW.getCaption(FeeUtil.getInstance().feeRepresentation)) | |
--- | |
> Text(text = EnumTransactionPriority.LOW.getCaption(FeeUtil.getInstance().feeRepresentation)) | |
251c250 | |
< text = stringResource(id = R.string.estimated_confirmation_time), | |
--- | |
> text = "Est confirmation time", | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/ReviewTxModel.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/ReviewTxModel.java | |
42a43 | |
> import com.samourai.wallet.api.fee.EnumFeeRepresentation; | |
321c322 | |
< final Map<String, Boolean> content = Maps.newHashMap(seenAddresses.getContent()); | |
--- | |
> final Map<String, Boolean> content = seenAddresses.getContent(); | |
357c358 | |
< setAddress(BIP47Util.getInstance(getApplication()).getSendAddressString(pcode)); | |
--- | |
> setAddress(BIP47Util.getInstance(getApplication()).getDestinationAddrFromPcode(pcode)); | |
420c421 | |
< SimpleTaskRunner.create().executeAsync(true, new Callable<Object>() { | |
--- | |
> SimpleTaskRunner.create().executeAsync(new Callable<Object>() { | |
503c504 | |
< SimpleTaskRunner.create().executeAsync(true, new Callable<Long>() { | |
--- | |
> SimpleTaskRunner.create().executeAsync(new Callable<Long>() { | |
585,602c586,592 | |
< transactionPriority.postValue(findTransactionPriority( | |
< feeRates, | |
< getFeeHighRate().getValue(), | |
< getFeeLowRate().getValue())); | |
< } | |
< } | |
< | |
< public static EnumTransactionPriority findTransactionPriority( | |
< final long feeRates, | |
< final long feeRatesHigh, | |
< final long feeRatesLow | |
< ) { | |
< if (feeRates >= feeRatesHigh) { | |
< return EnumTransactionPriority.NEXT_BLOCK; | |
< } else if (feeRates <= feeRatesLow) { | |
< return EnumTransactionPriority.VERY_LOW; | |
< } else { | |
< return EnumTransactionPriority.NORMAL; | |
--- | |
> if (feeRates >= getFeeHighRate().getValue()) { | |
> transactionPriority.postValue(EnumTransactionPriority.NEXT_BLOCK); | |
> } else if (feeRates <= getFeeLowRate().getValue()) { | |
> transactionPriority.postValue(EnumTransactionPriority.LOW); | |
> } else { | |
> transactionPriority.postValue(EnumTransactionPriority.NORMAL); | |
> } | |
762c752 | |
< //addCustomSelectionUtxos(txData.getValue().getSelectedUTXO()); | |
--- | |
> addCustomSelectionUtxos(txData.getValue().getSelectedUTXO()); | |
1373c1363 | |
< //addCustomSelectionUtxos(txData.getValue().getSelectedUTXO()); | |
--- | |
> addCustomSelectionUtxos(txData.getValue().getSelectedUTXO()); | |
1728,1729d1717 | |
< FeeUtil.getInstance().normalize(); | |
< | |
1732a1721,1769 | |
> | |
> if (feeLow == feeMed && feeMed == feeHigh) { | |
> // offset of low and high | |
> feeLow = max(1, feeMed * 85L / 100L); | |
> feeHigh = feeMed * 115L / 100L; | |
> final SuggestedFee lo_sf = new SuggestedFee(); | |
> lo_sf.setDefaultPerKB(BigInteger.valueOf(feeLow / 1000L * 1000L)); | |
> FeeUtil.getInstance().setLowFee(lo_sf); | |
> final SuggestedFee hi_sf = new SuggestedFee(); | |
> hi_sf.setDefaultPerKB(BigInteger.valueOf(feeHigh / 1000L * 1000L)); | |
> FeeUtil.getInstance().setHighFee(hi_sf); | |
> } else if (feeLow == feeMed || feeMed == feeHigh) { | |
> if (FeeUtil.getInstance().getFeeRepresentation() == EnumFeeRepresentation.BLOCK_COUNT) { | |
> // offset of mid | |
> feeMed = (feeLow + feeHigh) / 2L; | |
> final SuggestedFee mi_sf = new SuggestedFee(); | |
> mi_sf.setDefaultPerKB(BigInteger.valueOf(feeMed / 1000L * 1000L)); | |
> FeeUtil.getInstance().setNormalFee(mi_sf); | |
> } else if (feeLow == feeMed) { | |
> feeLow = max(1, feeMed * 85L / 100L); | |
> final SuggestedFee lo_sf = new SuggestedFee(); | |
> lo_sf.setDefaultPerKB(BigInteger.valueOf(feeLow / 1000L * 1000L)); | |
> FeeUtil.getInstance().setLowFee(lo_sf); | |
> } else { | |
> feeHigh = feeMed * 115L / 100L; | |
> final SuggestedFee hi_sf = new SuggestedFee(); | |
> hi_sf.setDefaultPerKB(BigInteger.valueOf(feeHigh / 1000L * 1000L)); | |
> FeeUtil.getInstance().setHighFee(hi_sf); | |
> } | |
> } | |
> | |
> if (feeLow < 1000L) { | |
> feeLow = 1000L; | |
> final SuggestedFee lo_sf = new SuggestedFee(); | |
> lo_sf.setDefaultPerKB(BigInteger.valueOf(feeLow)); | |
> FeeUtil.getInstance().setLowFee(lo_sf); | |
> } | |
> if (feeMed < 1000L) { | |
> feeMed = 1000L; | |
> final SuggestedFee mi_sf = new SuggestedFee(); | |
> mi_sf.setDefaultPerKB(BigInteger.valueOf(feeMed)); | |
> FeeUtil.getInstance().setNormalFee(mi_sf); | |
> } | |
> if (feeHigh < 1000L) { | |
> feeHigh = 1000L; | |
> final SuggestedFee hi_sf = new SuggestedFee(); | |
> hi_sf.setDefaultPerKB(BigInteger.valueOf(feeHigh)); | |
> FeeUtil.getInstance().setHighFee(hi_sf); | |
> } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/review/sendbutton/SwipeSendButton.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/review/sendbutton/SwipeSendButton.kt | |
63,64d62 | |
< import com.samourai.wallet.util.tech.HapticHelper.Companion.hapticDaDuration | |
< import com.samourai.wallet.util.tech.HapticHelper.Companion.hapticTadaPattern | |
196a195 | |
> val hapticTadaPattern = longArrayOf(30, 64, 120, 64) | |
278c277 | |
< vibratePhone(durationMs = hapticDaDuration, context = context) | |
--- | |
> vibratePhone(durationMs = 50L, context = context) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/send/SendActivity.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/send/SendActivity.java | |
3,13d2 | |
< import static com.samourai.wallet.send.batch.InputBatchSpendHelper.canParseAsBatchSpend; | |
< import static com.samourai.wallet.send.cahoots.JoinbotHelper.UTXO_COMPARATOR_BY_VALUE; | |
< import static com.samourai.wallet.send.cahoots.JoinbotHelper.isJoinbotPossibleWithCurrentUserUTXOs; | |
< import static com.samourai.wallet.util.func.SatoshiBitcoinUnitHelper.getBtcValue; | |
< import static com.samourai.wallet.util.func.SatoshiBitcoinUnitHelper.getSatValue; | |
< import static org.apache.commons.lang3.StringUtils.EMPTY; | |
< import static org.apache.commons.lang3.StringUtils.trim; | |
< import static java.lang.Math.max; | |
< import static java.util.Objects.isNull; | |
< import static java.util.Objects.nonNull; | |
< | |
47,52d35 | |
< import androidx.appcompat.widget.SwitchCompat; | |
< import androidx.appcompat.widget.Toolbar; | |
< import androidx.constraintlayout.widget.ConstraintLayout; | |
< import androidx.constraintlayout.widget.Group; | |
< import androidx.core.content.ContextCompat; | |
< | |
66,69d48 | |
< import com.samourai.wallet.api.fee.EnumFeeBlockCount; | |
< import com.samourai.wallet.api.fee.EnumFeeRate; | |
< import com.samourai.wallet.api.fee.EnumFeeRepresentation; | |
< import com.samourai.wallet.api.fee.RawFees; | |
105d83 | |
< import com.samourai.wallet.util.network.BackendApiAndroid; | |
118d95 | |
< import org.apache.commons.collections4.CollectionUtils; | |
147a125,129 | |
> import androidx.appcompat.widget.SwitchCompat; | |
> import androidx.appcompat.widget.Toolbar; | |
> import androidx.constraintlayout.widget.ConstraintLayout; | |
> import androidx.constraintlayout.widget.Group; | |
> import androidx.core.content.ContextCompat; | |
155a138,147 | |
> import static com.samourai.wallet.send.batch.InputBatchSpendHelper.canParseAsBatchSpend; | |
> import static com.samourai.wallet.send.cahoots.JoinbotHelper.UTXO_COMPARATOR_BY_VALUE; | |
> import static com.samourai.wallet.send.cahoots.JoinbotHelper.isJoinbotPossibleWithCurrentUserUTXOs; | |
> import static com.samourai.wallet.util.func.SatoshiBitcoinUnitHelper.getBtcValue; | |
> import static com.samourai.wallet.util.func.SatoshiBitcoinUnitHelper.getSatValue; | |
> import static java.util.Objects.isNull; | |
> import static java.util.Objects.nonNull; | |
> import static org.apache.commons.lang3.StringUtils.EMPTY; | |
> import static org.apache.commons.lang3.StringUtils.trim; | |
> | |
227,229d218 | |
< public final static String DONATION_ADDRESS_MAINNET = "bc1SamouraiDonationAddress_Mainnet"; | |
< public final static String DONATION_ADDRESS_TESTNET = "tb1q930wg92ymtz7a56c5ppfcgcpvphcrzcan53sx5"; | |
< | |
263,265c252,254 | |
< // joinbotSwitch = sendTransactionDetailsView.getTransactionView().findViewById(R.id.joinbot_switch); | |
< // joinbotTitle = sendTransactionDetailsView.getTransactionView().findViewById(R.id.joinbot_title); | |
< // joinbotDesc = sendTransactionDetailsView.getTransactionView().findViewById(R.id.joinbot_desc); | |
--- | |
> joinbotSwitch = sendTransactionDetailsView.getTransactionView().findViewById(R.id.joinbot_switch); | |
> joinbotTitle = sendTransactionDetailsView.getTransactionView().findViewById(R.id.joinbot_title); | |
> joinbotDesc = sendTransactionDetailsView.getTransactionView().findViewById(R.id.joinbot_desc); | |
281c270 | |
< // premiumAddonsJoinbot = sendTransactionDetailsView.findViewById(R.id.premium_addons_joinbot); | |
--- | |
> premiumAddonsJoinbot = sendTransactionDetailsView.findViewById(R.id.premium_addons_joinbot); | |
312c301 | |
< //setUpJoinBot(); | |
--- | |
> setUpJoinBot(); | |
327,334d315 | |
< if (getIntent().getExtras().containsKey("isDonation") && getIntent().getExtras().getBoolean("isDonation")) { | |
< if (SamouraiWallet.getInstance().isTestNet()) | |
< setToAddress(DONATION_ADDRESS_TESTNET); | |
< else | |
< setToAddress(DONATION_ADDRESS_MAINNET); | |
< toAddressEditText.setEnabled(false); | |
< } | |
< | |
347,348c328,329 | |
< return !AppUtil.getInstance(SendActivity.this).isBroadcastDisabled(); /*&& | |
< joinbotSwitch.isChecked();*/ | |
--- | |
> return !AppUtil.getInstance(SendActivity.this).isBroadcastDisabled() && | |
> joinbotSwitch.isChecked(); | |
393c374 | |
< if (CollectionUtils.isNotEmpty(preselectedUTXOs) && balance < 1_000_000l) { | |
--- | |
> if (preselectedUTXOs != null && preselectedUTXOs.size() > 0 && balance < 1_000_000l) { | |
424,426c405 | |
< try { | |
< premiumAddonsJoinbot.setVisibility(View.GONE); | |
< } catch (Exception ignored) {} | |
--- | |
> premiumAddonsJoinbot.setVisibility(View.GONE); | |
487c466 | |
< if (amount < max(0, balance - (RicochetMeta.samouraiFeeAmountV2.add(BigInteger.valueOf(50000L))).longValue())) { | |
--- | |
> if (amount < (balance - (RicochetMeta.samouraiFeeAmountV2.add(BigInteger.valueOf(50000L))).longValue())) { | |
494d472 | |
< SPEND_TYPE = SPEND_RICOCHET; | |
502d479 | |
< SPEND_TYPE = sendTransactionDetailsView.getStoneWallSwitch().isChecked() ? SPEND_BOLTZMANN : SPEND_SIMPLE; | |
588c565 | |
< //checkValidForJoinbot(); | |
--- | |
> checkValidForJoinbot(); | |
593c570 | |
< //joinbotSwitch.setChecked(false); | |
--- | |
> joinbotSwitch.setChecked(false); | |
612d588 | |
< /* | |
616d591 | |
< */ | |
657c632 | |
< XManagerClient xManagerClient = new XManagerClient(httpClient, SamouraiWallet.getInstance().isTestNet(), SamouraiTorManager.INSTANCE.isConnected()); | |
--- | |
> XManagerClient xManagerClient = new XManagerClient(httpClient, SamouraiWallet.getInstance().isTestNet(), SamouraiTorManager.INSTANCE.isConnected()); | |
960,964d934 | |
< | |
< if (amount == balance) { | |
< SPEND_TYPE = SPEND_SIMPLE; | |
< } | |
< | |
983c953 | |
< /* | |
--- | |
> | |
987c957 | |
< */ | |
--- | |
> | |
1750d1719 | |
< /* | |
1754d1722 | |
< */ | |
1936c1904,1905 | |
< final String apiServiceUrl = BackendApiAndroid.getApiServiceUrl("pushtx/schedule"); | |
--- | |
> String url = WebUtil.getAPIUrl(SendActivity.this); | |
> url += "pushtx/schedule"; | |
1939c1908,1915 | |
< result = WebUtil.getInstance(SendActivity.this).tor_postURL(apiServiceUrl, nLockTimeObj, null); | |
--- | |
> if (SamouraiTorManager.INSTANCE.isRequired()) { | |
> result = WebUtil.getInstance(SendActivity.this).tor_postURL(url, nLockTimeObj, null); | |
> | |
> } else { | |
> result = WebUtil.getInstance(SendActivity.this).postURL("application/json", url, nLockTimeObj.toString()); | |
> | |
> } | |
> // Log.d("SendActivity", "Ricochet staggered result:" + result); | |
2199c2175 | |
< .getSendAddressString(pcode); | |
--- | |
> .getDestinationAddrFromPcode(pcode); | |
2244d2219 | |
< /* | |
2249d2223 | |
< */ | |
2375c2349 | |
< doFees(SendActivity.this); | |
--- | |
> doFees(); | |
2378c2352 | |
< } /*else if (id == R.id.action_support) { | |
--- | |
> } else if (id == R.id.action_support) { | |
2380c2354 | |
< } */ else { | |
--- | |
> } else { | |
2420c2394 | |
< String url = null; //"https://samouraiwallet.com/support"; | |
--- | |
> String url = "https://samouraiwallet.com/support"; | |
2422c2396 | |
< url = null; //"http://72typmu5edrjmcdkzuzmv2i4zqru7rjlrcxwtod4nu6qtfsqegngzead.onion/support"; | |
--- | |
> url = "http://72typmu5edrjmcdkzuzmv2i4zqru7rjlrcxwtod4nu6qtfsqegngzead.onion/support"; | |
2450c2424 | |
< public static void doFees(final SamouraiActivity activity) { | |
--- | |
> private void doFees() { | |
2452c2426,2436 | |
< final StringBuilder sb = new StringBuilder(); | |
--- | |
> final SuggestedFee highFee = FeeUtil.getInstance().getHighFee(); | |
> final SuggestedFee normalFee = FeeUtil.getInstance().getNormalFee(); | |
> final SuggestedFee lowFee = FeeUtil.getInstance().getLowFee(); | |
> | |
> String message = getText(R.string.current_fee_selection) + " " + (FeeUtil.getInstance().getSuggestedFee().getDefaultPerKB().longValue() / 1000L) + " " + getText(R.string.slash_sat); | |
> message += "\n"; | |
> message += getText(R.string.current_hi_fee_value) + " " + (highFee.getDefaultPerKB().longValue() / 1000L) + " " + getText(R.string.slash_sat); | |
> message += "\n"; | |
> message += getText(R.string.current_mid_fee_value) + " " + (normalFee.getDefaultPerKB().longValue() / 1000L) + " " + getText(R.string.slash_sat); | |
> message += "\n"; | |
> message += getText(R.string.current_lo_fee_value) + " " + (lowFee.getDefaultPerKB().longValue() / 1000L) + " " + getText(R.string.slash_sat); | |
2454,2494c2438 | |
< for (final EnumFeeRepresentation feeRepresentation : EnumFeeRepresentation.values()) { | |
< sb.append(feeRepresentation.name()); | |
< sb.append(":"); | |
< sb.append(System.lineSeparator()); | |
< final RawFees rawFees = FeeUtil.getInstance().getRawFees(feeRepresentation); | |
< if (isNull(rawFees) || ! rawFees.hasFee()) { | |
< sb.append("none"); | |
< sb.append(System.lineSeparator()); | |
< } else { | |
< switch (feeRepresentation) { | |
< case NEXT_BLOCK_RATE: | |
< for (final EnumFeeRate feeRateType : EnumFeeRate.values()) { | |
< final Integer fee = rawFees.getFee(feeRateType); | |
< if (nonNull(fee)) { | |
< sb.append(feeRateType.getRateAsString()); | |
< sb.append(": "); | |
< sb.append(fee); | |
< sb.append(" sat/vB"); | |
< sb.append(System.lineSeparator()); | |
< } | |
< } | |
< break; | |
< case BLOCK_COUNT: | |
< for (final EnumFeeBlockCount blockCount : EnumFeeBlockCount.values()) { | |
< final Integer fee = rawFees.getFee(blockCount); | |
< if (nonNull(fee)) { | |
< sb.append(blockCount.getBlockCount()); | |
< sb.append(": "); | |
< sb.append(fee); | |
< sb.append(" sat/vB"); | |
< sb.append(System.lineSeparator()); | |
< } | |
< } | |
< break; | |
< } | |
< | |
< } | |
< sb.append(System.lineSeparator()); | |
< } | |
< | |
< final MaterialAlertDialogBuilder dlg = new MaterialAlertDialogBuilder(activity) | |
--- | |
> final MaterialAlertDialogBuilder dlg = new MaterialAlertDialogBuilder(SendActivity.this) | |
2496c2440 | |
< .setMessage(sb.toString()) | |
--- | |
> .setMessage(message) | |
2499,2500c2443 | |
< | |
< if (!activity.isFinishing()) { | |
--- | |
> if (!isFinishing()) { | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/service/WalletRefreshWorker.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/service/WalletRefreshWorker.kt | |
1,159c1,190 | |
< //package com.samourai.wallet.service | |
< // | |
< //import android.content.Context | |
< //import android.content.Intent | |
< //import android.util.Log | |
< //import android.widget.Toast | |
< //import androidx.localbroadcastmanager.content.LocalBroadcastManager | |
< //import androidx.work.CoroutineWorker | |
< //import androidx.work.OneTimeWorkRequestBuilder | |
< //import androidx.work.Operation | |
< //import androidx.work.WorkManager | |
< //import androidx.work.WorkerParameters | |
< //import androidx.work.workDataOf | |
< //import com.samourai.wallet.SamouraiWallet | |
< //import com.samourai.wallet.access.AccessFactory | |
< //import com.samourai.wallet.api.APIFactory | |
< //import com.samourai.wallet.bip47.BIP47Meta | |
< //import com.samourai.wallet.bip47.BIP47Util | |
< //import com.samourai.wallet.crypto.AESUtil | |
< //import com.samourai.wallet.crypto.DecryptionException | |
< //import com.samourai.wallet.payload.PayloadUtil | |
< //import com.samourai.wallet.ricochet.RicochetMeta | |
< //import com.samourai.wallet.util.CharSequenceX | |
< //import com.samourai.wallet.util.PrefsUtil | |
< //import com.samourai.wallet.util.func.WalletUtil | |
< //import com.samourai.wallet.util.tech.AppUtil | |
< //import kotlinx.coroutines.Dispatchers | |
< //import kotlinx.coroutines.async | |
< //import kotlinx.coroutines.coroutineScope | |
< //import kotlinx.coroutines.launch | |
< //import kotlinx.coroutines.withContext | |
< //import org.apache.commons.lang3.tuple.Pair | |
< //import org.bitcoinj.core.AddressFormatException | |
< //import org.bitcoinj.crypto.MnemonicException.MnemonicLengthException | |
< //import org.json.JSONException | |
< //import java.io.IOException | |
< // | |
< //class WalletRefreshWorker(private val context: Context, private val parameters: WorkerParameters) : | |
< // CoroutineWorker(context, parameters) { | |
< // | |
< // | |
< // override suspend fun doWork(): Result { | |
< // | |
< // val launch: Boolean = parameters.inputData.getBoolean(LAUNCHED, false) | |
< // val notifTx: Boolean = parameters.inputData.getBoolean(NOTIF_TX, false) | |
< // | |
< // AppUtil.getInstance(applicationContext).setWalletLoading(true) | |
< // APIFactory.getInstance(context).stayingAlive() | |
< // APIFactory.getInstance(context).initWallet() | |
< // | |
< // val _intentDisplay = Intent("com.samourai.wallet.BalanceFragment.DISPLAY") | |
< // LocalBroadcastManager.getInstance(context).sendBroadcast(_intentDisplay) | |
< // | |
< // if (notifTx && !AppUtil.getInstance(context).isOfflineMode) { | |
< // // | |
< // // check for incoming payment code notification tx | |
< // // | |
< // try { | |
< // val pcode = BIP47Util.getInstance(context).paymentCode | |
< // // Log.i("BalanceFragment", "payment code:" + pcode.toString()); | |
< //// Log.i("BalanceFragment", "notification address:" + pcode.notificationAddress().getAddressString()); | |
< // APIFactory.getInstance(context).getNotifAddress(pcode.notificationAddress(SamouraiWallet.getInstance().currentNetworkParams).addressString) | |
< // } catch (afe: AddressFormatException) { | |
< // afe.printStackTrace() | |
< // Toast.makeText(context, "HD wallet error", Toast.LENGTH_SHORT).show() | |
< // } catch (ex: Exception) { | |
< // ex.printStackTrace() | |
< // } | |
< // | |
< // loadConnectedPaynyms() | |
< // val _intent = Intent("com.samourai.wallet.MainActivity2.RESTART_SERVICE") | |
< // LocalBroadcastManager.getInstance(context).sendBroadcast(_intent) | |
< // } | |
< // | |
< // if (launch) { | |
< // | |
< // if (PrefsUtil.getInstance(context).getValue(PrefsUtil.GUID_V, 0) < 4) { | |
< // | |
< // Log.i(TAG, "guid_v < 4") | |
< // | |
< // try { | |
< // val _guid = AccessFactory.getInstance(context).createGUID() | |
< // val _hash = AccessFactory.getInstance(context).getHash(_guid, CharSequenceX(AccessFactory.getInstance(context).pin), AESUtil.DefaultPBKDF2Iterations) | |
< // PayloadUtil.getInstance(context).saveWalletToJSON(CharSequenceX(_guid + AccessFactory.getInstance().pin)) | |
< // PrefsUtil.getInstance(context).setValue(PrefsUtil.ACCESS_HASH, _hash) | |
< // PrefsUtil.getInstance(context).setValue(PrefsUtil.ACCESS_HASH2, _hash) | |
< // Log.i(TAG, "guid_v == 4") | |
< // } catch (e: MnemonicLengthException) { | |
< // } catch (e: IOException) { | |
< // } catch (e: JSONException) { | |
< // } catch (e: DecryptionException) { | |
< // } | |
< // } | |
< // | |
< // try { | |
< // val prevIdx = RicochetMeta.getInstance(context).index | |
< // APIFactory.getInstance(context).parseRicochetXPUB() | |
< // if (prevIdx > RicochetMeta.getInstance(context).index) { | |
< // RicochetMeta.getInstance(context).index = prevIdx | |
< // } | |
< // } catch (je: JSONException) { | |
< // } catch (e: Exception) { | |
< // } | |
< // } | |
< // | |
< // withContext(Dispatchers.IO) { | |
< // try { | |
< // WalletUtil.saveWallet(context) | |
< // } catch (ignored: Exception) { | |
< // } | |
< // } | |
< // | |
< // withContext(Dispatchers.Main) { | |
< // val _intent = Intent("com.samourai.wallet.BalanceFragment.DISPLAY") | |
< // LocalBroadcastManager.getInstance(context).sendBroadcast(_intent) | |
< // } | |
< // | |
< // AppUtil.getInstance(applicationContext).setWalletLoading(false) | |
< // val data = workDataOf(); | |
< // return Result.success(data) | |
< // } | |
< // | |
< // private fun loadConnectedPaynyms() { | |
< // // | |
< // // check on outgoing payment code notification tx | |
< // // | |
< // val outgoingUnconfirmed: List<Pair<String?, String?>> = BIP47Meta.getInstance().outgoingUnconfirmed | |
< // for (pair in outgoingUnconfirmed) { | |
< // val confirmations = APIFactory.getInstance(context).getNotifTxConfirmations(pair.right) | |
< // if (confirmations > 0) { | |
< // BIP47Meta.getInstance().setOutgoingStatus(pair.left, BIP47Meta.STATUS_SENT_CFM) | |
< // } | |
< // if (confirmations == -1) { | |
< // BIP47Meta.getInstance().setOutgoingStatus(pair.left, BIP47Meta.STATUS_NOT_SENT) | |
< // } | |
< // } | |
< // } | |
< // | |
< // companion object { | |
< // const val LAUNCHED = "LAUNCHED" | |
< // const val NOTIF_TX = "NOTIF_TX" | |
< // private const val TAG = "WalletRefreshWorker" | |
< // | |
< // fun enqueue(context: Context, notifTx: Boolean = false, launched: Boolean = false): Operation { | |
< // val workManager = WorkManager.getInstance(context) | |
< // val workRequest = OneTimeWorkRequestBuilder<WalletRefreshWorker>().apply { | |
< // setInputData( | |
< // workDataOf( | |
< // LAUNCHED to launched, | |
< // NOTIF_TX to notifTx | |
< // ) | |
< // ) | |
< // }.build() | |
< // return workManager.enqueue(workRequest) | |
< // } | |
< // } | |
< // | |
< // | |
< //} | |
\ No newline at end of file | |
--- | |
> package com.samourai.wallet.service | |
> | |
> import android.content.Context | |
> import android.content.Intent | |
> import android.util.Log | |
> import android.widget.Toast | |
> import androidx.localbroadcastmanager.content.LocalBroadcastManager | |
> import androidx.work.* | |
> import com.samourai.wallet.BuildConfig | |
> import com.samourai.wallet.SamouraiWallet | |
> import com.samourai.wallet.access.AccessFactory | |
> import com.samourai.wallet.api.APIFactory | |
> import com.samourai.wallet.bip47.BIP47Meta | |
> import com.samourai.wallet.bip47.BIP47Util | |
> import com.samourai.wallet.crypto.AESUtil | |
> import com.samourai.wallet.crypto.DecryptionException | |
> import com.samourai.wallet.hd.HD_WalletFactory | |
> import com.samourai.wallet.payload.PayloadUtil | |
> import com.samourai.wallet.ricochet.RicochetMeta | |
> import com.samourai.wallet.segwit.BIP49Util | |
> import com.samourai.wallet.segwit.BIP84Util | |
> import com.samourai.wallet.util.tech.AppUtil | |
> import com.samourai.wallet.util.CharSequenceX | |
> import com.samourai.wallet.util.tech.LogUtil | |
> import com.samourai.wallet.util.PrefsUtil | |
> import com.samourai.wallet.whirlpool.WhirlpoolMeta | |
> import kotlinx.coroutines.Dispatchers | |
> import kotlinx.coroutines.withContext | |
> import org.apache.commons.lang3.tuple.Pair | |
> import org.bitcoinj.core.AddressFormatException | |
> import org.bitcoinj.crypto.MnemonicException.MnemonicLengthException | |
> import org.json.JSONException | |
> import java.io.IOException | |
> | |
> class WalletRefreshWorker(private val context: Context, private val parameters: WorkerParameters) : | |
> CoroutineWorker(context, parameters) { | |
> | |
> | |
> override suspend fun doWork(): Result { | |
> | |
> val launch: Boolean = parameters.inputData.getBoolean(LAUNCHED, false) | |
> val notifTx: Boolean = parameters.inputData.getBoolean(NOTIF_TX, false) | |
> | |
> AppUtil.getInstance(applicationContext).setWalletLoading(true) | |
> APIFactory.getInstance(context).stayingAlive() | |
> APIFactory.getInstance(context).initWallet() | |
> | |
> val _intentDisplay = Intent("com.samourai.wallet.BalanceFragment.DISPLAY") | |
> LocalBroadcastManager.getInstance(context).sendBroadcast(_intentDisplay) | |
> | |
> PrefsUtil.getInstance(context).setValue(PrefsUtil.FIRST_RUN, false) | |
> | |
> if (notifTx && !AppUtil.getInstance(context).isOfflineMode) { | |
> // | |
> // check for incoming payment code notification tx | |
> // | |
> try { | |
> val pcode = BIP47Util.getInstance(context).paymentCode | |
> // Log.i("BalanceFragment", "payment code:" + pcode.toString()); | |
> // Log.i("BalanceFragment", "notification address:" + pcode.notificationAddress().getAddressString()); | |
> APIFactory.getInstance(context).getNotifAddress(pcode.notificationAddress(SamouraiWallet.getInstance().currentNetworkParams).addressString) | |
> } catch (afe: AddressFormatException) { | |
> afe.printStackTrace() | |
> Toast.makeText(context, "HD wallet error", Toast.LENGTH_SHORT).show() | |
> } catch (ex: Exception) { | |
> ex.printStackTrace() | |
> } | |
> | |
> loadConnectedPaynyms() | |
> val _intent = Intent("com.samourai.wallet.MainActivity2.RESTART_SERVICE") | |
> LocalBroadcastManager.getInstance(context).sendBroadcast(_intent) | |
> } | |
> | |
> if (launch) { | |
> if (PrefsUtil.getInstance(context).getValue(PrefsUtil.GUID_V, 0) < 4) { | |
> Log.i(TAG, "guid_v < 4") | |
> try { | |
> val _guid = AccessFactory.getInstance(context).createGUID() | |
> val _hash = AccessFactory.getInstance(context).getHash(_guid, CharSequenceX(AccessFactory.getInstance(context).pin), AESUtil.DefaultPBKDF2Iterations) | |
> PayloadUtil.getInstance(context).saveWalletToJSON(CharSequenceX(_guid + AccessFactory.getInstance().pin)) | |
> PrefsUtil.getInstance(context).setValue(PrefsUtil.ACCESS_HASH, _hash) | |
> PrefsUtil.getInstance(context).setValue(PrefsUtil.ACCESS_HASH2, _hash) | |
> Log.i(TAG, "guid_v == 4") | |
> } catch (e: MnemonicLengthException) { | |
> } catch (e: IOException) { | |
> } catch (e: JSONException) { | |
> } catch (e: DecryptionException) { | |
> } | |
> } | |
> if (!PrefsUtil.getInstance(context.applicationContext).getValue(PrefsUtil.XPUB44LOCK, false)) { | |
> val s = HD_WalletFactory.getInstance(context).get().xpuBs | |
> APIFactory.getInstance(context).lockXPUB(s[0], 44, null) | |
> } | |
> try { | |
> if (!PrefsUtil.getInstance(context).getValue(PrefsUtil.XPUB49LOCK, false)) { | |
> val ypub = BIP49Util.getInstance(context).wallet.getAccount(0).ypubstr() | |
> APIFactory.getInstance(context).lockXPUB(ypub, 49, null) | |
> } | |
> if (!PrefsUtil.getInstance(context).getValue(PrefsUtil.XPUB84LOCK, false)) { | |
> val zpub = BIP84Util.getInstance(context).wallet.getAccount(0).zpubstr() | |
> APIFactory.getInstance(context).lockXPUB(zpub, 84, null) | |
> } | |
> if (!PrefsUtil.getInstance(context).getValue(PrefsUtil.XPUBPRELOCK, false)) { | |
> val zpub = BIP84Util.getInstance(context).wallet.getAccount(WhirlpoolMeta.getInstance(context).whirlpoolPremixAccount).zpubstr() | |
> APIFactory.getInstance(context).lockXPUB(zpub, 84, PrefsUtil.XPUBPRELOCK) | |
> } | |
> if (!PrefsUtil.getInstance(context).getValue(PrefsUtil.XPUBPOSTLOCK, false)) { | |
> val zpub = BIP84Util.getInstance(context).wallet.getAccount(WhirlpoolMeta.getInstance(context).whirlpoolPostmix).zpubstr() | |
> APIFactory.getInstance(context).lockXPUB(zpub, 84, PrefsUtil.XPUBPOSTLOCK) | |
> } | |
> if (!PrefsUtil.getInstance(context).getValue(PrefsUtil.XPUBBADBANKLOCK, false)) { | |
> val zpub = BIP84Util.getInstance(context).wallet.getAccount(WhirlpoolMeta.getInstance(context).whirlpoolBadBank).zpubstr() | |
> APIFactory.getInstance(context).lockXPUB(zpub, 84, PrefsUtil.XPUBBADBANKLOCK) | |
> } | |
> if (!PrefsUtil.getInstance(context).getValue(PrefsUtil.XPUBRICOCHETLOCK, false)) { | |
> val zpub = BIP84Util.getInstance(context).wallet.getAccount(RicochetMeta.getInstance(context).ricochetAccount).zpubstr() | |
> APIFactory.getInstance(context).lockXPUB(zpub, 84, PrefsUtil.XPUBRICOCHETLOCK) | |
> } | |
> } catch (e: Exception) { | |
> LogUtil.error(TAG, e.message) | |
> if (BuildConfig.DEBUG) { | |
> e.printStackTrace() | |
> } | |
> } | |
> try { | |
> val prevIdx = RicochetMeta.getInstance(context).index | |
> APIFactory.getInstance(context).parseRicochetXPUB() | |
> if (prevIdx > RicochetMeta.getInstance(context).index) { | |
> RicochetMeta.getInstance(context).index = prevIdx | |
> } | |
> } catch (je: JSONException) { | |
> } catch (e: Exception) { | |
> } | |
> } | |
> withContext(Dispatchers.IO){ | |
> try { | |
> PayloadUtil.getInstance(context).saveWalletToJSON(CharSequenceX(AccessFactory.getInstance(context).guid + AccessFactory.getInstance(context).pin)) | |
> } catch (ignored: Exception) { | |
> } | |
> } | |
> withContext(Dispatchers.Main) { | |
> val _intent = Intent("com.samourai.wallet.BalanceFragment.DISPLAY") | |
> LocalBroadcastManager.getInstance(context).sendBroadcast(_intent) | |
> } | |
> | |
> AppUtil.getInstance(applicationContext).setWalletLoading(false) | |
> val data = workDataOf(); | |
> return Result.success(data) | |
> } | |
> | |
> private fun loadConnectedPaynyms() { | |
> // | |
> // check on outgoing payment code notification tx | |
> // | |
> val outgoingUnconfirmed: List<Pair<String?, String?>> = BIP47Meta.getInstance().outgoingUnconfirmed | |
> // Log.i("BalanceFragment", "outgoingUnconfirmed:" + outgoingUnconfirmed.size()); | |
> for (pair in outgoingUnconfirmed) { | |
> // Log.i("BalanceFragment", "outgoing payment code:" + pair.getLeft()); | |
> // Log.i("BalanceFragment", "outgoing payment code tx:" + pair.getRight()); | |
> val confirmations = APIFactory.getInstance(context).getNotifTxConfirmations(pair.right) | |
> if (confirmations > 0) { | |
> BIP47Meta.getInstance().setOutgoingStatus(pair.left, BIP47Meta.STATUS_SENT_CFM) | |
> } | |
> if (confirmations == -1) { | |
> BIP47Meta.getInstance().setOutgoingStatus(pair.left, BIP47Meta.STATUS_NOT_SENT) | |
> } | |
> } | |
> } | |
> | |
> companion object { | |
> const val LAUNCHED = "LAUNCHED" | |
> const val NOTIF_TX = "NOTIF_TX" | |
> private const val TAG = "WalletRefreshWorker" | |
> | |
> fun enqueue(context: Context, notifTx: Boolean = false, launched: Boolean = false): Operation { | |
> val workManager = WorkManager.getInstance(context) | |
> val workRequest = OneTimeWorkRequestBuilder<WalletRefreshWorker>().apply { | |
> setInputData( | |
> workDataOf( | |
> LAUNCHED to launched, | |
> NOTIF_TX to notifTx | |
> ) | |
> ) | |
> }.build() | |
> return workManager.enqueue(workRequest) | |
> } | |
> } | |
> | |
> | |
> } | |
\ No newline at end of file | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/service/WebSocketHandler.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/service/WebSocketHandler.java | |
19d18 | |
< import com.samourai.wallet.util.network.BackendApiAndroid; | |
21d19 | |
< import com.samourai.wallet.util.tech.LogUtil; | |
161c159 | |
< String wsUrl = BackendApiAndroid.getApiServiceUrl(URL_INV); | |
--- | |
> String wsUrl = BackendServer.get(testnet).getBackendUrl(onion)+URL_INV; | |
163c161 | |
< debug("WebSocketHandler", "doInBackground(): connecting WS: " + wsUrl); | |
--- | |
> debug("WebSocketHandler", "doInBackground(): connecting WS: "+wsUrl); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/service/WebSocketService.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/service/WebSocketService.java | |
16d15 | |
< import com.samourai.wallet.util.tech.SimpleTaskRunner; | |
58,73c57,70 | |
< SimpleTaskRunner.create().executeAsyncAndShutdown(() -> { | |
< // | |
< // prune BIP47 lookbehind | |
< // | |
< BIP47Meta.getInstance().pruneIncoming(); | |
< | |
< addrSubs = new ArrayList<>(); | |
< addrSubs.add(AddressFactory.getInstance(context).account2xpub().get(0)); | |
< addrSubs.add(BIP49Util.getInstance(context).getWallet().getAccount(0).xpubstr()); | |
< addrSubs.add(BIP84Util.getInstance(context).getWallet().getAccount(0).xpubstr()); | |
< addrSubs.addAll(Arrays.asList(BIP47Meta.getInstance().getIncomingLookAhead(context))); | |
< String[] addrs = addrSubs.toArray(new String[addrSubs.size()]); | |
< | |
< webSocketHandler = new WebSocketHandler(WebSocketService.this, addrs); | |
< connectToWebsocketIfNotConnected(); | |
< }); | |
--- | |
> // | |
> // prune BIP47 lookbehind | |
> // | |
> BIP47Meta.getInstance().pruneIncoming(); | |
> | |
> addrSubs = new ArrayList<String>(); | |
> addrSubs.add(AddressFactory.getInstance(context).account2xpub().get(0)); | |
> addrSubs.add(BIP49Util.getInstance(context).getWallet().getAccount(0).xpubstr()); | |
> addrSubs.add(BIP84Util.getInstance(context).getWallet().getAccount(0).xpubstr()); | |
> addrSubs.addAll(Arrays.asList(BIP47Meta.getInstance().getIncomingLookAhead(context))); | |
> String[] addrs = addrSubs.toArray(new String[addrSubs.size()]); | |
> | |
> webSocketHandler = new WebSocketHandler(WebSocketService.this, addrs); | |
> connectToWebsocketIfNotConnected(); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/settings/SettingsActivity.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/settings/SettingsActivity.java | |
8d7 | |
< import androidx.core.content.ContextCompat; | |
33,34d31 | |
< getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.grey_accent)); | |
< | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/settings/SettingsDetailsFragment.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/settings/SettingsDetailsFragment.kt | |
25a26 | |
> import com.samourai.wallet.AboutActivity | |
29d29 | |
< import com.samourai.wallet.SamouraiActivity.CLIPBOARD_SERVICE | |
36a37 | |
> import com.samourai.wallet.network.dojo.DojoUtil | |
112c113 | |
< activity?.title = "About" | |
--- | |
> activity?.title = "Settings | Other" | |
197,225d197 | |
< val exportPref = findPreference("export") as Preference? | |
< exportPref!!.onPreferenceClickListener = Preference.OnPreferenceClickListener { | |
< if (SamouraiWallet.getInstance().hasPassphrase(context)) { | |
< if (HD_WalletFactory.getInstance(context).get() != null && SamouraiWallet.getInstance().hasPassphrase(context)) { | |
< doBackup(HD_WalletFactory.getInstance(context).get().passphrase) | |
< } | |
< } else { | |
< val builder = MaterialAlertDialogBuilder(requireContext()) | |
< builder.setTitle(R.string.enter_backup_password) | |
< val view = layoutInflater.inflate(R.layout.password_input_dialog_layout, null) | |
< val password = view.findViewById<EditText>(R.id.restore_dialog_password_edittext) | |
< val message = view.findViewById<TextView>(R.id.dialogMessage) | |
< message.setText(R.string.backup_password) | |
< builder.setPositiveButton(R.string.confirm) { dialog: DialogInterface, which: Int -> | |
< val pw = password.text.toString() | |
< if (pw.length >= AppUtil.MIN_BACKUP_PW_LENGTH && pw.length <= AppUtil.MAX_BACKUP_PW_LENGTH) { | |
< doBackup(pw) | |
< } else { | |
< Toast.makeText(context, R.string.password_error, Toast.LENGTH_SHORT).show() | |
< } | |
< dialog.dismiss() | |
< } | |
< builder.setNegativeButton(R.string.cancel) { dialog: DialogInterface, which: Int -> dialog.dismiss() } | |
< builder.setView(view) | |
< builder.show() | |
< } | |
< return@OnPreferenceClickListener true | |
< } | |
< | |
239a212,216 | |
> WhirlpoolMeta.getInstance(requireContext().applicationContext).scode = null | |
> WhirlpoolNotificationService.stopService(requireContext().applicationContext) | |
> if (SamouraiTorManager.isConnected()) { | |
> SamouraiTorManager.start() | |
> } | |
343,396d319 | |
< private fun doBackup(passphrase: String) { | |
< val export_methods = arrayOfNulls<String>(2) | |
< export_methods[0] = getString(R.string.export_to_clipboard) | |
< export_methods[1] = "Share" | |
< MaterialAlertDialogBuilder(requireContext()) | |
< .setTitle(R.string.options_export) | |
< .setItems(export_methods, DialogInterface.OnClickListener { dialog, which -> | |
< try { | |
< PayloadUtil.getInstance(requireContext()).saveWalletToJSON(CharSequenceX(AccessFactory.getInstance(requireContext()).guid + AccessFactory.getInstance(requireContext()).pin)) | |
< } catch (ioe: IOException) { | |
< } catch (je: JSONException) { | |
< } catch (de: DecryptionException) { | |
< } catch (mle: MnemonicLengthException) { | |
< } | |
< var encrypted: String? = null | |
< try { | |
< encrypted = AESUtil.encryptSHA256(PayloadUtil.getInstance(requireContext()).payload.toString(), CharSequenceX(passphrase)) | |
< } catch (e: Exception) { | |
< Toast.makeText(requireContext(), e.message, Toast.LENGTH_SHORT).show() | |
< } finally { | |
< if (encrypted == null) { | |
< Toast.makeText(requireContext(), R.string.encryption_error, Toast.LENGTH_SHORT).show() | |
< return@OnClickListener | |
< } | |
< } | |
< val obj = PayloadUtil.getInstance(requireContext()).putPayload(encrypted, true) | |
< if (which == 0) { | |
< AlertDialog.Builder(requireContext()) | |
< .setTitle(R.string.app_name) | |
< .setMessage(R.string.receive_payload_export) | |
< .setCancelable(false) | |
< .setPositiveButton( | |
< R.string.yes | |
< ) { dialog, whichButton -> | |
< val clipboard = requireContext().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager | |
< var clip: ClipData? = null | |
< clip = ClipData.newPlainText("Wallet backup", obj.toString()) | |
< clipboard.setPrimaryClip(clip) | |
< Toast.makeText(requireContext(), R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show() | |
< }.setNegativeButton( | |
< R.string.no | |
< ) { dialog, whichButton -> }.show() | |
< } else { | |
< val email = Intent(Intent.ACTION_SEND) | |
< email.putExtra(Intent.EXTRA_SUBJECT, "Ashigaru backup") | |
< email.putExtra(Intent.EXTRA_TEXT, obj.toString()) | |
< email.type = "message/rfc822" | |
< startActivity(Intent.createChooser(email, getText(R.string.choose_email_client))) | |
< } | |
< dialog.dismiss() | |
< } | |
< ).show() | |
< } | |
< | |
476a400,411 | |
> val whirlpoolGUIPref = findPreference("whirlpool_gui") as Preference? | |
> whirlpoolGUIPref?.onPreferenceClickListener = Preference.OnPreferenceClickListener { | |
> doWhirlpoolGUIPairing() | |
> true | |
> } | |
> | |
> val swapsGUIPref = findPreference("swaps_gui") as Preference? | |
> swapsGUIPref?.onPreferenceClickListener = Preference.OnPreferenceClickListener { | |
> doSwapsGUIPairing() | |
> true | |
> } | |
> | |
521c456 | |
< /* | |
--- | |
> | |
527d461 | |
< */ | |
543,544c477 | |
< aboutPref?.summary = "v" + BuildConfig.VERSION_NAME | |
< /* | |
--- | |
> aboutPref?.summary = "Samourai," + " " + BuildConfig.VERSION_NAME | |
550d482 | |
< */ | |
782,783c714,715 | |
< val emailAddress = "contact@ashigaru.rs" | |
< val emailSubject = "Ashigaru support backup" | |
--- | |
> val emailAddress = "help@samourai.support" | |
> val emailSubject = "Samourai Wallet support backup" | |
803,804c735,736 | |
< email.putExtra(Intent.EXTRA_EMAIL, arrayOf("contact@ashigaru.rs")) | |
< email.putExtra(Intent.EXTRA_SUBJECT, "Ashigaru support backup") | |
--- | |
> email.putExtra(Intent.EXTRA_EMAIL, arrayOf("help@samourai.support")) | |
> email.putExtra(Intent.EXTRA_SUBJECT, "Samourai Wallet support backup") | |
820,821c752,753 | |
< email.data = Uri.parse("mailto:contact@ashigaru.rs") | |
< email.putExtra(Intent.EXTRA_SUBJECT, "Ashigaru support backup") | |
--- | |
> email.data = Uri.parse("mailto:help@samourai.support") | |
> email.putExtra(Intent.EXTRA_SUBJECT, "Samourai Wallet support backup") | |
925a858,1011 | |
> | |
> private fun doWhirlpoolGUIPairing() { | |
> | |
> fun showQR(pairingObj: JSONObject) { | |
> val dialog = QRBottomSheetDialog( | |
> qrData = pairingObj.toString(), | |
> getString(R.string.whirlpool_pairing), clipboardLabel = getString(R.string.whirlpool_pairing) | |
> ); | |
> dialog.show(requireActivity().supportFragmentManager, dialog.tag) | |
> } | |
> | |
> val pairingObj = JSONObject() | |
> val jsonObj = JSONObject() | |
> val dojoObj = JSONObject() | |
> try { | |
> if (DojoUtil.getInstance(requireContext()).dojoParams != null) { | |
> val params = DojoUtil.getInstance(requireContext()).dojoParams | |
> val url = DojoUtil.getInstance(requireContext()).getUrl(params) | |
> val apiKey = DojoUtil.getInstance(requireContext()).getApiKey(params) | |
> if (url != null && apiKey != null && url.isNotEmpty() && apiKey.isNotEmpty()) { | |
> dojoObj.put("apikey", apiKey) | |
> dojoObj.put("url", url) | |
> } | |
> } | |
> jsonObj.put("type", "whirlpool.gui") | |
> jsonObj.put("version", "3.0.0") | |
> jsonObj.put("network", if (SamouraiWallet.getInstance().isTestNet) "testnet" else "mainnet") | |
> val mnemonic = HD_WalletFactory.getInstance(requireContext()).get().mnemonic | |
> if (SamouraiWallet.getInstance().hasPassphrase(requireContext())) { | |
> val encrypted = AESUtil.encrypt(mnemonic, CharSequenceX(HD_WalletFactory.getInstance(requireContext()).get().passphrase), AESUtil.DefaultPBKDF2Iterations) | |
> jsonObj.put("passphrase", true) | |
> jsonObj.put("mnemonic", encrypted) | |
> pairingObj.put("pairing", jsonObj) | |
> if (dojoObj.has("url") && dojoObj.has("apikey")) { | |
> val apiKey = dojoObj.getString("apikey") | |
> val encryptedApiKey = AESUtil.encrypt(apiKey, CharSequenceX(HD_WalletFactory.getInstance(requireContext()).get().passphrase)) | |
> dojoObj.put("apikey", encryptedApiKey) | |
> pairingObj.put("dojo", dojoObj) | |
> } | |
> showQR(pairingObj) | |
> } else { | |
> | |
> val builder = MaterialAlertDialogBuilder(requireContext()) | |
> builder.setTitle(getString(R.string.enter_pairing_password)) | |
> val inflater = layoutInflater | |
> val view = inflater.inflate(R.layout.password_input_dialog_layout, null) | |
> val password = view.findViewById<EditText>(R.id.restore_dialog_password_edittext) | |
> val message = view.findViewById<TextView>(R.id.dialogMessage) | |
> message.setText(R.string.pairing_password) | |
> builder.setPositiveButton(R.string.confirm) { dialog: DialogInterface, which: Int -> | |
> val pw = password.text.toString() | |
> if (pw.length >= AppUtil.MIN_BACKUP_PW_LENGTH && pw.length <= AppUtil.MAX_BACKUP_PW_LENGTH) { | |
> val encrypted = AESUtil.encrypt(mnemonic, CharSequenceX(pw), AESUtil.DefaultPBKDF2Iterations) | |
> jsonObj.put("passphrase", false) | |
> jsonObj.put("mnemonic", encrypted) | |
> if (dojoObj.has("url") && dojoObj.has("apikey")) { | |
> val apiKey = dojoObj.getString("apikey") | |
> val encryptedApiKey = AESUtil.encrypt(apiKey, CharSequenceX(pw)) | |
> dojoObj.put("apikey", encryptedApiKey) | |
> pairingObj.put("dojo", dojoObj) | |
> } | |
> pairingObj.put("pairing", jsonObj) | |
> showQR(pairingObj) | |
> }else{ | |
> Toast.makeText(requireContext(), R.string.password_error, Toast.LENGTH_SHORT).show() | |
> } | |
> dialog.dismiss() | |
> } | |
> builder.setNegativeButton(R.string.cancel) { dialog: DialogInterface, _: Int -> dialog.cancel() } | |
> builder.setView(view) | |
> builder.show() | |
> } | |
> | |
> } catch (Er: Exception) { | |
> | |
> } | |
> } | |
> | |
> private fun doSwapsGUIPairing() { | |
> | |
> fun showQR(pairingObj: JSONObject) { | |
> val dialog = QRBottomSheetDialog( | |
> qrData = pairingObj.toString(), | |
> getString(R.string.swaps_pairing), clipboardLabel = getString(R.string.swaps_pairing) | |
> ); | |
> dialog.show(requireActivity().supportFragmentManager, dialog.tag) | |
> } | |
> | |
> val pairingObj = JSONObject() | |
> val jsonObj = JSONObject() | |
> val dojoObj = JSONObject() | |
> try { | |
> if (DojoUtil.getInstance(requireContext()).dojoParams != null) { | |
> val params = DojoUtil.getInstance(requireContext()).dojoParams | |
> val url = DojoUtil.getInstance(requireContext()).getUrl(params) | |
> val apiKey = DojoUtil.getInstance(requireContext()).getApiKey(params) | |
> if (url != null && apiKey != null && url.isNotEmpty() && apiKey.isNotEmpty()) { | |
> dojoObj.put("apikey", apiKey) | |
> dojoObj.put("url", url) | |
> } | |
> } | |
> jsonObj.put("type", "swaps.gui") | |
> jsonObj.put("version", "1.0.1") | |
> jsonObj.put("network", if (SamouraiWallet.getInstance().isTestNet) "testnet" else "mainnet") | |
> val mnemonic = HD_WalletFactory.getInstance(requireContext()).get().mnemonic | |
> if (SamouraiWallet.getInstance().hasPassphrase(requireContext())) { | |
> val encrypted = AESUtil.encrypt(mnemonic, CharSequenceX(HD_WalletFactory.getInstance(requireContext()).get().passphrase), AESUtil.DefaultPBKDF2Iterations) | |
> jsonObj.put("passphrase", true) | |
> jsonObj.put("mnemonic", encrypted) | |
> pairingObj.put("pairing", jsonObj) | |
> if (dojoObj.has("url") && dojoObj.has("apikey")) { | |
> val apiKey = dojoObj.getString("apikey") | |
> val encryptedApiKey = AESUtil.encrypt(apiKey, CharSequenceX(HD_WalletFactory.getInstance(requireContext()).get().passphrase)) | |
> dojoObj.put("apikey", encryptedApiKey) | |
> pairingObj.put("dojo", dojoObj) | |
> } | |
> showQR(pairingObj) | |
> } else { | |
> | |
> val builder = MaterialAlertDialogBuilder(requireContext()) | |
> builder.setTitle(getString(R.string.enter_pairing_password)) | |
> val inflater = layoutInflater | |
> val view = inflater.inflate(R.layout.password_input_dialog_layout, null) | |
> val password = view.findViewById<EditText>(R.id.restore_dialog_password_edittext) | |
> val message = view.findViewById<TextView>(R.id.dialogMessage) | |
> message.setText(R.string.pairing_password) | |
> builder.setPositiveButton(R.string.confirm) { dialog: DialogInterface, which: Int -> | |
> val pw = password.text.toString() | |
> if (pw.length >= AppUtil.MIN_BACKUP_PW_LENGTH && pw.length <= AppUtil.MAX_BACKUP_PW_LENGTH) { | |
> val encrypted = AESUtil.encrypt(mnemonic, CharSequenceX(pw), AESUtil.DefaultPBKDF2Iterations) | |
> jsonObj.put("passphrase", false) | |
> jsonObj.put("mnemonic", encrypted) | |
> if (dojoObj.has("url") && dojoObj.has("apikey")) { | |
> val apiKey = dojoObj.getString("apikey") | |
> val encryptedApiKey = AESUtil.encrypt(apiKey, CharSequenceX(pw)) | |
> dojoObj.put("apikey", encryptedApiKey) | |
> pairingObj.put("dojo", dojoObj) | |
> } | |
> pairingObj.put("pairing", jsonObj) | |
> showQR(pairingObj) | |
> }else{ | |
> Toast.makeText(requireContext(), R.string.password_error, Toast.LENGTH_SHORT).show() | |
> } | |
> dialog.dismiss() | |
> } | |
> builder.setNegativeButton(R.string.cancel) { dialog: DialogInterface, _: Int -> dialog.cancel() } | |
> builder.setView(view) | |
> builder.show() | |
> } | |
> | |
> } catch (Er: Exception) { | |
> | |
> } | |
> } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/theme/Color.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/theme/Color.kt | |
25,33d24 | |
< val samouraiBoxHeaderBackgroundGrey = Color(0xFF363636) | |
< val samouraiBoxHeaderBackgroundBlack = Color(0xFF242424) | |
< val samouraiBoxTextLightGrey = Color(0xFFC2C2C2) | |
< val samouraiBoxTextRed = Color(0xFFC22F2F) | |
< val samouraiBoxTextOrangeDark = Color(0xFFC2862F) | |
< val samouraiBoxCheckGreen = Color(0xFF0ECF96) | |
< val samouraiBoxYellow = Color(0xFFB6B260) | |
< val samouraiBoxGreenBlueLight = Color(0xFF60B6B2) | |
< val samouraiBoxGray = Color(0xFF5D5D5D) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tools/Auth47BottomSheet.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tools/Auth47BottomSheet.kt | |
283c283 | |
< painter = painterResource(id = R.drawable.qrcode_scan), | |
--- | |
> painter = painterResource(id = R.drawable.ic_crop_free_white_24dp), | |
339c339 | |
< var pcodeForAvatar by remember { mutableStateOf("") } | |
--- | |
> var paynymUrl by remember { mutableStateOf("") } | |
350c350 | |
< pcodeForAvatar = pcode | |
--- | |
> paynymUrl = "${WebUtil.PAYNYM_API}${pcode}/avatar" | |
367,368c367,368 | |
< if (!success && pcodeForAvatar.isNotEmpty()) PicassoImage( | |
< pcode = pcodeForAvatar, | |
--- | |
> if (!success && paynymUrl.isNotEmpty()) PicassoImage( | |
> url = paynymUrl, | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tools/BroadcastHexBottomSheet.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tools/BroadcastHexBottomSheet.kt | |
334c334 | |
< painter = painterResource(id = R.drawable.qrcode_scan), | |
--- | |
> painter = painterResource(id = R.drawable.ic_crop_free_white_24dp), | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tools/SignPSBTBottomSheet.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tools/SignPSBTBottomSheet.kt | |
343c343 | |
< painter = painterResource(id = R.drawable.qrcode_scan), | |
--- | |
> painter = painterResource(id = R.drawable.ic_crop_free_white_24dp), | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tools/SweepPrivateKey.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tools/SweepPrivateKey.kt | |
95d94 | |
< import com.samourai.wallet.util.PrivKeyReader | |
97d95 | |
< import com.samourai.wallet.util.func.FormatsUtil | |
98a97,98 | |
> import com.samourai.wallet.util.func.FormatsUtil | |
> import com.samourai.wallet.util.PrivKeyReader | |
329c329 | |
< painter = if (addressEdit.value.isNullOrEmpty()) painterResource(id = R.drawable.qrcode_scan) | |
--- | |
> painter = if (addressEdit.value.isNullOrEmpty()) painterResource(id = R.drawable.ic_crop_free_white_24dp) | |
712c712 | |
< title = stringResource(id = R.string.estimated_confirmation_time), | |
--- | |
> title = stringResource(id = R.string.estimated_wait_time), | |
754c754 | |
< text = if (validFees) "$satsPerByte sats/vB" else "_.__", | |
--- | |
> text = if (validFees) "$satsPerByte sats/b" else "_.__", | |
873,874c873 | |
< text = title, | |
< fontSize = 13.sp, | |
--- | |
> text = title, fontSize = 13.sp, | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tools/ToolsBottomSheet.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tools/ToolsBottomSheet.kt | |
42d41 | |
< import androidx.compose.ui.graphics.toArgb | |
240,241d238 | |
< | |
< window!!.statusBarColor = MaterialTheme.colors.primary.toArgb() | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tools/viewmodels/SweepViewModel.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tools/viewmodels/SweepViewModel.kt | |
24c24 | |
< import com.samourai.wallet.send.review.ReviewTxModel | |
--- | |
> import com.samourai.wallet.service.WalletRefreshWorker | |
26a27,29 | |
> import com.samourai.wallet.util.func.AddressFactory | |
> import com.samourai.wallet.util.tech.AppUtil | |
> import com.samourai.wallet.util.network.BackendApiAndroid | |
30,33d32 | |
< import com.samourai.wallet.util.func.AddressFactory | |
< import com.samourai.wallet.util.func.WalletRefreshUtil | |
< import com.samourai.wallet.util.network.BackendApiAndroid | |
< import com.samourai.wallet.util.tech.AppUtil | |
36d34 | |
< import kotlinx.coroutines.async | |
317,346c315,323 | |
< if (FeeUtil.getInstance().feeRepresentation.is1DolFeeEstimator) { | |
< | |
< var transactionPriority = | |
< ReviewTxModel.findTransactionPriority( | |
< feeForBlocks!!.toLong(), | |
< FeeUtil.getInstance().highFee.defaultPerKB.toLong(), | |
< FeeUtil.getInstance().lowFee.defaultPerKB.toLong()) | |
< | |
< var priorityDesc = transactionPriority!!.getDescription( | |
< FeeUtil.getInstance().feeRepresentation, | |
< feeForBlocks!!.toLong(), | |
< FeeUtil.getInstance().lowFee.defaultPerKB.toLong(), | |
< FeeUtil.getInstance().normalFee.defaultPerKB.toLong(), | |
< FeeUtil.getInstance().highFee.defaultPerKB.toLong() | |
< ) | |
< blocks.postValue(priorityDesc) | |
< } else { | |
< if (feeForBlocks != null) { | |
< if (feeForBlocks <= feeLow.toDouble()) { | |
< pct = feeLow.toDouble() / feeForBlocks | |
< nbBlocks = ceil(pct * 24.0).toInt() | |
< } else if (feeForBlocks >= feeHigh.toDouble()) { | |
< pct = feeHigh.toDouble() / feeForBlocks | |
< nbBlocks = ceil(pct * 2.0).toInt() | |
< if (nbBlocks < 1) { | |
< nbBlocks = 1 | |
< } | |
< } else { | |
< pct = feeMed.toDouble() / feeForBlocks | |
< nbBlocks = ceil(pct * 6.0).toInt() | |
--- | |
> if (feeForBlocks != null) { | |
> if (feeForBlocks <= feeLow.toDouble()) { | |
> pct = feeLow.toDouble() / feeForBlocks | |
> nbBlocks = ceil(pct * 24.0).toInt() | |
> } else if (feeForBlocks >= feeHigh.toDouble()) { | |
> pct = feeHigh.toDouble() / feeForBlocks | |
> nbBlocks = ceil(pct * 2.0).toInt() | |
> if (nbBlocks < 1) { | |
> nbBlocks = 1 | |
347a325,327 | |
> } else { | |
> pct = feeMed.toDouble() / feeForBlocks | |
> nbBlocks = ceil(pct * 6.0).toInt() | |
349,353d328 | |
< var strBlocks = "$nbBlocks blocks" | |
< if (nbBlocks > 50) { | |
< strBlocks = "50+ blocks" | |
< } | |
< blocks.postValue(strBlocks) | |
355c330,334 | |
< | |
--- | |
> var strBlocks = "$nbBlocks blocks" | |
> if (nbBlocks > 50) { | |
> strBlocks = "50+ blocks" | |
> } | |
> blocks.postValue(strBlocks) | |
407,446c386,413 | |
< async { | |
< delay(1500) | |
< try { | |
< val receiveAddress = AddressFactory.getInstance(context).getAddressAndIncrement(receiveAddressType.value).right | |
< val rbfOptin = PrefsUtil.getInstance(context).getValue(PrefsUtil.RBF_OPT_IN, false) | |
< val blockHeight = APIFactory.getInstance(context).latestBlockHeight | |
< val receivers: MutableMap<String, Long> = LinkedHashMap() | |
< receivers[receiveAddress] = sweepPreview!!.amount | |
< val bipFormatSupplier: BipFormatSupplier = getBipFormatSupplier(bipFormat.value); | |
< val outpoints: MutableCollection<MyTransactionOutPoint> = mutableListOf() | |
< sweepPreview!!.utxos | |
< .map { unspentOutput: UnspentOutput -> unspentOutput.computeOutpoint(params) }.toCollection(outpoints) | |
< | |
< val tr = createTransaction( | |
< receivers, | |
< outpoints, | |
< bipFormatSupplier, | |
< rbfOptin, | |
< blockHeight) | |
< | |
< transaction = TransactionForSweepHelper.signTransactionForSweep(tr, sweepPreview!!.privKey, params, bipFormatSupplier) | |
< } catch (e: Exception) { | |
< throw CancellationException("Sign: ${e.message}") | |
< } | |
< try { | |
< if (transaction != null) { | |
< val hexTx = TxUtil.getInstance().getTxHex(transaction) | |
< PushTx.getInstance(context).pushTx(hexTx) | |
< WalletRefreshUtil.refreshWallet( | |
< notifTx = false, | |
< launch = false, | |
< context = context) | |
< } | |
< } catch (e: Exception) { | |
< throw CancellationException("pushTx : ${e.message}") | |
< } | |
< }.invokeOnCompletion { | |
< broadcastLoading.postValue(false) | |
< if (it != null) { | |
< broadcastError.postValue(it.message) | |
--- | |
> delay(1500) | |
> try { | |
> val receiveAddress = AddressFactory.getInstance(context).getAddressAndIncrement(receiveAddressType.value).right | |
> val rbfOptin = PrefsUtil.getInstance(context).getValue(PrefsUtil.RBF_OPT_IN, false) | |
> val blockHeight = APIFactory.getInstance(context).latestBlockHeight | |
> val receivers: MutableMap<String, Long> = LinkedHashMap() | |
> receivers[receiveAddress] = sweepPreview!!.amount | |
> val bipFormatSupplier: BipFormatSupplier = getBipFormatSupplier(bipFormat.value); | |
> val outpoints: MutableCollection<MyTransactionOutPoint> = mutableListOf() | |
> sweepPreview!!.utxos | |
> .map { unspentOutput: UnspentOutput -> unspentOutput.computeOutpoint(params) }.toCollection(outpoints) | |
> | |
> val tr = createTransaction( | |
> receivers, | |
> outpoints, | |
> bipFormatSupplier, | |
> rbfOptin, | |
> blockHeight) | |
> | |
> transaction = TransactionForSweepHelper.signTransactionForSweep(tr, sweepPreview!!.privKey, params, bipFormatSupplier) | |
> } catch (e: Exception) { | |
> throw CancellationException("Sign: ${e.message}") | |
> } | |
> try { | |
> if (transaction != null) { | |
> val hexTx = TxUtil.getInstance().getTxHex(transaction) | |
> PushTx.getInstance(context).pushTx(hexTx) | |
> WalletRefreshWorker.enqueue(context, notifTx = false, launched = false) | |
447a415,416 | |
> } catch (e: Exception) { | |
> throw CancellationException("pushTx : ${e.message}") | |
448a418 | |
> | |
450a421,427 | |
> .invokeOnCompletion { | |
> broadcastLoading.postValue(false) | |
> if (it != null) { | |
> broadcastError.postValue(it.message) | |
> } | |
> } | |
> | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tor/kpm/TorKmpManager.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tor/kpm/TorKmpManager.kt | |
47d46 | |
< import kotlinx.coroutines.Job | |
51d49 | |
< import okhttp3.internal.wait | |
239,240c237,238 | |
< fun newIdentity(appContext: Application): Job { | |
< return appScope.launch { | |
--- | |
> fun newIdentity(appContext: Application) { | |
> appScope.launch { | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tor/SamouraiTorManager.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tor/SamouraiTorManager.kt | |
35,36c35 | |
< return true | |
< // return PrefsUtil.getInstance(appContext).getValue(PrefsUtil.ENABLE_TOR, false); | |
--- | |
> return PrefsUtil.getInstance(appContext).getValue(PrefsUtil.ENABLE_TOR, false); | |
47,50d45 | |
< suspend fun restartSync(): Result<Any?>? { | |
< return torKmpManager?.torOperationManager?.restart() | |
< } | |
< | |
52c47 | |
< torKmpManager?.torOperationManager?.stopQuietly() | |
--- | |
> torKmpManager?.torOperationManager?.stopQuietly(); | |
56c51 | |
< torKmpManager?.torOperationManager?.startQuietly() | |
--- | |
> torKmpManager?.torOperationManager?.startQuietly(); | |
62a58 | |
> @JvmStatic | |
64,71c60 | |
< torKmpManager?.newIdentity(appContext!!) | |
< } | |
< | |
< suspend fun newIdentitySync() { | |
< val job = torKmpManager?.newIdentity(appContext!!) | |
< if (job != null) { | |
< job.join() | |
< } | |
--- | |
> torKmpManager?.newIdentity(appContext!!); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/tx/TxDetailsActivity.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/tx/TxDetailsActivity.kt | |
16d15 | |
< import androidx.appcompat.widget.Toolbar | |
19d17 | |
< import com.google.android.material.appbar.AppBarLayout | |
30d27 | |
< import com.samourai.wallet.constants.SamouraiAccountIndex | |
42d38 | |
< import com.samourai.wallet.util.PrefsUtil | |
91,99d86 | |
< window.statusBarColor = resources.getColor(R.color.balance_blue) | |
< window.navigationBarColor = resources.getColor(R.color.networking) | |
< if (intent.hasExtra("_account")) { | |
< if (intent.getIntExtra("_account", 0) == SamouraiAccountIndex.POSTMIX) { | |
< findViewById<AppBarLayout>(R.id.appBarLayout4).setBackgroundColor(resources.getColor(R.color.postmix_balance)) | |
< findViewById<Toolbar>(R.id.toolbar).setBackgroundColor(resources.getColor(R.color.postmix_balance)) | |
< window.statusBarColor = resources.getColor(R.color.postmix_balance) | |
< } | |
< } | |
388d374 | |
< true, | |
489c475 | |
< if (jsonObject.has("vfeerate")) { | |
--- | |
> if (jsonObject.has("feerate")) { | |
534a521,524 | |
> if (SamouraiTorManager.isConnected()) { | |
> SamouraiTorManager.newIdentity() | |
> } | |
> | |
536,537d525 | |
< if (SamouraiTorManager.isConnected()) | |
< SamouraiTorManager.newIdentity() | |
547,548d534 | |
< if (PrefsUtil.getInstance(applicationContext).getValue(PrefsUtil.BLOCK_EXPLORER_URL, "").isNullOrEmpty()) | |
< menu.findItem(R.id.menu_item_block_explore).setVisible(false) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/activity/ActivityHelper.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/activity/ActivityHelper.java | |
3a4 | |
> | |
15a17 | |
> import androidx.core.app.TaskStackBuilder; | |
40c42 | |
< return null; // "http://72typmu5edrjmcdkzuzmv2i4zqru7rjlrcxwtod4nu6qtfsqegngzead.onion/support"; | |
--- | |
> return "http://72typmu5edrjmcdkzuzmv2i4zqru7rjlrcxwtod4nu6qtfsqegngzead.onion/support"; | |
42c44 | |
< return null; //"https://samouraiwallet.com/support"; | |
--- | |
> return "https://samouraiwallet.com/support"; | |
77,83c79,99 | |
< final Intent _intent = new Intent(currentActivity, BalanceActivity.class); | |
< _intent.putExtra("_account", account); | |
< _intent.putExtra("refresh", true); | |
< _intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | | |
< Intent.FLAG_ACTIVITY_NEW_TASK | | |
< Intent.FLAG_ACTIVITY_SINGLE_TOP); | |
< currentActivity.startActivity(_intent); | |
--- | |
> if (account != 0) { | |
> | |
> final Intent balanceHome = new Intent(currentActivity, BalanceActivity.class); | |
> balanceHome.putExtra("_account", account); | |
> balanceHome.putExtra("refresh", true); | |
> final Intent parentIntent = new Intent(currentActivity, BalanceActivity.class); | |
> parentIntent.putExtra("_account", 0); | |
> balanceHome.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |
> TaskStackBuilder.create(currentActivity.getApplicationContext()) | |
> .addNextIntent(parentIntent) | |
> .addNextIntent(balanceHome) | |
> .startActivities(); | |
> | |
> } else { | |
> final Intent _intent = new Intent(currentActivity, BalanceActivity.class); | |
> _intent.putExtra("refresh", true); | |
> _intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | | |
> Intent.FLAG_ACTIVITY_NEW_TASK | | |
> Intent.FLAG_ACTIVITY_SINGLE_TOP); | |
> currentActivity.startActivity(_intent); | |
> } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/func/AddressHelper.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/func/AddressHelper.java | |
3,6d2 | |
< import static com.samourai.wallet.constants.SamouraiAccountIndex.DEPOSIT; | |
< import static com.samourai.wallet.constants.SamouraiAccountIndex.POSTMIX; | |
< import static com.samourai.wallet.util.func.EnumAddressType.BIP84_SEGWIT_NATIVE; | |
< | |
46,49c42 | |
< public static AddressInfo isMyDepositOrPostmixAddress( | |
< final Context context, | |
< final String address, | |
< final int scanIndexMargin) { | |
--- | |
> public static boolean sendToMyDepositAddress(final Context context, final String sendAddress) { | |
53c46 | |
< final EnumAddressType addressType = EnumAddressType.fromAddress(address); | |
--- | |
> final EnumAddressType addressType = EnumAddressType.fromAddress(sendAddress); | |
55a49,50 | |
> final int receiveIndex; | |
> final int changeIndex; | |
80,88c75 | |
< if (isNull(addrTypeAsString)) { | |
< return AddressInfo.createAddressInfo( | |
< address, | |
< false, | |
< null, | |
< null, | |
< null, | |
< addressType.getType()); | |
< } | |
--- | |
> if (isNull(addrTypeAsString)) return false; | |
89a77 | |
> final int scanIndexMargin = 64; | |
95c83 | |
< address, | |
--- | |
> sendAddress, | |
101,109c89 | |
< if (indexFound < endIdx && indexFound >= startIdx) { | |
< return AddressInfo.createAddressInfo( | |
< address, | |
< true, | |
< indexFound, | |
< isExternal ? 0 : 1, | |
< DEPOSIT, | |
< addressType.getType()); | |
< } | |
--- | |
> if (indexFound < endIdx && indexFound >= startIdx) return true; | |
116c96 | |
< address, | |
--- | |
> sendAddress, | |
122,130c102 | |
< if (indexFound < endIdx && indexFound >= startIdx) { | |
< return AddressInfo.createAddressInfo( | |
< address, | |
< true, | |
< indexFound, | |
< isExternal ? 0 : 1, | |
< DEPOSIT, | |
< addressType.getType()); | |
< } | |
--- | |
> if (indexFound < endIdx && indexFound >= startIdx) return true; | |
132,233c104 | |
< if (addressType == BIP84_SEGWIT_NATIVE) { | |
< int index = addressFactory.getIndex(WALLET_INDEX.POSTMIX_RECEIVE); | |
< startIdx = max(0, index - scanIndexMargin); | |
< endIdx = index + scanIndexMargin; | |
< indexFound = searchAddressIndex( | |
< address, | |
< types[5], // postmix account | |
< true, | |
< startIdx, | |
< endIdx, | |
< context); | |
< | |
< if (indexFound < endIdx && indexFound >= startIdx) { | |
< return AddressInfo.createAddressInfo( | |
< address, | |
< true, | |
< indexFound, | |
< 0, | |
< POSTMIX, | |
< addressType.getType()); | |
< } | |
< | |
< index = addressFactory.getIndex(WALLET_INDEX.POSTMIX_CHANGE); | |
< startIdx = max(0, index - scanIndexMargin); | |
< endIdx = index + scanIndexMargin; | |
< indexFound = searchAddressIndex( | |
< address, | |
< types[5], // postmix account | |
< false, | |
< startIdx, | |
< endIdx, | |
< context); | |
< | |
< if (indexFound < endIdx && indexFound >= startIdx) { | |
< return AddressInfo.createAddressInfo( | |
< address, | |
< true, | |
< indexFound, | |
< 1, | |
< POSTMIX, | |
< addressType.getType()); | |
< } | |
< } | |
< | |
< return AddressInfo.createAddressInfo( | |
< address, | |
< false, | |
< null, | |
< null, | |
< null, | |
< addressType.getType()); | |
< } | |
< | |
< public static class AddressInfo { | |
< private String addr; | |
< private boolean found; | |
< private Integer index; | |
< private Integer chain; | |
< private Integer addrType; | |
< private Integer accountIdx; | |
< | |
< public static AddressInfo createAddressInfo( | |
< final String addr, | |
< final boolean found, | |
< final Integer index, | |
< final Integer chain, | |
< final Integer accountIdx, | |
< final Integer addrType | |
< ) { | |
< final AddressInfo addressInfo = new AddressInfo(); | |
< addressInfo.addr = addr; | |
< addressInfo.found = found; | |
< addressInfo.index = index; | |
< addressInfo.chain = chain; | |
< addressInfo.accountIdx = accountIdx; | |
< addressInfo.addrType = addrType; | |
< return addressInfo; | |
< } | |
< | |
< public String getAddr() { | |
< return addr; | |
< } | |
< | |
< public boolean isFound() { | |
< return found; | |
< } | |
< | |
< public Integer getIndex() { | |
< return index; | |
< } | |
< | |
< public Integer getChain() { | |
< return chain; | |
< } | |
< | |
< public Integer getAccountIdx() { | |
< return accountIdx; | |
< } | |
< | |
< public Integer getAddrType() { | |
< return addrType; | |
< } | |
--- | |
> return false; | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/func/BatchSendUtil.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/func/BatchSendUtil.java | |
54c54 | |
< .getSendAddressString(pcode); | |
--- | |
> .getDestinationAddrFromPcode(pcode); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/func/PayNymUtil.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/func/PayNymUtil.kt | |
4,5c4 | |
< import android.util.Log | |
< import com.google.gson.Gson | |
--- | |
> import com.samourai.wallet.access.AccessFactory | |
9d7 | |
< import com.samourai.wallet.bip47.paynym.WebUtil | |
12,22c10 | |
< import com.samourai.wallet.paynym.api.PayNymApiService | |
< import com.samourai.wallet.paynym.models.NymResponse | |
< import com.samourai.wallet.util.PrefsUtil | |
< import kotlinx.coroutines.CancellationException | |
< import org.apache.commons.lang3.StringUtils | |
< import org.apache.commons.lang3.StringUtils.defaultIfBlank | |
< import org.json.JSONException | |
< import org.json.JSONObject | |
< | |
< | |
< const val TAG = "PayNymUtil" | |
--- | |
> import com.samourai.wallet.util.CharSequenceX | |
25,28d12 | |
< synPayNym(pcode, true, context) | |
< } | |
< | |
< fun synPayNym(pcode : String?, saveWallet : Boolean, context : Context) { | |
37,40c21,25 | |
< val addr = BIP47Util.getInstance(context).getReceivePubKey(payment_code, i) | |
< BIP47Meta.getInstance().idx4AddrLookup[addr] = i | |
< BIP47Meta.getInstance().pCode4AddrLookup[addr] = payment_code.toString() | |
< addrs.add(addr) | |
--- | |
> BIP47Meta.getInstance().idx4AddrLookup[BIP47Util.getInstance(context) | |
> .getReceivePubKey(payment_code, i)] = i | |
> BIP47Meta.getInstance().pCode4AddrLookup[BIP47Util.getInstance(context) | |
> .getReceivePubKey(payment_code, i)] = payment_code.toString() | |
> addrs.add(BIP47Util.getInstance(context).getReceivePubKey(payment_code, i)) | |
57,60c42,49 | |
< val sendPubKey = BIP47Util.getInstance(context).getSendPubKey(payment_code, i) | |
< BIP47Meta.getInstance().idx4AddrLookup[sendPubKey] = i | |
< BIP47Meta.getInstance().pCode4AddrLookup[sendPubKey] = payment_code.toString() | |
< addrs.add(sendPubKey) | |
--- | |
> val sendAddress = BIP47Util.getInstance(context).getSendAddress(payment_code, i) | |
> // Log.i("PayNymDetailsActivity", "sync send to " + i + ":" + sendAddress.getSendECKey().toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString()); | |
> // BIP47Meta.getInstance().setOutgoingIdx(payment_code.toString(), i); | |
> BIP47Meta.getInstance().idx4AddrLookup[BIP47Util.getInstance(context) | |
> .getSendPubKey(payment_code, i)] = i | |
> BIP47Meta.getInstance().pCode4AddrLookup[BIP47Util.getInstance(context) | |
> .getSendPubKey(payment_code, i)] = payment_code.toString() | |
> addrs.add(BIP47Util.getInstance(context).getSendPubKey(payment_code, i)) | |
70d58 | |
< | |
72,228c60,65 | |
< | |
< if (saveWallet) { | |
< WalletUtil.saveWallet(context) | |
< } | |
< } | |
< | |
< suspend fun executeFeaturePayNymUpdate(context : Context) { | |
< var obj = JSONObject() | |
< obj.put("code", BIP47Util.getInstance(context).paymentCode.toString()) | |
< var res = WebUtil.getInstance(context).postURL("application/json", null, WebUtil.PAYNYM_API + "api/v1/token", obj.toString()) | |
< var responseObj = JSONObject(res) | |
< if (responseObj.has("token")) { | |
< val token = responseObj.getString("token") | |
< val sig = MessageSignUtil.getInstance(context).signMessage(BIP47Util.getInstance(context).notificationAddress.ecKey, token) | |
< obj = JSONObject() | |
< obj.put("nym", BIP47Util.getInstance(context).paymentCode.toString()) | |
< obj.put("code", BIP47Util.getInstance(context).featurePaymentCode.toString()) | |
< obj.put("signature", sig) | |
< | |
< res = WebUtil.getInstance(context).postURL("application/json", token, WebUtil.PAYNYM_API + "api/v1/nym/add", obj.toString()) | |
< responseObj = JSONObject(res) | |
< if (responseObj.has("segwit") && responseObj.has("token")) { | |
< PrefsUtil.getInstance(context).setValue(PrefsUtil.PAYNYM_FEATURED_SEGWIT, true) | |
< } else if (responseObj.has("claimed") && responseObj.getBoolean("claimed") == true) { | |
< PrefsUtil.getInstance(context).setValue(PrefsUtil.PAYNYM_FEATURED_SEGWIT, true) | |
< } | |
< } | |
< } | |
< | |
< suspend fun isClaimedAndFeaturedPayNym(context : Context) : Triple<Boolean, Boolean, String> { | |
< val pcode = BIP47Util.getInstance(context).paymentCode.toString() | |
< val nymInfo = getNymInfoOffline(pcode, context) | |
< var strNymName : String = "" | |
< if (nymInfo.has("nymName")) { | |
< strNymName = nymInfo.getString("nymName") | |
< BIP47Meta.getInstance().setName(pcode, strNymName) | |
< if (FormatsUtil.getInstance().isValidPaymentCode(BIP47Meta.getInstance().getLabel(pcode))) { | |
< BIP47Meta.getInstance().setLabel(pcode, strNymName) | |
< } | |
< } | |
< var featured : Boolean = false | |
< if (nymInfo.has("segwit") && nymInfo.getBoolean("segwit")) { | |
< featured = true | |
< } | |
< | |
< var claimed = isClaimedPayNym(pcode, nymInfo) | |
< | |
< return Triple(claimed, featured, strNymName) | |
< } | |
< | |
< suspend fun isClaimedPayNym(pcode : String, nymInfo: JSONObject): Boolean { | |
< | |
< var claimed : Boolean = false | |
< if (nymInfo.has("codes")) { | |
< val codeArray = nymInfo.getJSONArray("codes") | |
< | |
< for (i in 0 until codeArray.length()) { | |
< val codeInfo: JSONObject = codeArray.getJSONObject(i) | |
< if (codeInfo.has("code") && StringUtils.equals(codeInfo.getString("code"), pcode)) { | |
< claimed = codeInfo.has("claimed") && codeInfo.getBoolean("claimed"); | |
< break; | |
< } | |
< } | |
< } | |
< | |
< return claimed | |
< } | |
< | |
< suspend fun getNymInfoOffline(pcode: String, context: Context): JSONObject { | |
< val obj = JSONObject() | |
< obj.put("nym", pcode) | |
< val res = WebUtil.getInstance(context) | |
< .postURL("application/json", null, WebUtil.PAYNYM_API + "api/v1/nym", obj.toString()) | |
< return JSONObject(res) | |
< } | |
< | |
< suspend fun getNymInfo(pcode: String, context: Context): JSONObject { | |
< | |
< var nymInfo : JSONObject = JSONObject() | |
< val apiPayNymApiService = PayNymApiService(pcode, context) | |
< | |
< try { | |
< val nymResponse = apiPayNymApiService.getNymInfo() | |
< if (nymResponse.isSuccessful) { | |
< nymInfo = JSONObject(nymResponse.body?.string()) | |
< } | |
< } catch (ex: Exception) { | |
< throw CancellationException(ex.message) | |
< } | |
< return nymInfo; | |
< } | |
< | |
< suspend fun claim(context : Context) : Pair<Boolean, String> { | |
< | |
< val strPaymentCode = BIP47Util.getInstance(context).paymentCode.toString() | |
< val apiPayNymApiService = PayNymApiService(strPaymentCode, context) | |
< | |
< try { | |
< val response = apiPayNymApiService.claim() | |
< if (response.isSuccessful) { | |
< val nymResponse = apiPayNymApiService.getNymInfo() | |
< if (nymResponse.isSuccessful) { | |
< try { | |
< val data = JSONObject(nymResponse.body?.string()) | |
< PayloadUtil.getInstance(context).serializePayNyms(data) | |
< val nym = if (data.has("nymName")) data.getString("nymName") else "" | |
< return Pair(true, nym) | |
< } catch (ex: Exception) { | |
< throw CancellationException(ex.message) | |
< } | |
< } | |
< } | |
< } catch (ex: Exception) { | |
< throw CancellationException(ex.message) | |
< } | |
< return Pair(false, "") | |
< } | |
< | |
< suspend fun reinitBIP47Meta(context: Context) : Boolean { | |
< try { | |
< | |
< val pcodeLabelsToRestore = BIP47Meta.getInstance().copyOfPcodeLabels | |
< | |
< val pcode = BIP47Util.getInstance(context).paymentCode.toString() | |
< var jsonObject = getNymInfo(pcode, context) | |
< if (jsonObject.has("empty") || !jsonObject.has("codes")) { | |
< return true | |
< } | |
< val nym = Gson().fromJson(jsonObject.toString(), NymResponse::class.java); | |
< BIP47Meta.getInstance().partialClearOnRestoringWallet() | |
< | |
< nym.following?.let { codes -> | |
< codes.forEach { paynym -> | |
< BIP47Meta.getInstance().setSegwit(paynym.code, paynym.segwit) | |
< BIP47Meta.getInstance().setName(paynym.code, paynym.nymName) | |
< val pname = defaultIfBlank(pcodeLabelsToRestore.get(paynym.code), paynym.nymName) | |
< BIP47Meta.getInstance().setLabel(paynym.code, pname) | |
< } | |
< val followings = ArrayList(codes.distinctBy { it.code }.map { it.code }) | |
< BIP47Meta.getInstance().setFollowings(followings) | |
< } | |
< nym.followers?.let { codes -> | |
< codes.forEach { paynym -> | |
< BIP47Meta.getInstance().setSegwit(paynym.code, paynym.segwit) | |
< BIP47Meta.getInstance().setName(paynym.code, paynym.nymName) | |
< val pname = defaultIfBlank(pcodeLabelsToRestore.get(paynym.code), paynym.nymName) | |
< BIP47Meta.getInstance().setLabel(paynym.code, pname) | |
< } | |
< } | |
< | |
< PayloadUtil.getInstance(context).serializePayNyms(jsonObject); | |
< } catch (e: JSONException) { | |
< Log.e(TAG, "issue on registerPayNymContact", e) | |
< return false | |
< } | |
< return true | |
< } | |
--- | |
> PayloadUtil.getInstance(context).saveWalletToJSON( | |
> CharSequenceX( | |
> AccessFactory.getInstance(context).guid + AccessFactory.getInstance(context).pin | |
> ) | |
> ) | |
> } | |
\ No newline at end of file | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/func/WalletUtil.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/func/WalletUtil.java | |
5d4 | |
< import com.samourai.wallet.SamouraiActivity; | |
8,9d6 | |
< import com.samourai.wallet.stealth.StealthModeController; | |
< import com.samourai.wallet.tor.SamouraiTorManager; | |
11,12d7 | |
< import com.samourai.wallet.util.TimeOutUtil; | |
< import com.samourai.wallet.whirlpool.service.WhirlpoolNotificationService; | |
16,69d10 | |
< public static final String ASHIGARU_PUB_KEY = | |
< "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + | |
< "Comment: https://keybase.io/ashigarudev\n" + | |
< "Version: Keybase Go 6.3.1 (linux)\n" + | |
< "\n" + | |
< "xsFNBGZdzx4BEADmL1E5gLoHtAd+N9Cw22VbnD47em9Hn946aDeB90pbrx02m8TW\n" + | |
< "Acji5VOOmN1CNg2EomG0aGk6eox1TZkisYsu5rTCmpQX36CQ6/LvUFh8MTYF38kW\n" + | |
< "wukNxE93wrXz/emk2yW/jeos6XlQ6/iJmom4bRCHDLxstFn14ICitr2zKysAOHkC\n" + | |
< "iutQacwsGSLImi/7YEzQrIAi4WeTGrScyEFaJ0BxOQ4lzZeQw3Me+ESufZDOfB6+\n" + | |
< "u8wsZzqVP5drp/AStbhGPhkYXbHJGikgVDVxxm/C9Yy/jhcQGUPSEFqXREeFncTM\n" + | |
< "w7q3M5YG7Rl7m2VPEElNkZRYBI7fa5G5E6Iy01Y4/KxyutRwOf/DZHUaK/VQQQne\n" + | |
< "HJzH58PvISPvswZzJWKN3mHiNGrbWGyBcvJOXlfbekLbRML8I28usKnSDWbHdkWc\n" + | |
< "9Ls8P+H62TcY7npdGRvZAGIcM11BqGp66fndc911HDbX3/0IPp1DJEnpLn46gQqs\n" + | |
< "3GJ6rMTBbt++krIFam1/kIr3Atp5EBqoSgAvxY5Xk+OUsYaa/K3VBQONpI2f7qJZ\n" + | |
< "HN9GpqszwF2eeu1vKB/CRxISRQLjklVBssiZ2Zez7PZ470Ses1V7jK2tWGqzf5sG\n" + | |
< "C0Tpp53WqFHtn4u/YuRtPQJtO0FHsc82mZbynoCO5YhNSh1mivPQoxPj0QARAQAB\n" + | |
< "zQxBc2hpZ2FydSBEZXbCwXEEEwEKACUFAmZdzx4JEKE4BrH6KmdrAhsDBQsJCAcD\n" + | |
< "BRUKCQgLBRYCAwEAAAD0txAAzpXmxtqVRLxEEdUBx1kxp1kE8kDJAhBraX5VXGOv\n" + | |
< "HuThhcr3j5Esj4IOGcsiV5S9nRNPu+hjjTX8AoOVLQcfU0jymrNRBXLQcd7L03Jj\n" + | |
< "0vG3sb7HOVbnQdGAwCrabb941BB3smitsYqI/Xz12CjavsONSp6wImt+jVHsAYC6\n" + | |
< "y1xew4cBkPL9VmzKabTGNTV+wPe7xHSdptdAvK98EWFZ+Yq3ut/rt4mnqr35OQWW\n" + | |
< "qDcAiAqKndqJXVZklDOvdQ654VPsBlJG4V+K4evZ7ECUc4gRVWWe5Ijl9z0UGopv\n" + | |
< "FTkeTn9GnyHRZgLYooHkqd3oith/1fweldatvRGIXpdA1W02Tn7I0imjvzgBNDVq\n" + | |
< "MS3rCp8kFFDtcshpASbtXChiloMFaw1+VDymT7sF81S5obbsJYRRkt2Qo+xM3B2n\n" + | |
< "t0gZDMuLAJ2Er9VXxpcyrjl8U+Us8atbx7x4UyPaZJe4zj8nZYZly/uVZQ8JL/Nc\n" + | |
< "zMg8ES9c8LV9ZcSlsIgX8VT6omxlSzWZNtfswBrXMUruxJgc7WKn1I6JMFbeRUG5\n" + | |
< "fLtjLyn4/KufW+Liiq4RKcRQb/rxUaT+e7tzY90y4MqTzLD7kbVhCRx5RVBY5bZD\n" + | |
< "2pFtch6CPVnZx/EHjR3Yd2zZgbDCVSIEEA6y2QS3aMhHXu1orgjVayOWVTINZE0y\n" + | |
< "K3POwU0EZl3PHgEQAOOzDEJRk8paHDXqNGYiFiQZCxX3CIOK3+DR+zsS8oq4AtXT\n" + | |
< "R7WUBDRACwUkDpNhybmkpEWH6B3zdsZPaGJ80ApTImWXc6KMJagcAJPVrwSGttOb\n" + | |
< "zQHCsbsVfS3xXQ4G3uxncLd7Ck+fesR0GVsfJ4HsTOZaKmbuUYFifa4PevwEeYKR\n" + | |
< "AcPdfcx7dTRd18XBaBPLNRzbUfck1rCIiO9QXR6oVbUYBlOKPVDYMjgrav4hd2s2\n" + | |
< "BxWNLXxkE3MsyTSQ/+B8ty9Sz0C0aDrRRs5lA0/07hF9C3Wnv8op5XsUkO5eT7RD\n" + | |
< "1PeWk+WiQURcQhAJsmrxjG7rXWQWaU8QR095Ldd1VRZXzPoLx8+iTNWqNRj/VuWw\n" + | |
< "vhThYuWIP+RJTAV4kx/Mi8Os1dkV0KIKYQYsu+i0d7UBqL4LzCoY332Z/vJiaoVT\n" + | |
< "+Aa4T7+/hgoG0VYF5ddSyDZv+CwUOzLO7fh/Tg4Jv1CpHKgwq4NELf6G7SVjrnKH\n" + | |
< "LNd/JULHDMTpl6/RFn0rrwb/phmfQz0cbHU3ZXUJU5m9aqvjhdjV31+UP+Re0EBB\n" + | |
< "JKDTHqzggTfPtpu8+nIRrfxm8pyHHxmt4pa4wUYujLnySLyPpMYLuAi3U7FUSHyo\n" + | |
< "F3eZB1SeQ+9rQuZSRlvjXJTdNBDDUnJR9CiKC6K78jHKXHd5v7LPWh86g7SpABEB\n" + | |
< "AAHCwXYEGAEKACAWIQREX4B5lvcFhrcVx7ihOAax+ipnawUCZl3PHgIbDAAKCRCh\n" + | |
< "OAax+ipna9/OD/0bHstAeNKkUezn8QbI8ZuRXgkrcPo0EQ3dUNO6ZbyhqFUiM8Vt\n" + | |
< "1syF2vX72+BNewwFsOAWHrDTRSZ09dO+M1c58I+Lr1AVP14jfYQ0mmPGY8ND9sk5\n" + | |
< "WDheZjCbO6OJ55yQzC/ZTEra1Pxi3yWqcneyG3yX4z4ih3BazYIH3MR3EaSLVLjd\n" + | |
< "eo3TqviWsBE7upKI1ipKf58l/0JoYWWWyVSVbEk/kjHlod19NjHzBvxzAX7I17Co\n" + | |
< "+TMduAb2wrwVOqdDzOTS/X/KOAs7Q643rTgz9YqC2V/k9FLDKQIgqUvsADTnZtwF\n" + | |
< "1fzL3U/xcJdh46Yy3lmyi2e9Rt6oVSGTaRiSWSlPYGAgiLYiHGTpLhpAmupNGdaj\n" + | |
< "tJ0PZPoFehQ7zW75tOml1/8AIwUgzJsQHSKe3UCG7uSpXWT0sE4trfF71O0y0zoH\n" + | |
< "hJZZq0X9O6iC3qLOGi8l4ZmhTJhBd3YlPqtugHuQWSiBABR2EoCxrhgbu0W5+Dp/\n" + | |
< "db/0DMdwPhIwWwi1j6E3YKqQiz3q+mjUflUFiskJUeaYQe+YaeXJ43bZ4WPXZcfy\n" + | |
< "5WEKWZypGiuhirhfSrdmt4EPWQ3fR2j7/RafEpMsF9cWDvAoAvQQK3VM/EoCcj12\n" + | |
< "qbgNKNuFv/4hw+BF2AUIM3SojZ6yqaNw2NByy3zKd5Wx1U4Pd6OY4Jcrxg==\n" + | |
< "=iJA5\n" + | |
< "-----END PGP PUBLIC KEY BLOCK-----\n"; | |
< | |
82,96d22 | |
< } | |
< | |
< public static void stop(final SamouraiActivity activity) { | |
< if (SamouraiTorManager.INSTANCE.isConnected()) { | |
< SamouraiTorManager.INSTANCE.stop(); | |
< } | |
< if (WhirlpoolNotificationService.isRunning(activity)) { | |
< WhirlpoolNotificationService.stopService(activity); | |
< } | |
< TimeOutUtil.getInstance().reset(); | |
< if (StealthModeController.INSTANCE.isStealthEnabled(activity)) { | |
< StealthModeController.INSTANCE.enableStealth(activity); | |
< } | |
< activity.finishAffinity(); | |
< activity.finish(); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/network/BackendApiAndroid.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/network/BackendApiAndroid.java | |
3,4d2 | |
< import static org.apache.commons.lang3.StringUtils.strip; | |
< | |
15a14 | |
> import com.samourai.wallet.util.network.WebUtil; | |
18,19d16 | |
< public static final boolean FULL_DOJO_MODE_ONLY = true; | |
< public static final String URI_SEP = "/"; | |
22c19 | |
< public static BackendApi getInstance(final Context ctx) { | |
--- | |
> public static BackendApi getInstance(Context ctx) { | |
26c23,24 | |
< if (FULL_DOJO_MODE_ONLY || (DojoUtil.getInstance(ctx).getDojoParams() != null)) { | |
--- | |
> boolean useDojo = (DojoUtil.getInstance(ctx).getDojoParams() != null); | |
> if (useDojo) { | |
28,29c26,28 | |
< final String dojoApiKey = APIFactory.getInstance(ctx).getAppToken(); | |
< backendApi = BackendApi.newBackendApiDojo(httpClient, getApiBaseUrl(), dojoApiKey); | |
--- | |
> String dojoApiKey = APIFactory.getInstance(ctx).getAppToken(); | |
> String dojoUrl = testnet ? WebUtil.SAMOURAI_API2_TESTNET_TOR : WebUtil.SAMOURAI_API2_TOR; | |
> backendApi = BackendApi.newBackendApiDojo(httpClient, dojoUrl, dojoApiKey); | |
42,51d40 | |
< } | |
< | |
< public static String getApiBaseUrl() { | |
< return SamouraiWallet.getInstance().isTestNet() | |
< ? WebUtil.SAMOURAI_API2_TESTNET_TOR | |
< : WebUtil.SAMOURAI_API2_TOR; | |
< } | |
< | |
< public static String getApiServiceUrl(final String service) { | |
< return strip(getApiBaseUrl(), URI_SEP) + URI_SEP + strip(service, URI_SEP); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/network/BlockExplorerUtil.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/network/BlockExplorerUtil.java | |
5d4 | |
< import com.samourai.wallet.util.PrefsUtil; | |
8c7,9 | |
< /* | |
--- | |
> | |
> private static String strMainNetClearExplorer = "https://m.oxt.me/"; | |
> private static String strMainNetTorExplorer = "http://oxtmblv4v7q5rotqtbbmtbcc5aa5vehr72eiebyamclfo3rco5zm3did.onion/"; | |
11,13d11 | |
< private static String strMainNetClearExplorer = strTestNetClearExplorer; // "https://m.oxt.me/"; | |
< private static String strMainNetTorExplorer = strTestNetTorExplorer; // "http://oxtmblv4v7q5rotqtbbmtbcc5aa5vehr72eiebyamclfo3rco5zm3did.onion/"; | |
< */ | |
29,30c27,29 | |
< return null; | |
< /* | |
--- | |
> | |
> String ret = null; | |
> | |
51d49 | |
< */ | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/network/WebUtil.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/network/WebUtil.java | |
3d2 | |
< import static com.samourai.wallet.util.tech.LogUtil.debug; | |
6,7d4 | |
< import static org.apache.commons.lang3.StringUtils.EMPTY; | |
< | |
10,11d6 | |
< import androidx.annotation.NonNull; | |
< | |
22d16 | |
< import com.samourai.wallet.util.PrefsUtil; | |
26d19 | |
< import org.apache.commons.lang3.StringUtils; | |
53,66c46,52 | |
< //public static final String SAMOURAI_API = "https://api.samouraiwallet.com/"; | |
< //public static final String SAMOURAI_API_CHECK = "https://api.samourai.com/v1/status"; | |
< //public static final String SAMOURAI_API2 = "https://api.samouraiwallet.com/v2/"; | |
< //public static final String SAMOURAI_API2_TESTNET = "https://api.samouraiwallet.com/test/v2/"; | |
< | |
< //public static final String SAMOURAI_API2_TOR_DIST = "http://d2oagweysnavqgcfsfawqwql2rwxend7xxpriq676lzsmtfwbt75qbqd.onion/v2/"; | |
< //public static final String SAMOURAI_API2_TESTNET_TOR_DIST = "http://d2oagweysnavqgcfsfawqwql2rwxend7xxpriq676lzsmtfwbt75qbqd.onion/test/v2/"; | |
< | |
< public static final String SAMOURAI_API = null; | |
< public static final String SAMOURAI_API_CHECK = null; | |
< public static final String SAMOURAI_API2 = null; | |
< public static final String SAMOURAI_API2_TESTNET = null; | |
< public static final String SAMOURAI_API2_TESTNET_TOR_DIST = null; | |
< public static final String SAMOURAI_API2_TOR_DIST = null; | |
--- | |
> public static final String SAMOURAI_API = "https://api.samouraiwallet.com/"; | |
> public static final String SAMOURAI_API_CHECK = "https://api.samourai.com/v1/status"; | |
> public static final String SAMOURAI_API2 = "https://api.samouraiwallet.com/v2/"; | |
> public static final String SAMOURAI_API2_TESTNET = "https://api.samouraiwallet.com/test/v2/"; | |
> | |
> public static final String SAMOURAI_API2_TOR_DIST = "http://d2oagweysnavqgcfsfawqwql2rwxend7xxpriq676lzsmtfwbt75qbqd.onion/v2/"; | |
> public static final String SAMOURAI_API2_TESTNET_TOR_DIST = "http://d2oagweysnavqgcfsfawqwql2rwxend7xxpriq676lzsmtfwbt75qbqd.onion/test/v2/"; | |
98,102c84,96 | |
< if (SamouraiTorManager.INSTANCE.isRequired()) { | |
< if (urlParameters.startsWith("tx=")) { | |
< HashMap<String, String> args = new HashMap<String, String>(); | |
< args.put("tx", urlParameters.substring(3)); | |
< return tor_postURL(request, args, headers); | |
--- | |
> | |
> if (context == null) { | |
> return postURL(null, request, urlParameters, headers); | |
> } else { | |
> // Log.v("WebUtil", "Tor required status:" + SamouraiTorManager.INSTANCE.isRequired()); | |
> if (SamouraiTorManager.INSTANCE.isRequired()) { | |
> if (urlParameters.startsWith("tx=")) { | |
> HashMap<String, String> args = new HashMap<String, String>(); | |
> args.put("tx", urlParameters.substring(3)); | |
> return tor_postURL(request, args, headers); | |
> } else { | |
> return tor_postURL(request + urlParameters, new HashMap(), headers); | |
> } | |
104c98 | |
< return tor_postURL(request + urlParameters, new HashMap(), headers); | |
--- | |
> return postURL(null, request, urlParameters, headers); | |
106,107c100 | |
< } else { | |
< return postURL(null, request, urlParameters, headers); | |
--- | |
> | |
108a102 | |
> | |
111c105 | |
< private String postURL(String contentType, String request, String urlParameters) throws Exception { | |
--- | |
> public String postURL(String contentType, String request, String urlParameters) throws Exception { | |
115c109 | |
< private String postURL(String contentType, String request, String urlParameters, Map<String, String> headers) throws HttpException { | |
--- | |
> public String postURL(String contentType, String request, String urlParameters, Map<String, String> headers) throws HttpException { | |
187c181 | |
< private String deleteURL(String request, String urlParameters) throws Exception { | |
--- | |
> public String deleteURL(String request, String urlParameters) throws Exception { | |
252,261d245 | |
< final Map<String, String> headers = enrichHeaders(inputHeaders); | |
< if (SamouraiTorManager.INSTANCE.isRequired()) { | |
< return tor_getURL(url, headers, timeout); | |
< } else { | |
< return _getURL(url, headers, timeout); | |
< } | |
< } | |
< | |
< @NonNull | |
< private static Map<String, String> enrichHeaders(Map<String, String> inputHeaders) { | |
269c253,264 | |
< return headers; | |
--- | |
> | |
> if (context == null) { | |
> return _getURL(url, headers, timeout); | |
> } else { | |
> //if(TorUtil.getInstance(context).orbotIsRunning()) { | |
> //Log.v("WebUtil", "Tor required status:" + SamouraiTorManager.INSTANCE.isRequired()); | |
> if (SamouraiTorManager.INSTANCE.isRequired()) { | |
> return tor_getURL(url, headers, timeout); | |
> } else { | |
> return _getURL(url, headers, timeout); | |
> } | |
> } | |
327,334c322 | |
< public String tor_getURL( | |
< final String url, | |
< Map<String,String> headers | |
< ) throws HttpException { | |
< return tor_getURL(url, headers, DefaultRequestTimeout); | |
< } | |
< | |
< public String tor_getURL( | |
--- | |
> private String tor_getURL( | |
336c324 | |
< Map<String,String> inputHeaders, | |
--- | |
> Map<String,String> headers, | |
345,346c333,336 | |
< final Map<String, String> headers = enrichHeaders(inputHeaders); | |
< | |
--- | |
> // set headers | |
> if (headers == null) { | |
> headers = new HashMap<>(); | |
> } | |
373c363 | |
< if (args != null && !args.isEmpty()) { | |
--- | |
> if (args != null && args.size()!=0) { | |
375,376c365 | |
< if (key == null) continue; | |
< formBodyBuilder.add(key, StringUtils.defaultIfBlank(args.get(key), EMPTY)); | |
--- | |
> formBodyBuilder.add(key, args.get(key)); | |
425d413 | |
< debug("WebUtil", "HttpException: : " + URL + "=>" + e.getMessage()); | |
428d415 | |
< debug("WebUtil", "Exception: : " + URL + "=>" + e.getMessage()); | |
510a498,505 | |
> } | |
> | |
> public static String getAPIUrl(Context context) { | |
> if(SamouraiTorManager.INSTANCE.isRequired()) { | |
> return SamouraiWallet.getInstance().isTestNet() ? SAMOURAI_API2_TESTNET_TOR : SAMOURAI_API2_TOR; | |
> } else { | |
> return SamouraiWallet.getInstance().isTestNet() ? SAMOURAI_API2_TESTNET : SAMOURAI_API2; | |
> } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/PrefsUtil.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/PrefsUtil.java | |
20c20 | |
< public static final String WALLET_SCAN_COMPLETE = "wallet_scan_complete"; | |
--- | |
> public static final String FIRST_RUN = "1stRun"; | |
42,44d41 | |
< public static final String XPUBSWAPDEPOLOCK = "xpubswapsdepolock"; | |
< public static final String XPUBSWAPREFUNDSLOCK = "xpubswapsrefundslock"; | |
< public static final String XPUBSWAPASBLOCK = "xpubswapsasblock"; | |
65,66d61 | |
< public static final String BLOCK_EXPLORER_URL = "block_explorer_url"; | |
< public static final String DOJO_NAME = "dojo_name"; | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/tech/AppUtil.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/tech/AppUtil.java | |
9d8 | |
< import android.content.pm.ApplicationInfo; | |
14,15d12 | |
< import androidx.appcompat.app.AppCompatActivity; | |
< import androidx.fragment.app.FragmentActivity; | |
20d16 | |
< import com.samourai.wallet.SamouraiActivity; | |
33d28 | |
< import com.samourai.wallet.util.Util; | |
42d36 | |
< import java.io.FileInputStream; | |
50,51d43 | |
< public static final String TAG = "AppUtil"; | |
< | |
74d65 | |
< private static MutableLiveData<Boolean> hasUpdateBeenShown = new MutableLiveData<>(false); | |
121,128d111 | |
< public MutableLiveData<Boolean> getHasUpdateBeenShown() { | |
< return hasUpdateBeenShown; | |
< } | |
< | |
< public void setHasUpdateBeenShown(boolean beenShown) { | |
< hasUpdateBeenShown.postValue(beenShown); | |
< } | |
< | |
217,218c200,207 | |
< public void restartAppFromActivity(final Bundle extras, final FragmentActivity fromActivity) { | |
< final Intent intent = new Intent(fromActivity, MainActivity2.class); | |
--- | |
> public void restartApp(Bundle extras) { | |
> | |
> Intent intent = new Intent(context, MainActivity2.class); | |
> if (PrefsUtil.getInstance(context).getValue(PrefsUtil.ICON_HIDDEN, false) == true) { | |
> // intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_SINGLE_TOP); | |
> } else { | |
> // intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); | |
> } | |
222c211,237 | |
< fromActivity.startActivity(intent); | |
--- | |
> context.startActivity(intent); | |
> } | |
> | |
> public void restartApp(String name, boolean value) { | |
> Intent intent = new Intent(context, MainActivity2.class); | |
> if (PrefsUtil.getInstance(context).getValue(PrefsUtil.ICON_HIDDEN, false) == true) { | |
> intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_SINGLE_TOP); | |
> } else { | |
> intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); | |
> } | |
> if (name != null) { | |
> intent.putExtra(name, value); | |
> } | |
> context.startActivity(intent); | |
> } | |
> | |
> public void restartApp(String name, String value) { | |
> Intent intent = new Intent(context, MainActivity2.class); | |
> if (PrefsUtil.getInstance(context).getValue(PrefsUtil.ICON_HIDDEN, false) == true) { | |
> intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_SINGLE_TOP); | |
> } else { | |
> intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); | |
> } | |
> if (name != null && value != null) { | |
> intent.putExtra(name, value); | |
> } | |
> context.startActivity(intent); | |
323,336d337 | |
< } | |
< | |
< public String getApkSha256() { | |
< final ApplicationInfo appInfo = context.getApplicationContext().getApplicationInfo(); | |
< final String apkPath = appInfo.sourceDir; | |
< final File file = new File(apkPath); | |
< try (final FileInputStream fis = new FileInputStream(file)) { | |
< byte[] fileBytes = new byte[(int) file.length()]; | |
< fis.read(fileBytes); | |
< return Util.sha256ToString(fileBytes); | |
< } catch (final Exception e) { | |
< Log.e(TAG, "cannot getApkSha256()", e); | |
< return null; | |
< } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/tech/HapticHelper.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/tech/HapticHelper.kt | |
13,15d12 | |
< val hapticTadaPattern = longArrayOf(50L, 64L, 120L, 64L) | |
< val hapticDaDuration = 60L | |
< | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/tech/SimpleTaskRunner.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/tech/SimpleTaskRunner.java | |
13c13 | |
< private static final String TAG = SimpleTaskRunner.class.getSimpleName(); | |
--- | |
> public static final String TAG = SimpleTaskRunner.class.getSimpleName(); | |
23,29d22 | |
< public void executeAsyncAndShutdown(final Runnable runnable) { | |
< executor.execute(() -> { | |
< runnable.run(); | |
< shutdown(); | |
< }); | |
< } | |
< | |
34,45c27 | |
< public <T> void executeAsync( | |
< final Callable<T> callable, | |
< final SimpleCallback<T> simpleCallback) { | |
< | |
< executeAsync(false, callable, simpleCallback); | |
< } | |
< | |
< public <T> void executeAsync( | |
< final boolean shutdownAfterComplete, | |
< final Callable<T> callable, | |
< final SimpleCallback<T> simpleCallback) { | |
< | |
--- | |
> public <T> void executeAsync(final Callable<T> callable, final SimpleCallback<T> simpleCallback) { | |
58,60d39 | |
< if (shutdownAfterComplete) { | |
< shutdown(); | |
< } | |
63,66d41 | |
< } | |
< | |
< public void shutdown() { | |
< executor.shutdown(); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/tech/ThreadHelper.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/tech/ThreadHelper.java | |
19,29d18 | |
< | |
< public static boolean pauseMillisWithStatus(final long pause) { | |
< try { | |
< Thread.sleep(pause); | |
< return true; | |
< } catch (final InterruptedException e) { | |
< Thread.currentThread().interrupt(); | |
< Log.e(TAG, "InterruptedException on #pauseMillis", e); | |
< } | |
< return false; | |
< } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/util/view/SamCheckbox.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/util/view/SamCheckbox.kt | |
35,36c35 | |
< rectColor: Color = Color.White, | |
< rectColorUnchecked: Color = Color.Transparent | |
--- | |
> rectColor: Color = Color.White | |
49c48 | |
< color = if (checked) rectColor else rectColorUnchecked, | |
--- | |
> color = rectColor, | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/utxos/UTXODetailsActivity.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/utxos/UTXODetailsActivity.java | |
40d39 | |
< import com.samourai.wallet.util.PrefsUtil; | |
54d52 | |
< import org.apache.commons.lang3.StringUtils; | |
239,245c237 | |
< if (!StringUtils.equals(BIP47Meta.getInstance().getName(pcode), BIP47Meta.getInstance().getDisplayLabel(pcode))) { | |
< ((TextView) paynymLayout.findViewById(R.id.paynym_label)).setText(BIP47Meta.getInstance().getDisplayLabel(pcode)); | |
< ((TextView) paynymLayout.findViewById(R.id.paynym_code)).setText(BIP47Meta.getInstance().getName(pcode)); | |
< } else { | |
< ((TextView) paynymLayout.findViewById(R.id.paynym_code)).setText(BIP47Meta.getInstance().getName(pcode)); | |
< ((TextView) paynymLayout.findViewById(R.id.paynym_label)).setText(""); | |
< } | |
--- | |
> ((TextView) paynymLayout.findViewById(R.id.paynym_code)).setText(BIP47Meta.getInstance().getDisplayLabel(pcode)); | |
252d243 | |
< ((TextView) paynymLayout.findViewById(R.id.paynym_label)).setText(""); | |
385,388d375 | |
< if (PrefsUtil.getInstance(getApplicationContext()).getValue(PrefsUtil.BLOCK_EXPLORER_URL, "").isEmpty()) { | |
< menu.findItem(R.id.utxo_details_view_in_explorer).setVisible(false); | |
< } | |
< | |
406c393 | |
< /* | |
--- | |
> | |
411d397 | |
< */ | |
631c617 | |
< SamouraiTorManager.INSTANCE.newIdentity(); | |
--- | |
> SamouraiTorManager.newIdentity(); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/utxos/UTXOSActivity.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/utxos/UTXOSActivity.java | |
11d10 | |
< import android.util.Log; | |
59,61d57 | |
< import com.samourai.wallet.util.tech.SimpleCallback; | |
< import com.samourai.wallet.util.tech.SimpleTaskRunner; | |
< import com.samourai.wallet.util.tech.ThreadHelper; | |
65a62 | |
> import com.samourai.wallet.whirlpool.fragments.WhirlPoolLoaderDialog; | |
66a64 | |
> import com.samourai.whirlpool.client.wallet.AndroidWhirlpoolWalletService; | |
85d82 | |
< import java.util.concurrent.Callable; | |
134d130 | |
< | |
177c173 | |
< AppUtil.getInstance(getApplicationContext()).getWalletLoading().observe(this, aBoolean -> { | |
--- | |
> AppUtil.getInstance(getApplicationContext()).getWalletLoading().observe(this,aBoolean -> { | |
179,194c175,176 | |
< if(!aBoolean) { | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< new Callable<Void>() { | |
< @Override | |
< public Void call() throws Exception { | |
< ThreadHelper.pauseMillis(50L); | |
< return null; | |
< } | |
< }, new SimpleCallback<Void>() { | |
< @Override | |
< public void onComplete(Void result) { | |
< // ensore to call in main thread | |
< loadUTXOs(false); | |
< } | |
< }); | |
--- | |
> if(!aBoolean){ | |
> loadUTXOs(false); | |
269d250 | |
< | |
271,291c252,253 | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< new Callable<List<UTXOCoin>>() { | |
< @Override | |
< public List<UTXOCoin> call() throws Exception { | |
< return applyFilters(); | |
< } | |
< }, | |
< new SimpleCallback<List<UTXOCoin>>() { | |
< @Override | |
< public void onComplete(List<UTXOCoin> result) { | |
< adapter.updateList(result); | |
< adapter.notifyDataSetChanged(); | |
< } | |
< | |
< @Override | |
< public void onException(Throwable t) { | |
< Log.e(TAG, "issue on applyFilters()", t); | |
< } | |
< } | |
< ); | |
--- | |
> applyFilters(); | |
> adapter.notifyDataSetChanged(); | |
296,297c258,259 | |
< @NonNull | |
< private List<UTXOCoin> applyFilters() { | |
--- | |
> private void applyFilters() { | |
> | |
299c261 | |
< final List<UTXOCoin> filteredStatus = new ArrayList<>(); | |
--- | |
> ArrayList<UTXOCoin> filteredStatus = new ArrayList<>(); | |
366c328 | |
< final List<UTXOCoin> sectioned = new ArrayList<>(); | |
--- | |
> List<UTXOCoin> sectioned = new ArrayList<>(); | |
395c357,358 | |
< return sectioned; | |
--- | |
> | |
> this.adapter.updateList(sectioned); | |
425,432c388 | |
< synchronized private void loadUTXOs(boolean loadSilently) { | |
< | |
< if (loadSilently) { | |
< Log.i(TAG, "will start loading utxo silently"); | |
< } else { | |
< Log.i(TAG, "will start loading utxo"); | |
< } | |
< | |
--- | |
> private void loadUTXOs(boolean loadSilently) { | |
443,489c399,422 | |
< | |
< SimpleTaskRunner.create().executeAsync( | |
< true, | |
< new Callable<List<UTXOCoin>>() { | |
< @Override | |
< synchronized public List<UTXOCoin> call() throws Exception { | |
< final Map<String, Object> data = getUTXOs(); | |
< | |
< try { | |
< totalP2WPKH = (long) data.get("totalP2WPKH"); | |
< totalBlocked = (long) data.get("totalBlocked"); | |
< totalP2SH_P2WPKH = (long) data.get("totalP2SH_P2WPKH"); | |
< totalP2PKH = (long) data.get("totalP2PKH"); | |
< } catch (final Exception e) { | |
< Log.e(TAG, "issue on get long from stats map", e); | |
< } | |
< | |
< unFilteredUTXOS = new ArrayList<>((List<UTXOCoin>) data.get("utxos")); | |
< LogUtil.info(TAG, "loadUTXOs: ".concat(String.valueOf(unFilteredUTXOS.size()))); | |
< return applyFilters(); | |
< } | |
< }, | |
< new SimpleCallback<List<UTXOCoin>>() { | |
< @Override | |
< synchronized public void onComplete(final List<UTXOCoin> utxoRowsToDisplay) { | |
< adapter.updateList(utxoRowsToDisplay); | |
< if (!loadSilently) { | |
< utxoProgressBar.setVisibility(View.GONE); | |
< } | |
< if (loadSilently) { | |
< Log.i(TAG, "loading utxo silently is done"); | |
< } else { | |
< Log.i(TAG, "loading utxo is done"); | |
< } | |
< } | |
< | |
< @Override | |
< synchronized public void onException(final Throwable t) { | |
< if (loadSilently) { | |
< Log.i(TAG, "loading utxo silently is failed", t); | |
< } else { | |
< Log.i(TAG, "loading utxo is failed", t); | |
< } | |
< if (!loadSilently) { | |
< utxoSwipeRefresh.setRefreshing(false); | |
< utxoProgressBar.setVisibility(View.GONE); | |
< } | |
--- | |
> Disposable disposable = getUTXOs() | |
> .subscribeOn(Schedulers.io()) | |
> .observeOn(AndroidSchedulers.mainThread()) | |
> .subscribe(stringObjectMap -> { | |
> List<UTXOCoin> items = (List<UTXOCoin>) stringObjectMap.get("utxos"); | |
> LogUtil.info(TAG, "loadUTXOs: ".concat(String.valueOf(items.size()))); | |
> try { | |
> unFilteredUTXOS = new ArrayList<>(); | |
> unFilteredUTXOS.addAll(items); | |
> applyFilters(); | |
> } catch (Exception ex) { | |
> ex.printStackTrace(); | |
> } | |
> totalP2WPKH = (long) stringObjectMap.get("totalP2WPKH"); | |
> totalBlocked = (long) stringObjectMap.get("totalBlocked"); | |
> totalP2SH_P2WPKH = (long) stringObjectMap.get("totalP2SH_P2WPKH"); | |
> totalP2PKH = (long) stringObjectMap.get("totalP2PKH"); | |
> if (!loadSilently) { | |
> utxoProgressBar.setVisibility(View.GONE); | |
> } | |
> }, err -> { | |
> if (!loadSilently) { | |
> utxoSwipeRefresh.setRefreshing(false); | |
> utxoProgressBar.setVisibility(View.GONE); | |
491,492c424,425 | |
< } | |
< ); | |
--- | |
> }); | |
> compositeDisposable.add(disposable); | |
495,509c428,442 | |
< @NonNull | |
< private Map<String, Object> getUTXOs() { | |
< long totalP2WPKH = 0L; | |
< long totalBlocked = 0L; | |
< long totalP2PKH = 0L; | |
< long totalP2SH_P2WPKH = 0L; | |
< | |
< noteAmounts.clear(); | |
< tagAmounts.clear(); | |
< | |
< final Map<String, Object> dataSet = new HashMap<>(); | |
< List<UTXO> utxos = null; | |
< if (account == WhirlpoolMeta.getInstance(getApplicationContext()).getWhirlpoolPostmix()) { | |
< utxos = APIFactory.getInstance(getApplicationContext()).getUtxosPostMix(false); | |
< } else { | |
--- | |
> private Observable<Map<String, Object>> getUTXOs() { | |
> return Observable.fromCallable(() -> { | |
> long totalP2WPKH = 0L; | |
> long totalBlocked = 0L; | |
> long totalP2PKH = 0L; | |
> long totalP2SH_P2WPKH = 0L; | |
> | |
> noteAmounts.clear(); | |
> tagAmounts.clear(); | |
> | |
> Map<String, Object> dataSet = new HashMap<>(); | |
> List<UTXO> utxos = null; | |
> if (account == WhirlpoolMeta.getInstance(getApplicationContext()).getWhirlpoolPostmix()) { | |
> utxos = APIFactory.getInstance(getApplicationContext()).getUtxosPostMix(false); | |
> } else { | |
511,512c444,445 | |
< utxos = APIFactory.getInstance(getApplicationContext()).getUtxos(false); | |
< } | |
--- | |
> utxos = APIFactory.getInstance(getApplicationContext()).getUtxos(false); | |
> } | |
514,519c447,453 | |
< long amount = 0L; | |
< for (UTXO utxo : utxos) { | |
< for (MyTransactionOutPoint out : utxo.getOutpoints()) { | |
< debug("UTXOSActivity", "utxo:" + out.getAddress() + "," + out.getValue()); | |
< debug("UTXOSActivity", "utxo:" + utxo.getPath()); | |
< amount += out.getValue().longValue(); | |
--- | |
> long amount = 0L; | |
> for (UTXO utxo : utxos) { | |
> for (MyTransactionOutPoint out : utxo.getOutpoints()) { | |
> debug("UTXOSActivity", "utxo:" + out.getAddress() + "," + out.getValue()); | |
> debug("UTXOSActivity", "utxo:" + utxo.getPath()); | |
> amount += out.getValue().longValue(); | |
> } | |
521d454 | |
< } | |
523,528c456,461 | |
< ArrayList<UTXOCoin> items = new ArrayList<>(); | |
< for (UTXO utxo : utxos) { | |
< for (MyTransactionOutPoint outpoint : utxo.getOutpoints()) { | |
< UTXOCoin displayData = new UTXOCoin(outpoint, utxo); | |
< if (BlockedUTXO.getInstance().contains(outpoint.getTxHash().toString(), outpoint.getTxOutputN())) { | |
< totalBlocked += displayData.amount; | |
--- | |
> ArrayList<UTXOCoin> items = new ArrayList<>(); | |
> for (UTXO utxo : utxos) { | |
> for (MyTransactionOutPoint outpoint : utxo.getOutpoints()) { | |
> UTXOCoin displayData = new UTXOCoin(outpoint, utxo); | |
> if (BlockedUTXO.getInstance().contains(outpoint.getTxHash().toString(), outpoint.getTxOutputN())) { | |
> totalBlocked += displayData.amount; | |
530c463 | |
< } else if (BlockedUTXO.getInstance().containsPostMix(outpoint.getTxHash().toString(), outpoint.getTxOutputN())) { | |
--- | |
> } else if (BlockedUTXO.getInstance().containsPostMix(outpoint.getTxHash().toString(), outpoint.getTxOutputN())) { | |
532,538c465 | |
< totalBlocked += displayData.amount; | |
< } else { | |
< // Log.d("UTXOActivity", "unmarked"); | |
< if (FormatsUtil.getInstance().isValidBech32(displayData.address)) { | |
< totalP2WPKH += displayData.amount; | |
< } else if (Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), displayData.address).isP2SHAddress()) { | |
< totalP2SH_P2WPKH += displayData.amount; | |
--- | |
> totalBlocked += displayData.amount; | |
540c467,474 | |
< totalP2PKH += displayData.amount; | |
--- | |
> // Log.d("UTXOActivity", "unmarked"); | |
> if (FormatsUtil.getInstance().isValidBech32(displayData.address)) { | |
> totalP2WPKH += displayData.amount; | |
> } else if (Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), displayData.address).isP2SHAddress()) { | |
> totalP2SH_P2WPKH += displayData.amount; | |
> } else { | |
> totalP2PKH += displayData.amount; | |
> } | |
542d475 | |
< } | |
544,545c477,478 | |
< if (UTXOUtil.getInstance().get(outpoint.getTxHash().toString(), outpoint.getTxOutputN()) != null) { | |
< List<String> tags = UTXOUtil.getInstance().get(outpoint.getTxHash().toString(), outpoint.getTxOutputN()); | |
--- | |
> if (UTXOUtil.getInstance().get(outpoint.getTxHash().toString(), outpoint.getTxOutputN()) != null) { | |
> List<String> tags = UTXOUtil.getInstance().get(outpoint.getTxHash().toString(), outpoint.getTxOutputN()); | |
547,553c480,487 | |
< for (String tag : tags) { | |
< if (tagAmounts.containsKey(tag.toLowerCase())) { | |
< long val = tagAmounts.get(tag.toLowerCase()); | |
< val += displayData.amount; | |
< tagAmounts.put(tag.toLowerCase(), val); | |
< } else { | |
< tagAmounts.put(tag.toLowerCase(), displayData.amount); | |
--- | |
> for (String tag : tags) { | |
> if (tagAmounts.containsKey(tag.toLowerCase())) { | |
> long val = tagAmounts.get(tag.toLowerCase()); | |
> val += displayData.amount; | |
> tagAmounts.put(tag.toLowerCase(), val); | |
> } else { | |
> tagAmounts.put(tag.toLowerCase(), displayData.amount); | |
> } | |
554a489 | |
> | |
555a491,492 | |
> if (UTXOUtil.getInstance().getNote(outpoint.getTxHash().toString()) != null) { | |
> String note = UTXOUtil.getInstance().getNote(outpoint.getTxHash().toString()); | |
557,559c494,500 | |
< } | |
< if (UTXOUtil.getInstance().getNote(outpoint.getTxHash().toString()) != null) { | |
< String note = UTXOUtil.getInstance().getNote(outpoint.getTxHash().toString()); | |
--- | |
> if (noteAmounts.containsKey(note.toLowerCase())) { | |
> long val = noteAmounts.get(note.toLowerCase()); | |
> val += displayData.amount; | |
> noteAmounts.put(note.toLowerCase(), val); | |
> } else { | |
> noteAmounts.put(note.toLowerCase(), displayData.amount); | |
> } | |
561,566d501 | |
< if (noteAmounts.containsKey(note.toLowerCase())) { | |
< long val = noteAmounts.get(note.toLowerCase()); | |
< val += displayData.amount; | |
< noteAmounts.put(note.toLowerCase(), val); | |
< } else { | |
< noteAmounts.put(note.toLowerCase(), displayData.amount); | |
569,574c504,508 | |
< } | |
< | |
< boolean exist = false; | |
< for (int i = 0; i < items.size(); i++) { | |
< if (items.get(i).hash.equals(displayData.hash) && items.get(i).idx == displayData.idx && items.get(i).path.equals(displayData.path)) { | |
< exist = true; | |
--- | |
> boolean exist = false; | |
> for (int i = 0; i < items.size(); i++) { | |
> if (items.get(i).hash.equals(displayData.hash) && items.get(i).idx == displayData.idx && items.get(i).path.equals(displayData.path)) { | |
> exist = true; | |
> } | |
576,578c510,513 | |
< } | |
< if (!exist) { | |
< items.add(displayData); | |
--- | |
> if (!exist) { | |
> items.add(displayData); | |
> } | |
> | |
581a517,521 | |
> dataSet.put("totalP2WPKH", totalP2WPKH); | |
> dataSet.put("totalBlocked", totalBlocked); | |
> dataSet.put("totalP2SH_P2WPKH", totalP2SH_P2WPKH); | |
> dataSet.put("totalP2PKH", totalP2PKH); | |
> dataSet.put("utxos", items); | |
583,590c523,524 | |
< } | |
< dataSet.put("totalP2WPKH", totalP2WPKH); | |
< dataSet.put("totalBlocked", totalBlocked); | |
< dataSet.put("totalP2SH_P2WPKH", totalP2SH_P2WPKH); | |
< dataSet.put("totalP2PKH", totalP2PKH); | |
< dataSet.put("utxos", items); | |
< | |
< return dataSet; | |
--- | |
> return dataSet; | |
> }); | |
761d694 | |
< /* | |
797d729 | |
< */ | |
1096c1028 | |
< holder.rootViewGroup.setBackgroundColor(ContextCompat.getColor(getBaseContext(), R.color.networking)); | |
--- | |
> holder.rootViewGroup.setBackgroundColor(ContextCompat.getColor(getBaseContext(), R.color.windowDark)); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/whirlpool/newPool/fragments/SelectPoolFragment.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/whirlpool/newPool/fragments/SelectPoolFragment.kt | |
7a8,15 | |
> import androidx.recyclerview.widget.RecyclerView | |
> import com.samourai.wallet.whirlpool.adapters.PoolsAdapter | |
> import com.samourai.wallet.whirlpool.models.PoolViewModel | |
> import com.google.android.material.button.MaterialButton | |
> import com.samourai.wallet.whirlpool.models.PoolCyclePriority | |
> import io.reactivex.disposables.CompositeDisposable | |
> import com.samourai.wallet.whirlpool.newPool.NewPoolViewModel | |
> import com.samourai.wallet.utxos.models.UTXOCoin | |
9c17,21 | |
< import android.util.TypedValue | |
--- | |
> import android.util.Log | |
> import com.samourai.wallet.R | |
> import androidx.recyclerview.widget.DefaultItemAnimator | |
> import androidx.core.content.ContextCompat | |
> import androidx.recyclerview.widget.LinearLayoutManager | |
11d22 | |
< import android.view.View | |
15c26,28 | |
< import androidx.core.content.ContextCompat | |
--- | |
> import androidx.recyclerview.widget.RecyclerView.ItemDecoration | |
> import android.util.TypedValue | |
> import android.view.View | |
18,23c31 | |
< import androidx.recyclerview.widget.DefaultItemAnimator | |
< import androidx.recyclerview.widget.LinearLayoutManager | |
< import androidx.recyclerview.widget.RecyclerView | |
< import androidx.recyclerview.widget.RecyclerView.ItemDecoration | |
< import com.google.android.material.button.MaterialButton | |
< import com.samourai.wallet.R | |
--- | |
> import com.google.android.material.snackbar.Snackbar | |
26,31d33 | |
< import com.samourai.wallet.send.FeeUtil | |
< import com.samourai.wallet.utxos.models.UTXOCoin | |
< import com.samourai.wallet.whirlpool.adapters.PoolsAdapter | |
< import com.samourai.wallet.whirlpool.models.PoolCyclePriority | |
< import com.samourai.wallet.whirlpool.models.PoolViewModel | |
< import com.samourai.wallet.whirlpool.newPool.NewPoolViewModel | |
33c35 | |
< import io.reactivex.disposables.CompositeDisposable | |
--- | |
> import java.util.ArrayList | |
75,80d76 | |
< } | |
< | |
< if (FeeUtil.getInstance().feeRepresentation.is1DolFeeEstimator) { | |
< binding.feeHighBtn.setText("Next Block") | |
< } else { | |
< binding.feeHighBtn.setText("HIGH") | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/whirlpool/WhirlpoolHome.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/whirlpool/WhirlpoolHome.kt | |
36a37 | |
> import com.samourai.wallet.service.WalletRefreshWorker | |
39d39 | |
< import com.samourai.wallet.util.func.WalletRefreshUtil | |
50d49 | |
< import kotlinx.coroutines.async | |
103,109c102,104 | |
< withContext(Dispatchers.IO) { | |
< async { | |
< WalletRefreshUtil.refreshWallet( | |
< notifTx = false, | |
< launch = false, | |
< context = applicationContext) | |
< } | |
--- | |
> withContext(Dispatchers.Default){ | |
> delay(800) | |
> WalletRefreshWorker.enqueue(applicationContext, notifTx = false, launched = false); | |
252,261c247 | |
< whirlPoolHomeViewModel.viewModelScope.launch { | |
< withContext(Dispatchers.IO) { | |
< async { | |
< WalletRefreshUtil.refreshWallet( | |
< notifTx = false, | |
< launch = false, | |
< context = applicationContext) | |
< } | |
< } | |
< } | |
--- | |
> WalletRefreshWorker.enqueue(applicationContext, launched = false, notifTx = false) | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/whirlpool/WhirlPoolHomeViewModel.kt /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/whirlpool/WhirlPoolHomeViewModel.kt | |
16c16 | |
< import com.samourai.wallet.util.func.WalletRefreshUtil | |
--- | |
> import com.samourai.wallet.service.WalletRefreshWorker | |
26d25 | |
< import kotlinx.coroutines.async | |
226,231c225,227 | |
< async(Dispatchers.IO) { | |
< WalletRefreshUtil.refreshWallet( | |
< notifTx = false, | |
< launch = false, | |
< context = context) | |
< }.await() | |
--- | |
> withContext(Dispatchers.Main){ | |
> WalletRefreshWorker.enqueue(context, notifTx = false,launched = false) | |
> } | |
234c230 | |
< } catch (e:Exception){ | |
--- | |
> }catch (e:Exception){ | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/wallet/widgets/TransactionProgressView.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/wallet/widgets/TransactionProgressView.java | |
214c214 | |
< optionBtn2.setVisibility(GONE); | |
--- | |
> optionBtn2.setVisibility(VISIBLE); | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/main/java/com/samourai/whirlpool/client/wallet/data/AndroidMinerFeeSupplier.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/main/java/com/samourai/whirlpool/client/wallet/data/AndroidMinerFeeSupplier.java | |
3,7d2 | |
< import static java.lang.Math.min; | |
< import static java.util.Objects.nonNull; | |
< | |
< import android.util.Log; | |
< | |
9,10d3 | |
< import com.samourai.wallet.api.fee.EnumFeeRate; | |
< import com.samourai.wallet.api.fee.RawFees; | |
37,85d29 | |
< feeUtil.normalize(); | |
< switch (feeUtil.getFeeRepresentation()) { | |
< case NEXT_BLOCK_RATE: | |
< return getNextBlockFeeRate(feeTarget); | |
< case BLOCK_COUNT: | |
< default: | |
< return getBlockCountFeeRate(feeTarget); | |
< } | |
< } | |
< | |
< private int getNextBlockFeeRate(final MinerFeeTarget feeTarget) { | |
< | |
< final RawFees rawFees = feeUtil.getRawFees(); | |
< BigInteger feePerKB = feeUtil.getNormalFee().getDefaultPerKB(); | |
< | |
< switch (feeTarget) { | |
< case BLOCKS_2: case BLOCKS_4: | |
< feePerKB = feeUtil.getHighFee().getDefaultPerKB(); | |
< break; | |
< | |
< case BLOCKS_6: | |
< feePerKB = feeUtil.getNormalFee().getDefaultPerKB(); | |
< break; | |
< | |
< case BLOCKS_12: case BLOCKS_24: { | |
< final Integer fee100 = rawFees.getFee(EnumFeeRate.RATE_100); | |
< if (nonNull(fee100)) return fee100; | |
< final Integer fee990 = rawFees.getFee(EnumFeeRate.RATE_990); | |
< if (nonNull(fee990)) { | |
< return min(fee990 / 2, feeUtil.getNormalFee().getDefaultPerKB().intValue() / 1000); | |
< } else { | |
< feePerKB = feeUtil.getLowFee().getDefaultPerKB(); | |
< Log.e( | |
< AndroidMinerFeeSupplier.class.getSimpleName(), | |
< "inconsistent state : " + EnumFeeRate.RATE_990.getRateAsString() + " is null"); | |
< } | |
< break; | |
< } | |
< | |
< default: | |
< log.error("unknown MinerFeeTarget: "+feeTarget); | |
< break; | |
< } | |
< long feePerB = feePerKB.longValue() / 1000L; | |
< return (int)feePerB; | |
< } | |
< | |
< private int getBlockCountFeeRate(final MinerFeeTarget feeTarget) { | |
< | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/test/java/com/samourai/whirlpool/client/wallet/AbstractWhirlpoolTest.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/test/java/com/samourai/whirlpool/client/wallet/AbstractWhirlpoolTest.java | |
60c60 | |
< // init Ashigaru | |
--- | |
> // init Samourai Wallet | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/app/src/test/java/com/samourai/whirlpool/client/wallet/WhirlpoolWalletTest.java /home/laurent/dev_samourai/samourai-wallet-android/app/src/test/java/com/samourai/whirlpool/client/wallet/WhirlpoolWalletTest.java | |
15d14 | |
< import com.samourai.wallet.util.network.BackendApiAndroid; | |
63c62 | |
< BackendApi backendApi = new BackendApi(httpClient, BackendApiAndroid.getApiBaseUrl(), null) { | |
--- | |
> BackendApi backendApi = new BackendApi(httpClient, BackendServer.TESTNET.getBackendUrl(onion), null) { | |
122,144c121,142 | |
< /* needs to be upgraded in according to extlibj */ | |
< // @Test | |
< // public void testTx0() throws Exception { | |
< // Collection<UnspentOutput> spendFroms = new LinkedList<>(); | |
< // SimpleUtxoKeyProvider utxoKeyProvider = new SimpleUtxoKeyProvider(); | |
< // | |
< // ECKey ecKey = bip84w.getAccount(0).getChain(0).getAddressAt(61).getECKey(); | |
< // UnspentOutput unspentOutput = newUnspentOutput( | |
< // "cc588cdcb368f894a41c372d1f905770b61ecb3fb8e5e01a97e7cedbf5e324ae", 1, 500000000); | |
< // unspentOutput.addr = new SegwitAddress(ecKey, networkParameters).getBech32AsString(); | |
< // spendFroms.add(unspentOutput); | |
< // utxoKeyProvider.setKey(unspentOutput.computeOutpoint(networkParameters), ecKey); | |
< // | |
< // Pool pool = whirlpoolWallet.getPoolSupplier().findPoolById("0.01btc"); | |
< // Tx0Info tx0Info = AsyncUtil.getInstance().blockingGet(whirlpoolWallet.fetchTx0Info()); | |
< // Tx0Config tx0Config = tx0Info.getTx0Config(Tx0FeeTarget.BLOCKS_2, Tx0FeeTarget.BLOCKS_2); | |
< // Tx0Previews tx0Previews = tx0Info.tx0Previews(tx0Config, spendFroms); | |
< // Tx0Preview tx0Preview = tx0Previews.getTx0Preview(pool.getPoolId()); | |
< // Tx0 tx0 = tx0Info.tx0(whirlpoolWallet.getWalletSupplier(), whirlpoolWallet.getUtxoSupplier(), spendFroms, tx0Config, pool); | |
< // | |
< // Assert.assertEquals("dc398c99cf9ce18123ea916d69bb99da44a3979a625eeaac5e17837f879a8874", tx0.getTx().getHashAsString()); | |
< // Assert.assertEquals("01000000000101ae24e3f5dbcee7971ae0e5b83fcb1eb67057901f2d371ca494f868b3dc8c58cc0100000000ffffffff040000000000000000426a408a9eb379a44ff4d4579118c64b64bbd327cd95ba826ac68f334155fd9ca4e3acd64acdfd75dd7c3cc5bc34d31af6c6e68b4db37eac62b574890f6cfc7b904d9950c300000000000016001441021632871b0f1cf61a7ac7b6a0187e88628291b44b0f00000000001600147e4a4628dd8fbd638681a728e39f7d92ada04070e954bd1d00000000160014df3a4bc83635917ad18621f3ba78cef6469c5f5902483045022100c48f02762ab9877533b5c7b0bc729479ce7809596b89cb9f62b740ea3350068f02205ef46ca67df39d35f940e33223c5ddd56669d953b6ef4948e355c1f3430f32e10121032e46baef8bcde0c3a19cadb378197fa31d69adb21535de3f84de699a1cf88b4500000000", new String(Hex.encode(tx0.getTx().bitcoinSerialize()))); | |
< // } | |
--- | |
> @Test | |
> public void testTx0() throws Exception { | |
> Collection<UnspentOutput> spendFroms = new LinkedList<>(); | |
> SimpleUtxoKeyProvider utxoKeyProvider = new SimpleUtxoKeyProvider(); | |
> | |
> ECKey ecKey = bip84w.getAccount(0).getChain(0).getAddressAt(61).getECKey(); | |
> UnspentOutput unspentOutput = newUnspentOutput( | |
> "cc588cdcb368f894a41c372d1f905770b61ecb3fb8e5e01a97e7cedbf5e324ae", 1, 500000000); | |
> unspentOutput.addr = new SegwitAddress(ecKey, networkParameters).getBech32AsString(); | |
> spendFroms.add(unspentOutput); | |
> utxoKeyProvider.setKey(unspentOutput.computeOutpoint(networkParameters), ecKey); | |
> | |
> Pool pool = whirlpoolWallet.getPoolSupplier().findPoolById("0.01btc"); | |
> Tx0Info tx0Info = AsyncUtil.getInstance().blockingGet(whirlpoolWallet.fetchTx0Info()); | |
> Tx0Config tx0Config = tx0Info.getTx0Config(Tx0FeeTarget.BLOCKS_2, Tx0FeeTarget.BLOCKS_2); | |
> Tx0Previews tx0Previews = tx0Info.tx0Previews(tx0Config, spendFroms); | |
> Tx0Preview tx0Preview = tx0Previews.getTx0Preview(pool.getPoolId()); | |
> Tx0 tx0 = tx0Info.tx0(whirlpoolWallet.getWalletSupplier(), whirlpoolWallet.getUtxoSupplier(), spendFroms, tx0Config, pool); | |
> | |
> Assert.assertEquals("dc398c99cf9ce18123ea916d69bb99da44a3979a625eeaac5e17837f879a8874", tx0.getTx().getHashAsString()); | |
> Assert.assertEquals("01000000000101ae24e3f5dbcee7971ae0e5b83fcb1eb67057901f2d371ca494f868b3dc8c58cc0100000000ffffffff040000000000000000426a408a9eb379a44ff4d4579118c64b64bbd327cd95ba826ac68f334155fd9ca4e3acd64acdfd75dd7c3cc5bc34d31af6c6e68b4db37eac62b574890f6cfc7b904d9950c300000000000016001441021632871b0f1cf61a7ac7b6a0187e88628291b44b0f00000000001600147e4a4628dd8fbd638681a728e39f7d92ada04070e954bd1d00000000160014df3a4bc83635917ad18621f3ba78cef6469c5f5902483045022100c48f02762ab9877533b5c7b0bc729479ce7809596b89cb9f62b740ea3350068f02205ef46ca67df39d35f940e33223c5ddd56669d953b6ef4948e355c1f3430f32e10121032e46baef8bcde0c3a19cadb378197fa31d69adb21535de3f84de699a1cf88b4500000000", new String(Hex.encode(tx0.getTx().bitcoinSerialize()))); | |
> } | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/gradlew /home/laurent/dev_samourai/samourai-wallet-android/gradlew | |
1,17c1 | |
< #!/bin/sh | |
< | |
< # | |
< # Copyright © 2015-2021 the original authors. | |
< # | |
< # Licensed under the Apache License, Version 2.0 (the "License"); | |
< # you may not use this file except in compliance with the License. | |
< # You may obtain a copy of the License at | |
< # | |
< # https://www.apache.org/licenses/LICENSE-2.0 | |
< # | |
< # Unless required by applicable law or agreed to in writing, software | |
< # distributed under the License is distributed on an "AS IS" BASIS, | |
< # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
< # See the License for the specific language governing permissions and | |
< # limitations under the License. | |
< # | |
--- | |
> #!/usr/bin/env bash | |
20,62c4,6 | |
< # | |
< # Gradle start up script for POSIX generated by Gradle. | |
< # | |
< # Important for running: | |
< # | |
< # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is | |
< # noncompliant, but you have some other compliant shell such as ksh or | |
< # bash, then to run this script, type that shell name before the whole | |
< # command line, like: | |
< # | |
< # ksh Gradle | |
< # | |
< # Busybox and similar reduced shells will NOT work, because this script | |
< # requires all of these POSIX shell features: | |
< # * functions; | |
< # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», | |
< # «${var#prefix}», «${var%suffix}», and «$( cmd )»; | |
< # * compound commands having a testable exit status, especially «case»; | |
< # * various built-in commands including «command», «set», and «ulimit». | |
< # | |
< # Important for patching: | |
< # | |
< # (2) This script targets any POSIX shell, so it avoids extensions provided | |
< # by Bash, Ksh, etc; in particular arrays are avoided. | |
< # | |
< # The "traditional" practice of packing multiple parameters into a | |
< # space-separated string is a well documented source of bugs and security | |
< # problems, so this is (mostly) avoided, by progressively accumulating | |
< # options in "$@", and eventually passing that to Java. | |
< # | |
< # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, | |
< # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; | |
< # see the in-line comments for details. | |
< # | |
< # There are tweaks for specific operating systems such as AIX, CygWin, | |
< # Darwin, MinGW, and NonStop. | |
< # | |
< # (3) This script is generated from the Groovy template | |
< # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | |
< # within the Gradle project. | |
< # | |
< # You can find Gradle at https://github.com/gradle/gradle/. | |
< # | |
--- | |
> ## | |
> ## Gradle start up script for UN*X | |
> ## | |
65,81c9,10 | |
< # Attempt to set APP_HOME | |
< | |
< # Resolve links: $0 may be a link | |
< app_path=$0 | |
< | |
< # Need this for daisy-chained symlinks. | |
< while | |
< APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path | |
< [ -h "$app_path" ] | |
< do | |
< ls=$( ls -ld "$app_path" ) | |
< link=${ls#*' -> '} | |
< case $link in #( | |
< /*) app_path=$link ;; #( | |
< *) app_path=$APP_HOME$link ;; | |
< esac | |
< done | |
--- | |
> # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |
> DEFAULT_JVM_OPTS="" | |
83,87c12,13 | |
< # This is normally unused | |
< # shellcheck disable=SC2034 | |
< APP_BASE_NAME=${0##*/} | |
< # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) | |
< APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit | |
--- | |
> APP_NAME="Gradle" | |
> APP_BASE_NAME=`basename "$0"` | |
90c16 | |
< MAX_FD=maximum | |
--- | |
> MAX_FD="maximum" | |
92c18 | |
< warn () { | |
--- | |
> warn ( ) { | |
94c20 | |
< } >&2 | |
--- | |
> } | |
96c22 | |
< die () { | |
--- | |
> die ( ) { | |
101c27 | |
< } >&2 | |
--- | |
> } | |
107,112c33,42 | |
< nonstop=false | |
< case "$( uname )" in #( | |
< CYGWIN* ) cygwin=true ;; #( | |
< Darwin* ) darwin=true ;; #( | |
< MSYS* | MINGW* ) msys=true ;; #( | |
< NONSTOP* ) nonstop=true ;; | |
--- | |
> case "`uname`" in | |
> CYGWIN* ) | |
> cygwin=true | |
> ;; | |
> Darwin* ) | |
> darwin=true | |
> ;; | |
> MINGW* ) | |
> msys=true | |
> ;; | |
115c45,61 | |
< CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | |
--- | |
> # Attempt to set APP_HOME | |
> # Resolve links: $0 may be a link | |
> PRG="$0" | |
> # Need this for relative symlinks. | |
> while [ -h "$PRG" ] ; do | |
> ls=`ls -ld "$PRG"` | |
> link=`expr "$ls" : '.*-> \(.*\)$'` | |
> if expr "$link" : '/.*' > /dev/null; then | |
> PRG="$link" | |
> else | |
> PRG=`dirname "$PRG"`"/$link" | |
> fi | |
> done | |
> SAVED="`pwd`" | |
> cd "`dirname \"$PRG\"`/" >/dev/null | |
> APP_HOME="`pwd -P`" | |
> cd "$SAVED" >/dev/null | |
116a63 | |
> CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | |
122c69 | |
< JAVACMD=$JAVA_HOME/jre/sh/java | |
--- | |
> JAVACMD="$JAVA_HOME/jre/sh/java" | |
124c71 | |
< JAVACMD=$JAVA_HOME/bin/java | |
--- | |
> JAVACMD="$JAVA_HOME/bin/java" | |
133,136c80,81 | |
< JAVACMD=java | |
< if ! command -v java >/dev/null 2>&1 | |
< then | |
< die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | |
--- | |
> JAVACMD="java" | |
> which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | |
140d84 | |
< fi | |
144,159c88,100 | |
< if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | |
< case $MAX_FD in #( | |
< max*) | |
< # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. | |
< # shellcheck disable=SC2039,SC3045 | |
< MAX_FD=$( ulimit -H -n ) || | |
< warn "Could not query maximum file descriptor limit" | |
< esac | |
< case $MAX_FD in #( | |
< '' | soft) :;; #( | |
< *) | |
< # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. | |
< # shellcheck disable=SC2039,SC3045 | |
< ulimit -n "$MAX_FD" || | |
< warn "Could not set maximum file descriptor limit to $MAX_FD" | |
< esac | |
--- | |
> if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then | |
> MAX_FD_LIMIT=`ulimit -H -n` | |
> if [ $? -eq 0 ] ; then | |
> if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | |
> MAX_FD="$MAX_FD_LIMIT" | |
> fi | |
> ulimit -n $MAX_FD | |
> if [ $? -ne 0 ] ; then | |
> warn "Could not set maximum file descriptor limit: $MAX_FD" | |
> fi | |
> else | |
> warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | |
> fi | |
162,175c103,106 | |
< # Collect all arguments for the java command, stacking in reverse order: | |
< # * args from the command line | |
< # * the main class name | |
< # * -classpath | |
< # * -D...appname settings | |
< # * --module-path (only if needed) | |
< # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. | |
< | |
< # For Cygwin or MSYS, switch paths to Windows format before running java | |
< if "$cygwin" || "$msys" ; then | |
< APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) | |
< CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) | |
< | |
< JAVACMD=$( cygpath --unix "$JAVACMD" ) | |
--- | |
> # For Darwin, add options to specify how the application appears in the dock | |
> if $darwin; then | |
> GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | |
> fi | |
176a108,125 | |
> # For Cygwin, switch paths to Windows format before running java | |
> if $cygwin ; then | |
> APP_HOME=`cygpath --path --mixed "$APP_HOME"` | |
> CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | |
> JAVACMD=`cygpath --unix "$JAVACMD"` | |
> | |
> # We build the pattern for arguments to be converted via cygpath | |
> ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | |
> SEP="" | |
> for dir in $ROOTDIRSRAW ; do | |
> ROOTDIRS="$ROOTDIRS$SEP$dir" | |
> SEP="|" | |
> done | |
> OURCYGPATTERN="(^($ROOTDIRS))" | |
> # Add a user-defined pattern to the cygpath arguments | |
> if [ "$GRADLE_CYGPATTERN" != "" ] ; then | |
> OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | |
> fi | |
178,187c127,135 | |
< for arg do | |
< if | |
< case $arg in #( | |
< -*) false ;; # don't mess with options #( | |
< /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath | |
< [ -e "$t" ] ;; #( | |
< *) false ;; | |
< esac | |
< then | |
< arg=$( cygpath --path --ignore --mixed "$arg" ) | |
--- | |
> i=0 | |
> for arg in "$@" ; do | |
> CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | |
> CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option | |
> | |
> if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition | |
> eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | |
> else | |
> eval `echo args$i`="\"$arg\"" | |
189,197c137 | |
< # Roll the args list around exactly as many times as the number of | |
< # args, so each arg winds up back in the position where it started, but | |
< # possibly modified. | |
< # | |
< # NB: a `for` loop captures its iteration list before it begins, so | |
< # changing the positional parameters here affects neither the number of | |
< # iterations, nor the values presented in `arg`. | |
< shift # remove old arg | |
< set -- "$@" "$arg" # push replacement arg | |
--- | |
> i=$((i+1)) | |
198a139,150 | |
> case $i in | |
> (0) set -- ;; | |
> (1) set -- "$args0" ;; | |
> (2) set -- "$args0" "$args1" ;; | |
> (3) set -- "$args0" "$args1" "$args2" ;; | |
> (4) set -- "$args0" "$args1" "$args2" "$args3" ;; | |
> (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | |
> (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | |
> (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | |
> (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | |
> (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | |
> esac | |
200a153,158 | |
> # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules | |
> function splitJvmOpts() { | |
> JVM_OPTS=("$@") | |
> } | |
> eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS | |
> JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" | |
202,249c160 | |
< # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |
< DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | |
< | |
< # Collect all arguments for the java command: | |
< # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, | |
< # and any embedded shellness will be escaped. | |
< # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be | |
< # treated as '${Hostname}' itself on the command line. | |
< | |
< set -- \ | |
< "-Dorg.gradle.appname=$APP_BASE_NAME" \ | |
< -classpath "$CLASSPATH" \ | |
< org.gradle.wrapper.GradleWrapperMain \ | |
< "$@" | |
< | |
< # Stop when "xargs" is not available. | |
< if ! command -v xargs >/dev/null 2>&1 | |
< then | |
< die "xargs is not available" | |
< fi | |
< | |
< # Use "xargs" to parse quoted args. | |
< # | |
< # With -n1 it outputs one arg per line, with the quotes and backslashes removed. | |
< # | |
< # In Bash we could simply go: | |
< # | |
< # readarray ARGS < <( xargs -n1 <<<"$var" ) && | |
< # set -- "${ARGS[@]}" "$@" | |
< # | |
< # but POSIX shell has neither arrays nor command substitution, so instead we | |
< # post-process each arg (as a line of input to sed) to backslash-escape any | |
< # character that might be a shell metacharacter, then use eval to reverse | |
< # that process (while maintaining the separation between arguments), and wrap | |
< # the whole thing up as a single "set" statement. | |
< # | |
< # This will of course break if any of these variables contains a newline or | |
< # an unmatched quote. | |
< # | |
< | |
< eval "set -- $( | |
< printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | | |
< xargs -n1 | | |
< sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | | |
< tr '\n' ' ' | |
< )" '"$@"' | |
< | |
< exec "$JAVACMD" "$@" | |
--- | |
> exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/gradlew.bat /home/laurent/dev_samourai/samourai-wallet-android/gradlew.bat | |
1,17c1 | |
< @rem | |
< @rem Copyright 2015 the original author or authors. | |
< @rem | |
< @rem Licensed under the Apache License, Version 2.0 (the "License"); | |
< @rem you may not use this file except in compliance with the License. | |
< @rem You may obtain a copy of the License at | |
< @rem | |
< @rem https://www.apache.org/licenses/LICENSE-2.0 | |
< @rem | |
< @rem Unless required by applicable law or agreed to in writing, software | |
< @rem distributed under the License is distributed on an "AS IS" BASIS, | |
< @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
< @rem See the License for the specific language governing permissions and | |
< @rem limitations under the License. | |
< @rem | |
< | |
< @if "%DEBUG%"=="" @echo off | |
--- | |
> @if "%DEBUG%" == "" @echo off | |
26a11,13 | |
> @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |
> set DEFAULT_JVM_OPTS= | |
> | |
28,29c15 | |
< if "%DIRNAME%"=="" set DIRNAME=. | |
< @rem This is normally unused | |
--- | |
> if "%DIRNAME%" == "" set DIRNAME=. | |
33,38d18 | |
< @rem Resolve any "." and ".." in APP_HOME to make it shorter. | |
< for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi | |
< | |
< @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |
< set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" | |
< | |
44c24 | |
< if %ERRORLEVEL% equ 0 goto execute | |
--- | |
> if "%ERRORLEVEL%" == "0" goto init | |
46,50c26,30 | |
< echo. 1>&2 | |
< echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 | |
< echo. 1>&2 | |
< echo Please set the JAVA_HOME variable in your environment to match the 1>&2 | |
< echo location of your Java installation. 1>&2 | |
--- | |
> echo. | |
> echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | |
> echo. | |
> echo Please set the JAVA_HOME variable in your environment to match the | |
> echo location of your Java installation. | |
58c38 | |
< if exist "%JAVA_EXE%" goto execute | |
--- | |
> if exist "%JAVA_EXE%" goto init | |
60,64c40,44 | |
< echo. 1>&2 | |
< echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 | |
< echo. 1>&2 | |
< echo Please set the JAVA_HOME variable in your environment to match the 1>&2 | |
< echo location of your Java installation. 1>&2 | |
--- | |
> echo. | |
> echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | |
> echo. | |
> echo Please set the JAVA_HOME variable in your environment to match the | |
> echo location of your Java installation. | |
67a48,68 | |
> :init | |
> @rem Get command-line arguments, handling Windowz variants | |
> | |
> if not "%OS%" == "Windows_NT" goto win9xME_args | |
> if "%@eval[2+2]" == "4" goto 4NT_args | |
> | |
> :win9xME_args | |
> @rem Slurp the command line arguments. | |
> set CMD_LINE_ARGS= | |
> set _SKIP=2 | |
> | |
> :win9xME_args_slurp | |
> if "x%~1" == "x" goto execute | |
> | |
> set CMD_LINE_ARGS=%* | |
> goto execute | |
> | |
> :4NT_args | |
> @rem Get arguments from the 4NT Shell from JP Software | |
> set CMD_LINE_ARGS=%$ | |
> | |
73d73 | |
< | |
75c75 | |
< "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* | |
--- | |
> "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | |
79c79 | |
< if %ERRORLEVEL% equ 0 goto mainEnd | |
--- | |
> if "%ERRORLEVEL%"=="0" goto mainEnd | |
84,87c84,85 | |
< set EXIT_CODE=%ERRORLEVEL% | |
< if %EXIT_CODE% equ 0 set EXIT_CODE=1 | |
< if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% | |
< exit /b %EXIT_CODE% | |
--- | |
> if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | |
> exit /b 1 | |
$ diff /home/laurent/dev/ashigaru_commit2/ashigaru-mobile/settings.gradle /home/laurent/dev_samourai/samourai-wallet-android/settings.gradle | |
3,4d2 | |
< | |
< include ':ExtLibJ' | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment