SwiftUI Router Setup
This commit is contained in:
parent
52d3b8610a
commit
15ef90cb40
|
@ -7,6 +7,14 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0D170A7226BC802800EB6A46 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D170A7126BC802800EB6A46 /* Router.swift */; };
|
||||
0D1922EA26BDD96A00052649 /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1922E926BDD96A00052649 /* ViewModel.swift */; };
|
||||
0D1922ED26BDE0C600052649 /* AppRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1922EC26BDE0C600052649 /* AppRouter.swift */; };
|
||||
0D1922EF26BDE1A300052649 /* Services.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1922EE26BDE1A300052649 /* Services.swift */; };
|
||||
0D1922F226BDE29300052649 /* ZcashSDKStubs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1922F126BDE29300052649 /* ZcashSDKStubs.swift */; };
|
||||
0D1922F426BDE5F200052649 /* MnemonicSeedPhraseHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1922F326BDE5F200052649 /* MnemonicSeedPhraseHandling.swift */; };
|
||||
0D1922F626BDE74500052649 /* KeyStoring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1922F526BDE74500052649 /* KeyStoring.swift */; };
|
||||
0D1922F826BDEB3500052649 /* MockServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1922F726BDEB3500052649 /* MockServices.swift */; };
|
||||
0D4E7A0926B364170058B01E /* SecantApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4E7A0826B364170058B01E /* SecantApp.swift */; };
|
||||
0D4E7A0B26B364170058B01E /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4E7A0A26B364170058B01E /* ContentView.swift */; };
|
||||
0D4E7A0D26B364180058B01E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0D4E7A0C26B364180058B01E /* Assets.xcassets */; };
|
||||
|
@ -33,6 +41,14 @@
|
|||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0D170A7126BC802800EB6A46 /* Router.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = "<group>"; };
|
||||
0D1922E926BDD96A00052649 /* ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModel.swift; sourceTree = "<group>"; };
|
||||
0D1922EC26BDE0C600052649 /* AppRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppRouter.swift; sourceTree = "<group>"; };
|
||||
0D1922EE26BDE1A300052649 /* Services.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Services.swift; sourceTree = "<group>"; };
|
||||
0D1922F126BDE29300052649 /* ZcashSDKStubs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZcashSDKStubs.swift; sourceTree = "<group>"; };
|
||||
0D1922F326BDE5F200052649 /* MnemonicSeedPhraseHandling.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MnemonicSeedPhraseHandling.swift; sourceTree = "<group>"; };
|
||||
0D1922F526BDE74500052649 /* KeyStoring.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyStoring.swift; sourceTree = "<group>"; };
|
||||
0D1922F726BDEB3500052649 /* MockServices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockServices.swift; sourceTree = "<group>"; };
|
||||
0D4E7A0526B364170058B01E /* secant.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = secant.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0D4E7A0826B364170058B01E /* SecantApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecantApp.swift; sourceTree = "<group>"; };
|
||||
0D4E7A0A26B364170058B01E /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
|
@ -72,6 +88,49 @@
|
|||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
0D170A7326BC802E00EB6A46 /* Routers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0D1922EC26BDE0C600052649 /* AppRouter.swift */,
|
||||
);
|
||||
path = Routers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0D170A7426BC9B7500EB6A46 /* Dependencies */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0D1922F326BDE5F200052649 /* MnemonicSeedPhraseHandling.swift */,
|
||||
0D1922EE26BDE1A300052649 /* Services.swift */,
|
||||
0D1922F526BDE74500052649 /* KeyStoring.swift */,
|
||||
);
|
||||
path = Dependencies;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0D1922E826BDD95000052649 /* Base */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0D170A7126BC802800EB6A46 /* Router.swift */,
|
||||
0D1922E926BDD96A00052649 /* ViewModel.swift */,
|
||||
);
|
||||
path = Base;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0D1922EB26BDD9A500052649 /* Screens */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
path = Screens;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0D1922F026BDE27D00052649 /* Stubs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0D1922F126BDE29300052649 /* ZcashSDKStubs.swift */,
|
||||
0D1922F726BDEB3500052649 /* MockServices.swift */,
|
||||
);
|
||||
path = Stubs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0D4E79FC26B364170058B01E = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -95,11 +154,16 @@
|
|||
0D4E7A0726B364170058B01E /* secant */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0D1922F026BDE27D00052649 /* Stubs */,
|
||||
0D1922EB26BDD9A500052649 /* Screens */,
|
||||
0D1922E826BDD95000052649 /* Base */,
|
||||
0D170A7426BC9B7500EB6A46 /* Dependencies */,
|
||||
0D4E7A0826B364170058B01E /* SecantApp.swift */,
|
||||
0D4E7A0A26B364170058B01E /* ContentView.swift */,
|
||||
0D4E7A0C26B364180058B01E /* Assets.xcassets */,
|
||||
0D4E7A1126B364180058B01E /* Info.plist */,
|
||||
0D4E7A0E26B364180058B01E /* Preview Content */,
|
||||
0D170A7326BC802E00EB6A46 /* Routers */,
|
||||
);
|
||||
path = secant;
|
||||
sourceTree = "<group>";
|
||||
|
@ -259,7 +323,15 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0D1922ED26BDE0C600052649 /* AppRouter.swift in Sources */,
|
||||
0D1922F226BDE29300052649 /* ZcashSDKStubs.swift in Sources */,
|
||||
0D1922EF26BDE1A300052649 /* Services.swift in Sources */,
|
||||
0D1922F826BDEB3500052649 /* MockServices.swift in Sources */,
|
||||
0D4E7A0B26B364170058B01E /* ContentView.swift in Sources */,
|
||||
0D1922F426BDE5F200052649 /* MnemonicSeedPhraseHandling.swift in Sources */,
|
||||
0D170A7226BC802800EB6A46 /* Router.swift in Sources */,
|
||||
0D1922F626BDE74500052649 /* KeyStoring.swift in Sources */,
|
||||
0D1922EA26BDD96A00052649 /* ViewModel.swift in Sources */,
|
||||
0D4E7A0926B364170058B01E /* SecantApp.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// Router.swift
|
||||
// secant
|
||||
//
|
||||
// Created by Francisco Gindre on 8/5/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
public protocol Router: ObservableObject {
|
||||
associatedtype ViewOutput: View
|
||||
|
||||
func rootView() -> ViewOutput
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// ViewModel.swift
|
||||
// secant
|
||||
//
|
||||
// Created by Francisco Gindre on 8/6/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
open class BaseViewModel<S> {
|
||||
|
||||
public var services: S
|
||||
|
||||
public init(services: S) {
|
||||
self.services = services
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
//
|
||||
// AppRouterRouter.swift
|
||||
// secant
|
||||
//
|
||||
// Created by Francisco Gindre on 8/6/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
enum AppRouterScreen {
|
||||
case appLoading
|
||||
case createRestoreWallet
|
||||
case home
|
||||
}
|
||||
|
||||
class AppRouter: Router {
|
||||
|
||||
// MARK: - Published vars
|
||||
@Published var screen: AppRouterScreen = .appLoading
|
||||
|
||||
// MARK: - Private vars
|
||||
|
||||
// MARK: - Internal vars
|
||||
var services: Services
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
init(services: Services) {
|
||||
self.services = services
|
||||
}
|
||||
|
||||
// MARK: - Methods
|
||||
|
||||
@ViewBuilder func rootView() -> some View {
|
||||
// Add your content here
|
||||
NavigationView {
|
||||
AppRouterView(router: self)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder func createNew() -> some View {
|
||||
Text("Create New")
|
||||
}
|
||||
|
||||
@ViewBuilder func home() -> some View {
|
||||
Text("Home Screen")
|
||||
}
|
||||
|
||||
@ViewBuilder func loadingScreen() -> some View {
|
||||
Text("Loading")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct AppRouterView: View {
|
||||
@StateObject var router: AppRouter
|
||||
|
||||
@ViewBuilder func viewForScreen(_ screen: AppRouterScreen) -> some View {
|
||||
switch self.router.screen {
|
||||
case .appLoading:
|
||||
self.router.loadingScreen()
|
||||
case .createRestoreWallet:
|
||||
self.router.createNew()
|
||||
case .home:
|
||||
self.router.home()
|
||||
}
|
||||
}
|
||||
var body: some View {
|
||||
viewForScreen(router.screen)
|
||||
.onAppear() {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
if router.services.keyStorage.keysPresent {
|
||||
router.screen = .home
|
||||
} else {
|
||||
router.screen = .createRestoreWallet
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,9 +9,11 @@ import SwiftUI
|
|||
|
||||
@main
|
||||
struct SecantApp: App {
|
||||
|
||||
@StateObject var appRouter = AppRouter(services: MockAppServices())
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
ContentView()
|
||||
appRouter.rootView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
//
|
||||
// MockServices.swift
|
||||
// secant
|
||||
//
|
||||
// Created by Francisco Gindre on 8/6/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class MockAppServices: Services {
|
||||
init(){}
|
||||
var networkProvider: ZcashNetworkProvider {
|
||||
MockNetworkProvider()
|
||||
}
|
||||
var seedHandler: MnemonicSeedPhraseHandling {
|
||||
MockMnemonicPhraseHandling()
|
||||
}
|
||||
|
||||
var keyStorage: KeyStoring {
|
||||
MockKeyStoring()
|
||||
}
|
||||
}
|
||||
|
||||
class MockNetworkProvider: ZcashNetworkProvider {
|
||||
func currentNetwork() -> ZcashNetwork {
|
||||
ZcashMainnet()
|
||||
}
|
||||
}
|
||||
|
||||
class MockMnemonicPhraseHandling: MnemonicSeedPhraseHandling {
|
||||
|
||||
class TestSeed {
|
||||
|
||||
/**
|
||||
test account: "still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread"
|
||||
*/
|
||||
let seedString = Data(base64Encoded: "9VDVOZZZOWWHpZtq1Ebridp3Qeux5C+HwiRR0g7Oi7HgnMs8Gfln83+/Q1NnvClcaSwM4ADFL1uZHxypEWlWXg==")!
|
||||
|
||||
func seed() -> [UInt8] {
|
||||
[UInt8](seedString)
|
||||
}
|
||||
}
|
||||
|
||||
func randomMnemonic() throws -> String {
|
||||
"still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread"
|
||||
}
|
||||
|
||||
func randomMnemonicWords() throws -> [String] {
|
||||
"still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread".components(separatedBy: " ")
|
||||
}
|
||||
|
||||
func toSeed(mnemonic: String) throws -> [UInt8] {
|
||||
TestSeed().seed()
|
||||
}
|
||||
|
||||
func asWords(mnemonic: String) throws -> [String] {
|
||||
"still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread".components(separatedBy: " ")
|
||||
}
|
||||
|
||||
func isValid(mnemonic: String) throws {}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class MockKeyStoring: KeyStoring {
|
||||
var birthday: BlockHeight?
|
||||
var phrase: String?
|
||||
func importBirthday(_ height: BlockHeight) throws {
|
||||
guard birthday == nil else {
|
||||
throw KeyStoringError.alreadyImported
|
||||
}
|
||||
birthday = height
|
||||
}
|
||||
|
||||
func exportBirthday() throws -> BlockHeight {
|
||||
guard let b = birthday else {
|
||||
throw KeyStoringError.uninitializedWallet
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func importPhrase(bip39 phrase: String) throws {
|
||||
guard self.phrase == nil else {
|
||||
throw KeyStoringError.alreadyImported
|
||||
}
|
||||
self.phrase = phrase
|
||||
}
|
||||
|
||||
func exportPhrase() throws -> String {
|
||||
guard let p = self.phrase else {
|
||||
throw KeyStoringError.uninitializedWallet
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
var keysPresent: Bool {
|
||||
return self.phrase != nil && self.birthday != nil
|
||||
}
|
||||
|
||||
func nukePhrase() {
|
||||
self.phrase = nil
|
||||
}
|
||||
|
||||
func nukeBirthday() {
|
||||
self.birthday = nil
|
||||
}
|
||||
|
||||
func nukeWallet() {
|
||||
nukePhrase()
|
||||
nukeBirthday()
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
//
|
||||
// ZcashSDKStubs.swift
|
||||
// secant
|
||||
//
|
||||
// Created by Francisco Gindre on 8/6/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
public typealias BlockHeight = Int
|
||||
public protocol ZcashNetwork {
|
||||
var networkType: NetworkType { get }
|
||||
var constants: NetworkConstants.Type { get }
|
||||
}
|
||||
|
||||
public enum NetworkType {
|
||||
case mainnet
|
||||
case testnet
|
||||
|
||||
var networkId: UInt32 {
|
||||
switch self {
|
||||
case .mainnet:
|
||||
return 1
|
||||
case .testnet:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension NetworkType {
|
||||
static func forChainName(_ chainame: String) -> NetworkType? {
|
||||
switch chainame {
|
||||
case "test":
|
||||
return .testnet
|
||||
case "main":
|
||||
return .mainnet
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ZcashNetworkBuilder {
|
||||
public static func network(for networkType: NetworkType) -> ZcashNetwork {
|
||||
switch networkType {
|
||||
case .mainnet:
|
||||
return ZcashMainnet()
|
||||
case .testnet:
|
||||
return ZcashTestnet()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ZcashTestnet: ZcashNetwork {
|
||||
var networkType: NetworkType = .testnet
|
||||
var constants: NetworkConstants.Type = ZcashSDKTestnetConstants.self
|
||||
}
|
||||
|
||||
class ZcashMainnet: ZcashNetwork {
|
||||
var networkType: NetworkType = .mainnet
|
||||
var constants: NetworkConstants.Type = ZcashSDKMainnetConstants.self
|
||||
}
|
||||
|
||||
/**
|
||||
Constants of ZcashLightClientKit. this constants don't
|
||||
*/
|
||||
public class ZcashSDK {
|
||||
|
||||
/**
|
||||
The number of zatoshi that equal 1 ZEC.
|
||||
*/
|
||||
public static var ZATOSHI_PER_ZEC: BlockHeight = 100_000_000
|
||||
|
||||
/**
|
||||
The theoretical maximum number of blocks in a reorg, due to other bottlenecks in the protocol design.
|
||||
*/
|
||||
public static var MAX_REORG_SIZE = 100
|
||||
/**
|
||||
The amount of blocks ahead of the current height where new transactions are set to expire. This value is controlled
|
||||
by the rust backend but it is helpful to know what it is set to and should be kept in sync.
|
||||
*/
|
||||
public static var EXPIRY_OFFSET = 20
|
||||
//
|
||||
// Defaults
|
||||
//
|
||||
/**
|
||||
Default size of batches of blocks to request from the compact block service.
|
||||
*/
|
||||
public static var DEFAULT_BATCH_SIZE = 100
|
||||
/**
|
||||
Default amount of time, in in seconds, to poll for new blocks. Typically, this should be about half the average
|
||||
block time.
|
||||
*/
|
||||
public static var DEFAULT_POLL_INTERVAL: TimeInterval = 20
|
||||
/**
|
||||
Default attempts at retrying.
|
||||
*/
|
||||
public static var DEFAULT_RETRIES: Int = 5
|
||||
/**
|
||||
The default maximum amount of time to wait during retry backoff intervals. Failed loops will never wait longer than
|
||||
this before retyring.
|
||||
*/
|
||||
public static var DEFAULT_MAX_BACKOFF_INTERVAL: TimeInterval = 600
|
||||
/**
|
||||
Default number of blocks to rewind when a chain reorg is detected. This should be large enough to recover from the
|
||||
reorg but smaller than the theoretical max reorg size of 100.
|
||||
*/
|
||||
public static var DEFAULT_REWIND_DISTANCE: Int = 10
|
||||
/**
|
||||
The number of blocks to allow before considering our data to be stale. This usually helps with what to do when
|
||||
returning from the background and is exposed via the Synchronizer's isStale function.
|
||||
*/
|
||||
public static var DEFAULT_STALE_TOLERANCE: Int = 10
|
||||
|
||||
/**
|
||||
Default Name for LibRustZcash data.db
|
||||
*/
|
||||
public static var DEFAULT_DATA_DB_NAME = "data.db"
|
||||
|
||||
/**
|
||||
Default Name for Compact Block caches db
|
||||
*/
|
||||
public static var DEFAULT_CACHES_DB_NAME = "caches.db"
|
||||
/**
|
||||
Default name for pending transactions db
|
||||
*/
|
||||
public static var DEFAULT_PENDING_DB_NAME = "pending.db"
|
||||
|
||||
/**
|
||||
File name for the sapling spend params
|
||||
*/
|
||||
public static var SPEND_PARAM_FILE_NAME = "sapling-spend.params"
|
||||
/**
|
||||
File name for the sapling output params
|
||||
*/
|
||||
public static var OUTPUT_PARAM_FILE_NAME = "sapling-output.params"
|
||||
/**
|
||||
The Url that is used by default in zcashd.
|
||||
We'll want to make this externally configurable, rather than baking it into the SDK but
|
||||
this will do for now, since we're using a cloudfront URL that already redirects.
|
||||
*/
|
||||
public static var CLOUD_PARAM_DIR_URL = "https://z.cash/downloads/"
|
||||
}
|
||||
|
||||
public protocol NetworkConstants {
|
||||
|
||||
/**
|
||||
The height of the first sapling block. When it comes to shielded transactions, we do not need to consider any blocks
|
||||
prior to this height, at all.
|
||||
*/
|
||||
static var SAPLING_ACTIVATION_HEIGHT: BlockHeight { get }
|
||||
|
||||
/**
|
||||
Default Name for LibRustZcash data.db
|
||||
*/
|
||||
static var DEFAULT_DATA_DB_NAME: String { get }
|
||||
/**
|
||||
Default Name for Compact Block caches db
|
||||
*/
|
||||
static var DEFAULT_CACHES_DB_NAME: String { get }
|
||||
/**
|
||||
Default name for pending transactions db
|
||||
*/
|
||||
static var DEFAULT_PENDING_DB_NAME: String { get }
|
||||
static var DEFAULT_DB_NAME_PREFIX: String { get }
|
||||
|
||||
/**
|
||||
fixed height where the SDK considers that the ZIP-321 was deployed. This is a workaround
|
||||
for librustzcash not figuring out the tx fee from the tx itself.
|
||||
*/
|
||||
static var FEE_CHANGE_HEIGHT: BlockHeight { get }
|
||||
|
||||
static func defaultFee(for height: BlockHeight) -> Int64
|
||||
|
||||
}
|
||||
|
||||
public extension NetworkConstants {
|
||||
|
||||
static func defaultFee(for height: BlockHeight = BlockHeight.max) -> Int64 {
|
||||
guard height >= FEE_CHANGE_HEIGHT else { return 10_000 }
|
||||
|
||||
return 1_000
|
||||
}
|
||||
}
|
||||
|
||||
public class ZcashSDKMainnetConstants: NetworkConstants {
|
||||
|
||||
private init() {}
|
||||
|
||||
/**
|
||||
The height of the first sapling block. When it comes to shielded transactions, we do not need to consider any blocks
|
||||
prior to this height, at all.
|
||||
*/
|
||||
public static var SAPLING_ACTIVATION_HEIGHT: BlockHeight = 419_200
|
||||
|
||||
/**
|
||||
Default Name for LibRustZcash data.db
|
||||
*/
|
||||
public static var DEFAULT_DATA_DB_NAME = "data.db"
|
||||
/**
|
||||
Default Name for Compact Block caches db
|
||||
*/
|
||||
public static var DEFAULT_CACHES_DB_NAME = "caches.db"
|
||||
/**
|
||||
Default name for pending transactions db
|
||||
*/
|
||||
public static var DEFAULT_PENDING_DB_NAME = "pending.db"
|
||||
|
||||
public static var DEFAULT_DB_NAME_PREFIX = "ZcashSdk_mainnet_"
|
||||
|
||||
public static var FEE_CHANGE_HEIGHT: BlockHeight = 1_077_550
|
||||
}
|
||||
|
||||
public class ZcashSDKTestnetConstants: NetworkConstants {
|
||||
private init() {}
|
||||
|
||||
/**
|
||||
The height of the first sapling block. When it comes to shielded transactions, we do not need to consider any blocks
|
||||
prior to this height, at all.
|
||||
*/
|
||||
public static var SAPLING_ACTIVATION_HEIGHT: BlockHeight = 280_000
|
||||
|
||||
/**
|
||||
Default Name for LibRustZcash data.db
|
||||
*/
|
||||
public static var DEFAULT_DATA_DB_NAME = "data.db"
|
||||
/**
|
||||
Default Name for Compact Block caches db
|
||||
*/
|
||||
public static var DEFAULT_CACHES_DB_NAME = "caches.db"
|
||||
/**
|
||||
Default name for pending transactions db
|
||||
*/
|
||||
public static var DEFAULT_PENDING_DB_NAME = "pending.db"
|
||||
|
||||
public static var DEFAULT_DB_NAME_PREFIX = "ZcashSdk_testnet_"
|
||||
|
||||
/**
|
||||
Estimated height where wallets are supposed to change the fee
|
||||
*/
|
||||
public static var FEE_CHANGE_HEIGHT: BlockHeight = 1_028_500
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
ln -s $PWD/xctemplates ~/Library/Developer/Xcode/Templates
|
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
Kind = "Xcode.IDEFoundation.TextSubstitutionFileTemplateKind";
|
||||
Platforms = (
|
||||
"com.apple.platform.iphoneos",
|
||||
"com.apple.platform.macosx",
|
||||
);
|
||||
Options = (
|
||||
{
|
||||
Description = "The name of the module to create";
|
||||
Identifier = productName;
|
||||
Name = Router;
|
||||
Required = YES;
|
||||
Type = text;
|
||||
Default = Router;
|
||||
},
|
||||
);
|
||||
}
|
31
xctemplates/Router Templates/Router.xctemplate/___FILEBASENAME___Router.swift
vendored
Normal file
31
xctemplates/Router Templates/Router.xctemplate/___FILEBASENAME___Router.swift
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
//___FILEHEADER___
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
class ___FILEBASENAMEASIDENTIFIER___: Router {
|
||||
|
||||
// MARK: - Published vars
|
||||
// Put published vars here
|
||||
|
||||
// MARK: - Private vars
|
||||
|
||||
// MARK: - Internal vars
|
||||
var services: Services
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
init(services: Services) {
|
||||
self.services = services
|
||||
}
|
||||
|
||||
// MARK: - Methods
|
||||
|
||||
func rootView() -> some View {
|
||||
// Add your content here
|
||||
NavigationView {
|
||||
Text("Hello Word")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
Kind = "Xcode.IDEFoundation.TextSubstitutionFileTemplateKind";
|
||||
Platforms = (
|
||||
"com.apple.platform.iphoneos",
|
||||
);
|
||||
Options = (
|
||||
{
|
||||
Description = "The name of the module to create";
|
||||
Identifier = productName;
|
||||
Name = Module;
|
||||
Required = YES;
|
||||
Type = text;
|
||||
Default = Module;
|
||||
},
|
||||
);
|
||||
}
|
22
xctemplates/Router Templates/SwiftUI Screen.xctemplate/___FILEBASENAME___Screen.swift
vendored
Normal file
22
xctemplates/Router Templates/SwiftUI Screen.xctemplate/___FILEBASENAME___Screen.swift
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
//___FILEHEADER___
|
||||
|
||||
import SwiftUI
|
||||
|
||||
protocol ___FILEBASENAMEASIDENTIFIER___Router: AnyObject {
|
||||
}
|
||||
|
||||
struct ___FILEBASENAMEASIDENTIFIER___: View {
|
||||
@State var router: ___FILEBASENAMEASIDENTIFIER___Router?
|
||||
|
||||
@ObservedObject var viewModel: ___FILEBASENAME___ViewModel
|
||||
|
||||
var body: some View {
|
||||
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
|
||||
}
|
||||
}
|
||||
|
||||
struct ___FILEBASENAMEASIDENTIFIER___Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
___FILEBASENAMEASIDENTIFIER___(viewModel: ___FILEBASENAME___ViewModel(services: MockServices()))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
//___FILEHEADER___
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
class ___FILEBASENAMEASIDENTIFIER___: BaseViewModel<Services>, ObservableObject {
|
||||
|
||||
}
|
Loading…
Reference in New Issue