2022-09-27 06:01:53 -07:00
|
|
|
package cash.z.ecc.android.sdk.model
|
|
|
|
|
2023-05-18 04:36:15 -07:00
|
|
|
import cash.z.ecc.android.sdk.internal.jni.RustBackend
|
|
|
|
import cash.z.ecc.android.sdk.internal.model.JniUnifiedSpendingKey
|
2022-09-29 10:04:00 -07:00
|
|
|
|
2022-09-27 06:01:53 -07:00
|
|
|
/**
|
|
|
|
* A [ZIP 316](https://zips.z.cash/zip-0316) Unified Spending Key.
|
|
|
|
*
|
|
|
|
* This is the spend authority for an account under the wallet's seed.
|
|
|
|
*
|
|
|
|
* An instance of this class contains all of the per-pool spending keys that could be
|
|
|
|
* derived at the time of its creation. As such, it is not suitable for long-term storage,
|
|
|
|
* export/import, or backup purposes.
|
|
|
|
*/
|
2022-10-04 05:25:13 -07:00
|
|
|
class UnifiedSpendingKey private constructor(
|
2022-10-06 10:44:34 -07:00
|
|
|
val account: Account,
|
2022-09-27 06:01:53 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The binary encoding of the [ZIP 316](https://zips.z.cash/zip-0316) Unified Spending
|
|
|
|
* Key for [account].
|
|
|
|
*
|
|
|
|
* This encoding **MUST NOT** be exposed to users. It is an internal encoding that is
|
|
|
|
* inherently unstable, and only intended to be passed between the SDK and the storage
|
|
|
|
* backend. Wallets **MUST NOT** allow this encoding to be exported or imported.
|
|
|
|
*/
|
2022-10-04 05:25:13 -07:00
|
|
|
private val bytes: FirstClassByteArray
|
2022-09-27 06:01:53 -07:00
|
|
|
) {
|
2022-10-04 05:25:13 -07:00
|
|
|
|
2023-05-18 04:36:15 -07:00
|
|
|
internal constructor(uskJni: JniUnifiedSpendingKey) : this(
|
2023-04-10 07:35:40 -07:00
|
|
|
Account(uskJni.account),
|
2023-05-18 04:36:15 -07:00
|
|
|
FirstClassByteArray(uskJni.bytes.copyOf())
|
2023-04-10 07:35:40 -07:00
|
|
|
)
|
2022-10-04 05:25:13 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The binary encoding of the [ZIP 316](https://zips.z.cash/zip-0316) Unified Spending
|
|
|
|
* Key for [account].
|
|
|
|
*
|
|
|
|
* This encoding **MUST NOT** be exposed to users. It is an internal encoding that is
|
|
|
|
* inherently unstable, and only intended to be passed between the SDK and the storage
|
|
|
|
* backend. Wallets **MUST NOT** allow this encoding to be exported or imported.
|
|
|
|
*/
|
|
|
|
fun copyBytes() = bytes.byteArray.copyOf()
|
|
|
|
|
2022-09-27 06:01:53 -07:00
|
|
|
// Override to prevent leaking key to logs
|
|
|
|
override fun toString() = "UnifiedSpendingKey(account=$account)"
|
|
|
|
|
2022-10-04 05:25:13 -07:00
|
|
|
override fun equals(other: Any?): Boolean {
|
|
|
|
if (this === other) return true
|
|
|
|
if (javaClass != other?.javaClass) return false
|
|
|
|
|
|
|
|
other as UnifiedSpendingKey
|
|
|
|
|
|
|
|
if (account != other.account) return false
|
|
|
|
if (bytes != other.bytes) return false
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun hashCode(): Int {
|
|
|
|
var result = account.hashCode()
|
|
|
|
result = 31 * result + bytes.hashCode()
|
|
|
|
return result
|
|
|
|
}
|
2022-09-29 10:04:00 -07:00
|
|
|
|
|
|
|
companion object {
|
2022-10-06 10:44:34 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This method may fail if the [bytes] no longer represent a valid key. A key could become invalid due to
|
|
|
|
* network upgrades or other internal changes. If a non-successful result is returned, clients are expected
|
|
|
|
* to use [DerivationTool.deriveUnifiedSpendingKey] to regenerate the key from the seed.
|
|
|
|
*
|
|
|
|
* @return A validated UnifiedSpendingKey.
|
|
|
|
*/
|
|
|
|
suspend fun new(account: Account, bytes: ByteArray): Result<UnifiedSpendingKey> {
|
2022-09-29 10:04:00 -07:00
|
|
|
val bytesCopy = bytes.copyOf()
|
2022-12-12 21:02:25 -08:00
|
|
|
RustBackend.loadLibrary()
|
2022-10-06 10:44:34 -07:00
|
|
|
return runCatching {
|
2023-05-18 04:36:15 -07:00
|
|
|
require(RustBackend.validateUnifiedSpendingKey(bytesCopy))
|
2022-10-06 10:44:34 -07:00
|
|
|
UnifiedSpendingKey(account, FirstClassByteArray(bytesCopy))
|
2022-09-29 10:04:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-09-27 06:01:53 -07:00
|
|
|
}
|