2019-11-26 14:32:20 -08:00
|
|
|
//
|
|
|
|
// WalletTransactionEncoder.swift
|
|
|
|
// ZcashLightClientKit
|
|
|
|
//
|
|
|
|
// Created by Francisco Gindre on 11/20/19.
|
|
|
|
//
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
|
|
|
class WalletTransactionEncoder: TransactionEncoder {
|
2023-05-05 10:30:47 -07:00
|
|
|
let lightWalletService: LightWalletService
|
2023-04-24 14:15:20 -07:00
|
|
|
let rustBackend: ZcashRustBackendWelding
|
|
|
|
let repository: TransactionRepository
|
2023-03-22 05:47:32 -07:00
|
|
|
let logger: Logger
|
2021-09-17 06:49:58 -07:00
|
|
|
|
2023-04-24 14:15:20 -07:00
|
|
|
private let outputParamsURL: URL
|
|
|
|
private let spendParamsURL: URL
|
|
|
|
private let dataDbURL: URL
|
|
|
|
private let fsBlockDbRoot: URL
|
|
|
|
private let networkType: NetworkType
|
2020-06-04 14:36:25 -07:00
|
|
|
|
2021-09-17 06:49:58 -07:00
|
|
|
init(
|
2023-03-31 10:10:35 -07:00
|
|
|
rustBackend: ZcashRustBackendWelding,
|
2021-09-17 06:49:58 -07:00
|
|
|
dataDb: URL,
|
2023-02-02 08:58:12 -08:00
|
|
|
fsBlockDbRoot: URL,
|
2023-05-05 10:30:47 -07:00
|
|
|
service: LightWalletService,
|
2021-09-17 06:49:58 -07:00
|
|
|
repository: TransactionRepository,
|
|
|
|
outputParams: URL,
|
|
|
|
spendParams: URL,
|
2023-03-22 05:47:32 -07:00
|
|
|
networkType: NetworkType,
|
|
|
|
logger: Logger
|
2021-09-17 06:49:58 -07:00
|
|
|
) {
|
2023-03-31 10:10:35 -07:00
|
|
|
self.rustBackend = rustBackend
|
2019-12-16 14:25:45 -08:00
|
|
|
self.dataDbURL = dataDb
|
2023-02-02 08:58:12 -08:00
|
|
|
self.fsBlockDbRoot = fsBlockDbRoot
|
2023-05-05 10:30:47 -07:00
|
|
|
self.lightWalletService = service
|
2019-11-26 14:32:20 -08:00
|
|
|
self.repository = repository
|
2019-12-16 14:25:45 -08:00
|
|
|
self.outputParamsURL = outputParams
|
|
|
|
self.spendParamsURL = spendParams
|
2021-07-28 09:59:10 -07:00
|
|
|
self.networkType = networkType
|
2023-03-22 05:47:32 -07:00
|
|
|
self.logger = logger
|
2019-12-16 14:25:45 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
convenience init(initializer: Initializer) {
|
2021-09-17 06:49:58 -07:00
|
|
|
self.init(
|
2023-03-31 10:10:35 -07:00
|
|
|
rustBackend: initializer.rustBackend,
|
2021-09-17 06:49:58 -07:00
|
|
|
dataDb: initializer.dataDbURL,
|
2023-02-02 08:58:12 -08:00
|
|
|
fsBlockDbRoot: initializer.fsBlockDbRoot,
|
2023-05-05 10:30:47 -07:00
|
|
|
service: initializer.lightWalletService,
|
2021-09-17 06:49:58 -07:00
|
|
|
repository: initializer.transactionRepository,
|
|
|
|
outputParams: initializer.outputParamsURL,
|
|
|
|
spendParams: initializer.spendParamsURL,
|
2023-03-22 05:47:32 -07:00
|
|
|
networkType: initializer.network.networkType,
|
|
|
|
logger: initializer.logger
|
2021-09-17 06:49:58 -07:00
|
|
|
)
|
2019-11-26 14:32:20 -08:00
|
|
|
}
|
2021-09-17 06:49:58 -07:00
|
|
|
|
2024-02-20 16:54:34 -08:00
|
|
|
func proposeTransfer(
|
|
|
|
accountIndex: Int,
|
|
|
|
recipient: String,
|
|
|
|
amount: Zatoshi,
|
|
|
|
memoBytes: MemoBytes?
|
|
|
|
) async throws -> Proposal {
|
2024-01-26 19:07:18 -08:00
|
|
|
let proposal = try await rustBackend.proposeTransfer(
|
2024-02-20 16:54:34 -08:00
|
|
|
account: Int32(accountIndex),
|
|
|
|
to: recipient,
|
|
|
|
value: amount.amount,
|
2023-03-31 10:10:35 -07:00
|
|
|
memo: memoBytes
|
2021-09-17 06:49:58 -07:00
|
|
|
)
|
2023-03-31 10:10:35 -07:00
|
|
|
|
2024-02-20 16:54:34 -08:00
|
|
|
return Proposal(inner: proposal)
|
2019-11-26 14:32:20 -08:00
|
|
|
}
|
2024-02-20 16:54:34 -08:00
|
|
|
|
|
|
|
func proposeShielding(
|
|
|
|
accountIndex: Int,
|
2023-02-02 08:58:12 -08:00
|
|
|
shieldingThreshold: Zatoshi,
|
2024-02-20 16:54:34 -08:00
|
|
|
memoBytes: MemoBytes?
|
|
|
|
) async throws -> Proposal {
|
|
|
|
let proposal = try await rustBackend.proposeShielding(
|
|
|
|
account: Int32(accountIndex),
|
2022-05-31 05:27:24 -07:00
|
|
|
memo: memoBytes,
|
2024-02-20 16:54:34 -08:00
|
|
|
shieldingThreshold: shieldingThreshold
|
2021-09-17 06:49:58 -07:00
|
|
|
)
|
2024-02-20 16:54:34 -08:00
|
|
|
|
|
|
|
return Proposal(inner: proposal)
|
2020-12-23 15:01:09 -08:00
|
|
|
}
|
2022-12-15 03:27:59 -08:00
|
|
|
|
2024-02-20 16:54:34 -08:00
|
|
|
func createProposedTransactions(
|
|
|
|
proposal: Proposal,
|
|
|
|
spendingKey: UnifiedSpendingKey
|
|
|
|
) async throws -> [ZcashTransaction.Overview] {
|
2023-03-17 02:18:35 -07:00
|
|
|
guard ensureParams(spend: self.spendParamsURL, output: self.outputParamsURL) else {
|
2024-02-20 16:54:34 -08:00
|
|
|
throw ZcashError.walletTransEncoderCreateTransactionMissingSaplingParams
|
2020-12-23 15:01:09 -08:00
|
|
|
}
|
2024-01-26 19:07:18 -08:00
|
|
|
|
|
|
|
let txId = try await rustBackend.createProposedTransaction(
|
2024-02-20 16:54:34 -08:00
|
|
|
proposal: proposal.inner,
|
2024-01-26 19:07:18 -08:00
|
|
|
usk: spendingKey
|
|
|
|
)
|
|
|
|
|
2024-02-20 16:54:34 -08:00
|
|
|
logger.debug("transaction id: \(txId)")
|
|
|
|
return [try await repository.find(rawID: txId)]
|
2020-12-23 15:01:09 -08:00
|
|
|
}
|
2023-05-05 10:30:47 -07:00
|
|
|
|
|
|
|
func submit(
|
|
|
|
transaction: EncodedTransaction
|
|
|
|
) async throws {
|
|
|
|
let response = try await self.lightWalletService.submit(spendTransaction: transaction.raw)
|
|
|
|
|
|
|
|
guard response.errorCode >= 0 else {
|
2023-05-08 02:04:29 -07:00
|
|
|
throw TransactionEncoderError.submitError(code: Int(response.errorCode), message: response.errorMessage)
|
2023-05-05 10:30:47 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-26 14:32:20 -08:00
|
|
|
func ensureParams(spend: URL, output: URL) -> Bool {
|
|
|
|
let readableSpend = FileManager.default.isReadableFile(atPath: spend.path)
|
|
|
|
let readableOutput = FileManager.default.isReadableFile(atPath: output.path)
|
|
|
|
|
2023-01-18 08:09:04 -08:00
|
|
|
// TODO: [#713] change this to something that makes sense, https://github.com/zcash/ZcashLightClientKit/issues/713
|
|
|
|
return readableSpend && readableOutput
|
2019-11-26 14:32:20 -08:00
|
|
|
}
|
2023-05-05 10:30:47 -07:00
|
|
|
|
|
|
|
func closeDBConnection() {
|
|
|
|
self.repository.closeDBConnection()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension ZcashTransaction.Overview {
|
|
|
|
func encodedTransaction() throws -> EncodedTransaction {
|
|
|
|
guard let raw else {
|
2023-09-18 14:23:44 -07:00
|
|
|
throw TransactionEncoderError.notEncoded(txId: self.rawID)
|
2023-05-05 10:30:47 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return EncodedTransaction(transactionId: self.rawID, raw: raw)
|
|
|
|
}
|
2019-11-26 14:32:20 -08:00
|
|
|
}
|