Skip to content

Commit

Permalink
[Electric-Coin-Company#1092] Adopt proposal API
Browse files Browse the repository at this point in the history
- TCA sdkSYnchronizer dependency extended with 3 new Proposal APIs
- proposeTransfer tested, works as expected

[Electric-Coin-Company#1092] Adopt proposal API

- send transaction via new proposal API implemented

[Electric-Coin-Company#1092] Adopt proposal API

- code cleaned up and finished

[Electric-Coin-Company#1092] Adopt proposal API

- unit tests fixed

[Electric-Coin-Company#1092] Adopt proposal API

- Typical Fee < 0.001 localized and updated in the UI
  • Loading branch information
LukasKorba committed Mar 7, 2024
1 parent 6970b6f commit d767f85
Show file tree
Hide file tree
Showing 18 changed files with 224 additions and 111 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ directly impact users rather than highlighting other crucial architectural updat
### Added
- Pending values (changes) at the Balances tab.
- Choose a Server feature: available at settings, pre-defined servers + custom server setup.
- ZIP317: dynamic fees integrated

### Fixed
- Restore mode in the UI was missing when Zashi was deleted from an iPhone and reinstalled again.
Expand Down
2 changes: 1 addition & 1 deletion modules/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ let package = Package(
.package(url: "https://github.com/pointfreeco/swift-case-paths", from: "1.1.0"),
.package(url: "https://github.com/pointfreeco/swift-url-routing", from: "0.6.0"),
.package(url: "https://github.com/zcash-hackworks/MnemonicSwift", from: "2.2.4"),
.package(url: "https://github.com/zcash/ZcashLightClientKit", from: "2.0.10"),
.package(url: "https://github.com/zcash/ZcashLightClientKit", branch: "1204-expose-proposals"),
.package(url: "https://github.com/firebase/firebase-ios-sdk", from: "10.17.0")
],
targets: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,9 @@ public struct SDKSynchronizerClient {
public var wipe: () -> AnyPublisher<Void, Error>?

public var switchToEndpoint: (LightWalletEndpoint) async throws -> Void

// Proposals
public var proposeTransfer: (Int, Recipient, Zatoshi, Memo?) async throws -> Proposal
public var createProposedTransactions: (Proposal, UnifiedSpendingKey) async throws -> AsyncThrowingStream<TransactionSubmitResult, Error>
public var proposeShielding: (Int, Zatoshi, Memo, TransparentAddress?) async throws -> Proposal?
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,28 @@ extension SDKSynchronizerClient: DependencyKey {
wipe: { synchronizer.wipe() },
switchToEndpoint: { endpoint in
try await synchronizer.switchTo(endpoint: endpoint)
},
proposeTransfer: { accountIndex, recipient, amount, memo in
try await synchronizer.proposeTransfer(
accountIndex: accountIndex,
recipient: recipient,
amount: amount,
memo: memo
)
},
createProposedTransactions: { proposal, spendingKey in
try await synchronizer.createProposedTransactions(
proposal: proposal,
spendingKey: spendingKey
)
},
proposeShielding: { accountIndex, shieldingThreshold, memo, transparentReceiver in
try await synchronizer.proposeShielding(
accountIndex: accountIndex,
shieldingThreshold: shieldingThreshold,
memo: memo,
transparentReceiver: transparentReceiver
)
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ extension SDKSynchronizerClient: TestDependencyKey {
sendTransaction: XCTUnimplemented("\(Self.self).sendTransaction", placeholder: .placeholder()),
shieldFunds: XCTUnimplemented("\(Self.self).shieldFunds", placeholder: .placeholder()),
wipe: XCTUnimplemented("\(Self.self).wipe"),
switchToEndpoint: XCTUnimplemented("\(Self.self).switchToEndpoint")
switchToEndpoint: XCTUnimplemented("\(Self.self).switchToEndpoint"),
proposeTransfer: XCTUnimplemented("\(Self.self).proposeTransfer", placeholder: .testOnlyFakeProposal(totalFee: 0)),
createProposedTransactions: XCTUnimplemented("\(Self.self).createProposedTransactions", placeholder: .never),
proposeShielding: XCTUnimplemented("\(Self.self).proposeShielding", placeholder: nil)
)
}

Expand All @@ -52,7 +55,10 @@ extension SDKSynchronizerClient {
sendTransaction: { _, _, _, _ in return .placeholder() },
shieldFunds: { _, _, _ in return .placeholder() },
wipe: { Empty<Void, Error>().eraseToAnyPublisher() },
switchToEndpoint: { _ in }
switchToEndpoint: { _ in },
proposeTransfer: { _, _, _, _ in .testOnlyFakeProposal(totalFee: 0) },
createProposedTransactions: { _, _ in .never },
proposeShielding: { _, _, _, _ in nil }
)

public static let mock = Self.mocked()
Expand Down Expand Up @@ -172,7 +178,13 @@ extension SDKSynchronizerClient {
)
},
wipe: @escaping () -> AnyPublisher<Void, Error>? = { Fail(error: "Error").eraseToAnyPublisher() },
switchToEndpoint: @escaping (LightWalletEndpoint) async throws -> Void = { _ in }
switchToEndpoint: @escaping (LightWalletEndpoint) async throws -> Void = { _ in },
proposeTransfer:
@escaping (Int, Recipient, Zatoshi, Memo?) async throws -> Proposal = { _, _, _, _ in .testOnlyFakeProposal(totalFee: 0) },
createProposedTransactions:
@escaping (Proposal, UnifiedSpendingKey) async throws -> AsyncThrowingStream<TransactionSubmitResult, Error> = { _, _ in .never },
proposeShielding:
@escaping (Int, Zatoshi, Memo, TransparentAddress?) async throws -> Proposal? = { _, _, _, _ in nil }
) -> SDKSynchronizerClient {
SDKSynchronizerClient(
stateStream: stateStream,
Expand All @@ -191,7 +203,10 @@ extension SDKSynchronizerClient {
sendTransaction: sendTransaction,
shieldFunds: shieldFunds,
wipe: wipe,
switchToEndpoint: switchToEndpoint
switchToEndpoint: switchToEndpoint,
proposeTransfer: proposeTransfer,
createProposedTransactions: createProposedTransactions,
proposeShielding: proposeShielding
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,6 @@ public struct ZcashSDKEnvironment {
public let network: ZcashNetwork
public let requiredTransactionConfirmations: Int
public let sdkVersion: String
public let shieldingThreshold: Zatoshi
public let tokenName: String
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ extension ZcashSDKEnvironment {
network: network,
requiredTransactionConfirmations: ZcashSDKConstants.requiredTransactionConfirmations,
sdkVersion: "0.18.1-beta",
shieldingThreshold: Zatoshi(100_000),
tokenName: network.networkType == .testnet ? "TAZ" : "ZEC"
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ extension ZcashSDKEnvironment: TestDependencyKey {
network: ZcashNetworkBuilder.network(for: .testnet),
requiredTransactionConfirmations: ZcashSDKConstants.requiredTransactionConfirmations,
sdkVersion: "0.18.1-beta",
shieldingThreshold: Zatoshi(100_000),
tokenName: "TAZ"
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,11 @@ public struct BalanceBreakdownReducer: Reducer {
case restoreWalletTask
case restoreWalletValue(Bool)
case shieldFunds
case shieldFundsSuccess(TransactionState)
case shieldFundsSuccess
case shieldFundsFailure(ZcashError)
case synchronizerStateChanged(RedactableSynchronizerState)
case syncProgress(SyncProgressReducer.Action)
case transactionSubmitResult(TransactionSubmitResult)
case updateHintBoxVisibility(Bool)
}

Expand Down Expand Up @@ -119,6 +120,7 @@ public struct BalanceBreakdownReducer: Reducer {
return .none

case .onAppear:
state.autoShieldingThreshold = zcashSDKEnvironment.shieldingThreshold
return .publisher {
sdkSynchronizer.stateStream()
.throttle(for: .seconds(0.2), scheduler: mainQueue, latest: true)
Expand All @@ -143,22 +145,30 @@ public struct BalanceBreakdownReducer: Reducer {

case .shieldFunds:
state.isShieldingFunds = true
return .run { [state] send in
return .run { send in
do {
let storedWallet = try walletStorage.exportWallet()
let seedBytes = try mnemonic.toSeed(storedWallet.seedPhrase.value())
let spendingKey = try derivationTool.deriveSpendingKey(seedBytes, 0, zcashSDKEnvironment.network.networkType)

guard let uAddress = try await sdkSynchronizer.getUnifiedAddress(0) else { throw "sdkSynchronizer.getUnifiedAddress" }

let transaction = try await sdkSynchronizer.shieldFunds(spendingKey, Memo(string: ""), state.autoShieldingThreshold)

await send(.shieldFundsSuccess(transaction))
let address = try uAddress.transparentReceiver()
let proposal = try await sdkSynchronizer.proposeShielding(0, zcashSDKEnvironment.shieldingThreshold, .empty, address)

guard let proposal else { throw "sdkSynchronizer.proposeShielding" }

let stream = try await sdkSynchronizer.createProposedTransactions(proposal, spendingKey)

for try await transactionSubmitResult in stream {
await send(.transactionSubmitResult(transactionSubmitResult))
}
} catch {
await send(.shieldFundsFailure(error.toZcashError()))
}
}

case .shieldFundsSuccess:
state.isShieldingFunds = false
state.transparentBalance = .zero
return .none

Expand All @@ -179,6 +189,22 @@ public struct BalanceBreakdownReducer: Reducer {
case .syncProgress:
return .none

case .transactionSubmitResult(let transactionSubmitResult):
switch transactionSubmitResult {
case .success:
state.isShieldingFunds = false
return .send(.shieldFundsSuccess)
case .grpcFailure(txId: _, error: let error):
let zcashError = error.toZcashError()
return .send(.shieldFundsFailure(zcashError))
case let .submitFailure(txId: _, code: code, description: description):
let zcashError = "submitFailure, code(\(code) desc: \(description)".toZcashError()
return .send(.shieldFundsFailure(zcashError))
case .notAttempted(txId: _):
let zcashError = "transactionSubmitResult notAttempted".toZcashError()
return .send(.shieldFundsFailure(zcashError))
}

case .updateHintBoxVisibility(let visibility):
state.isHintBoxVisible = visibility
return .none
Expand All @@ -203,7 +229,7 @@ extension AlertState where Action == BalanceBreakdownReducer.Action {

extension BalanceBreakdownReducer.State {
public static let placeholder = BalanceBreakdownReducer.State(
autoShieldingThreshold: Zatoshi(1_000_000),
autoShieldingThreshold: .zero,
changePending: .zero,
isShieldingFunds: false,
pendingTransactions: .zero,
Expand All @@ -214,7 +240,7 @@ extension BalanceBreakdownReducer.State {
)

public static let initial = BalanceBreakdownReducer.State(
autoShieldingThreshold: Zatoshi(1_000_000),
autoShieldingThreshold: .zero,
changePending: .zero,
isShieldingFunds: false,
pendingTransactions: .zero,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ extension BalanceBreakdownView {
.padding(.bottom, 15)
.disabled(!viewStore.isShieldableBalanceAvailable || viewStore.isShieldingFunds)

Text(L10n.Balances.fee(ZatoshiStringRepresentation.feeFormat))
Text(ZatoshiStringRepresentation.feeFormat)
.font(.custom(FontFamily.Inter.semiBold.name, size: 11))
}
}
Expand Down
Loading

0 comments on commit d767f85

Please sign in to comment.