ZcashLightClientKit/Sources/ZcashLightClientKit/DAO/TransactionBuilder.swift

177 lines
6.0 KiB
Swift

//
// TransactionBuilder.swift
// ZcashLightClientKit
//
// Created by Francisco Gindre on 11/18/19.
//
import Foundation
import SQLite
enum TransactionBuilder {
enum ConfirmedColumns: Int {
case id
case minedHeight
case transactionIndex
case rawTransactionId
case expiryHeight
case raw
case toAddress
case value
case memo
case noteId
case blockTimeInSeconds
case fee
}
enum ReceivedColumns: Int {
case id
case minedHeight
case transactionIndex
case rawTransactionId
case raw
case value
case memo
case noteId
case blockTimeInSeconds
case fee
}
enum TransactionEntityColumns: Int {
case id
case minedHeight
case txIndex
case txid
case expiryHeight
case raw
case fee
}
static func createTransactionEntity(txId: Data, rawTransaction: RawTransaction) -> TransactionEntity {
Transaction(
id: nil,
transactionId: txId,
created: nil,
transactionIndex: nil,
expiryHeight: nil,
minedHeight: Int(exactly: rawTransaction.height),
raw: rawTransaction.data,
fee: nil
)
}
static func createTransactionEntity(from bindings: [Binding?]) -> TransactionEntity? {
guard let txId = bindings[TransactionEntityColumns.txid.rawValue] as? Blob else {
return nil
}
var rawData: Data?
if let raw = bindings[TransactionEntityColumns.raw.rawValue] as? Blob {
rawData = Data(blob: raw)
}
return Transaction(
id: bindings[TransactionEntityColumns.id.rawValue] as? Int,
transactionId: Data(blob: txId),
created: nil,
transactionIndex: bindings[TransactionEntityColumns.txIndex.rawValue] as? Int,
expiryHeight: bindings[TransactionEntityColumns.expiryHeight.rawValue] as? Int,
minedHeight: bindings[TransactionEntityColumns.minedHeight.rawValue] as? Int,
raw: rawData,
fee: (bindings[TransactionEntityColumns.fee.rawValue] as? Int?)?.flatMap({ Zatoshi(Int64($0)) })
)
}
static func createConfirmedTransaction(from bindings: [Binding?]) -> ConfirmedTransaction? {
guard
let id = bindings[ConfirmedColumns.id.rawValue] as? Int64,
let noteId = bindings[ConfirmedColumns.noteId.rawValue] as? Int64,
let transactionIndex = bindings[ConfirmedColumns.transactionIndex.rawValue] as? Int64,
let value = bindings[ConfirmedColumns.value.rawValue] as? Int64
else { return nil }
let minedHeight = bindings[ConfirmedColumns.minedHeight.rawValue] as? Int64 ?? -1
let blockTimeInSeconds = bindings[ConfirmedColumns.blockTimeInSeconds.rawValue] as? Int64 ?? 0
// Optional values
let toAddress = bindings[ConfirmedColumns.toAddress.rawValue] as? String
var expiryHeight: BlockHeight?
if let expiry = bindings[ConfirmedColumns.expiryHeight.rawValue] as? Int64 {
expiryHeight = BlockHeight(expiry)
}
var raw: Data?
if let rawBlob = bindings[ConfirmedColumns.raw.rawValue] as? Blob {
raw = Data(blob: rawBlob)
}
var memo: Data?
if let memoBlob = bindings[ConfirmedColumns.memo.rawValue] as? Blob {
memo = Data(blob: memoBlob)
}
var transactionId: Data?
if let txIdBlob = bindings[ConfirmedColumns.rawTransactionId.rawValue] as? Blob {
transactionId = Data(blob: txIdBlob)
}
return ConfirmedTransaction(
toAddress: toAddress,
expiryHeight: expiryHeight,
minedHeight: Int(minedHeight),
noteId: Int(noteId),
blockTimeInSeconds: TimeInterval(integerLiteral: blockTimeInSeconds),
transactionIndex: Int(transactionIndex),
raw: raw,
id: Int(id),
value: Zatoshi(value),
memo: memo,
rawTransactionId: transactionId,
fee: (bindings[ConfirmedColumns.fee.rawValue] as? Int).map({ Zatoshi(Int64($0)) })
)
}
static func createReceivedTransaction(from bindings: [Binding?]) -> ConfirmedTransaction? {
guard let id = bindings[ReceivedColumns.id.rawValue] as? Int64,
let minedHeight = bindings[ReceivedColumns.minedHeight.rawValue] as? Int64,
let noteId = bindings[ReceivedColumns.noteId.rawValue] as? Int64,
let blockTimeInSeconds = bindings[ReceivedColumns.blockTimeInSeconds.rawValue] as? Int64,
let transactionIndex = bindings[ReceivedColumns.transactionIndex.rawValue] as? Int64,
let value = bindings[ReceivedColumns.value.rawValue] as? Int64
else { return nil }
// Optional values
var memo: Data?
if let memoBlob = bindings[ReceivedColumns.memo.rawValue] as? Blob {
memo = Data(blob: memoBlob)
}
var transactionId: Data?
if let txIdBlob = bindings[ReceivedColumns.rawTransactionId.rawValue] as? Blob {
transactionId = Data(blob: txIdBlob)
}
var rawData: Data?
if let rawBlob = bindings[ReceivedColumns.raw.rawValue] as? Blob {
rawData = Data(blob: rawBlob)
}
return ConfirmedTransaction(
toAddress: nil,
expiryHeight: nil,
minedHeight: Int(minedHeight),
noteId: Int(noteId),
blockTimeInSeconds: TimeInterval(integerLiteral: blockTimeInSeconds),
transactionIndex: Int(transactionIndex),
raw: rawData,
id: Int(id),
value: Zatoshi(value),
memo: memo,
rawTransactionId: transactionId,
fee: (bindings[ReceivedColumns.fee.rawValue] as? Int).map({ Zatoshi(Int64($0)) })
)
}
}