[#293] Refactor non-public APIs to internal package

This commit is contained in:
Carter Jernigan 2021-10-04 07:18:37 -04:00
parent 07d7f17387
commit 28853b5a84
54 changed files with 200 additions and 652 deletions

View File

@ -3,7 +3,7 @@ package cash.z.ecc.android.sdk.darkside // package cash.z.ecc.android.sdk.integr
// import cash.z.ecc.android.sdk.test.ScopedTest
// import cash.z.ecc.android.sdk.ext.twig
// import cash.z.ecc.android.sdk.ext.twigTask
// import cash.z.ecc.android.sdk.service.LightWalletGrpcService
// import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
// import cash.z.ecc.android.sdk.darkside.test.DarksideTestCoordinator
// import cash.z.ecc.android.sdk.util.SimpleMnemonics
// import cash.z.wallet.sdk.rpc.CompactFormats

View File

@ -3,7 +3,7 @@ package cash.z.ecc.android.sdk.darkside.test
import android.content.Context
import cash.z.ecc.android.sdk.R
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.type.ZcashNetwork
import cash.z.wallet.sdk.rpc.Darkside
import cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL

View File

@ -9,7 +9,7 @@ import cash.z.ecc.android.sdk.Synchronizer
import cash.z.ecc.android.sdk.db.entity.isPending
import cash.z.ecc.android.sdk.ext.Twig
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.sdk.type.ZcashNetwork

View File

@ -1,17 +1,26 @@
package cash.z.ecc.android.sdk.sample.demoapp
package cash.z.wallet.sdk.sample.demoapp
import androidx.test.platform.app.InstrumentationRegistry
import cash.z.ecc.android.sdk.Initializer
import cash.z.ecc.android.sdk.Synchronizer
import cash.z.ecc.android.sdk.entity.isFailure
import cash.z.ecc.android.sdk.db.entity.isFailure
import cash.z.ecc.android.sdk.ext.TroubleshootingTwig
import cash.z.ecc.android.sdk.ext.Twig
import cash.z.ecc.android.sdk.ext.ZcashSdk
import cash.z.ecc.android.sdk.ext.convertZecToZatoshi
import cash.z.ecc.android.sdk.ext.toHex
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.jni.RustBackend
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.transaction.PagedTransactionRepository
import cash.z.ecc.android.sdk.transaction.WalletTransactionEncoder
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.internal.transaction.PagedTransactionRepository
import cash.z.ecc.android.sdk.internal.transaction.WalletTransactionEncoder
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.ZcashNetwork
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.BeforeClass
import org.junit.Ignore
import org.junit.Test
@ -47,7 +56,7 @@ class SampleCodeTest {
// ///////////////////////////////////////////////////
// Derive Extended Spending Key
@Test fun deriveSpendingKey() {
val spendingKeys = RustBackend().deriveSpendingKeys(seed)
val spendingKeys = DerivationTool.deriveSpendingKeys(seed, ZcashNetwork.Mainnet)
assertEquals(1, spendingKeys.size)
log("Spending Key: ${spendingKeys?.get(0)}")
}
@ -95,22 +104,22 @@ class SampleCodeTest {
@Test fun queryIncomingTransactions() {
}
// ///////////////////////////////////////////////////
// Create a signed transaction (with memo)
@Test fun createTransaction() = runBlocking {
val rustBackend = RustBackend().init(context)
val repository = PagedTransactionRepository(context)
val encoder = WalletTransactionEncoder(rustBackend, repository)
val spendingKey = rustBackend.deriveSpendingKeys(seed)[0]
val amount = 0.123.convertZecToZatoshi()
val address = "ztestsapling1tklsjr0wyw0d58f3p7wufvrj2cyfv6q6caumyueadq8qvqt8lda6v6tpx474rfru9y6u75u7qnw"
val memo = "Test Transaction".toByteArray()
val encodedTx = encoder.createTransaction(spendingKey, amount, address, memo)
assertTrue(encodedTx.raw.isNotEmpty())
log("Transaction ID: ${encodedTx.txId.toHex()}")
}
// // ///////////////////////////////////////////////////
// // Create a signed transaction (with memo)
// @Test fun createTransaction() = runBlocking {
// val rustBackend = RustBackend.init(context)
// val repository = PagedTransactionRepository(context)
// val encoder = WalletTransactionEncoder(rustBackend, repository)
// val spendingKey = DerivationTool.deriveSpendingKeys(seed, ZcashNetwork.Mainnet)[0]
//
// val amount = 0.123.convertZecToZatoshi()
// val address = "ztestsapling1tklsjr0wyw0d58f3p7wufvrj2cyfv6q6caumyueadq8qvqt8lda6v6tpx474rfru9y6u75u7qnw"
// val memo = "Test Transaction".toByteArray()
//
// val encodedTx = encoder.createTransaction(spendingKey, amount, address, memo)
// assertTrue(encodedTx.raw.isNotEmpty())
// log("Transaction ID: ${encodedTx.txId.toHex()}")
// }
// ///////////////////////////////////////////////////
// Create a signed transaction (with memo) and broadcast
@ -118,11 +127,11 @@ class SampleCodeTest {
val amount = 0.123.convertZecToZatoshi()
val address = "ztestsapling1tklsjr0wyw0d58f3p7wufvrj2cyfv6q6caumyueadq8qvqt8lda6v6tpx474rfru9y6u75u7qnw"
val memo = "Test Transaction"
val spendingKey = RustBackend().deriveSpendingKeys(seed)[0]
val spendingKey = DerivationTool.deriveSpendingKeys(seed, ZcashNetwork.Mainnet)[0]
val transactionFlow = synchronizer.sendToAddress(spendingKey, amount, address, memo)
transactionFlow.collect {
log("pending transaction updated $it")
assertTrue("Failed to send funds. See log for details.", it?.isFailure() == false)
assertTrue("Failed to send funds. See log for details.", !it?.isFailure())
}
}
@ -132,10 +141,10 @@ class SampleCodeTest {
companion object {
private val seed = "Insert seed for testing".toByteArray()
private val lightwalletdHost: String = ZcashSdk.DEFAULT_LIGHTWALLETD_HOST
private val lightwalletdHost: String = ZcashNetwork.Mainnet.defaultHost
private val context = InstrumentationRegistry.getInstrumentation().targetContext
private val synchronizer = Synchronizer(context, lightwalletdHost, seed)
private val synchronizer = Synchronizer(Initializer(context) {})
@BeforeClass
@JvmStatic

View File

@ -18,8 +18,8 @@ import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import androidx.viewbinding.ViewBinding
import cash.z.ecc.android.sdk.demoapp.util.fromResources
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.service.LightWalletService
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.internal.service.LightWalletService
import cash.z.ecc.android.sdk.type.ZcashNetwork
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.navigation.NavigationView

31
docs/tests/Public APIs.md Normal file
View File

@ -0,0 +1,31 @@
# Public APIs
The SDK has a variety of public APIs that should be kept stable for SDK consumers, unless an explicit decision is made to introduce a breaking API change. To reduce the introduction of incompatible changes, these test cases covers how to verify our own apps don't break.
# Compile Compatibility
1. Publish the SDK to mavenLocal
1. Bump the SDK version in [gradle.properties](../../gradle.properties)
1. Navigate to the root of the SDK checkout
1. Run the Gradle task `./gradlew publishToMavenLocal`
1. Modify the wallet app to build against the new SDK
1. Check out the [Zcash Android Wallet](https://github.com/zcash/zcash-android-wallet)
1. Modify settings.gradle to additionally include `mavenLocal()` in the `dependencyResolutionManagement` block
1. Modify [Dependencies.kt](https://github.com/zcash/zcash-android-wallet/blob/master/buildSrc/src/main/java/cash/z/ecc/android/Dependencies.kt) to use the new SDK version defined in the first step
1. Navigate to the root of the wallet app checkout
1. Build the wallet app and unit tests with the task `./gradlew assembleAndroidTest`
1. Verify the build completes successfully
# Upgrade Compatibility
1. Install the wallet app using the old SDK
1. Ensure that no version of the Android wallet is currently installed on your test Android device or emulator
1. Build the unmodified version of the wallet app
1. Run the wallet app and create a new wallet
1. Publish the SDK to mavenLocal
1. Bump the SDK version in [gradle.properties](../../gradle.properties)
1. Navigate to the root of the SDK checkout
1. Run the Gradle task `./gradlew publishToMavenLocal`
1. Modify the wallet app to build against the new SDK
1. Check out the [Zcash Android Wallet](https://github.com/zcash/zcash-android-wallet)
1. Modify settings.gradle to additionally include `mavenLocal()` in the `dependencyResolutionManagement` block
1. Modify [Dependencies.kt](https://github.com/zcash/zcash-android-wallet/blob/master/buildSrc/src/main/java/cash/z/ecc/android/Dependencies.kt) to use the new SDK version defined in the first step
1. Install the wallet app using the new SDK
1. Verify that the wallet behaves correctly (it should not act as if it is starting fresh; user data persisted by the old version of the SDK should still be present after SDK upgrade)

View File

@ -1,40 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "0ca7a6d68543409fd85d2f5bfe9b93c5",
"entities": [
{
"tableName": "compactblocks",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`height` INTEGER NOT NULL, `data` BLOB NOT NULL, PRIMARY KEY(`height`))",
"fields": [
{
"fieldPath": "height",
"columnName": "height",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "data",
"columnName": "data",
"affinity": "BLOB",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"height"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '0ca7a6d68543409fd85d2f5bfe9b93c5')"
]
}
}

View File

@ -1,345 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 5,
"identityHash": "d6e9b05e0607d399f821058adb43dc15",
"entities": [
{
"tableName": "transactions",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id_tx` INTEGER, `txid` BLOB NOT NULL, `tx_index` INTEGER, `created` TEXT, `expiry_height` INTEGER, `block` INTEGER, `raw` BLOB, PRIMARY KEY(`id_tx`), FOREIGN KEY(`block`) REFERENCES `blocks`(`height`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "id",
"columnName": "id_tx",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "transactionId",
"columnName": "txid",
"affinity": "BLOB",
"notNull": true
},
{
"fieldPath": "transactionIndex",
"columnName": "tx_index",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "created",
"columnName": "created",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "expiryHeight",
"columnName": "expiry_height",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "minedHeight",
"columnName": "block",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "raw",
"columnName": "raw",
"affinity": "BLOB",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id_tx"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": [
{
"table": "blocks",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"block"
],
"referencedColumns": [
"height"
]
}
]
},
{
"tableName": "blocks",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`height` INTEGER, `hash` BLOB NOT NULL, `time` INTEGER NOT NULL, `sapling_tree` BLOB NOT NULL, PRIMARY KEY(`height`))",
"fields": [
{
"fieldPath": "height",
"columnName": "height",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "hash",
"columnName": "hash",
"affinity": "BLOB",
"notNull": true
},
{
"fieldPath": "time",
"columnName": "time",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "saplingTree",
"columnName": "sapling_tree",
"affinity": "BLOB",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"height"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "received_notes",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id_note` INTEGER, `tx` INTEGER NOT NULL, `output_index` INTEGER NOT NULL, `account` INTEGER NOT NULL, `value` INTEGER NOT NULL, `spent` INTEGER, `diversifier` BLOB NOT NULL, `rcm` BLOB NOT NULL, `nf` BLOB NOT NULL, `is_change` INTEGER NOT NULL, `memo` BLOB, PRIMARY KEY(`id_note`), FOREIGN KEY(`tx`) REFERENCES `transactions`(`id_tx`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`account`) REFERENCES `accounts`(`account`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`spent`) REFERENCES `transactions`(`id_tx`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "id",
"columnName": "id_note",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "transactionId",
"columnName": "tx",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "outputIndex",
"columnName": "output_index",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "account",
"columnName": "account",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "value",
"columnName": "value",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "spent",
"columnName": "spent",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "diversifier",
"columnName": "diversifier",
"affinity": "BLOB",
"notNull": true
},
{
"fieldPath": "rcm",
"columnName": "rcm",
"affinity": "BLOB",
"notNull": true
},
{
"fieldPath": "nf",
"columnName": "nf",
"affinity": "BLOB",
"notNull": true
},
{
"fieldPath": "isChange",
"columnName": "is_change",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "memo",
"columnName": "memo",
"affinity": "BLOB",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id_note"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": [
{
"table": "transactions",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"tx"
],
"referencedColumns": [
"id_tx"
]
},
{
"table": "accounts",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"account"
],
"referencedColumns": [
"account"
]
},
{
"table": "transactions",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"spent"
],
"referencedColumns": [
"id_tx"
]
}
]
},
{
"tableName": "accounts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`account` INTEGER, `extfvk` TEXT NOT NULL, `address` TEXT NOT NULL, PRIMARY KEY(`account`))",
"fields": [
{
"fieldPath": "account",
"columnName": "account",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "extendedFullViewingKey",
"columnName": "extfvk",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "address",
"columnName": "address",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"account"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "sent_notes",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id_note` INTEGER, `tx` INTEGER NOT NULL, `output_index` INTEGER NOT NULL, `from_account` INTEGER NOT NULL, `address` TEXT NOT NULL, `value` INTEGER NOT NULL, `memo` BLOB, PRIMARY KEY(`id_note`), FOREIGN KEY(`tx`) REFERENCES `transactions`(`id_tx`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`from_account`) REFERENCES `accounts`(`account`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "id",
"columnName": "id_note",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "transactionId",
"columnName": "tx",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "outputIndex",
"columnName": "output_index",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "account",
"columnName": "from_account",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "address",
"columnName": "address",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "value",
"columnName": "value",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "memo",
"columnName": "memo",
"affinity": "BLOB",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id_note"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": [
{
"table": "transactions",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"tx"
],
"referencedColumns": [
"id_tx"
]
},
{
"table": "accounts",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"from_account"
],
"referencedColumns": [
"account"
]
}
]
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd6e9b05e0607d399f821058adb43dc15')"
]
}
}

View File

@ -1,118 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "ea8cbb874a6d62d7b17d7fd5ea82dc8d",
"entities": [
{
"tableName": "pending_transactions",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `toAddress` TEXT NOT NULL, `value` INTEGER NOT NULL, `memo` BLOB, `accountIndex` INTEGER NOT NULL, `minedHeight` INTEGER NOT NULL, `expiryHeight` INTEGER NOT NULL, `cancelled` INTEGER NOT NULL, `encodeAttempts` INTEGER NOT NULL, `submitAttempts` INTEGER NOT NULL, `errorMessage` TEXT, `errorCode` INTEGER, `createTime` INTEGER NOT NULL, `raw` BLOB NOT NULL, `rawTransactionId` BLOB)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "toAddress",
"columnName": "toAddress",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "value",
"columnName": "value",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "memo",
"columnName": "memo",
"affinity": "BLOB",
"notNull": false
},
{
"fieldPath": "accountIndex",
"columnName": "accountIndex",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "minedHeight",
"columnName": "minedHeight",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "expiryHeight",
"columnName": "expiryHeight",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "cancelled",
"columnName": "cancelled",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "encodeAttempts",
"columnName": "encodeAttempts",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "submitAttempts",
"columnName": "submitAttempts",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "errorMessage",
"columnName": "errorMessage",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "errorCode",
"columnName": "errorCode",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "createTime",
"columnName": "createTime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "raw",
"columnName": "raw",
"affinity": "BLOB",
"notNull": true
},
{
"fieldPath": "rawTransactionId",
"columnName": "rawTransactionId",
"affinity": "BLOB",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ea8cbb874a6d62d7b17d7fd5ea82dc8d')"
]
}
}

View File

@ -5,7 +5,7 @@ import cash.z.ecc.android.sdk.integration.SmokeTest
import cash.z.ecc.android.sdk.integration.service.ChangeServiceTest
import cash.z.ecc.android.sdk.jni.BranchIdTest
import cash.z.ecc.android.sdk.jni.TransparentTest
import cash.z.ecc.android.sdk.transaction.PersistentTransactionManagerTest
import cash.z.ecc.android.sdk.internal.transaction.PersistentTransactionManagerTest
import org.junit.runner.RunWith
import org.junit.runners.Suite

View File

@ -4,7 +4,7 @@ import androidx.test.filters.LargeTest
import androidx.test.filters.MediumTest
import cash.z.ecc.android.sdk.annotation.MaintainedTest
import cash.z.ecc.android.sdk.annotation.TestPurpose
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.util.TestWallet
import kotlinx.coroutines.runBlocking
import org.junit.Assert

View File

@ -11,7 +11,7 @@ import cash.z.ecc.android.sdk.ext.Twig
import cash.z.ecc.android.sdk.ext.ZcashSdk
import cash.z.ecc.android.sdk.ext.onFirst
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.test.ScopedTest
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.tool.WalletBirthdayTool

View File

@ -4,13 +4,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import cash.z.ecc.android.sdk.annotation.MaintainedTest
import cash.z.ecc.android.sdk.annotation.TestPurpose
import cash.z.ecc.android.sdk.block.CompactBlockDownloader
import cash.z.ecc.android.sdk.block.CompactBlockStore
import cash.z.ecc.android.sdk.internal.block.CompactBlockDownloader
import cash.z.ecc.android.sdk.internal.block.CompactBlockStore
import cash.z.ecc.android.sdk.exception.LightWalletException.ChangeServerException.ChainInfoNotMatching
import cash.z.ecc.android.sdk.exception.LightWalletException.ChangeServerException.StatusException
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.service.LightWalletService
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.internal.service.LightWalletService
import cash.z.ecc.android.sdk.test.ScopedTest
import cash.z.ecc.android.sdk.type.ZcashNetwork
import kotlinx.coroutines.delay

View File

@ -1,9 +1,10 @@
package cash.z.ecc.android.sdk.tool
package cash.z.ecc.android.sdk.internal
import android.content.Context
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import cash.z.ecc.android.sdk.ext.ZcashSdk
import cash.z.ecc.android.sdk.internal.SaplingParamTool
import kotlinx.coroutines.runBlocking
import org.junit.Assert
import org.junit.Before

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.transaction
package cash.z.ecc.android.sdk.internal.transaction
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@ -10,7 +10,7 @@ import cash.z.ecc.android.sdk.db.entity.isCancelled
import cash.z.ecc.android.sdk.ext.TroubleshootingTwig
import cash.z.ecc.android.sdk.ext.Twig
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.service.LightWalletService
import cash.z.ecc.android.sdk.internal.service.LightWalletService
import cash.z.ecc.android.sdk.test.ScopedTest
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.stub

View File

@ -9,7 +9,7 @@ import cash.z.ecc.android.sdk.Synchronizer
import cash.z.ecc.android.sdk.db.entity.isPending
import cash.z.ecc.android.sdk.ext.Twig
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.sdk.type.ZcashNetwork

View File

@ -4,7 +4,7 @@ import androidx.test.platform.app.InstrumentationRegistry
import cash.z.ecc.android.sdk.ext.TroubleshootingTwig
import cash.z.ecc.android.sdk.ext.Twig
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.type.ZcashNetwork
import org.junit.Ignore
import org.junit.Test

View File

@ -8,8 +8,8 @@ import cash.z.ecc.android.sdk.Synchronizer.Status.SCANNING
import cash.z.ecc.android.sdk.Synchronizer.Status.STOPPED
import cash.z.ecc.android.sdk.Synchronizer.Status.SYNCED
import cash.z.ecc.android.sdk.Synchronizer.Status.VALIDATING
import cash.z.ecc.android.sdk.block.CompactBlockDbStore
import cash.z.ecc.android.sdk.block.CompactBlockDownloader
import cash.z.ecc.android.sdk.internal.block.CompactBlockDbStore
import cash.z.ecc.android.sdk.internal.block.CompactBlockDownloader
import cash.z.ecc.android.sdk.block.CompactBlockProcessor
import cash.z.ecc.android.sdk.block.CompactBlockProcessor.State.Disconnected
import cash.z.ecc.android.sdk.block.CompactBlockProcessor.State.Downloading
@ -19,7 +19,7 @@ import cash.z.ecc.android.sdk.block.CompactBlockProcessor.State.Scanned
import cash.z.ecc.android.sdk.block.CompactBlockProcessor.State.Scanning
import cash.z.ecc.android.sdk.block.CompactBlockProcessor.State.Stopped
import cash.z.ecc.android.sdk.block.CompactBlockProcessor.State.Validating
import cash.z.ecc.android.sdk.block.CompactBlockStore
import cash.z.ecc.android.sdk.internal.block.CompactBlockStore
import cash.z.ecc.android.sdk.db.entity.PendingTransaction
import cash.z.ecc.android.sdk.db.entity.hasRawTransactionId
import cash.z.ecc.android.sdk.db.entity.isCancelled
@ -34,19 +34,19 @@ import cash.z.ecc.android.sdk.db.entity.isSubmitted
import cash.z.ecc.android.sdk.exception.SynchronizerException
import cash.z.ecc.android.sdk.ext.ConsensusBranchId
import cash.z.ecc.android.sdk.ext.ZcashSdk
import cash.z.ecc.android.sdk.ext.toHexReversed
import cash.z.ecc.android.sdk.ext.tryNull
import cash.z.ecc.android.sdk.internal.ext.toHexReversed
import cash.z.ecc.android.sdk.internal.ext.tryNull
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.ext.twigTask
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.service.LightWalletService
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.internal.service.LightWalletService
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.transaction.OutboundTransactionManager
import cash.z.ecc.android.sdk.transaction.PagedTransactionRepository
import cash.z.ecc.android.sdk.transaction.PersistentTransactionManager
import cash.z.ecc.android.sdk.transaction.TransactionEncoder
import cash.z.ecc.android.sdk.transaction.TransactionRepository
import cash.z.ecc.android.sdk.transaction.WalletTransactionEncoder
import cash.z.ecc.android.sdk.internal.transaction.OutboundTransactionManager
import cash.z.ecc.android.sdk.internal.transaction.PagedTransactionRepository
import cash.z.ecc.android.sdk.internal.transaction.PersistentTransactionManager
import cash.z.ecc.android.sdk.internal.transaction.TransactionEncoder
import cash.z.ecc.android.sdk.internal.transaction.TransactionRepository
import cash.z.ecc.android.sdk.internal.transaction.WalletTransactionEncoder
import cash.z.ecc.android.sdk.type.AddressType
import cash.z.ecc.android.sdk.type.AddressType.Shielded
import cash.z.ecc.android.sdk.type.AddressType.Transparent

View File

@ -29,15 +29,16 @@ import cash.z.ecc.android.sdk.ext.ZcashSdk.POLL_INTERVAL
import cash.z.ecc.android.sdk.ext.ZcashSdk.RETRIES
import cash.z.ecc.android.sdk.ext.ZcashSdk.REWIND_DISTANCE
import cash.z.ecc.android.sdk.ext.ZcashSdk.SCAN_BATCH_SIZE
import cash.z.ecc.android.sdk.ext.retryUpTo
import cash.z.ecc.android.sdk.ext.retryWithBackoff
import cash.z.ecc.android.sdk.ext.toHexReversed
import cash.z.ecc.android.sdk.internal.ext.retryUpTo
import cash.z.ecc.android.sdk.internal.ext.retryWithBackoff
import cash.z.ecc.android.sdk.internal.ext.toHexReversed
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.ext.twigTask
import cash.z.ecc.android.sdk.internal.block.CompactBlockDownloader
import cash.z.ecc.android.sdk.jni.RustBackend
import cash.z.ecc.android.sdk.jni.RustBackendWelding
import cash.z.ecc.android.sdk.transaction.PagedTransactionRepository
import cash.z.ecc.android.sdk.transaction.TransactionRepository
import cash.z.ecc.android.sdk.internal.transaction.PagedTransactionRepository
import cash.z.ecc.android.sdk.internal.transaction.TransactionRepository
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.wallet.sdk.rpc.Service
import io.grpc.StatusRuntimeException

View File

@ -3,48 +3,6 @@ package cash.z.ecc.android.sdk.ext
import kotlin.math.max
import kotlin.math.min
/**
* Simple implementation of Simple moving average.
*/
class Sma(val window: Int = 3) {
private val values = Array(window) { 0.0 }
var average = 0.0
private set
var count: Int = 0
var index: Int = 0
fun add(value: Number) = add(value.toDouble())
fun add(value: Double): Double {
when {
// full window
count == window -> {
index = (index + 1) % window
average += ((value - values[index]) / count.toFloat())
values[index] = value
}
// partially-filled window
count != 0 -> {
index = (index + 1) % window
average = ((value + count.toFloat() * average) / (count + 1).toFloat())
values[index] = value
count++
}
// empty window
else -> {
// simply assign given value as current average:
average = value
values[0] = value
count = 1
}
}
return average
}
fun format(places: Int = 0) = "%.${places}f".format(average)
}
class BatchMetrics(val range: IntRange, val batchSize: Int, private val onMetricComplete: ((BatchMetrics, Boolean) -> Unit)? = null) {
private var completedBatches = 0
private var rangeStartTime = 0L

View File

@ -7,14 +7,8 @@ fun ByteArray.toHex(): String {
return sb.toString()
}
fun ByteArray.toHexReversed(): String {
val sb = StringBuilder(size * 2)
var i = size - 1
while (i >= 0)
sb.append(String.format("%02x", this[i--]))
return sb.toString()
}
// Not used within the SDK, but is used by the Wallet app
@Suppress("unused")
fun String.fromHex(): ByteArray {
val len = length
val data = ByteArray(len / 2)

View File

@ -42,6 +42,8 @@ fun <T> Flow<T>.collectWith(scope: CoroutineScope, block: (T) -> Unit) {
* Utility for performing the given action on the first emission of a flow and running that action
* in the given scope.
*/
// Unused in the SDK but is used by the wallet app
@Suppress("unused")
fun <T, S> Flow<T>.onFirstWith(scope: CoroutineScope, block: suspend (T) -> S) {
scope.launch {
onEach {

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.tool
package cash.z.ecc.android.sdk.internal
import cash.z.ecc.android.sdk.exception.TransactionEncoderException
import cash.z.ecc.android.sdk.ext.Bush

View File

@ -0,0 +1,43 @@
package cash.z.ecc.android.sdk.internal
/**
* Simple implementation of Simple moving average.
*/
class Sma(val window: Int = 3) {
private val values = Array(window) { 0.0 }
var average = 0.0
private set
var count: Int = 0
var index: Int = 0
fun add(value: Number) = add(value.toDouble())
fun add(value: Double): Double {
when {
// full window
count == window -> {
index = (index + 1) % window
average += ((value - values[index]) / count.toFloat())
values[index] = value
}
// partially-filled window
count != 0 -> {
index = (index + 1) % window
average = ((value + count.toFloat() * average) / (count + 1).toFloat())
values[index] = value
count++
}
// empty window
else -> {
// simply assign given value as current average:
average = value
values[0] = value
count = 1
}
}
return average
}
fun format(places: Int = 0) = "%.${places}f".format(average)
}

View File

@ -1,10 +1,10 @@
package cash.z.ecc.android.sdk.block
package cash.z.ecc.android.sdk.internal.block
import android.content.Context
import androidx.room.Room
import androidx.room.RoomDatabase
import cash.z.ecc.android.sdk.db.CompactBlockDao
import cash.z.ecc.android.sdk.db.CompactBlockDb
import cash.z.ecc.android.sdk.internal.db.CompactBlockDao
import cash.z.ecc.android.sdk.internal.db.CompactBlockDb
import cash.z.ecc.android.sdk.db.entity.CompactBlockEntity
import cash.z.wallet.sdk.rpc.CompactFormats
import kotlinx.coroutines.Dispatchers.IO

View File

@ -1,9 +1,9 @@
package cash.z.ecc.android.sdk.block // iimport cash.z.ecc.android.sdk.exception.LightWalletException
package cash.z.ecc.android.sdk.internal.block
import cash.z.ecc.android.sdk.exception.LightWalletException
import cash.z.ecc.android.sdk.ext.retryUpTo
import cash.z.ecc.android.sdk.ext.tryWarn
import cash.z.ecc.android.sdk.internal.ext.retryUpTo
import cash.z.ecc.android.sdk.internal.ext.tryWarn
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.service.LightWalletService
import cash.z.ecc.android.sdk.internal.service.LightWalletService
import cash.z.wallet.sdk.rpc.Service
import io.grpc.StatusRuntimeException
import kotlinx.coroutines.CoroutineScope

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.block
package cash.z.ecc.android.sdk.internal.block
import cash.z.wallet.sdk.rpc.CompactFormats

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.db
package cash.z.ecc.android.sdk.internal.db
import androidx.room.Dao
import androidx.room.Database

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.db
package cash.z.ecc.android.sdk.internal.db
import androidx.paging.DataSource
import androidx.room.Dao

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.db
package cash.z.ecc.android.sdk.internal.db
import androidx.room.Dao
import androidx.room.Database

View File

@ -0,0 +1,9 @@
package cash.z.ecc.android.sdk.internal.ext
internal fun ByteArray.toHexReversed(): String {
val sb = StringBuilder(size * 2)
var i = size - 1
while (i >= 0)
sb.append(String.format("%02x", this[i--]))
return sb.toString()
}

View File

@ -1,4 +1,6 @@
package cash.z.ecc.android.sdk.ext
package cash.z.ecc.android.sdk.internal.ext
import cash.z.ecc.android.sdk.ext.twig
internal inline fun <R> tryNull(block: () -> R): R? {
return try {

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.ext
package cash.z.ecc.android.sdk.internal.ext
import android.annotation.SuppressLint
import android.content.Context

View File

@ -1,7 +1,8 @@
package cash.z.ecc.android.sdk.ext
package cash.z.ecc.android.sdk.internal.ext
import android.content.Context
import cash.z.ecc.android.sdk.ext.ZcashSdk.MAX_BACKOFF_INTERVAL
import cash.z.ecc.android.sdk.ext.twig
import kotlinx.coroutines.delay
import java.io.File
import kotlin.random.Random

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.ext.android
package cash.z.ecc.android.sdk.internal.ext.android
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.ext.android
package cash.z.ecc.android.sdk.internal.ext.android
import android.annotation.SuppressLint
import androidx.paging.Config

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.ext.android
package cash.z.ecc.android.sdk.internal.ext.android
import android.annotation.SuppressLint
import android.os.Handler

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.service
package cash.z.ecc.android.sdk.internal.service
import android.content.Context
import cash.z.ecc.android.sdk.R

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.service
package cash.z.ecc.android.sdk.internal.service
import cash.z.wallet.sdk.rpc.CompactFormats
import cash.z.wallet.sdk.rpc.Service

View File

@ -1,20 +1,20 @@
package cash.z.ecc.android.sdk.transaction
package cash.z.ecc.android.sdk.internal.transaction
import android.content.Context
import androidx.paging.PagedList
import androidx.room.Room
import androidx.room.RoomDatabase
import cash.z.ecc.android.sdk.db.AccountDao
import cash.z.ecc.android.sdk.db.BlockDao
import cash.z.ecc.android.sdk.db.DerivedDataDb
import cash.z.ecc.android.sdk.db.TransactionDao
import cash.z.ecc.android.sdk.internal.db.AccountDao
import cash.z.ecc.android.sdk.internal.db.BlockDao
import cash.z.ecc.android.sdk.internal.db.DerivedDataDb
import cash.z.ecc.android.sdk.internal.db.TransactionDao
import cash.z.ecc.android.sdk.db.entity.ConfirmedTransaction
import cash.z.ecc.android.sdk.exception.RepositoryException
import cash.z.ecc.android.sdk.ext.ZcashSdk
import cash.z.ecc.android.sdk.ext.android.RefreshableDataSourceFactory
import cash.z.ecc.android.sdk.ext.android.toFlowPagedList
import cash.z.ecc.android.sdk.ext.android.toRefreshable
import cash.z.ecc.android.sdk.ext.tryWarn
import cash.z.ecc.android.sdk.internal.ext.android.RefreshableDataSourceFactory
import cash.z.ecc.android.sdk.internal.ext.android.toFlowPagedList
import cash.z.ecc.android.sdk.internal.ext.android.toRefreshable
import cash.z.ecc.android.sdk.internal.ext.tryWarn
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.jni.RustBackend
import cash.z.ecc.android.sdk.type.UnifiedAddressAccount

View File

@ -1,17 +1,17 @@
package cash.z.ecc.android.sdk.transaction
package cash.z.ecc.android.sdk.internal.transaction
import android.content.Context
import androidx.room.Room
import androidx.room.RoomDatabase
import cash.z.ecc.android.sdk.db.PendingTransactionDao
import cash.z.ecc.android.sdk.db.PendingTransactionDb
import cash.z.ecc.android.sdk.internal.db.PendingTransactionDao
import cash.z.ecc.android.sdk.internal.db.PendingTransactionDb
import cash.z.ecc.android.sdk.db.entity.PendingTransaction
import cash.z.ecc.android.sdk.db.entity.PendingTransactionEntity
import cash.z.ecc.android.sdk.db.entity.isCancelled
import cash.z.ecc.android.sdk.db.entity.isFailedEncoding
import cash.z.ecc.android.sdk.db.entity.isSubmitted
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.service.LightWalletService
import cash.z.ecc.android.sdk.internal.service.LightWalletService
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.flow.Flow

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.transaction
package cash.z.ecc.android.sdk.internal.transaction
import cash.z.ecc.android.sdk.db.entity.EncodedTransaction

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.transaction
package cash.z.ecc.android.sdk.internal.transaction
import cash.z.ecc.android.sdk.db.entity.PendingTransaction
import kotlinx.coroutines.flow.Flow

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.transaction
package cash.z.ecc.android.sdk.internal.transaction
import cash.z.ecc.android.sdk.db.entity.ConfirmedTransaction
import cash.z.ecc.android.sdk.db.entity.EncodedTransaction

View File

@ -1,4 +1,4 @@
package cash.z.ecc.android.sdk.transaction
package cash.z.ecc.android.sdk.internal.transaction
import cash.z.ecc.android.sdk.db.entity.EncodedTransaction
import cash.z.ecc.android.sdk.exception.TransactionEncoderException
@ -7,7 +7,7 @@ import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.ext.twigTask
import cash.z.ecc.android.sdk.jni.RustBackend
import cash.z.ecc.android.sdk.jni.RustBackendWelding
import cash.z.ecc.android.sdk.tool.SaplingParamTool
import cash.z.ecc.android.sdk.internal.SaplingParamTool
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.withContext