diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentLedgerUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentLedgerUpdateJob.java index f6d247493d..a0d3cd4443 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentLedgerUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PaymentLedgerUpdateJob.java @@ -3,6 +3,8 @@ package org.thoughtcrime.securesms.jobs; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.mobilecoin.lib.exceptions.FogSyncException; + import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.database.PaymentDatabase; import org.thoughtcrime.securesms.database.SignalDatabase; @@ -54,7 +56,7 @@ public final class PaymentLedgerUpdateJob extends BaseJob { } @Override - protected void onRun() throws IOException, RetryLaterException { + protected void onRun() throws IOException, RetryLaterException, FogSyncException { if (!SignalStore.paymentsValues().mobileCoinPaymentsEnabled()) { Log.w(TAG, "Payments are not enabled"); return; diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/MobileCoinMainNetConfig.java b/app/src/main/java/org/thoughtcrime/securesms/payments/MobileCoinMainNetConfig.java index bc10d74b44..2562aa1aaf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/MobileCoinMainNetConfig.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/MobileCoinMainNetConfig.java @@ -7,7 +7,6 @@ import androidx.annotation.NonNull; import com.mobilecoin.lib.ClientConfig; import com.mobilecoin.lib.Verifier; import com.mobilecoin.lib.exceptions.AttestationException; -import com.mobilecoin.lib.util.Hex; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.util.Base64; @@ -65,31 +64,39 @@ final class MobileCoinMainNetConfig extends MobileCoinConfig { @Override @NonNull ClientConfig getConfig() { try { - byte[] mrEnclaveConsensus = Hex.toByteArray("e66db38b8a43a33f6c1610d335a361963bb2b31e056af0dc0a895ac6c857cab9"); - byte[] mrEnclaveConsensusNew = Hex.toByteArray("653228afd2b02a6c28f1dc3b108b1dfa457d170b32ae8ec2978f941bd1655c83"); - byte[] mrEnclaveReport = Hex.toByteArray("709ab90621e3a8d9eb26ed9e2830e091beceebd55fb01c5d7c31d27e83b9b0d1"); - byte[] mrEnclaveReportNew = Hex.toByteArray("f3f7e9a674c55fb2af543513527b6a7872de305bac171783f6716a0bf6919499"); - byte[] mrEnclaveLedger = Hex.toByteArray("511eab36de691ded50eb08b173304194da8b9d86bfdd7102001fe6bb279c3666"); - byte[] mrEnclaveLedgerNew = Hex.toByteArray("89db0d1684fcc98258295c39f4ab68f7de5917ef30f0004d9a86f29930cebbbd"); - byte[] mrEnclaveView = Hex.toByteArray("ddd59da874fdf3239d5edb1ef251df07a8728c9ef63057dd0b50ade5a9ddb041"); - byte[] mrEnclaveViewNew = Hex.toByteArray("dd84abda7f05116e21fcd1ee6361b0ec29445fff0472131eaf37bf06255b567a"); - Set trustRoots = getTrustRoots(R.raw.signal_mobilecoin_authority); ClientConfig config = new ClientConfig(); String[] hardeningAdvisories = { "INTEL-SA-00334" }; + VerifierFactory verifierFactory = new VerifierFactory(hardeningAdvisories, + new ServiceConfig( + "e66db38b8a43a33f6c1610d335a361963bb2b31e056af0dc0a895ac6c857cab9", + "709ab90621e3a8d9eb26ed9e2830e091beceebd55fb01c5d7c31d27e83b9b0d1", + "511eab36de691ded50eb08b173304194da8b9d86bfdd7102001fe6bb279c3666", + "ddd59da874fdf3239d5edb1ef251df07a8728c9ef63057dd0b50ade5a9ddb041" + ), + new ServiceConfig( + "653228afd2b02a6c28f1dc3b108b1dfa457d170b32ae8ec2978f941bd1655c83", + "f3f7e9a674c55fb2af543513527b6a7872de305bac171783f6716a0bf6919499", + "89db0d1684fcc98258295c39f4ab68f7de5917ef30f0004d9a86f29930cebbbd", + "dd84abda7f05116e21fcd1ee6361b0ec29445fff0472131eaf37bf06255b567a" + ), + new ServiceConfig( + "733080d6ece4504f66ba606fa8163dae0a5220f3dbf6ca55fbafbac12c6f1897", + "660103d766cde0fd1e1cfb443b99e52da2ce0617d0dee42f8b875f7104942c6b", + "ed8ed6e1b4b6827e5543b25c1c13b9c06b478d819f8df912eb11fa140780fc51", + "c64a3b04348b10596442868758875f312dc3a755b450805149774a091d2822d3" + )); + config.logAdapter = new MobileCoinLogAdapter(); config.fogView = new ClientConfig.Service().withTrustRoots(trustRoots) - .withVerifier(new Verifier().withMrEnclave(mrEnclaveView, null, hardeningAdvisories) - .withMrEnclave(mrEnclaveViewNew, null, hardeningAdvisories)); + .withVerifier(verifierFactory.createViewVerifier()); config.fogLedger = new ClientConfig.Service().withTrustRoots(trustRoots) - .withVerifier(new Verifier().withMrEnclave(mrEnclaveLedger, null, hardeningAdvisories) - .withMrEnclave(mrEnclaveLedgerNew, null, hardeningAdvisories)); + .withVerifier(verifierFactory.createLedgerVerifier()); config.consensus = new ClientConfig.Service().withTrustRoots(trustRoots) - .withVerifier(new Verifier().withMrEnclave(mrEnclaveConsensus, null, hardeningAdvisories) - .withMrEnclave(mrEnclaveConsensusNew, null, hardeningAdvisories)); - config.report = new ClientConfig.Service().withVerifier(new Verifier().withMrEnclave(mrEnclaveReport, null, hardeningAdvisories) - .withMrEnclave(mrEnclaveReportNew, null, hardeningAdvisories)); + .withVerifier(verifierFactory.createConsensusVerifier()); + config.report = new ClientConfig.Service().withVerifier(verifierFactory.createReportVerifier()); + return config; } catch (AttestationException ex) { throw new IllegalStateException(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/MobileCoinTestNetConfig.java b/app/src/main/java/org/thoughtcrime/securesms/payments/MobileCoinTestNetConfig.java index 42aeafbf73..15427d7ecc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/MobileCoinTestNetConfig.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/MobileCoinTestNetConfig.java @@ -49,18 +49,7 @@ final class MobileCoinTestNetConfig extends MobileCoinConfig { @Override @NonNull byte[] getFogAuthoritySpki() { - return Base64.decodeOrThrow("MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoCMq8nnjTq5EEQ4EI7yr\n" - + "ABL9P4y4h1P/h0DepWgXx+w/fywcfRSZINxbaMpvcV3uSJayExrpV1KmaS2wfASe\n" - + "YhSj+rEzAm0XUOw3Q94NOx5A/dOQag/d1SS6/QpF3PQYZTULnRFetmM4yzEnXsXc\n" - + "WtzEu0hh02wYJbLeAq4CCcPTPe2qckrbUP9sD18/KOzzNeypF4p5dQ2m/ezfxtga\n" - + "LvdUMVDVIAs2v9a5iu6ce4bIcwTIUXgX0w3+UKRx8zqowc3HIqo9yeaGn4ZOwQHv\n" - + "AJZecPmb2pH1nK+BtDUvHpvf+Y3/NJxwh+IPp6Ef8aoUxs2g5oIBZ3Q31fjS2Bh2\n" - + "gmwoVooyytEysPAHvRPVBxXxLi36WpKfk1Vq8K7cgYh3IraOkH2/l2Pyi8EYYFkW\n" - + "sLYofYogaiPzVoq2ZdcizfoJWIYei5mgq+8m0ZKZYLebK1i2GdseBJNIbSt3wCNX\n" - + "ZxyN6uqFHOCB29gmA5cbKvs/j9mDz64PJe9LCanqcDQV1U5l9dt9UdmUt7Ab1PjB\n" - + "toIFaP+u473Z0hmZdCgAivuiBMMYMqt2V2EIw4IXLASE3roLOYp0p7h0IQHb+lVI\n" - + "uEl0ZmwAI30ZmzgcWc7RBeWD1/zNt55zzhfPRLx/DfDY5Kdp6oFHWMvI2r1/oZkd\n" - + "hjFp7pV6qrl7vOyR5QqmuRkCAwEAAQ=="); + return Base64.decodeOrThrow("MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoCMq8nnjTq5EEQ4EI7yrABL9P4y4h1P/h0DepWgXx+w/fywcfRSZINxbaMpvcV3uSJayExrpV1KmaS2wfASeYhSj+rEzAm0XUOw3Q94NOx5A/dOQag/d1SS6/QpF3PQYZTULnRFetmM4yzEnXsXcWtzEu0hh02wYJbLeAq4CCcPTPe2qckrbUP9sD18/KOzzNeypF4p5dQ2m/ezfxtgaLvdUMVDVIAs2v9a5iu6ce4bIcwTIUXgX0w3+UKRx8zqowc3HIqo9yeaGn4ZOwQHvAJZecPmb2pH1nK+BtDUvHpvf+Y3/NJxwh+IPp6Ef8aoUxs2g5oIBZ3Q31fjS2Bh2gmwoVooyytEysPAHvRPVBxXxLi36WpKfk1Vq8K7cgYh3IraOkH2/l2Pyi8EYYFkWsLYofYogaiPzVoq2ZdcizfoJWIYei5mgq+8m0ZKZYLebK1i2GdseBJNIbSt3wCNXZxyN6uqFHOCB29gmA5cbKvs/j9mDz64PJe9LCanqcDQV1U5l9dt9UdmUt7Ab1PjBtoIFaP+u473Z0hmZdCgAivuiBMMYMqt2V2EIw4IXLASE3roLOYp0p7h0IQHb+lVIuEl0ZmwAI30ZmzgcWc7RBeWD1/zNt55zzhfPRLx/DfDY5Kdp6oFHWMvI2r1/oZkdhjFp7pV6qrl7vOyR5QqmuRkCAwEAAQ=="); } @Override @@ -71,10 +60,10 @@ final class MobileCoinTestNetConfig extends MobileCoinConfig { @Override @NonNull ClientConfig getConfig() { try { - byte[] mrEnclaveConsensus = Hex.toByteArray("9659ea738275b3999bf1700398b60281be03af5cb399738a89b49ea2496595af"); - byte[] mrEnclaveReport = Hex.toByteArray("a4764346f91979b4906d4ce26102228efe3aba39216dec1e7d22e6b06f919f11"); - byte[] mrEnclaveLedger = Hex.toByteArray("768f7bea6171fb83d775ee8485e4b5fcebf5f664ca7e8b9ceef9c7c21e9d9bf3"); - byte[] mrEnclaveView = Hex.toByteArray("e154f108c7758b5aa7161c3824c176f0c20f63012463bf3cc5651e678f02fb9e"); + byte[] mrEnclaveConsensus = Hex.toByteArray("4f134dcfd9c0885956f2f9af0f05c2050d8bdee2dc63b468a640670d7adeb7f8"); + byte[] mrEnclaveReport = Hex.toByteArray("8f2f3bf81f24bf493fa6d76e29e0f081815022592b1e854f95bda750aece7452"); + byte[] mrEnclaveLedger = Hex.toByteArray("685481b33f2846585f33506ab65649c98a4a6d1244989651fd0fcde904ebd82f"); + byte[] mrEnclaveView = Hex.toByteArray("719ca43abbe02f507bb91ea11ff8bc900aa86363a7d7e77b8130426fc53d8684"); byte[] mrSigner = Hex.toByteArray("bf7fa957a6a94acb588851bc8767e0ca57706c79f4fc2aa6bcb993012c3c386c"); Set trustRoots = getTrustRoots(R.raw.signal_mobilecoin_authority); ClientConfig config = new ClientConfig(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/ServiceConfig.kt b/app/src/main/java/org/thoughtcrime/securesms/payments/ServiceConfig.kt new file mode 100644 index 0000000000..75b790e576 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/ServiceConfig.kt @@ -0,0 +1,19 @@ +package org.thoughtcrime.securesms.payments + +import com.mobilecoin.lib.util.Hex + +/** + * Represents the service configuration values for a given MobileCoin config, used to build + * Verifiers. + */ +class ServiceConfig( + consensus: String, + report: String, + ledger: String, + view: String +) { + val consensus: ByteArray = Hex.toByteArray(consensus) + val report: ByteArray = Hex.toByteArray(report) + val ledger: ByteArray = Hex.toByteArray(ledger) + val view: ByteArray = Hex.toByteArray(view) +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/VerifierFactory.kt b/app/src/main/java/org/thoughtcrime/securesms/payments/VerifierFactory.kt new file mode 100644 index 0000000000..3f5ed03b60 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/VerifierFactory.kt @@ -0,0 +1,39 @@ +package org.thoughtcrime.securesms.payments + +import com.mobilecoin.lib.Verifier +import com.mobilecoin.lib.exceptions.AttestationException + +/** + * Wraps the given service configurations and provides methods to grab a fully constructed verifier instance. + * This is to ease the addition of new service configurations moving forward, which simply need a new ServiceConfig object + * to be added to the given list. + */ +class VerifierFactory(private val hardeningAdvisories: Array, private vararg val serviceConfigs: ServiceConfig) { + + @Throws(AttestationException::class) + fun createConsensusVerifier(): Verifier { + return createVerifier(ServiceConfig::consensus) + } + + @Throws(AttestationException::class) + fun createLedgerVerifier(): Verifier { + return createVerifier(ServiceConfig::ledger) + } + + @Throws(AttestationException::class) + fun createViewVerifier(): Verifier { + return createVerifier(ServiceConfig::view) + } + + @Throws(AttestationException::class) + fun createReportVerifier(): Verifier { + return createVerifier(ServiceConfig::report) + } + + @Throws(AttestationException::class) + private fun createVerifier(getConfigValue: (ServiceConfig) -> ByteArray): Verifier { + return serviceConfigs.fold(Verifier()) { verifier, config -> + verifier.withMrEnclave(getConfigValue(config), null, hardeningAdvisories) + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/payments/Wallet.java b/app/src/main/java/org/thoughtcrime/securesms/payments/Wallet.java index ea48178dc2..9c966f0578 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/payments/Wallet.java +++ b/app/src/main/java/org/thoughtcrime/securesms/payments/Wallet.java @@ -8,18 +8,22 @@ import androidx.annotation.WorkerThread; import com.google.protobuf.ByteString; import com.mobilecoin.lib.AccountKey; import com.mobilecoin.lib.AccountSnapshot; +import com.mobilecoin.lib.Amount; import com.mobilecoin.lib.DefragmentationDelegate; import com.mobilecoin.lib.MobileCoinClient; import com.mobilecoin.lib.OwnedTxOut; import com.mobilecoin.lib.PendingTransaction; import com.mobilecoin.lib.Receipt; +import com.mobilecoin.lib.TokenId; import com.mobilecoin.lib.Transaction; +import com.mobilecoin.lib.TxOutMemoBuilder; import com.mobilecoin.lib.UnsignedLong; import com.mobilecoin.lib.exceptions.AmountDecoderException; import com.mobilecoin.lib.exceptions.AttestationException; import com.mobilecoin.lib.exceptions.BadEntropyException; import com.mobilecoin.lib.exceptions.FeeRejectedException; import com.mobilecoin.lib.exceptions.FogReportException; +import com.mobilecoin.lib.exceptions.FogSyncException; import com.mobilecoin.lib.exceptions.FragmentedAccountException; import com.mobilecoin.lib.exceptions.InsufficientFundsException; import com.mobilecoin.lib.exceptions.InvalidFogResponse; @@ -29,6 +33,7 @@ import com.mobilecoin.lib.exceptions.InvalidUriException; import com.mobilecoin.lib.exceptions.NetworkException; import com.mobilecoin.lib.exceptions.SerializationException; import com.mobilecoin.lib.exceptions.TransactionBuilderException; +import com.mobilecoin.lib.network.TransportProtocol; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.keyvalue.PaymentsValues; @@ -65,7 +70,8 @@ public final class Wallet { this.mobileCoinClient = new MobileCoinClient(account, mobileCoinConfig.getFogUri(), mobileCoinConfig.getConsensusUri(), - mobileCoinConfig.getConfig()); + mobileCoinConfig.getConfig(), + TransportProtocol.forGRPC()); } catch (InvalidUriException | BadEntropyException e) { throw new AssertionError(e); } @@ -102,7 +108,7 @@ public final class Wallet { MobileCoinLedgerWrapper ledger = tryGetFullLedger(null); paymentsValues.setMobileCoinFullLedger(Objects.requireNonNull(ledger)); - } catch (IOException e) { + } catch (IOException | FogSyncException e) { if ((retryOnAuthFailure && e.getCause() instanceof NetworkException) && (((NetworkException) e.getCause()).statusCode == 401)) { @@ -117,7 +123,7 @@ public final class Wallet { } @WorkerThread - public @Nullable MobileCoinLedgerWrapper tryGetFullLedger(@Nullable Long minimumBlockIndex) throws IOException { + public @Nullable MobileCoinLedgerWrapper tryGetFullLedger(@Nullable Long minimumBlockIndex) throws IOException, FogSyncException { try { MobileCoinLedger.Builder builder = MobileCoinLedger.newBuilder(); BigInteger totalUnspent = BigInteger.ZERO; @@ -125,7 +131,7 @@ public final class Wallet { UnsignedLong highestBlockIndex = UnsignedLong.ZERO; final long asOfTimestamp = System.currentTimeMillis(); AccountSnapshot accountSnapshot = mobileCoinClient.getAccountSnapshot(); - final BigInteger minimumTxFee = mobileCoinClient.getOrFetchMinimumTxFee(); + final Amount minimumTxFee = mobileCoinClient.getOrFetchMinimumTxFee(TokenId.MOB); if (minimumBlockIndex != null) { long snapshotBlockIndex = accountSnapshot.getBlockIndex().longValue(); @@ -135,9 +141,10 @@ public final class Wallet { } } - for (OwnedTxOut txOut : accountSnapshot.getAccountActivity().getAllTxOuts()) { + for (OwnedTxOut txOut : accountSnapshot.getAccountActivity().getAllTokenTxOuts(TokenId.MOB)) { + final Amount txOutAmount = txOut.getAmount(); MobileCoinLedger.OwnedTXO.Builder txoBuilder = MobileCoinLedger.OwnedTXO.newBuilder() - .setAmount(Uint64Util.bigIntegerToUInt64(txOut.getValue())) + .setAmount(Uint64Util.bigIntegerToUInt64(txOutAmount.getValue())) .setReceivedInBlock(getBlock(txOut.getReceivedBlockIndex(), txOut.getReceivedBlockTimestamp())) .setKeyImage(ByteString.copyFrom(txOut.getKeyImage().getData())) .setPublicKey(ByteString.copyFrom(txOut.getPublicKey().getKeyBytes())); @@ -147,7 +154,7 @@ public final class Wallet { txoBuilder.setSpentInBlock(getBlock(txOut.getSpentBlockIndex(), txOut.getSpentBlockTimestamp())); builder.addSpentTxos(txoBuilder); } else { - totalUnspent = totalUnspent.add(txOut.getValue()); + totalUnspent = totalUnspent.add(txOutAmount.getValue()); builder.addUnspentTxos(txoBuilder); } @@ -168,7 +175,7 @@ public final class Wallet { } } builder.setBalance(Uint64Util.bigIntegerToUInt64(totalUnspent)) - .setTransferableBalance(Uint64Util.bigIntegerToUInt64(accountSnapshot.getTransferableAmount(minimumTxFee))) + .setTransferableBalance(Uint64Util.bigIntegerToUInt64(accountSnapshot.getTransferableAmount(minimumTxFee).getValue())) .setAsOfTimeStamp(asOfTimestamp) .setHighestBlock(MobileCoinLedger.Block.newBuilder() .setBlockNumber(highestBlockIndex.longValue()) @@ -206,11 +213,11 @@ public final class Wallet { public @NonNull Money.MobileCoin getFee(@NonNull Money.MobileCoin amount) throws IOException { try { BigInteger picoMob = amount.requireMobileCoin().toPicoMobBigInteger(); - return Money.picoMobileCoin(mobileCoinClient.estimateTotalFee(picoMob)); + return Money.picoMobileCoin(mobileCoinClient.estimateTotalFee(Amount.ofMOB(picoMob)).getValue()); } catch (InvalidFogResponse | AttestationException | InsufficientFundsException e) { Log.w(TAG, "Failed to get fee", e); return Money.MobileCoin.ZERO; - } catch (NetworkException e) { + } catch (NetworkException | FogSyncException e) { Log.w(TAG, "Failed to get fee", e); throw new IOException(e); } @@ -227,7 +234,7 @@ public final class Wallet { } @WorkerThread - public @NonNull TransactionStatusResult getSentTransactionStatus(@NonNull PaymentTransactionId transactionId) throws IOException { + public @NonNull TransactionStatusResult getSentTransactionStatus(@NonNull PaymentTransactionId transactionId) throws IOException, FogSyncException { try { PaymentTransactionId.MobileCoin mobcoinTransaction = (PaymentTransactionId.MobileCoin) transactionId; Transaction transaction = Transaction.fromBytes(mobcoinTransaction.getTransaction()); @@ -255,7 +262,7 @@ public final class Wallet { } @WorkerThread - public @NonNull ReceivedTransactionStatus getReceivedTransactionStatus(@NonNull byte[] receiptBytes) throws IOException { + public @NonNull ReceivedTransactionStatus getReceivedTransactionStatus(@NonNull byte[] receiptBytes) throws IOException, FogSyncException { try { Receipt receipt = Receipt.fromBytes(receiptBytes); Receipt.Status status = mobileCoinClient.getReceiptStatus(receipt); @@ -266,8 +273,8 @@ public final class Wallet { case FAILED: return ReceivedTransactionStatus.failed(); case RECEIVED: - BigInteger amount = receipt.getAmount(account); - return ReceivedTransactionStatus.complete(Money.picoMobileCoin(amount), status.getBlockIndex().longValue()); + final Amount amount = receipt.getAmountData(account); + return ReceivedTransactionStatus.complete(Money.picoMobileCoin(amount.getValue()), status.getBlockIndex().longValue()); default: throw new IllegalStateException("Unknown Transaction Status: " + status); } @@ -297,7 +304,7 @@ public final class Wallet { Log.w(TAG, "Insufficient funds", e); results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.INSUFFICIENT_FUNDS, true)); return; - } catch (TimeoutException | InvalidTransactionException | InvalidFogResponse | AttestationException | TransactionBuilderException | NetworkException | FogReportException e) { + } catch (TimeoutException | InvalidTransactionException | InvalidFogResponse | AttestationException | TransactionBuilderException | NetworkException | FogReportException | FogSyncException e) { Log.w(TAG, "Defragment failed", e); results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, true)); return; @@ -318,8 +325,9 @@ public final class Wallet { try { pendingTransaction = mobileCoinClient.prepareTransaction(to.getAddress(), - picoMob, - feeMobileCoin.toPicoMobBigInteger()); + Amount.ofMOB(picoMob), + Amount.ofMOB(feeMobileCoin.toPicoMobBigInteger()), + TxOutMemoBuilder.createSenderAndDestinationRTHMemoBuilder(account)); } catch (InsufficientFundsException e) { Log.w(TAG, "Insufficient funds", e); results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.INSUFFICIENT_FUNDS, false)); @@ -346,6 +354,9 @@ public final class Wallet { } catch (TransactionBuilderException e) { Log.w(TAG, "Builder problem", e); results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false)); + } catch(FogSyncException e) { + Log.w(TAG, "Fog currently out of sync", e); + results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.NETWORK_FAILURE, false)); } if (pendingTransaction == null) { @@ -379,11 +390,11 @@ public final class Wallet { */ @WorkerThread private @NonNull Money.MobileCoin defragment(@NonNull Money.MobileCoin amount, @NonNull List results) - throws TransactionBuilderException, NetworkException, InvalidTransactionException, AttestationException, FogReportException, InvalidFogResponse, TimeoutException, InsufficientFundsException + throws TransactionBuilderException, NetworkException, InvalidTransactionException, AttestationException, FogReportException, InvalidFogResponse, TimeoutException, InsufficientFundsException, FogSyncException { Log.i(TAG, "Defragmenting account"); DefragDelegate defragDelegate = new DefragDelegate(mobileCoinClient, results); - mobileCoinClient.defragmentAccount(amount.toPicoMobBigInteger(), defragDelegate); + mobileCoinClient.defragmentAccount(Amount.ofMOB(amount.toPicoMobBigInteger()), defragDelegate, true); Log.i(TAG, "Account defragmented at a cost of " + defragDelegate.totalFeesSpent); return defragDelegate.totalFeesSpent; } diff --git a/dependencies.gradle b/dependencies.gradle index 3c604f4f14..4702b8cf96 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -92,7 +92,7 @@ dependencyResolutionManagement { alias('rxjava3-rxkotlin').to('io.reactivex.rxjava3:rxkotlin:3.0.1') alias('rxdogtag').to('com.uber.rxdogtag2:rxdogtag:2.0.1') alias('conscrypt-android').to('org.conscrypt:conscrypt-android:2.0.0') - alias('mobilecoin').to('com.mobilecoin:android-sdk:1.1.0') + alias('mobilecoin').to('com.mobilecoin:android-sdk:1.2.2.1') alias('leolin-shortcutbadger').to('me.leolin:ShortcutBadger:1.1.22') alias('emilsjolander-stickylistheaders').to('se.emilsjolander:stickylistheaders:2.7.0') alias('jpardogo-materialtabstrip').to('com.jpardogo.materialtabstrip:library:1.0.9') diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 6812771c7c..7f0b359b52 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -73,6 +73,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + @@ -2505,6 +2513,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + @@ -2814,6 +2827,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + @@ -2822,6 +2840,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + @@ -3344,6 +3367,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + @@ -3360,6 +3388,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + @@ -3376,6 +3409,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + @@ -3392,6 +3430,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + @@ -3416,6 +3459,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + @@ -3432,6 +3480,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + +