- migration of the protocol's methods done - split the code so there's blocking and non-blocking API separately [463] Migrate LightwalletService to Async/Await - draft [463] Migrate LightwalletService to Async/Await - failing tests under investigation [463] Migrate LightwalletService to Async/Await - code cleanup - tests cleanup - async throws unit tests added [463] Migrate LightwalletService to Async/Await - sample app updated to the latest API [463] Migrate LightwalletService to Async/Await - cleanup [463] Migrate LightwalletService to Async/Await - cleanup [463] Migrate LightwalletService to Async/Await - fixed non-building tests [463] Migrate LightwalletService to Async/Await - reverting back to lastHeight() [463] Migrate LightwalletService to Async/Await updated code to AsyncStream [463] Migrate LightwalletService to Async/Await (493) - tests fixed - blockRange reimplemented to use AsyncStream - grpc proto files regenerated to exclude Server
This commit is contained in:
parent
29e06d0b8a
commit
f1a570bbc2
|
@ -30,7 +30,7 @@ enum DemoAppConfig {
|
|||
}()
|
||||
|
||||
static var endpoint: LightWalletEndpoint {
|
||||
return LightWalletEndpoint(address: self.host, port: self.port, secure: true)
|
||||
return LightWalletEndpoint(address: self.host, port: self.port, secure: true, streamingCallTimeoutInMillis: 10 * 60 * 60 * 1000)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,18 +28,13 @@ class LatestHeightViewController: UIViewController {
|
|||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
service.latestBlockHeight { result in
|
||||
switch result {
|
||||
case .success(let height):
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
self?.model = height
|
||||
}
|
||||
|
||||
case .failure(let error):
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
self?.fail(error)
|
||||
}
|
||||
|
||||
/// Note: It's safe to modify model or call fail() because all methods of a UIViewController are MainActor methods by default.
|
||||
Task {
|
||||
do {
|
||||
model = try await service.latestBlockHeightAsync()
|
||||
} catch {
|
||||
fail(error as? LightWalletServiceError ?? .unknown)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ class CompactBlockStreamDownloadOperation: ZcashOperation {
|
|||
private var service: LightWalletService
|
||||
private var done = false
|
||||
private var cancelable: CancellableCall?
|
||||
private var cancelableTask: Task<Void, Error>?
|
||||
private var startHeight: BlockHeight?
|
||||
private var targetHeight: BlockHeight?
|
||||
private var blockBufferSize: Int
|
||||
|
@ -93,13 +94,13 @@ class CompactBlockStreamDownloadOperation: ZcashOperation {
|
|||
self.name = "Download Stream Operation"
|
||||
}
|
||||
|
||||
// swiftlint:disable cyclomatic_complexity
|
||||
override func main() {
|
||||
guard !shouldCancel() else {
|
||||
cancel()
|
||||
return
|
||||
}
|
||||
self.startedHandler?()
|
||||
|
||||
do {
|
||||
if self.targetHeight == nil {
|
||||
self.targetHeight = try service.latestBlockHeight()
|
||||
|
@ -109,38 +110,32 @@ class CompactBlockStreamDownloadOperation: ZcashOperation {
|
|||
}
|
||||
let latestDownloaded = try storage.latestHeight()
|
||||
let startHeight = max(self.startHeight ?? BlockHeight.empty(), latestDownloaded)
|
||||
|
||||
self.cancelable = self.service.blockStream(startHeight: startHeight, endHeight: latestHeight) { [weak self] blockResult in
|
||||
switch blockResult {
|
||||
case .success(let result):
|
||||
switch result {
|
||||
case .success:
|
||||
do {
|
||||
try self?.flush()
|
||||
self?.done = true
|
||||
} catch {
|
||||
self?.fail(error: error)
|
||||
}
|
||||
return
|
||||
case .error(let e):
|
||||
self?.fail(error: e)
|
||||
}
|
||||
case .failure(let e):
|
||||
if case .userCancelled = e {
|
||||
self?.done = true
|
||||
} else {
|
||||
self?.fail(error: e)
|
||||
}
|
||||
}
|
||||
} handler: {[weak self] block in
|
||||
guard let self = self else { return }
|
||||
|
||||
let stream = service.blockStream(
|
||||
startHeight: startHeight,
|
||||
endHeight: latestHeight
|
||||
)
|
||||
|
||||
cancelableTask = Task {
|
||||
do {
|
||||
try self.cache(block, flushCache: false)
|
||||
for try await zcashCompactBlock in stream {
|
||||
try self.cache(zcashCompactBlock, flushCache: false)
|
||||
let progress = BlockProgress(
|
||||
startHeight: startHeight,
|
||||
targetHeight: latestHeight,
|
||||
progressHeight: zcashCompactBlock.height
|
||||
)
|
||||
self.progressDelegate?.progressUpdated(.download(progress))
|
||||
}
|
||||
try self.flush()
|
||||
self.done = true
|
||||
} catch {
|
||||
self.fail(error: error)
|
||||
if let err = error as? LightWalletServiceError, case .userCancelled = err {
|
||||
self.done = true
|
||||
} else {
|
||||
self.fail(error: error)
|
||||
}
|
||||
}
|
||||
} progress: { progress in
|
||||
self.progressDelegate?.progressUpdated(.download(progress))
|
||||
}
|
||||
|
||||
while !done && !isCancelled {
|
||||
|
@ -153,11 +148,13 @@ class CompactBlockStreamDownloadOperation: ZcashOperation {
|
|||
|
||||
override func fail(error: Error? = nil) {
|
||||
self.cancelable?.cancel()
|
||||
self.cancelableTask?.cancel()
|
||||
super.fail(error: error)
|
||||
}
|
||||
|
||||
override func cancel() {
|
||||
self.cancelable?.cancel()
|
||||
self.cancelableTask?.cancel()
|
||||
super.cancel()
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,8 @@ public extension BlockProgress {
|
|||
public class LightWalletGRPCService {
|
||||
let channel: Channel
|
||||
let connectionManager: ConnectionStatusManager
|
||||
let compactTxStreamer: CompactTxStreamerClient
|
||||
let compactTxStreamer: CompactTxStreamerNIOClient
|
||||
let compactTxStreamerAsync: CompactTxStreamerAsyncClient
|
||||
let singleCallTimeout: TimeLimit
|
||||
let streamingCallTimeout: TimeLimit
|
||||
|
||||
|
@ -135,7 +136,14 @@ public class LightWalletGRPCService {
|
|||
|
||||
self.channel = channel
|
||||
|
||||
compactTxStreamer = CompactTxStreamerClient(
|
||||
compactTxStreamer = CompactTxStreamerNIOClient(
|
||||
channel: self.channel,
|
||||
defaultCallOptions: Self.callOptions(
|
||||
timeLimit: self.singleCallTimeout
|
||||
)
|
||||
)
|
||||
|
||||
compactTxStreamerAsync = CompactTxStreamerAsyncClient(
|
||||
channel: self.channel,
|
||||
defaultCallOptions: Self.callOptions(
|
||||
timeLimit: self.singleCallTimeout
|
||||
|
@ -146,6 +154,7 @@ public class LightWalletGRPCService {
|
|||
deinit {
|
||||
_ = channel.close()
|
||||
_ = compactTxStreamer.channel.close()
|
||||
_ = compactTxStreamerAsync.channel.close()
|
||||
}
|
||||
|
||||
func stop() {
|
||||
|
@ -155,7 +164,7 @@ public class LightWalletGRPCService {
|
|||
func blockRange(startHeight: BlockHeight, endHeight: BlockHeight? = nil, result: @escaping (CompactBlock) -> Void) throws -> ServerStreamingCall<BlockRange, CompactBlock> {
|
||||
compactTxStreamer.getBlockRange(BlockRange(startHeight: startHeight, endHeight: endHeight), handler: result)
|
||||
}
|
||||
|
||||
|
||||
func latestBlock() throws -> BlockID {
|
||||
try compactTxStreamer.getLatestBlock(ChainSpec()).response.wait()
|
||||
}
|
||||
|
@ -179,122 +188,18 @@ public class LightWalletGRPCService {
|
|||
}
|
||||
}
|
||||
|
||||
extension LightWalletGRPCService: LightWalletService {
|
||||
@discardableResult
|
||||
public func blockStream(
|
||||
startHeight: BlockHeight,
|
||||
endHeight: BlockHeight,
|
||||
result: @escaping (Result<GRPCResult, LightWalletServiceError>) -> Void,
|
||||
handler: @escaping (ZcashCompactBlock) -> Void,
|
||||
progress: @escaping (BlockProgress) -> Void
|
||||
) -> CancellableCall {
|
||||
let future = compactTxStreamer.getBlockRange(
|
||||
BlockRange(
|
||||
startHeight: startHeight,
|
||||
endHeight: endHeight
|
||||
),
|
||||
callOptions: Self.callOptions(timeLimit: self.streamingCallTimeout),
|
||||
handler: { compactBlock in
|
||||
handler(ZcashCompactBlock(compactBlock: compactBlock))
|
||||
progress(
|
||||
BlockProgress(
|
||||
startHeight: startHeight,
|
||||
targetHeight: endHeight,
|
||||
progressHeight: BlockHeight(compactBlock.height)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
future.status.whenComplete { completionResult in
|
||||
switch completionResult {
|
||||
case .success(let status):
|
||||
switch status.code {
|
||||
case .ok:
|
||||
result(.success(GRPCResult.success))
|
||||
default:
|
||||
result(.failure(LightWalletServiceError.mapCode(status)))
|
||||
}
|
||||
case .failure(let error):
|
||||
result(.failure(LightWalletServiceError.genericError(error: error)))
|
||||
}
|
||||
}
|
||||
return future
|
||||
}
|
||||
|
||||
// MARK: - LightWalletServiceBlockingAPI
|
||||
|
||||
extension LightWalletGRPCService: LightWalletServiceBlockingAPI {
|
||||
public func getInfo() throws -> LightWalletdInfo {
|
||||
try compactTxStreamer.getLightdInfo(Empty()).response.wait()
|
||||
}
|
||||
|
||||
public func getInfo(result: @escaping (Result<LightWalletdInfo, LightWalletServiceError>) -> Void) {
|
||||
compactTxStreamer.getLightdInfo(Empty()).response.whenComplete { completionResult in
|
||||
switch completionResult {
|
||||
case .success(let info):
|
||||
result(.success(info))
|
||||
case .failure(let error):
|
||||
result(.failure(error.mapToServiceError()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func closeConnection() {
|
||||
_ = channel.close()
|
||||
}
|
||||
|
||||
public func fetchTransaction(txId: Data) throws -> TransactionEntity {
|
||||
var txFilter = TxFilter()
|
||||
txFilter.hash = txId
|
||||
|
||||
do {
|
||||
let rawTx = try compactTxStreamer.getTransaction(txFilter).response.wait()
|
||||
|
||||
return TransactionBuilder.createTransactionEntity(txId: txId, rawTransaction: rawTx)
|
||||
} catch {
|
||||
throw error.mapToServiceError()
|
||||
}
|
||||
}
|
||||
|
||||
public func fetchTransaction(txId: Data, result: @escaping (Result<TransactionEntity, LightWalletServiceError>) -> Void) {
|
||||
var txFilter = TxFilter()
|
||||
txFilter.hash = txId
|
||||
|
||||
compactTxStreamer.getTransaction(txFilter).response.whenComplete { response in
|
||||
switch response {
|
||||
case .failure(let error):
|
||||
result(.failure(error.mapToServiceError()))
|
||||
case .success(let rawTx):
|
||||
result(.success(TransactionBuilder.createTransactionEntity(txId: txId, rawTransaction: rawTx)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func submit(spendTransaction: Data, result: @escaping (Result<LightWalletServiceResponse, LightWalletServiceError>) -> Void) {
|
||||
do {
|
||||
let transaction = try RawTransaction(serializedData: spendTransaction)
|
||||
let response = self.compactTxStreamer.sendTransaction(transaction).response
|
||||
|
||||
response.whenComplete { responseResult in
|
||||
switch responseResult {
|
||||
case .failure(let error):
|
||||
result(.failure(LightWalletServiceError.sentFailed(error: error)))
|
||||
case .success(let success):
|
||||
result(.success(success))
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
result(.failure(error.mapToServiceError()))
|
||||
}
|
||||
}
|
||||
|
||||
public func submit(spendTransaction: Data) throws -> LightWalletServiceResponse {
|
||||
let rawTx = RawTransaction.with { raw in
|
||||
raw.data = spendTransaction
|
||||
}
|
||||
do {
|
||||
return try compactTxStreamer.sendTransaction(rawTx).response.wait()
|
||||
} catch {
|
||||
throw error.mapToServiceError()
|
||||
public func latestBlockHeight() throws -> BlockHeight {
|
||||
guard let height = try? compactTxStreamer.getLatestBlock(ChainSpec()).response.wait().compactBlockHeight() else {
|
||||
throw LightWalletServiceError.timeOut
|
||||
}
|
||||
return height
|
||||
}
|
||||
|
||||
public func blockRange(_ range: CompactBlockRange) throws -> [ZcashCompactBlock] {
|
||||
|
@ -315,51 +220,30 @@ extension LightWalletGRPCService: LightWalletService {
|
|||
}
|
||||
}
|
||||
|
||||
public func latestBlockHeight(result: @escaping (Result<BlockHeight, LightWalletServiceError>) -> Void) {
|
||||
let response = compactTxStreamer.getLatestBlock(ChainSpec()).response
|
||||
|
||||
response.whenSuccessBlocking(onto: queue) { blockID in
|
||||
guard let blockHeight = Int(exactly: blockID.height) else {
|
||||
result(.failure(LightWalletServiceError.generalError(message: "error creating blockheight from BlockID \(blockID)")))
|
||||
return
|
||||
}
|
||||
result(.success(blockHeight))
|
||||
public func submit(spendTransaction: Data) throws -> LightWalletServiceResponse {
|
||||
let rawTx = RawTransaction.with { raw in
|
||||
raw.data = spendTransaction
|
||||
}
|
||||
|
||||
response.whenFailureBlocking(onto: queue) { error in
|
||||
result(.failure(error.mapToServiceError()))
|
||||
do {
|
||||
return try compactTxStreamer.sendTransaction(rawTx).response.wait()
|
||||
} catch {
|
||||
throw error.mapToServiceError()
|
||||
}
|
||||
}
|
||||
|
||||
public func blockRange(_ range: CompactBlockRange, result: @escaping (Result<[ZcashCompactBlock], LightWalletServiceError>) -> Void) {
|
||||
queue.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
var blocks: [CompactBlock] = []
|
||||
let response = self.compactTxStreamer.getBlockRange(range.blockRange(), handler: { blocks.append($0) })
|
||||
|
||||
do {
|
||||
let status = try response.status.wait()
|
||||
switch status.code {
|
||||
case .ok:
|
||||
result(.success(blocks.asZcashCompactBlocks()))
|
||||
|
||||
default:
|
||||
result(.failure(.mapCode(status)))
|
||||
}
|
||||
} catch {
|
||||
result(.failure(error.mapToServiceError()))
|
||||
}
|
||||
public func fetchTransaction(txId: Data) throws -> TransactionEntity {
|
||||
var txFilter = TxFilter()
|
||||
txFilter.hash = txId
|
||||
|
||||
do {
|
||||
let rawTx = try compactTxStreamer.getTransaction(txFilter).response.wait()
|
||||
|
||||
return TransactionBuilder.createTransactionEntity(txId: txId, rawTransaction: rawTx)
|
||||
} catch {
|
||||
throw error.mapToServiceError()
|
||||
}
|
||||
}
|
||||
|
||||
public func latestBlockHeight() throws -> BlockHeight {
|
||||
guard let height = try? latestBlock().compactBlockHeight() else {
|
||||
throw LightWalletServiceError.timeOut
|
||||
}
|
||||
return height
|
||||
}
|
||||
|
||||
public func fetchUTXOs(for tAddress: String, height: BlockHeight) throws -> [UnspentTransactionOutputEntity] {
|
||||
let arg = GetAddressUtxosArg.with { utxoArgs in
|
||||
utxoArgs.addresses = [tAddress]
|
||||
|
@ -383,7 +267,168 @@ extension LightWalletGRPCService: LightWalletService {
|
|||
}
|
||||
}
|
||||
|
||||
public func fetchUTXOs(for tAddress: String, height: BlockHeight, result: @escaping (Result<[UnspentTransactionOutputEntity], LightWalletServiceError>) -> Void) {
|
||||
public func fetchUTXOs(for tAddresses: [String], height: BlockHeight) throws -> [UnspentTransactionOutputEntity] {
|
||||
guard !tAddresses.isEmpty else {
|
||||
return [] // FIXME: throw a real error
|
||||
}
|
||||
|
||||
var utxos: [UnspentTransactionOutputEntity] = []
|
||||
|
||||
let arg = GetAddressUtxosArg.with { utxoArgs in
|
||||
utxoArgs.addresses = tAddresses
|
||||
utxoArgs.startHeight = UInt64(height)
|
||||
}
|
||||
utxos.append(
|
||||
contentsOf:
|
||||
try self.compactTxStreamer.getAddressUtxos(arg).response.wait().addressUtxos.map { reply in
|
||||
UTXO(
|
||||
id: nil,
|
||||
address: reply.address,
|
||||
prevoutTxId: reply.txid,
|
||||
prevoutIndex: Int(reply.index),
|
||||
script: reply.script,
|
||||
valueZat: Int(reply.valueZat),
|
||||
height: Int(reply.height),
|
||||
spentInTx: nil
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
return utxos
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - LightWalletServiceNonBlockingAPI
|
||||
|
||||
extension LightWalletGRPCService: LightWalletServiceNonBlockingAPI {
|
||||
public func getInfo(result: @escaping (Result<LightWalletdInfo, LightWalletServiceError>) -> Void) {
|
||||
compactTxStreamer.getLightdInfo(Empty()).response.whenComplete { completionResult in
|
||||
switch completionResult {
|
||||
case .success(let info):
|
||||
result(.success(info))
|
||||
case .failure(let error):
|
||||
result(.failure(error.mapToServiceError()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func getInfoAsync() async throws -> LightWalletdInfo {
|
||||
try await compactTxStreamerAsync.getLightdInfo(Empty())
|
||||
}
|
||||
|
||||
public func latestBlockHeight(result: @escaping (Result<BlockHeight, LightWalletServiceError>) -> Void) {
|
||||
let response = compactTxStreamer.getLatestBlock(ChainSpec()).response
|
||||
|
||||
response.whenSuccessBlocking(onto: queue) { blockID in
|
||||
guard let blockHeight = Int(exactly: blockID.height) else {
|
||||
result(.failure(LightWalletServiceError.generalError(message: "error creating blockheight from BlockID \(blockID)")))
|
||||
return
|
||||
}
|
||||
result(.success(blockHeight))
|
||||
}
|
||||
|
||||
response.whenFailureBlocking(onto: queue) { error in
|
||||
result(.failure(error.mapToServiceError()))
|
||||
}
|
||||
}
|
||||
|
||||
public func latestBlockHeightAsync() async throws -> BlockHeight {
|
||||
try await BlockHeight(compactTxStreamerAsync.getLatestBlock(ChainSpec()).height)
|
||||
}
|
||||
|
||||
public func blockRange(_ range: CompactBlockRange, result: @escaping (Result<[ZcashCompactBlock], LightWalletServiceError>) -> Void) {
|
||||
queue.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
var blocks: [CompactBlock] = []
|
||||
let response = self.compactTxStreamer.getBlockRange(range.blockRange(), handler: { blocks.append($0) })
|
||||
|
||||
do {
|
||||
let status = try response.status.wait()
|
||||
switch status.code {
|
||||
case .ok:
|
||||
result(.success(blocks.asZcashCompactBlocks()))
|
||||
|
||||
default:
|
||||
result(.failure(.mapCode(status)))
|
||||
}
|
||||
} catch {
|
||||
result(.failure(error.mapToServiceError()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func blockRange(_ range: CompactBlockRange) -> AsyncThrowingStream<ZcashCompactBlock, Error> {
|
||||
let stream = compactTxStreamerAsync.getBlockRange(range.blockRange())
|
||||
|
||||
return AsyncThrowingStream { continuation in
|
||||
Task {
|
||||
do {
|
||||
for try await block in stream {
|
||||
continuation.yield(ZcashCompactBlock(compactBlock: block))
|
||||
}
|
||||
continuation.finish(throwing: nil)
|
||||
} catch {
|
||||
continuation.finish(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func submit(spendTransaction: Data, result: @escaping (Result<LightWalletServiceResponse, LightWalletServiceError>) -> Void) {
|
||||
do {
|
||||
let transaction = try RawTransaction(serializedData: spendTransaction)
|
||||
let response = self.compactTxStreamer.sendTransaction(transaction).response
|
||||
|
||||
response.whenComplete { responseResult in
|
||||
switch responseResult {
|
||||
case .failure(let error):
|
||||
result(.failure(LightWalletServiceError.sentFailed(error: error)))
|
||||
case .success(let success):
|
||||
result(.success(success))
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
result(.failure(error.mapToServiceError()))
|
||||
}
|
||||
}
|
||||
|
||||
public func submitAsync(spendTransaction: Data) async throws -> LightWalletServiceResponse {
|
||||
do {
|
||||
let transaction = try RawTransaction(serializedData: spendTransaction)
|
||||
return try await compactTxStreamerAsync.sendTransaction(transaction)
|
||||
} catch {
|
||||
throw LightWalletServiceError.sentFailed(error: error)
|
||||
}
|
||||
}
|
||||
|
||||
public func fetchTransaction(txId: Data, result: @escaping (Result<TransactionEntity, LightWalletServiceError>) -> Void) {
|
||||
var txFilter = TxFilter()
|
||||
txFilter.hash = txId
|
||||
|
||||
compactTxStreamer.getTransaction(txFilter).response.whenComplete { response in
|
||||
switch response {
|
||||
case .failure(let error):
|
||||
result(.failure(error.mapToServiceError()))
|
||||
case .success(let rawTx):
|
||||
result(.success(TransactionBuilder.createTransactionEntity(txId: txId, rawTransaction: rawTx)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func fetchTransactionAsync(txId: Data) async throws -> TransactionEntity {
|
||||
var txFilter = TxFilter()
|
||||
txFilter.hash = txId
|
||||
|
||||
let rawTx = try await compactTxStreamerAsync.getTransaction(txFilter)
|
||||
return TransactionBuilder.createTransactionEntity(txId: txId, rawTransaction: rawTx)
|
||||
}
|
||||
|
||||
public func fetchUTXOs(
|
||||
for tAddress: String,
|
||||
height: BlockHeight,
|
||||
result: @escaping (Result<[UnspentTransactionOutputEntity], LightWalletServiceError>
|
||||
) -> Void) {
|
||||
queue.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
let arg = GetAddressUtxosArg.with { utxoArgs in
|
||||
|
@ -420,36 +465,13 @@ extension LightWalletGRPCService: LightWalletService {
|
|||
}
|
||||
}
|
||||
|
||||
public func fetchUTXOs(for tAddresses: [String], height: BlockHeight) throws -> [UnspentTransactionOutputEntity] {
|
||||
guard !tAddresses.isEmpty else {
|
||||
return [] // FIXME: throw a real error
|
||||
}
|
||||
|
||||
var utxos: [UnspentTransactionOutputEntity] = []
|
||||
|
||||
let arg = GetAddressUtxosArg.with { utxoArgs in
|
||||
utxoArgs.addresses = tAddresses
|
||||
utxoArgs.startHeight = UInt64(height)
|
||||
}
|
||||
utxos.append(
|
||||
contentsOf:
|
||||
try self.compactTxStreamer.getAddressUtxos(arg).response.wait().addressUtxos.map { reply in
|
||||
UTXO(
|
||||
id: nil,
|
||||
address: reply.address,
|
||||
prevoutTxId: reply.txid,
|
||||
prevoutIndex: Int(reply.index),
|
||||
script: reply.script,
|
||||
valueZat: Int(reply.valueZat),
|
||||
height: Int(reply.height),
|
||||
spentInTx: nil
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
return utxos
|
||||
public func fetchUTXOs(
|
||||
for tAddress: String,
|
||||
height: BlockHeight
|
||||
) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error> {
|
||||
return fetchUTXOs(for: [tAddress], height: height)
|
||||
}
|
||||
|
||||
|
||||
public func fetchUTXOs(
|
||||
for tAddresses: [String],
|
||||
height: BlockHeight,
|
||||
|
@ -495,6 +517,119 @@ extension LightWalletGRPCService: LightWalletService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func fetchUTXOs(
|
||||
for tAddresses: [String],
|
||||
height: BlockHeight
|
||||
) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error> {
|
||||
guard !tAddresses.isEmpty else {
|
||||
return AsyncThrowingStream { _ in }
|
||||
}
|
||||
|
||||
let args = GetAddressUtxosArg.with { utxoArgs in
|
||||
utxoArgs.addresses = tAddresses
|
||||
utxoArgs.startHeight = UInt64(height)
|
||||
}
|
||||
let stream = compactTxStreamerAsync.getAddressUtxosStream(args)
|
||||
|
||||
return AsyncThrowingStream { continuation in
|
||||
Task {
|
||||
do {
|
||||
for try await reply in stream {
|
||||
continuation.yield(
|
||||
UTXO(
|
||||
id: nil,
|
||||
address: reply.address,
|
||||
prevoutTxId: reply.txid,
|
||||
prevoutIndex: Int(reply.index),
|
||||
script: reply.script,
|
||||
valueZat: Int(reply.valueZat),
|
||||
height: Int(reply.height),
|
||||
spentInTx: nil
|
||||
)
|
||||
)
|
||||
}
|
||||
continuation.finish(throwing: nil)
|
||||
} catch {
|
||||
continuation.finish(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
public func blockStream(
|
||||
startHeight: BlockHeight,
|
||||
endHeight: BlockHeight,
|
||||
result: @escaping (Result<GRPCResult, LightWalletServiceError>) -> Void,
|
||||
handler: @escaping (ZcashCompactBlock) -> Void,
|
||||
progress: @escaping (BlockProgress) -> Void
|
||||
) -> CancellableCall {
|
||||
let future = compactTxStreamer.getBlockRange(
|
||||
BlockRange(
|
||||
startHeight: startHeight,
|
||||
endHeight: endHeight
|
||||
),
|
||||
callOptions: Self.callOptions(timeLimit: self.streamingCallTimeout),
|
||||
handler: { compactBlock in
|
||||
handler(ZcashCompactBlock(compactBlock: compactBlock))
|
||||
progress(
|
||||
BlockProgress(
|
||||
startHeight: startHeight,
|
||||
targetHeight: endHeight,
|
||||
progressHeight: BlockHeight(compactBlock.height)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
future.status.whenComplete { completionResult in
|
||||
switch completionResult {
|
||||
case .success(let status):
|
||||
switch status.code {
|
||||
case .ok:
|
||||
result(.success(GRPCResult.success))
|
||||
default:
|
||||
result(.failure(LightWalletServiceError.mapCode(status)))
|
||||
}
|
||||
case .failure(let error):
|
||||
result(.failure(LightWalletServiceError.genericError(error: error)))
|
||||
}
|
||||
}
|
||||
return future
|
||||
}
|
||||
|
||||
public func blockStream(
|
||||
startHeight: BlockHeight,
|
||||
endHeight: BlockHeight
|
||||
) -> AsyncThrowingStream<ZcashCompactBlock, Error> {
|
||||
let stream = compactTxStreamerAsync.getBlockRange(
|
||||
BlockRange(
|
||||
startHeight: startHeight,
|
||||
endHeight: endHeight
|
||||
),
|
||||
callOptions: Self.callOptions(timeLimit: self.streamingCallTimeout)
|
||||
)
|
||||
|
||||
return AsyncThrowingStream { continuation in
|
||||
Task {
|
||||
do {
|
||||
for try await compactBlock in stream {
|
||||
continuation.yield(ZcashCompactBlock(compactBlock: compactBlock))
|
||||
}
|
||||
continuation.finish(throwing: nil)
|
||||
} catch {
|
||||
continuation.finish(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension LightWalletGRPCService: LightWalletService {
|
||||
public func closeConnection() {
|
||||
_ = channel.close()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Extensions
|
||||
|
|
|
@ -101,49 +101,102 @@ public protocol LightWalletServiceResponse {
|
|||
|
||||
extension SendResponse: LightWalletServiceResponse {}
|
||||
|
||||
public protocol LightWalletService {
|
||||
/**
|
||||
returns the info for this lightwalletd server (blocking)
|
||||
*/
|
||||
/// Blocking API - used for the testing purposes
|
||||
public protocol LightWalletServiceBlockingAPI {
|
||||
/// Returns the info for this lightwalletd server (blocking)
|
||||
func getInfo() throws -> LightWalletdInfo
|
||||
|
||||
/**
|
||||
returns the info for this lightwalletd server
|
||||
*/
|
||||
func getInfo(result: @escaping (Result<LightWalletdInfo, LightWalletServiceError>) -> Void)
|
||||
|
||||
/**
|
||||
Return the latest block height known to the service.
|
||||
|
||||
- Parameter result: a result containing the height or an Error
|
||||
*/
|
||||
func latestBlockHeight(result: @escaping (Result<BlockHeight, LightWalletServiceError>) -> Void)
|
||||
|
||||
/**
|
||||
Return the latest block height known to the service.
|
||||
|
||||
- Parameter result: a result containing the height or an Error
|
||||
*/
|
||||
///
|
||||
/// Return the latest block height known to the service.
|
||||
/// - Parameter result: a result containing the height or an Error
|
||||
func latestBlockHeight() throws -> BlockHeight
|
||||
|
||||
/**
|
||||
Return the given range of blocks.
|
||||
|
||||
- Parameter range: the inclusive range to fetch.
|
||||
For instance if 1..5 is given, then every block in that will be fetched, including 1 and 5.
|
||||
Non blocking
|
||||
*/
|
||||
func blockRange(_ range: CompactBlockRange, result: @escaping (Result<[ZcashCompactBlock], LightWalletServiceError>) -> Void )
|
||||
|
||||
/**
|
||||
Return the given range of blocks.
|
||||
|
||||
- Parameter range: the inclusive range to fetch.
|
||||
For instance if 1..5 is given, then every block in that will be fetched, including 1 and 5.
|
||||
blocking
|
||||
*/
|
||||
/// Return the given range of blocks.
|
||||
///
|
||||
/// - Parameter range: the inclusive range to fetch.
|
||||
/// For instance if 1..5 is given, then every block in that will be fetched, including 1 and 5.
|
||||
func blockRange(_ range: CompactBlockRange) throws -> [ZcashCompactBlock]
|
||||
|
||||
|
||||
/// Submits a raw transaction over lightwalletd. Blocking
|
||||
/// - Parameter spendTransaction: data representing the transaction to be sent
|
||||
/// - Throws: LightWalletServiceError
|
||||
/// - Returns: LightWalletServiceResponse
|
||||
func submit(spendTransaction: Data) throws -> LightWalletServiceResponse
|
||||
|
||||
/// Gets a transaction by id
|
||||
/// - Parameter txId: data representing the transaction ID
|
||||
/// - Throws: LightWalletServiceError
|
||||
/// - Returns: LightWalletServiceResponse
|
||||
func fetchTransaction(txId: Data) throws -> TransactionEntity
|
||||
|
||||
func fetchUTXOs(
|
||||
for tAddress: String,
|
||||
height: BlockHeight
|
||||
) throws -> [UnspentTransactionOutputEntity]
|
||||
|
||||
func fetchUTXOs(
|
||||
for tAddresses: [String],
|
||||
height: BlockHeight
|
||||
) throws -> [UnspentTransactionOutputEntity]
|
||||
}
|
||||
|
||||
public protocol LightWalletServiceNonBlockingAPI {
|
||||
/// Returns the info for this lightwalletd server
|
||||
@available(*, deprecated, message: "This function will be removed soon. Use the `getInfoAsync()` instead.")
|
||||
func getInfo(result: @escaping (Result<LightWalletdInfo, LightWalletServiceError>) -> Void)
|
||||
func getInfoAsync() async throws -> LightWalletdInfo
|
||||
|
||||
///
|
||||
/// Return the latest block height known to the service.
|
||||
/// - Parameter result: a result containing the height or an Error
|
||||
@available(*, deprecated, message: "This function will be removed soon. Use the `latestBlockHeightAsync()` instead.")
|
||||
func latestBlockHeight(result: @escaping (Result<BlockHeight, LightWalletServiceError>) -> Void)
|
||||
func latestBlockHeightAsync() async throws -> BlockHeight
|
||||
|
||||
/// Return the given range of blocks.
|
||||
/// - Parameter range: the inclusive range to fetch.
|
||||
/// For instance if 1..5 is given, then every block in that will be fetched, including 1 and 5.
|
||||
@available(*, deprecated, message: "This function will be removed soon. Use the `blockRange(...) -> AsyncThrowingStream<ZcashCompactBlock, Error>` instead.")
|
||||
func blockRange(_ range: CompactBlockRange, result: @escaping (Result<[ZcashCompactBlock], LightWalletServiceError>) -> Void)
|
||||
func blockRange(_ range: CompactBlockRange) -> AsyncThrowingStream<ZcashCompactBlock, Error>
|
||||
|
||||
/// Submits a raw transaction over lightwalletd. Non-Blocking
|
||||
/// - Parameter spendTransaction: data representing the transaction to be sent
|
||||
/// - Parameter result: escaping closure that takes a result containing either LightWalletServiceResponse or LightWalletServiceError
|
||||
@available(*, deprecated, message: "This function will be removed soon. Use the `submitAsync(spendTransaction: Data)` instead.")
|
||||
func submit(spendTransaction: Data, result: @escaping(Result<LightWalletServiceResponse, LightWalletServiceError>) -> Void)
|
||||
func submitAsync(spendTransaction: Data) async throws -> LightWalletServiceResponse
|
||||
|
||||
/// Gets a transaction by id
|
||||
/// - Parameter txId: data representing the transaction ID
|
||||
/// - Parameter result: handler for the result
|
||||
/// - Throws: LightWalletServiceError
|
||||
/// - Returns: LightWalletServiceResponse
|
||||
@available(*, deprecated, message: "This function will be removed soon. Use the `fetchTransactionAsync(txId: Data)` instead.")
|
||||
func fetchTransaction(
|
||||
txId: Data,
|
||||
result: @escaping (Result<TransactionEntity, LightWalletServiceError>) -> Void
|
||||
)
|
||||
func fetchTransactionAsync(txId: Data) async throws -> TransactionEntity
|
||||
|
||||
@available(*, deprecated, message: "This function will be removed soon. Use the `fetchUTXOs(for tAddress:...) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error>` instead.")
|
||||
func fetchUTXOs(
|
||||
for tAddress: String,
|
||||
height: BlockHeight,
|
||||
result: @escaping(Result<[UnspentTransactionOutputEntity], LightWalletServiceError>) -> Void
|
||||
)
|
||||
func fetchUTXOs(for tAddress: String, height: BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error>
|
||||
|
||||
@available(*, deprecated, message: "This function will be removed soon. Use the `fetchUTXOs(for tAddresses:...) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error>` instead.")
|
||||
func fetchUTXOs(
|
||||
for tAddresses: [String],
|
||||
height: BlockHeight,
|
||||
result: @escaping(Result<[UnspentTransactionOutputEntity], LightWalletServiceError>) -> Void
|
||||
)
|
||||
func fetchUTXOs(for tAddresses: [String], height: BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error>
|
||||
|
||||
@available(*, deprecated, message: "This function will be removed soon. Use the `blockStream(...) -> AsyncThrowingStream<ZcashCompactBlock, Error>` instead.")
|
||||
@discardableResult
|
||||
func blockStream(
|
||||
startHeight: BlockHeight,
|
||||
|
@ -153,62 +206,12 @@ public protocol LightWalletService {
|
|||
progress: @escaping (BlockProgress) -> Void
|
||||
) -> CancellableCall
|
||||
|
||||
/**
|
||||
Submits a raw transaction over lightwalletd. Non-Blocking
|
||||
- Parameter spendTransaction: data representing the transaction to be sent
|
||||
- Parameter result: escaping closure that takes a result containing either LightWalletServiceResponse or LightWalletServiceError
|
||||
*/
|
||||
func submit(spendTransaction: Data, result: @escaping(Result<LightWalletServiceResponse, LightWalletServiceError>) -> Void)
|
||||
|
||||
/**
|
||||
Submits a raw transaction over lightwalletd. Blocking
|
||||
- Parameter spendTransaction: data representing the transaction to be sent
|
||||
- Throws: LightWalletServiceError
|
||||
- Returns: LightWalletServiceResponse
|
||||
*/
|
||||
func submit(spendTransaction: Data) throws -> LightWalletServiceResponse
|
||||
|
||||
/**
|
||||
Gets a transaction by id
|
||||
- Parameter txId: data representing the transaction ID
|
||||
- Throws: LightWalletServiceError
|
||||
- Returns: LightWalletServiceResponse
|
||||
*/
|
||||
func fetchTransaction(txId: Data) throws -> TransactionEntity
|
||||
|
||||
/**
|
||||
Gets a transaction by id
|
||||
- Parameter txId: data representing the transaction ID
|
||||
- Parameter result: handler for the result
|
||||
- Throws: LightWalletServiceError
|
||||
- Returns: LightWalletServiceResponse
|
||||
*/
|
||||
func fetchTransaction(
|
||||
txId: Data,
|
||||
result: @escaping (Result<TransactionEntity, LightWalletServiceError>) -> Void
|
||||
)
|
||||
|
||||
func fetchUTXOs(
|
||||
for tAddress: String,
|
||||
height: BlockHeight
|
||||
) throws -> [UnspentTransactionOutputEntity]
|
||||
|
||||
func fetchUTXOs(
|
||||
for tAddress: String,
|
||||
height: BlockHeight,
|
||||
result: @escaping(Result<[UnspentTransactionOutputEntity], LightWalletServiceError>) -> Void
|
||||
)
|
||||
|
||||
func fetchUTXOs(
|
||||
for tAddresses: [String],
|
||||
height: BlockHeight
|
||||
) throws -> [UnspentTransactionOutputEntity]
|
||||
|
||||
func fetchUTXOs(
|
||||
for tAddresses: [String],
|
||||
height: BlockHeight,
|
||||
result: @escaping(Result<[UnspentTransactionOutputEntity], LightWalletServiceError>) -> Void
|
||||
)
|
||||
|
||||
func blockStream(
|
||||
startHeight: BlockHeight,
|
||||
endHeight: BlockHeight
|
||||
) -> AsyncThrowingStream<ZcashCompactBlock, Error>
|
||||
}
|
||||
|
||||
public protocol LightWalletService: LightWalletServiceNonBlockingAPI, LightWalletServiceBlockingAPI {
|
||||
func closeConnection()
|
||||
}
|
||||
|
|
|
@ -22,11 +22,15 @@
|
|||
//
|
||||
import GRPC
|
||||
import NIO
|
||||
import NIOConcurrencyHelpers
|
||||
import SwiftProtobuf
|
||||
|
||||
|
||||
/// Usage: instantiate CompactTxStreamerClient, then call methods of this protocol to make API calls.
|
||||
/// Usage: instantiate `CompactTxStreamerClient`, then call methods of this protocol to make API calls.
|
||||
internal protocol CompactTxStreamerClientProtocol: GRPCClient {
|
||||
var serviceName: String { get }
|
||||
var interceptors: CompactTxStreamerClientInterceptorFactoryProtocol? { get }
|
||||
|
||||
func getLatestBlock(
|
||||
_ request: ChainSpec,
|
||||
callOptions: CallOptions?
|
||||
|
@ -99,10 +103,12 @@ internal protocol CompactTxStreamerClientProtocol: GRPCClient {
|
|||
_ request: Duration,
|
||||
callOptions: CallOptions?
|
||||
) -> UnaryCall<Duration, PingResponse>
|
||||
|
||||
}
|
||||
|
||||
extension CompactTxStreamerClientProtocol {
|
||||
internal var serviceName: String {
|
||||
return "cash.z.wallet.sdk.rpc.CompactTxStreamer"
|
||||
}
|
||||
|
||||
/// Return the height of the tip of the best chain
|
||||
///
|
||||
|
@ -115,9 +121,10 @@ extension CompactTxStreamerClientProtocol {
|
|||
callOptions: CallOptions? = nil
|
||||
) -> UnaryCall<ChainSpec, BlockID> {
|
||||
return self.makeUnaryCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLatestBlock",
|
||||
path: CompactTxStreamerClientMetadata.Methods.getLatestBlock.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetLatestBlockInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -132,9 +139,10 @@ extension CompactTxStreamerClientProtocol {
|
|||
callOptions: CallOptions? = nil
|
||||
) -> UnaryCall<BlockID, CompactBlock> {
|
||||
return self.makeUnaryCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlock",
|
||||
path: CompactTxStreamerClientMetadata.Methods.getBlock.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetBlockInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -151,9 +159,10 @@ extension CompactTxStreamerClientProtocol {
|
|||
handler: @escaping (CompactBlock) -> Void
|
||||
) -> ServerStreamingCall<BlockRange, CompactBlock> {
|
||||
return self.makeServerStreamingCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlockRange",
|
||||
path: CompactTxStreamerClientMetadata.Methods.getBlockRange.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetBlockRangeInterceptors() ?? [],
|
||||
handler: handler
|
||||
)
|
||||
}
|
||||
|
@ -169,9 +178,10 @@ extension CompactTxStreamerClientProtocol {
|
|||
callOptions: CallOptions? = nil
|
||||
) -> UnaryCall<TxFilter, RawTransaction> {
|
||||
return self.makeUnaryCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTransaction",
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTransaction.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTransactionInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -186,9 +196,10 @@ extension CompactTxStreamerClientProtocol {
|
|||
callOptions: CallOptions? = nil
|
||||
) -> UnaryCall<RawTransaction, SendResponse> {
|
||||
return self.makeUnaryCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/SendTransaction",
|
||||
path: CompactTxStreamerClientMetadata.Methods.sendTransaction.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeSendTransactionInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -205,9 +216,10 @@ extension CompactTxStreamerClientProtocol {
|
|||
handler: @escaping (RawTransaction) -> Void
|
||||
) -> ServerStreamingCall<TransparentAddressBlockFilter, RawTransaction> {
|
||||
return self.makeServerStreamingCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTaddressTxids",
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTaddressTxids.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTaddressTxidsInterceptors() ?? [],
|
||||
handler: handler
|
||||
)
|
||||
}
|
||||
|
@ -223,9 +235,10 @@ extension CompactTxStreamerClientProtocol {
|
|||
callOptions: CallOptions? = nil
|
||||
) -> UnaryCall<AddressList, Balance> {
|
||||
return self.makeUnaryCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTaddressBalance",
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTaddressBalance.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTaddressBalanceInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -241,8 +254,9 @@ extension CompactTxStreamerClientProtocol {
|
|||
callOptions: CallOptions? = nil
|
||||
) -> ClientStreamingCall<Address, Balance> {
|
||||
return self.makeClientStreamingCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTaddressBalanceStream",
|
||||
callOptions: callOptions ?? self.defaultCallOptions
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTaddressBalanceStream.path,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTaddressBalanceStreamInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -267,9 +281,10 @@ extension CompactTxStreamerClientProtocol {
|
|||
handler: @escaping (CompactTx) -> Void
|
||||
) -> ServerStreamingCall<Exclude, CompactTx> {
|
||||
return self.makeServerStreamingCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetMempoolTx",
|
||||
path: CompactTxStreamerClientMetadata.Methods.getMempoolTx.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetMempoolTxInterceptors() ?? [],
|
||||
handler: handler
|
||||
)
|
||||
}
|
||||
|
@ -288,9 +303,10 @@ extension CompactTxStreamerClientProtocol {
|
|||
callOptions: CallOptions? = nil
|
||||
) -> UnaryCall<BlockID, TreeState> {
|
||||
return self.makeUnaryCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTreeState",
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTreeState.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTreeStateInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -305,9 +321,10 @@ extension CompactTxStreamerClientProtocol {
|
|||
callOptions: CallOptions? = nil
|
||||
) -> UnaryCall<GetAddressUtxosArg, GetAddressUtxosReplyList> {
|
||||
return self.makeUnaryCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetAddressUtxos",
|
||||
path: CompactTxStreamerClientMetadata.Methods.getAddressUtxos.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetAddressUtxosInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -324,9 +341,10 @@ extension CompactTxStreamerClientProtocol {
|
|||
handler: @escaping (GetAddressUtxosReply) -> Void
|
||||
) -> ServerStreamingCall<GetAddressUtxosArg, GetAddressUtxosReply> {
|
||||
return self.makeServerStreamingCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetAddressUtxosStream",
|
||||
path: CompactTxStreamerClientMetadata.Methods.getAddressUtxosStream.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetAddressUtxosStreamInterceptors() ?? [],
|
||||
handler: handler
|
||||
)
|
||||
}
|
||||
|
@ -342,9 +360,10 @@ extension CompactTxStreamerClientProtocol {
|
|||
callOptions: CallOptions? = nil
|
||||
) -> UnaryCall<Empty, LightdInfo> {
|
||||
return self.makeUnaryCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLightdInfo",
|
||||
path: CompactTxStreamerClientMetadata.Methods.getLightdInfo.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetLightdInfoInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -359,25 +378,679 @@ extension CompactTxStreamerClientProtocol {
|
|||
callOptions: CallOptions? = nil
|
||||
) -> UnaryCall<Duration, PingResponse> {
|
||||
return self.makeUnaryCall(
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/Ping",
|
||||
path: CompactTxStreamerClientMetadata.Methods.ping.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makePingInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#if compiler(>=5.6)
|
||||
@available(*, deprecated)
|
||||
extension CompactTxStreamerClient: @unchecked Sendable {}
|
||||
#endif // compiler(>=5.6)
|
||||
|
||||
@available(*, deprecated, renamed: "CompactTxStreamerNIOClient")
|
||||
internal final class CompactTxStreamerClient: CompactTxStreamerClientProtocol {
|
||||
private let lock = Lock()
|
||||
private var _defaultCallOptions: CallOptions
|
||||
private var _interceptors: CompactTxStreamerClientInterceptorFactoryProtocol?
|
||||
internal let channel: GRPCChannel
|
||||
internal var defaultCallOptions: CallOptions
|
||||
internal var defaultCallOptions: CallOptions {
|
||||
get { self.lock.withLock { return self._defaultCallOptions } }
|
||||
set { self.lock.withLockVoid { self._defaultCallOptions = newValue } }
|
||||
}
|
||||
internal var interceptors: CompactTxStreamerClientInterceptorFactoryProtocol? {
|
||||
get { self.lock.withLock { return self._interceptors } }
|
||||
set { self.lock.withLockVoid { self._interceptors = newValue } }
|
||||
}
|
||||
|
||||
/// Creates a client for the cash.z.wallet.sdk.rpc.CompactTxStreamer service.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - channel: `GRPCChannel` to the service host.
|
||||
/// - defaultCallOptions: Options to use for each service call if the user doesn't provide them.
|
||||
internal init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) {
|
||||
/// - interceptors: A factory providing interceptors for each RPC.
|
||||
internal init(
|
||||
channel: GRPCChannel,
|
||||
defaultCallOptions: CallOptions = CallOptions(),
|
||||
interceptors: CompactTxStreamerClientInterceptorFactoryProtocol? = nil
|
||||
) {
|
||||
self.channel = channel
|
||||
self.defaultCallOptions = defaultCallOptions
|
||||
self._defaultCallOptions = defaultCallOptions
|
||||
self._interceptors = interceptors
|
||||
}
|
||||
}
|
||||
|
||||
internal struct CompactTxStreamerNIOClient: CompactTxStreamerClientProtocol {
|
||||
internal var channel: GRPCChannel
|
||||
internal var defaultCallOptions: CallOptions
|
||||
internal var interceptors: CompactTxStreamerClientInterceptorFactoryProtocol?
|
||||
|
||||
/// Creates a client for the cash.z.wallet.sdk.rpc.CompactTxStreamer service.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - channel: `GRPCChannel` to the service host.
|
||||
/// - defaultCallOptions: Options to use for each service call if the user doesn't provide them.
|
||||
/// - interceptors: A factory providing interceptors for each RPC.
|
||||
internal init(
|
||||
channel: GRPCChannel,
|
||||
defaultCallOptions: CallOptions = CallOptions(),
|
||||
interceptors: CompactTxStreamerClientInterceptorFactoryProtocol? = nil
|
||||
) {
|
||||
self.channel = channel
|
||||
self.defaultCallOptions = defaultCallOptions
|
||||
self.interceptors = interceptors
|
||||
}
|
||||
}
|
||||
|
||||
#if compiler(>=5.6)
|
||||
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|
||||
internal protocol CompactTxStreamerAsyncClientProtocol: GRPCClient {
|
||||
static var serviceDescriptor: GRPCServiceDescriptor { get }
|
||||
var interceptors: CompactTxStreamerClientInterceptorFactoryProtocol? { get }
|
||||
|
||||
func makeGetLatestBlockCall(
|
||||
_ request: ChainSpec,
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncUnaryCall<ChainSpec, BlockID>
|
||||
|
||||
func makeGetBlockCall(
|
||||
_ request: BlockID,
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncUnaryCall<BlockID, CompactBlock>
|
||||
|
||||
func makeGetBlockRangeCall(
|
||||
_ request: BlockRange,
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncServerStreamingCall<BlockRange, CompactBlock>
|
||||
|
||||
func makeGetTransactionCall(
|
||||
_ request: TxFilter,
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncUnaryCall<TxFilter, RawTransaction>
|
||||
|
||||
func makeSendTransactionCall(
|
||||
_ request: RawTransaction,
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncUnaryCall<RawTransaction, SendResponse>
|
||||
|
||||
func makeGetTaddressTxidsCall(
|
||||
_ request: TransparentAddressBlockFilter,
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncServerStreamingCall<TransparentAddressBlockFilter, RawTransaction>
|
||||
|
||||
func makeGetTaddressBalanceCall(
|
||||
_ request: AddressList,
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncUnaryCall<AddressList, Balance>
|
||||
|
||||
func makeGetTaddressBalanceStreamCall(
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncClientStreamingCall<Address, Balance>
|
||||
|
||||
func makeGetMempoolTxCall(
|
||||
_ request: Exclude,
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncServerStreamingCall<Exclude, CompactTx>
|
||||
|
||||
func makeGetTreeStateCall(
|
||||
_ request: BlockID,
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncUnaryCall<BlockID, TreeState>
|
||||
|
||||
func makeGetAddressUtxosCall(
|
||||
_ request: GetAddressUtxosArg,
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncUnaryCall<GetAddressUtxosArg, GetAddressUtxosReplyList>
|
||||
|
||||
func makeGetAddressUtxosStreamCall(
|
||||
_ request: GetAddressUtxosArg,
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncServerStreamingCall<GetAddressUtxosArg, GetAddressUtxosReply>
|
||||
|
||||
func makeGetLightdInfoCall(
|
||||
_ request: Empty,
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncUnaryCall<Empty, LightdInfo>
|
||||
|
||||
func makePingCall(
|
||||
_ request: Duration,
|
||||
callOptions: CallOptions?
|
||||
) -> GRPCAsyncUnaryCall<Duration, PingResponse>
|
||||
}
|
||||
|
||||
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|
||||
extension CompactTxStreamerAsyncClientProtocol {
|
||||
internal static var serviceDescriptor: GRPCServiceDescriptor {
|
||||
return CompactTxStreamerClientMetadata.serviceDescriptor
|
||||
}
|
||||
|
||||
internal var interceptors: CompactTxStreamerClientInterceptorFactoryProtocol? {
|
||||
return nil
|
||||
}
|
||||
|
||||
internal func makeGetLatestBlockCall(
|
||||
_ request: ChainSpec,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncUnaryCall<ChainSpec, BlockID> {
|
||||
return self.makeAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getLatestBlock.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetLatestBlockInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func makeGetBlockCall(
|
||||
_ request: BlockID,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncUnaryCall<BlockID, CompactBlock> {
|
||||
return self.makeAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getBlock.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetBlockInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func makeGetBlockRangeCall(
|
||||
_ request: BlockRange,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncServerStreamingCall<BlockRange, CompactBlock> {
|
||||
return self.makeAsyncServerStreamingCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getBlockRange.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetBlockRangeInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func makeGetTransactionCall(
|
||||
_ request: TxFilter,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncUnaryCall<TxFilter, RawTransaction> {
|
||||
return self.makeAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTransaction.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTransactionInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func makeSendTransactionCall(
|
||||
_ request: RawTransaction,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncUnaryCall<RawTransaction, SendResponse> {
|
||||
return self.makeAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.sendTransaction.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeSendTransactionInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func makeGetTaddressTxidsCall(
|
||||
_ request: TransparentAddressBlockFilter,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncServerStreamingCall<TransparentAddressBlockFilter, RawTransaction> {
|
||||
return self.makeAsyncServerStreamingCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTaddressTxids.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTaddressTxidsInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func makeGetTaddressBalanceCall(
|
||||
_ request: AddressList,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncUnaryCall<AddressList, Balance> {
|
||||
return self.makeAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTaddressBalance.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTaddressBalanceInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func makeGetTaddressBalanceStreamCall(
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncClientStreamingCall<Address, Balance> {
|
||||
return self.makeAsyncClientStreamingCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTaddressBalanceStream.path,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTaddressBalanceStreamInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func makeGetMempoolTxCall(
|
||||
_ request: Exclude,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncServerStreamingCall<Exclude, CompactTx> {
|
||||
return self.makeAsyncServerStreamingCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getMempoolTx.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetMempoolTxInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func makeGetTreeStateCall(
|
||||
_ request: BlockID,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncUnaryCall<BlockID, TreeState> {
|
||||
return self.makeAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTreeState.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTreeStateInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func makeGetAddressUtxosCall(
|
||||
_ request: GetAddressUtxosArg,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncUnaryCall<GetAddressUtxosArg, GetAddressUtxosReplyList> {
|
||||
return self.makeAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getAddressUtxos.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetAddressUtxosInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func makeGetAddressUtxosStreamCall(
|
||||
_ request: GetAddressUtxosArg,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncServerStreamingCall<GetAddressUtxosArg, GetAddressUtxosReply> {
|
||||
return self.makeAsyncServerStreamingCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getAddressUtxosStream.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetAddressUtxosStreamInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func makeGetLightdInfoCall(
|
||||
_ request: Empty,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncUnaryCall<Empty, LightdInfo> {
|
||||
return self.makeAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getLightdInfo.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetLightdInfoInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func makePingCall(
|
||||
_ request: Duration,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncUnaryCall<Duration, PingResponse> {
|
||||
return self.makeAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.ping.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makePingInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|
||||
extension CompactTxStreamerAsyncClientProtocol {
|
||||
internal func getLatestBlock(
|
||||
_ request: ChainSpec,
|
||||
callOptions: CallOptions? = nil
|
||||
) async throws -> BlockID {
|
||||
return try await self.performAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getLatestBlock.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetLatestBlockInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func getBlock(
|
||||
_ request: BlockID,
|
||||
callOptions: CallOptions? = nil
|
||||
) async throws -> CompactBlock {
|
||||
return try await self.performAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getBlock.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetBlockInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func getBlockRange(
|
||||
_ request: BlockRange,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncResponseStream<CompactBlock> {
|
||||
return self.performAsyncServerStreamingCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getBlockRange.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetBlockRangeInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func getTransaction(
|
||||
_ request: TxFilter,
|
||||
callOptions: CallOptions? = nil
|
||||
) async throws -> RawTransaction {
|
||||
return try await self.performAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTransaction.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTransactionInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func sendTransaction(
|
||||
_ request: RawTransaction,
|
||||
callOptions: CallOptions? = nil
|
||||
) async throws -> SendResponse {
|
||||
return try await self.performAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.sendTransaction.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeSendTransactionInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func getTaddressTxids(
|
||||
_ request: TransparentAddressBlockFilter,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncResponseStream<RawTransaction> {
|
||||
return self.performAsyncServerStreamingCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTaddressTxids.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTaddressTxidsInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func getTaddressBalance(
|
||||
_ request: AddressList,
|
||||
callOptions: CallOptions? = nil
|
||||
) async throws -> Balance {
|
||||
return try await self.performAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTaddressBalance.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTaddressBalanceInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func getTaddressBalanceStream<RequestStream>(
|
||||
_ requests: RequestStream,
|
||||
callOptions: CallOptions? = nil
|
||||
) async throws -> Balance where RequestStream: Sequence, RequestStream.Element == Address {
|
||||
return try await self.performAsyncClientStreamingCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTaddressBalanceStream.path,
|
||||
requests: requests,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTaddressBalanceStreamInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func getTaddressBalanceStream<RequestStream>(
|
||||
_ requests: RequestStream,
|
||||
callOptions: CallOptions? = nil
|
||||
) async throws -> Balance where RequestStream: AsyncSequence & Sendable, RequestStream.Element == Address {
|
||||
return try await self.performAsyncClientStreamingCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTaddressBalanceStream.path,
|
||||
requests: requests,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTaddressBalanceStreamInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func getMempoolTx(
|
||||
_ request: Exclude,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncResponseStream<CompactTx> {
|
||||
return self.performAsyncServerStreamingCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getMempoolTx.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetMempoolTxInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func getTreeState(
|
||||
_ request: BlockID,
|
||||
callOptions: CallOptions? = nil
|
||||
) async throws -> TreeState {
|
||||
return try await self.performAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getTreeState.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetTreeStateInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func getAddressUtxos(
|
||||
_ request: GetAddressUtxosArg,
|
||||
callOptions: CallOptions? = nil
|
||||
) async throws -> GetAddressUtxosReplyList {
|
||||
return try await self.performAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getAddressUtxos.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetAddressUtxosInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func getAddressUtxosStream(
|
||||
_ request: GetAddressUtxosArg,
|
||||
callOptions: CallOptions? = nil
|
||||
) -> GRPCAsyncResponseStream<GetAddressUtxosReply> {
|
||||
return self.performAsyncServerStreamingCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getAddressUtxosStream.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetAddressUtxosStreamInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func getLightdInfo(
|
||||
_ request: Empty,
|
||||
callOptions: CallOptions? = nil
|
||||
) async throws -> LightdInfo {
|
||||
return try await self.performAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.getLightdInfo.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makeGetLightdInfoInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
|
||||
internal func ping(
|
||||
_ request: Duration,
|
||||
callOptions: CallOptions? = nil
|
||||
) async throws -> PingResponse {
|
||||
return try await self.performAsyncUnaryCall(
|
||||
path: CompactTxStreamerClientMetadata.Methods.ping.path,
|
||||
request: request,
|
||||
callOptions: callOptions ?? self.defaultCallOptions,
|
||||
interceptors: self.interceptors?.makePingInterceptors() ?? []
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|
||||
internal struct CompactTxStreamerAsyncClient: CompactTxStreamerAsyncClientProtocol {
|
||||
internal var channel: GRPCChannel
|
||||
internal var defaultCallOptions: CallOptions
|
||||
internal var interceptors: CompactTxStreamerClientInterceptorFactoryProtocol?
|
||||
|
||||
internal init(
|
||||
channel: GRPCChannel,
|
||||
defaultCallOptions: CallOptions = CallOptions(),
|
||||
interceptors: CompactTxStreamerClientInterceptorFactoryProtocol? = nil
|
||||
) {
|
||||
self.channel = channel
|
||||
self.defaultCallOptions = defaultCallOptions
|
||||
self.interceptors = interceptors
|
||||
}
|
||||
}
|
||||
|
||||
#endif // compiler(>=5.6)
|
||||
|
||||
internal protocol CompactTxStreamerClientInterceptorFactoryProtocol: GRPCSendable {
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'getLatestBlock'.
|
||||
func makeGetLatestBlockInterceptors() -> [ClientInterceptor<ChainSpec, BlockID>]
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'getBlock'.
|
||||
func makeGetBlockInterceptors() -> [ClientInterceptor<BlockID, CompactBlock>]
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'getBlockRange'.
|
||||
func makeGetBlockRangeInterceptors() -> [ClientInterceptor<BlockRange, CompactBlock>]
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'getTransaction'.
|
||||
func makeGetTransactionInterceptors() -> [ClientInterceptor<TxFilter, RawTransaction>]
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'sendTransaction'.
|
||||
func makeSendTransactionInterceptors() -> [ClientInterceptor<RawTransaction, SendResponse>]
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'getTaddressTxids'.
|
||||
func makeGetTaddressTxidsInterceptors() -> [ClientInterceptor<TransparentAddressBlockFilter, RawTransaction>]
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'getTaddressBalance'.
|
||||
func makeGetTaddressBalanceInterceptors() -> [ClientInterceptor<AddressList, Balance>]
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'getTaddressBalanceStream'.
|
||||
func makeGetTaddressBalanceStreamInterceptors() -> [ClientInterceptor<Address, Balance>]
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'getMempoolTx'.
|
||||
func makeGetMempoolTxInterceptors() -> [ClientInterceptor<Exclude, CompactTx>]
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'getTreeState'.
|
||||
func makeGetTreeStateInterceptors() -> [ClientInterceptor<BlockID, TreeState>]
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'getAddressUtxos'.
|
||||
func makeGetAddressUtxosInterceptors() -> [ClientInterceptor<GetAddressUtxosArg, GetAddressUtxosReplyList>]
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'getAddressUtxosStream'.
|
||||
func makeGetAddressUtxosStreamInterceptors() -> [ClientInterceptor<GetAddressUtxosArg, GetAddressUtxosReply>]
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'getLightdInfo'.
|
||||
func makeGetLightdInfoInterceptors() -> [ClientInterceptor<Empty, LightdInfo>]
|
||||
|
||||
/// - Returns: Interceptors to use when invoking 'ping'.
|
||||
func makePingInterceptors() -> [ClientInterceptor<Duration, PingResponse>]
|
||||
}
|
||||
|
||||
internal enum CompactTxStreamerClientMetadata {
|
||||
internal static let serviceDescriptor = GRPCServiceDescriptor(
|
||||
name: "CompactTxStreamer",
|
||||
fullName: "cash.z.wallet.sdk.rpc.CompactTxStreamer",
|
||||
methods: [
|
||||
CompactTxStreamerClientMetadata.Methods.getLatestBlock,
|
||||
CompactTxStreamerClientMetadata.Methods.getBlock,
|
||||
CompactTxStreamerClientMetadata.Methods.getBlockRange,
|
||||
CompactTxStreamerClientMetadata.Methods.getTransaction,
|
||||
CompactTxStreamerClientMetadata.Methods.sendTransaction,
|
||||
CompactTxStreamerClientMetadata.Methods.getTaddressTxids,
|
||||
CompactTxStreamerClientMetadata.Methods.getTaddressBalance,
|
||||
CompactTxStreamerClientMetadata.Methods.getTaddressBalanceStream,
|
||||
CompactTxStreamerClientMetadata.Methods.getMempoolTx,
|
||||
CompactTxStreamerClientMetadata.Methods.getTreeState,
|
||||
CompactTxStreamerClientMetadata.Methods.getAddressUtxos,
|
||||
CompactTxStreamerClientMetadata.Methods.getAddressUtxosStream,
|
||||
CompactTxStreamerClientMetadata.Methods.getLightdInfo,
|
||||
CompactTxStreamerClientMetadata.Methods.ping,
|
||||
]
|
||||
)
|
||||
|
||||
internal enum Methods {
|
||||
internal static let getLatestBlock = GRPCMethodDescriptor(
|
||||
name: "GetLatestBlock",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLatestBlock",
|
||||
type: GRPCCallType.unary
|
||||
)
|
||||
|
||||
internal static let getBlock = GRPCMethodDescriptor(
|
||||
name: "GetBlock",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlock",
|
||||
type: GRPCCallType.unary
|
||||
)
|
||||
|
||||
internal static let getBlockRange = GRPCMethodDescriptor(
|
||||
name: "GetBlockRange",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlockRange",
|
||||
type: GRPCCallType.serverStreaming
|
||||
)
|
||||
|
||||
internal static let getTransaction = GRPCMethodDescriptor(
|
||||
name: "GetTransaction",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTransaction",
|
||||
type: GRPCCallType.unary
|
||||
)
|
||||
|
||||
internal static let sendTransaction = GRPCMethodDescriptor(
|
||||
name: "SendTransaction",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/SendTransaction",
|
||||
type: GRPCCallType.unary
|
||||
)
|
||||
|
||||
internal static let getTaddressTxids = GRPCMethodDescriptor(
|
||||
name: "GetTaddressTxids",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTaddressTxids",
|
||||
type: GRPCCallType.serverStreaming
|
||||
)
|
||||
|
||||
internal static let getTaddressBalance = GRPCMethodDescriptor(
|
||||
name: "GetTaddressBalance",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTaddressBalance",
|
||||
type: GRPCCallType.unary
|
||||
)
|
||||
|
||||
internal static let getTaddressBalanceStream = GRPCMethodDescriptor(
|
||||
name: "GetTaddressBalanceStream",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTaddressBalanceStream",
|
||||
type: GRPCCallType.clientStreaming
|
||||
)
|
||||
|
||||
internal static let getMempoolTx = GRPCMethodDescriptor(
|
||||
name: "GetMempoolTx",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetMempoolTx",
|
||||
type: GRPCCallType.serverStreaming
|
||||
)
|
||||
|
||||
internal static let getTreeState = GRPCMethodDescriptor(
|
||||
name: "GetTreeState",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTreeState",
|
||||
type: GRPCCallType.unary
|
||||
)
|
||||
|
||||
internal static let getAddressUtxos = GRPCMethodDescriptor(
|
||||
name: "GetAddressUtxos",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetAddressUtxos",
|
||||
type: GRPCCallType.unary
|
||||
)
|
||||
|
||||
internal static let getAddressUtxosStream = GRPCMethodDescriptor(
|
||||
name: "GetAddressUtxosStream",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetAddressUtxosStream",
|
||||
type: GRPCCallType.serverStreaming
|
||||
)
|
||||
|
||||
internal static let getLightdInfo = GRPCMethodDescriptor(
|
||||
name: "GetLightdInfo",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLightdInfo",
|
||||
type: GRPCCallType.unary
|
||||
)
|
||||
|
||||
internal static let ping = GRPCMethodDescriptor(
|
||||
name: "Ping",
|
||||
path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/Ping",
|
||||
type: GRPCCallType.unary
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ struct BlockID {
|
|||
|
||||
var height: UInt64 = 0
|
||||
|
||||
var hash: Data = SwiftProtobuf.Internal.emptyData
|
||||
var hash: Data = Data()
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
|
@ -95,7 +95,7 @@ struct TxFilter {
|
|||
var index: UInt64 = 0
|
||||
|
||||
/// transaction ID (hash, txid)
|
||||
var hash: Data = SwiftProtobuf.Internal.emptyData
|
||||
var hash: Data = Data()
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
|
@ -112,7 +112,7 @@ struct RawTransaction {
|
|||
// methods supported on all messages.
|
||||
|
||||
/// exact data returned by Zcash 'getrawtransaction'
|
||||
var data: Data = SwiftProtobuf.Internal.emptyData
|
||||
var data: Data = Data()
|
||||
|
||||
/// height that the transaction was mined (or -1)
|
||||
var height: UInt64 = 0
|
||||
|
@ -367,11 +367,11 @@ struct GetAddressUtxosReply {
|
|||
|
||||
var address: String = String()
|
||||
|
||||
var txid: Data = SwiftProtobuf.Internal.emptyData
|
||||
var txid: Data = Data()
|
||||
|
||||
var index: Int32 = 0
|
||||
|
||||
var script: Data = SwiftProtobuf.Internal.emptyData
|
||||
var script: Data = Data()
|
||||
|
||||
var valueZat: Int64 = 0
|
||||
|
||||
|
@ -394,6 +394,28 @@ struct GetAddressUtxosReplyList {
|
|||
init() {}
|
||||
}
|
||||
|
||||
#if swift(>=5.5) && canImport(_Concurrency)
|
||||
extension BlockID: @unchecked Sendable {}
|
||||
extension BlockRange: @unchecked Sendable {}
|
||||
extension TxFilter: @unchecked Sendable {}
|
||||
extension RawTransaction: @unchecked Sendable {}
|
||||
extension SendResponse: @unchecked Sendable {}
|
||||
extension ChainSpec: @unchecked Sendable {}
|
||||
extension Empty: @unchecked Sendable {}
|
||||
extension LightdInfo: @unchecked Sendable {}
|
||||
extension TransparentAddressBlockFilter: @unchecked Sendable {}
|
||||
extension Duration: @unchecked Sendable {}
|
||||
extension PingResponse: @unchecked Sendable {}
|
||||
extension Address: @unchecked Sendable {}
|
||||
extension AddressList: @unchecked Sendable {}
|
||||
extension Balance: @unchecked Sendable {}
|
||||
extension Exclude: @unchecked Sendable {}
|
||||
extension TreeState: @unchecked Sendable {}
|
||||
extension GetAddressUtxosArg: @unchecked Sendable {}
|
||||
extension GetAddressUtxosReply: @unchecked Sendable {}
|
||||
extension GetAddressUtxosReplyList: @unchecked Sendable {}
|
||||
#endif // swift(>=5.5) && canImport(_Concurrency)
|
||||
|
||||
// MARK: - Code below here is support for the SwiftProtobuf runtime.
|
||||
|
||||
fileprivate let _protobuf_package = "cash.z.wallet.sdk.rpc"
|
||||
|
@ -407,9 +429,12 @@ extension BlockID: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularUInt64Field(value: &self.height)
|
||||
case 2: try decoder.decodeSingularBytesField(value: &self.hash)
|
||||
case 1: try { try decoder.decodeSingularUInt64Field(value: &self.height) }()
|
||||
case 2: try { try decoder.decodeSingularBytesField(value: &self.hash) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -442,21 +467,28 @@ extension BlockRange: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularMessageField(value: &self._start)
|
||||
case 2: try decoder.decodeSingularMessageField(value: &self._end)
|
||||
case 1: try { try decoder.decodeSingularMessageField(value: &self._start) }()
|
||||
case 2: try { try decoder.decodeSingularMessageField(value: &self._end) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if let v = self._start {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._start {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
|
||||
}
|
||||
if let v = self._end {
|
||||
} }()
|
||||
try { if let v = self._end {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
|
||||
}
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
|
@ -478,19 +510,26 @@ extension TxFilter: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularMessageField(value: &self._block)
|
||||
case 2: try decoder.decodeSingularUInt64Field(value: &self.index)
|
||||
case 3: try decoder.decodeSingularBytesField(value: &self.hash)
|
||||
case 1: try { try decoder.decodeSingularMessageField(value: &self._block) }()
|
||||
case 2: try { try decoder.decodeSingularUInt64Field(value: &self.index) }()
|
||||
case 3: try { try decoder.decodeSingularBytesField(value: &self.hash) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if let v = self._block {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._block {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
|
||||
}
|
||||
} }()
|
||||
if self.index != 0 {
|
||||
try visitor.visitSingularUInt64Field(value: self.index, fieldNumber: 2)
|
||||
}
|
||||
|
@ -518,9 +557,12 @@ extension RawTransaction: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularBytesField(value: &self.data)
|
||||
case 2: try decoder.decodeSingularUInt64Field(value: &self.height)
|
||||
case 1: try { try decoder.decodeSingularBytesField(value: &self.data) }()
|
||||
case 2: try { try decoder.decodeSingularUInt64Field(value: &self.height) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -553,9 +595,12 @@ extension SendResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularInt32Field(value: &self.errorCode)
|
||||
case 2: try decoder.decodeSingularStringField(value: &self.errorMessage)
|
||||
case 1: try { try decoder.decodeSingularInt32Field(value: &self.errorCode) }()
|
||||
case 2: try { try decoder.decodeSingularStringField(value: &self.errorMessage) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -638,21 +683,24 @@ extension LightdInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularStringField(value: &self.version)
|
||||
case 2: try decoder.decodeSingularStringField(value: &self.vendor)
|
||||
case 3: try decoder.decodeSingularBoolField(value: &self.taddrSupport)
|
||||
case 4: try decoder.decodeSingularStringField(value: &self.chainName)
|
||||
case 5: try decoder.decodeSingularUInt64Field(value: &self.saplingActivationHeight)
|
||||
case 6: try decoder.decodeSingularStringField(value: &self.consensusBranchID)
|
||||
case 7: try decoder.decodeSingularUInt64Field(value: &self.blockHeight)
|
||||
case 8: try decoder.decodeSingularStringField(value: &self.gitCommit)
|
||||
case 9: try decoder.decodeSingularStringField(value: &self.branch)
|
||||
case 10: try decoder.decodeSingularStringField(value: &self.buildDate)
|
||||
case 11: try decoder.decodeSingularStringField(value: &self.buildUser)
|
||||
case 12: try decoder.decodeSingularUInt64Field(value: &self.estimatedHeight)
|
||||
case 13: try decoder.decodeSingularStringField(value: &self.zcashdBuild)
|
||||
case 14: try decoder.decodeSingularStringField(value: &self.zcashdSubversion)
|
||||
case 1: try { try decoder.decodeSingularStringField(value: &self.version) }()
|
||||
case 2: try { try decoder.decodeSingularStringField(value: &self.vendor) }()
|
||||
case 3: try { try decoder.decodeSingularBoolField(value: &self.taddrSupport) }()
|
||||
case 4: try { try decoder.decodeSingularStringField(value: &self.chainName) }()
|
||||
case 5: try { try decoder.decodeSingularUInt64Field(value: &self.saplingActivationHeight) }()
|
||||
case 6: try { try decoder.decodeSingularStringField(value: &self.consensusBranchID) }()
|
||||
case 7: try { try decoder.decodeSingularUInt64Field(value: &self.blockHeight) }()
|
||||
case 8: try { try decoder.decodeSingularStringField(value: &self.gitCommit) }()
|
||||
case 9: try { try decoder.decodeSingularStringField(value: &self.branch) }()
|
||||
case 10: try { try decoder.decodeSingularStringField(value: &self.buildDate) }()
|
||||
case 11: try { try decoder.decodeSingularStringField(value: &self.buildUser) }()
|
||||
case 12: try { try decoder.decodeSingularUInt64Field(value: &self.estimatedHeight) }()
|
||||
case 13: try { try decoder.decodeSingularStringField(value: &self.zcashdBuild) }()
|
||||
case 14: try { try decoder.decodeSingularStringField(value: &self.zcashdSubversion) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -733,21 +781,28 @@ extension TransparentAddressBlockFilter: SwiftProtobuf.Message, SwiftProtobuf._M
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularStringField(value: &self.address)
|
||||
case 2: try decoder.decodeSingularMessageField(value: &self._range)
|
||||
case 1: try { try decoder.decodeSingularStringField(value: &self.address) }()
|
||||
case 2: try { try decoder.decodeSingularMessageField(value: &self._range) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
if !self.address.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.address, fieldNumber: 1)
|
||||
}
|
||||
if let v = self._range {
|
||||
try { if let v = self._range {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
|
||||
}
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
|
@ -767,8 +822,11 @@ extension Duration: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularInt64Field(value: &self.intervalUs)
|
||||
case 1: try { try decoder.decodeSingularInt64Field(value: &self.intervalUs) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -797,9 +855,12 @@ extension PingResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularInt64Field(value: &self.entry)
|
||||
case 2: try decoder.decodeSingularInt64Field(value: &self.exit)
|
||||
case 1: try { try decoder.decodeSingularInt64Field(value: &self.entry) }()
|
||||
case 2: try { try decoder.decodeSingularInt64Field(value: &self.exit) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -831,8 +892,11 @@ extension Address: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularStringField(value: &self.address)
|
||||
case 1: try { try decoder.decodeSingularStringField(value: &self.address) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -860,8 +924,11 @@ extension AddressList: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeRepeatedStringField(value: &self.addresses)
|
||||
case 1: try { try decoder.decodeRepeatedStringField(value: &self.addresses) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -889,8 +956,11 @@ extension Balance: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularInt64Field(value: &self.valueZat)
|
||||
case 1: try { try decoder.decodeSingularInt64Field(value: &self.valueZat) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -918,8 +988,11 @@ extension Exclude: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeRepeatedBytesField(value: &self.txid)
|
||||
case 1: try { try decoder.decodeRepeatedBytesField(value: &self.txid) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -951,12 +1024,15 @@ extension TreeState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularStringField(value: &self.network)
|
||||
case 2: try decoder.decodeSingularUInt64Field(value: &self.height)
|
||||
case 3: try decoder.decodeSingularStringField(value: &self.hash)
|
||||
case 4: try decoder.decodeSingularUInt32Field(value: &self.time)
|
||||
case 5: try decoder.decodeSingularStringField(value: &self.tree)
|
||||
case 1: try { try decoder.decodeSingularStringField(value: &self.network) }()
|
||||
case 2: try { try decoder.decodeSingularUInt64Field(value: &self.height) }()
|
||||
case 3: try { try decoder.decodeSingularStringField(value: &self.hash) }()
|
||||
case 4: try { try decoder.decodeSingularUInt32Field(value: &self.time) }()
|
||||
case 5: try { try decoder.decodeSingularStringField(value: &self.tree) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -1002,10 +1078,13 @@ extension GetAddressUtxosArg: SwiftProtobuf.Message, SwiftProtobuf._MessageImple
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeRepeatedStringField(value: &self.addresses)
|
||||
case 2: try decoder.decodeSingularUInt64Field(value: &self.startHeight)
|
||||
case 3: try decoder.decodeSingularUInt32Field(value: &self.maxEntries)
|
||||
case 1: try { try decoder.decodeRepeatedStringField(value: &self.addresses) }()
|
||||
case 2: try { try decoder.decodeSingularUInt64Field(value: &self.startHeight) }()
|
||||
case 3: try { try decoder.decodeSingularUInt32Field(value: &self.maxEntries) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -1046,13 +1125,16 @@ extension GetAddressUtxosReply: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularBytesField(value: &self.txid)
|
||||
case 2: try decoder.decodeSingularInt32Field(value: &self.index)
|
||||
case 3: try decoder.decodeSingularBytesField(value: &self.script)
|
||||
case 4: try decoder.decodeSingularInt64Field(value: &self.valueZat)
|
||||
case 5: try decoder.decodeSingularUInt64Field(value: &self.height)
|
||||
case 6: try decoder.decodeSingularStringField(value: &self.address)
|
||||
case 1: try { try decoder.decodeSingularBytesField(value: &self.txid) }()
|
||||
case 2: try { try decoder.decodeSingularInt32Field(value: &self.index) }()
|
||||
case 3: try { try decoder.decodeSingularBytesField(value: &self.script) }()
|
||||
case 4: try { try decoder.decodeSingularInt64Field(value: &self.valueZat) }()
|
||||
case 5: try { try decoder.decodeSingularUInt64Field(value: &self.height) }()
|
||||
case 6: try { try decoder.decodeSingularStringField(value: &self.address) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -1100,8 +1182,11 @@ extension GetAddressUtxosReplyList: SwiftProtobuf.Message, SwiftProtobuf._Messag
|
|||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try decoder.decodeRepeatedMessageField(value: &self.addressUtxos)
|
||||
case 1: try { try decoder.decodeRepeatedMessageField(value: &self.addressUtxos) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,21 @@ class LightWalletServiceTests: XCTestCase {
|
|||
wait(for: [expect], timeout: 10)
|
||||
}
|
||||
|
||||
func testHundredBlocks() async throws {
|
||||
let count = 99
|
||||
let lowerRange: BlockHeight = network.constants.saplingActivationHeight
|
||||
let upperRange: BlockHeight = network.constants.saplingActivationHeight + count
|
||||
let blockRange = lowerRange ... upperRange
|
||||
|
||||
var blocks: [ZcashCompactBlock] = []
|
||||
for try await block in service.blockRange(blockRange) {
|
||||
blocks.append(block)
|
||||
}
|
||||
XCTAssertEqual(blocks.count, blockRange.count)
|
||||
XCTAssertEqual(blocks[0].height, lowerRange)
|
||||
XCTAssertEqual(blocks.last!.height, upperRange)
|
||||
}
|
||||
|
||||
func testSyncBlockRange() {
|
||||
let lowerRange: BlockHeight = network.constants.saplingActivationHeight
|
||||
let upperRange: BlockHeight = network.constants.saplingActivationHeight + 99
|
||||
|
@ -74,6 +89,18 @@ class LightWalletServiceTests: XCTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
func testSyncBlockRange() async throws {
|
||||
let lowerRange: BlockHeight = network.constants.saplingActivationHeight
|
||||
let upperRange: BlockHeight = network.constants.saplingActivationHeight + 99
|
||||
let blockRange = lowerRange ... upperRange
|
||||
|
||||
var blocks: [ZcashCompactBlock] = []
|
||||
for try await block in service.blockRange(blockRange) {
|
||||
blocks.append(block)
|
||||
}
|
||||
XCTAssertEqual(blocks.count, blockRange.count)
|
||||
}
|
||||
|
||||
func testLatestBlock() {
|
||||
let expect = XCTestExpectation(description: self.description)
|
||||
service.latestBlockHeight { result in
|
||||
|
@ -88,4 +115,9 @@ class LightWalletServiceTests: XCTestCase {
|
|||
|
||||
wait(for: [expect], timeout: 10)
|
||||
}
|
||||
|
||||
func testLatestBlock() async throws {
|
||||
let height = try await service.latestBlockHeightAsync()
|
||||
XCTAssertTrue(height > self.network.constants.saplingActivationHeight)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,10 @@ class DarksideWalletService: LightWalletService {
|
|||
)
|
||||
}
|
||||
|
||||
func blockStream(startHeight: BlockHeight, endHeight: BlockHeight) -> AsyncThrowingStream<ZcashCompactBlock, Error> {
|
||||
service.blockStream(startHeight: startHeight, endHeight: endHeight)
|
||||
}
|
||||
|
||||
func getInfo() throws -> LightWalletdInfo {
|
||||
try service.getInfo()
|
||||
}
|
||||
|
@ -87,7 +91,11 @@ class DarksideWalletService: LightWalletService {
|
|||
}
|
||||
|
||||
func fetchUTXOs(for tAddress: String, height: BlockHeight) throws -> [UnspentTransactionOutputEntity] {
|
||||
return []
|
||||
try service.fetchUTXOs(for: tAddress, height: height)
|
||||
}
|
||||
|
||||
func fetchUTXOs(for tAddresses: [String], height: BlockHeight) throws -> [UnspentTransactionOutputEntity] {
|
||||
try service.fetchUTXOs(for: tAddresses, height: height)
|
||||
}
|
||||
|
||||
func fetchUTXOs(
|
||||
|
@ -98,8 +106,8 @@ class DarksideWalletService: LightWalletService {
|
|||
service.fetchUTXOs(for: tAddress, height: height, result: result)
|
||||
}
|
||||
|
||||
func fetchUTXOs(for tAddresses: [String], height: BlockHeight) throws -> [UnspentTransactionOutputEntity] {
|
||||
try service.fetchUTXOs(for: tAddresses, height: height)
|
||||
func fetchUTXOs(for tAddress: String, height: BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error> {
|
||||
service.fetchUTXOs(for: tAddress, height: height)
|
||||
}
|
||||
|
||||
func fetchUTXOs(
|
||||
|
@ -109,7 +117,10 @@ class DarksideWalletService: LightWalletService {
|
|||
) {
|
||||
service.fetchUTXOs(for: tAddresses, height: height, result: result)
|
||||
}
|
||||
|
||||
|
||||
func fetchUTXOs(for tAddresses: [String], height: BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error> {
|
||||
service.fetchUTXOs(for: tAddresses, height: height)
|
||||
}
|
||||
|
||||
func fetchTransaction(txId: Data) throws -> TransactionEntity {
|
||||
try service.fetchTransaction(txId: txId)
|
||||
|
@ -222,6 +233,26 @@ class DarksideWalletService: LightWalletService {
|
|||
func clearAddedUTXOs() throws {
|
||||
_ = try darksideService.clearAddressUtxo(Empty(), callOptions: nil).response.wait()
|
||||
}
|
||||
|
||||
func getInfoAsync() async throws -> LightWalletdInfo {
|
||||
try service.getInfo()
|
||||
}
|
||||
|
||||
func latestBlockHeightAsync() async throws -> BlockHeight {
|
||||
try service.latestBlockHeight()
|
||||
}
|
||||
|
||||
func blockRange(_ range: CompactBlockRange) -> AsyncThrowingStream<ZcashCompactBlock, Error> {
|
||||
service.blockRange(range)
|
||||
}
|
||||
|
||||
func submitAsync(spendTransaction: Data) async throws -> LightWalletServiceResponse {
|
||||
try service.submit(spendTransaction: spendTransaction)
|
||||
}
|
||||
|
||||
func fetchTransactionAsync(txId: Data) async throws -> TransactionEntity {
|
||||
try service.fetchTransaction(txId: txId)
|
||||
}
|
||||
}
|
||||
|
||||
enum DarksideWalletDConstants: NetworkConstants {
|
||||
|
|
|
@ -35,6 +35,10 @@ class MockLightWalletService: LightWalletService {
|
|||
return MockCancellable()
|
||||
}
|
||||
|
||||
func blockStream(startHeight: BlockHeight, endHeight: BlockHeight) -> AsyncThrowingStream<ZcashCompactBlock, Error> {
|
||||
AsyncThrowingStream { _ in }
|
||||
}
|
||||
|
||||
func getInfo() throws -> LightWalletdInfo {
|
||||
guard let info = mockLightDInfo else {
|
||||
throw LightWalletServiceError.generalError(message: "Not Implemented")
|
||||
|
@ -59,28 +63,30 @@ class MockLightWalletService: LightWalletService {
|
|||
[]
|
||||
}
|
||||
|
||||
func fetchUTXOs(for tAddresses: [String], height: BlockHeight) throws -> [UnspentTransactionOutputEntity] {
|
||||
[]
|
||||
}
|
||||
|
||||
func fetchUTXOs(
|
||||
for tAddress: String,
|
||||
height: BlockHeight,
|
||||
result: @escaping (Result<[UnspentTransactionOutputEntity], LightWalletServiceError>) -> Void
|
||||
) {
|
||||
}
|
||||
|
||||
func fetchUTXOs(for tAddresses: [String], height: BlockHeight) throws -> [UnspentTransactionOutputEntity] {
|
||||
[]
|
||||
|
||||
func fetchUTXOs(for tAddress: String, height: BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error> {
|
||||
AsyncThrowingStream { _ in }
|
||||
}
|
||||
|
||||
|
||||
func fetchUTXOs(
|
||||
for tAddresses: [String],
|
||||
height: BlockHeight,
|
||||
result: @escaping (Result<[UnspentTransactionOutputEntity], LightWalletServiceError>) -> Void
|
||||
) {
|
||||
}
|
||||
|
||||
func fetchUTXOs(
|
||||
for tAddress: String,
|
||||
result: @escaping (Result<[UnspentTransactionOutputEntity], LightWalletServiceError>) -> Void
|
||||
) {
|
||||
|
||||
func fetchUTXOs(for tAddresses: [String], height: BlockHeight) -> AsyncThrowingStream<UnspentTransactionOutputEntity, Error> {
|
||||
AsyncThrowingStream { _ in }
|
||||
}
|
||||
|
||||
private var service: LightWalletService
|
||||
|
@ -126,4 +132,35 @@ class MockLightWalletService: LightWalletService {
|
|||
|
||||
func fetchTransaction(txId: Data, result: @escaping (Result<TransactionEntity, LightWalletServiceError>) -> Void) {
|
||||
}
|
||||
|
||||
func getInfoAsync() async throws -> LightWalletdInfo {
|
||||
guard let info = mockLightDInfo else {
|
||||
throw LightWalletServiceError.generalError(message: "Not Implemented")
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
func latestBlockHeightAsync() async throws -> BlockHeight {
|
||||
latestHeight
|
||||
}
|
||||
|
||||
func blockRange(_ range: CompactBlockRange) -> AsyncThrowingStream<ZcashCompactBlock, Error> {
|
||||
service.blockRange(range)
|
||||
}
|
||||
|
||||
func submitAsync(spendTransaction: Data) async throws -> LightWalletServiceResponse {
|
||||
LightWalletServiceMockResponse(errorCode: 0, errorMessage: "", unknownFields: UnknownStorage())
|
||||
}
|
||||
|
||||
func fetchTransactionAsync(txId: Data) async throws -> TransactionEntity {
|
||||
Transaction(id: 1, transactionId: Data(), created: "Today", transactionIndex: 1, expiryHeight: -1, minedHeight: -1, raw: nil)
|
||||
}
|
||||
|
||||
func fetchUTXOsAsync(for tAddress: String, height: BlockHeight) async throws -> [UnspentTransactionOutputEntity] {
|
||||
[]
|
||||
}
|
||||
|
||||
func fetchUTXOsAsync(for tAddresses: [String], height: BlockHeight) async throws -> [UnspentTransactionOutputEntity] {
|
||||
[]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue