Skip to content

Commit

Permalink
Upgrade react-native-zcash
Browse files Browse the repository at this point in the history
  • Loading branch information
peachbits committed Sep 5, 2023
1 parent ffc4357 commit ec16d01
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 95 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
"prettier": "^2.2.0",
"process": "^0.11.10",
"react-native-piratechain": "^0.3.2",
"react-native-zcash": "^0.3.2",
"react-native-zcash": "0.4.0",
"rimraf": "^3.0.2",
"stream-browserify": "^2.0.2",
"stream-http": "^3.2.0",
Expand All @@ -155,6 +155,6 @@
},
"peerDependencies": {
"react-native-piratechain": "^0.3.2",
"react-native-zcash": "^0.3.2"
"react-native-zcash": "^0.4.0"
}
}
23 changes: 10 additions & 13 deletions src/react-native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import {
Synchronizer as PirateSynchronizer
} from 'react-native-piratechain'
import {
AddressTool as ZcashAddressTool,
KeyTool as ZcashKeyTool,
makeSynchronizer as ZcashMakeSynchronizer,
Synchronizer as ZcashSynchronizer
Synchronizer as ZcashSynchronizer,
Tools as ZcashNativeTools
} from 'react-native-zcash'
import { bridgifyObject, emit, onMethod } from 'yaob'

Expand Down Expand Up @@ -79,20 +78,20 @@ const makeZcashSynchronizer = async (
const out: ZcashSynchronizer = bridgifyObject({
// @ts-expect-error
on: onMethod,
start: async () => {
return await realSynchronizer.start()
deriveUnifiedAddress: async () => {
return await realSynchronizer.deriveUnifiedAddress()
},
getTransactions: async blockRange => {
return await realSynchronizer.getTransactions(blockRange)
},
rescan: height => {
return realSynchronizer.rescan(height)
rescan: () => {
return realSynchronizer.rescan()
},
sendToAddress: async spendInfo => {
return await realSynchronizer.sendToAddress(spendInfo)
},
getShieldedBalance: async () => {
return await realSynchronizer.getShieldedBalance()
getBalance: async () => {
return await realSynchronizer.getBalance()
},
stop: async () => {
return await realSynchronizer.stop()
Expand All @@ -104,8 +103,7 @@ const makeZcashSynchronizer = async (
export function makePluginIo(): EdgeOtherMethods {
bridgifyObject(PiratechainKeyTool)
bridgifyObject(PiratechainAddressTool)
bridgifyObject(ZcashKeyTool)
bridgifyObject(ZcashAddressTool)
bridgifyObject(ZcashNativeTools)

return {
async fetchText(uri: string, opts: Object) {
Expand All @@ -128,8 +126,7 @@ export function makePluginIo(): EdgeOtherMethods {
}
}),
zcash: bridgifyObject({
KeyTool: ZcashKeyTool,
AddressTool: ZcashAddressTool,
Tools: ZcashNativeTools,
async makeSynchronizer(config: ZcashInitializerConfig) {
return await makeZcashSynchronizer(config)
}
Expand Down
80 changes: 56 additions & 24 deletions src/zcash/ZcashEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
EdgeCurrencyEngine,
EdgeCurrencyEngineOptions,
EdgeEnginePrivateKeyOptions,
EdgeFreshAddress,
EdgeSpendInfo,
EdgeTransaction,
EdgeWalletInfo,
Expand Down Expand Up @@ -35,18 +36,21 @@ export class ZcashEngine extends CurrencyEngine<
pluginId: string
networkInfo: ZcashNetworkInfo
otherData!: ZcashWalletOtherData
synchronizer!: ZcashSynchronizer
synchronizerStatus!: ZcashSynchronizerStatus
availableZatoshi!: string
initialNumBlocksToDownload!: number
initializer!: ZcashInitializerConfig
alias!: string
progressRatio!: number
queryMutex: boolean
makeSynchronizer: (
config: ZcashInitializerConfig
) => Promise<ZcashSynchronizer>

// Synchronizer management
started: boolean
stopSyncing?: (value: number | PromiseLike<number>) => void
synchronizer?: ZcashSynchronizer

constructor(
env: PluginEnvironment<ZcashNetworkInfo>,
tools: ZcashTools,
Expand All @@ -60,14 +64,16 @@ export class ZcashEngine extends CurrencyEngine<
this.networkInfo = networkInfo
this.makeSynchronizer = makeSynchronizer
this.queryMutex = false

this.started = false
}

setOtherData(raw: any): void {
this.otherData = asZcashWalletOtherData(raw)
}

initData(): void {
const { birthdayHeight, alias } = this.initializer
const { birthdayHeight } = this.initializer

// walletLocalData
if (this.otherData.blockRange.first === 0) {
Expand All @@ -78,14 +84,14 @@ export class ZcashEngine extends CurrencyEngine<
}

// Engine variables
this.alias = alias
this.initialNumBlocksToDownload = -1
this.synchronizerStatus = 'DISCONNECTED'
this.availableZatoshi = '0'
this.progressRatio = 0
}

initSubscriptions(): void {
if (this.synchronizer == null) return
this.synchronizer.on('update', async payload => {
const { lastDownloadedHeight, scanProgress, networkBlockHeight } = payload
this.onUpdateBlockHeight(networkBlockHeight)
Expand Down Expand Up @@ -175,10 +181,8 @@ export class ZcashEngine extends CurrencyEngine<
}

async startEngine(): Promise<void> {
this.initData()
this.synchronizer = await this.makeSynchronizer(this.initializer)
await this.synchronizer.start()
this.initSubscriptions()
this.engineOn = true
this.started = true
await super.startEngine()
}

Expand All @@ -188,9 +192,9 @@ export class ZcashEngine extends CurrencyEngine<
}

async queryBalance(): Promise<void> {
if (!this.isSynced()) return
if (!this.isSynced() || this.synchronizer == null) return
try {
const balances = await this.synchronizer.getShieldedBalance()
const balances = await this.synchronizer.getBalance()
if (balances.totalZatoshi === '-1') return
this.availableZatoshi = balances.availableZatoshi
this.updateBalance(this.currencyInfo.currencyCode, balances.totalZatoshi)
Expand All @@ -201,6 +205,7 @@ export class ZcashEngine extends CurrencyEngine<
}

async queryTransactions(): Promise<void> {
if (this.synchronizer == null) return
try {
let first = this.otherData.blockRange.first
let last = this.otherData.blockRange.last
Expand Down Expand Up @@ -270,8 +275,37 @@ export class ZcashEngine extends CurrencyEngine<
this.addTransaction(this.currencyInfo.currencyCode, edgeTransaction)
}

async syncNetwork(opts: EdgeEnginePrivateKeyOptions): Promise<number> {
if (!this.started) return 1000

const zcashPrivateKeys = asZcashPrivateKeys(this.currencyInfo.pluginId)(
opts?.privateKeys
)

const { rpcNode } = this.networkInfo
this.initializer = {
mnemonicSeed: zcashPrivateKeys.mnemonic,
birthdayHeight: zcashPrivateKeys.birthdayHeight,
alias: this.walletInfo.keys.publicKey.slice(0, 99),
...rpcNode
}

this.synchronizer = await this.makeSynchronizer(this.initializer)
this.initData()
this.initSubscriptions()

return await new Promise(resolve => {
this.stopSyncing = resolve
})
}

async killEngine(): Promise<void> {
await this.synchronizer.stop()
this.started = false
if (this.stopSyncing != null) {
await this.stopSyncing(1000)
this.stopSyncing = undefined
}
await this.synchronizer?.stop()
await super.killEngine()
}

Expand All @@ -285,8 +319,10 @@ export class ZcashEngine extends CurrencyEngine<
await this.clearBlockchainCache()
await this.startEngine()
this.synchronizer
.rescan(this.walletInfo.keys.birthdayHeight)
?.rescan()
.catch((e: any) => this.warn('resyncBlockchain failed: ', e))
this.initData()
this.synchronizerStatus = 'SYNCING'
}

async getMaxSpendable(): Promise<string> {
Expand Down Expand Up @@ -364,6 +400,7 @@ export class ZcashEngine extends CurrencyEngine<
edgeTransaction: EdgeTransaction,
opts?: EdgeEnginePrivateKeyOptions
): Promise<EdgeTransaction> {
if (this.synchronizer == null) throw new Error('Synchronizer undefined')
const zcashPrivateKeys = asZcashPrivateKeys(this.pluginId)(
opts?.privateKeys
)
Expand All @@ -382,7 +419,7 @@ export class ZcashEngine extends CurrencyEngine<
toAddress: spendTarget.publicAddress,
memo: spendTarget.memo ?? spendTarget.uniqueIdentifier ?? '',
fromAccountIndex: 0,
spendingKey: zcashPrivateKeys.spendKey
mnemonicSeed: zcashPrivateKeys.mnemonic
}

try {
Expand All @@ -398,20 +435,15 @@ export class ZcashEngine extends CurrencyEngine<
return edgeTransaction
}

async loadEngine(): Promise<void> {
const { walletInfo } = this
await super.loadEngine()
this.engineOn = true

const { rpcNode } = this.networkInfo
this.initializer = {
fullViewingKey: walletInfo.keys.unifiedViewingKeys,
birthdayHeight: walletInfo.keys.birthdayHeight,
alias: walletInfo.keys.publicKey,
...rpcNode
async getFreshAddress(): Promise<EdgeFreshAddress> {
if (this.synchronizer == null) throw new Error('Synchronizer undefined')
const unifiedAddress = await this.synchronizer.deriveUnifiedAddress()
return {
publicAddress: unifiedAddress
}
}
}

export async function makeCurrencyEngine(
env: PluginEnvironment<ZcashNetworkInfo>,
tools: ZcashTools,
Expand Down
46 changes: 11 additions & 35 deletions src/zcash/ZcashTools.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { div } from 'biggystring'
import { entropyToMnemonic, mnemonicToSeed, validateMnemonic } from 'bip39'
import { entropyToMnemonic, validateMnemonic } from 'bip39'
import { Buffer } from 'buffer'
import {
EdgeCurrencyInfo,
Expand All @@ -12,10 +12,7 @@ import {
EdgeWalletInfo,
JsonObject
} from 'edge-core-js/types'
import {
AddressTool as AddressToolType,
KeyTool as KeyToolType
} from 'react-native-zcash'
import { Tools as ToolsType } from 'react-native-zcash'

import { PluginEnvironment } from '../common/innerPlugin'
import { asIntegerString } from '../common/types'
Expand All @@ -34,9 +31,7 @@ export class ZcashTools implements EdgeCurrencyTools {
currencyInfo: EdgeCurrencyInfo
io: EdgeIo
networkInfo: ZcashNetworkInfo

KeyTool: typeof KeyToolType
AddressTool: typeof AddressToolType
nativeTools: typeof ToolsType

constructor(env: PluginEnvironment<ZcashNetworkInfo>) {
const { builtinTokens, currencyInfo, io, networkInfo } = env
Expand All @@ -51,8 +46,7 @@ export class ZcashTools implements EdgeCurrencyTools {
}
const { Tools } = RNAccountbased.zcash

this.KeyTool = KeyTool
this.AddressTool = AddressTool
this.nativeTools = Tools
}

async getDisplayPrivateKey(
Expand All @@ -65,12 +59,12 @@ export class ZcashTools implements EdgeCurrencyTools {

async getDisplayPublicKey(publicWalletInfo: EdgeWalletInfo): Promise<string> {
const { keys } = asSafeZcashWalletInfo(publicWalletInfo)
return keys.unifiedViewingKeys?.extfvk
return keys.publicKey
}

async getNewWalletBirthdayBlockheight(): Promise<number> {
try {
return await this.KeyTool.getBirthdayHeight(
return await this.nativeTools.getBirthdayHeight(
this.networkInfo.rpcNode.defaultHost,
this.networkInfo.rpcNode.defaultPort
)
Expand All @@ -80,10 +74,7 @@ export class ZcashTools implements EdgeCurrencyTools {
}

async isValidAddress(address: string): Promise<boolean> {
return (
(await this.AddressTool.isValidShieldedAddress(address)) ||
(await this.AddressTool.isValidTransparentAddress(address))
)
return await this.nativeTools.isValidAddress(address)
}

// will actually use MNEMONIC version of private key
Expand All @@ -95,13 +86,6 @@ export class ZcashTools implements EdgeCurrencyTools {
const isValid = validateMnemonic(userInput)
if (!isValid)
throw new Error(`Invalid ${this.currencyInfo.currencyCode} mnemonic`)
const hexBuffer = await mnemonicToSeed(userInput)
const hex = hexBuffer.toString('hex')
const spendKey = await this.KeyTool.deriveSpendingKey(
hex,
this.networkInfo.rpcNode.networkName
)
if (typeof spendKey !== 'string') throw new Error('Invalid spendKey type')

// Get current network height for the birthday height
const currentNetworkHeight = await this.getNewWalletBirthdayBlockheight()
Expand All @@ -122,7 +106,6 @@ export class ZcashTools implements EdgeCurrencyTools {

return {
[`${pluginId}Mnemonic`]: userInput,
[`${pluginId}SpendKey`]: spendKey,
[`${pluginId}BirthdayHeight`]: height
}
}
Expand Down Expand Up @@ -157,21 +140,14 @@ export class ZcashTools implements EdgeCurrencyTools {
if (typeof mnemonic !== 'string') {
throw new Error('InvalidMnemonic')
}
const hexBuffer = await mnemonicToSeed(mnemonic)
const hex = hexBuffer.toString('hex')
const unifiedViewingKeys: UnifiedViewingKey =
await this.KeyTool.deriveViewingKey(
hex,
const unifiedViewingKey: UnifiedViewingKey =
await this.nativeTools.deriveViewingKey(
mnemonic,
this.networkInfo.rpcNode.networkName
)
const shieldedAddress = await this.AddressTool.deriveShieldedAddress(
unifiedViewingKeys.extfvk,
this.networkInfo.rpcNode.networkName
)
return {
birthdayHeight: zcashPrivateKeys.birthdayHeight,
publicKey: shieldedAddress,
unifiedViewingKeys
publicKey: unifiedViewingKey
}
}

Expand Down
1 change: 1 addition & 0 deletions src/zcash/zcashInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const currencyInfo: EdgeCurrencyInfo = {

metaTokens: [], // Deprecated

unsafeSyncNetwork: true,
unsafeBroadcastTx: true
}

Expand Down
Loading

0 comments on commit ec16d01

Please sign in to comment.