Skip to content

Commit 6ed9c0f

Browse files
authored
Merge pull request #1008 from PayButton/chore/upgrade-chronik
Chore/upgrade chronik
2 parents 4f867e4 + 788d688 commit 6ed9c0f

6 files changed

Lines changed: 48 additions & 48 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"bitcoinjs-lib": "^6.0.2",
3838
"bs58": "^5.0.0",
3939
"chart.js": "^3.8.0",
40-
"chronik-client-cashtokens": "^0.28.2-alpha",
40+
"chronik-client-cashtokens": "^3.1.1-rc0",
4141
"cors": "^2.8.5",
4242
"cross-env": "^7.0.2",
4343
"dotenv-cli": "^5.1.0",

pages/api/address/balance/[address].ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { parseAddress } from 'utils/validators'
44
import Cors from 'cors'
55
import { runMiddleware, satoshisToUnit } from 'utils/index'
66
import xecaddr from 'xecaddrjs'
7-
import { Prisma } from '@prisma/client'
87
import { multiBlockchainClient } from 'services/chronikService'
98

109
const { ADDRESS_NOT_PROVIDED_400 } = RESPONSE_MESSAGES
@@ -18,7 +17,7 @@ export default async (req: NextApiRequest, res: NextApiResponse): Promise<void>
1817
try {
1918
const address = parseAddress(req.query.address as string)
2019
const response = await multiBlockchainClient.getBalance(address)
21-
const balance = await satoshisToUnit(new Prisma.Decimal(response), xecaddr.detectAddressFormat(address))
20+
const balance = await satoshisToUnit(response, xecaddr.detectAddressFormat(address))
2221
res.status(200).send(balance)
2322
} catch (err: any) {
2423
switch (err.message) {

services/chronikService.ts

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { BlockInfo_InNode, ChronikClientNode, ScriptType_InNode, ScriptUtxo_InNode, Tx_InNode, WsConfig_InNode, WsEndpoint_InNode, WsMsgClient, WsSubScriptClient } from 'chronik-client-cashtokens'
1+
import { BlockInfo, ChronikClient, ScriptType, ScriptUtxo, Tx, WsConfig, WsEndpoint, WsMsgClient, WsSubScriptClient } from 'chronik-client-cashtokens'
22
import { encode, decode } from 'ecashaddrjs'
33
import bs58 from 'bs58'
4-
import { AddressWithTransaction, BlockchainInfo, BlockInfo, TransactionDetails, ProcessedMessages, SubbedAddressesLog, SyncAndSubscriptionReturn, SubscriptionReturn } from 'types/chronikTypes'
4+
import { AddressWithTransaction, BlockchainInfo, TransactionDetails, ProcessedMessages, SubbedAddressesLog, SyncAndSubscriptionReturn, SubscriptionReturn, SimpleBlockInfo } from 'types/chronikTypes'
55
import { CHRONIK_MESSAGE_CACHE_DELAY, RESPONSE_MESSAGES, XEC_TIMESTAMP_THRESHOLD, XEC_NETWORK_ID, BCH_NETWORK_ID, BCH_TIMESTAMP_THRESHOLD, FETCH_DELAY, FETCH_N, KeyValueT, NETWORK_IDS_FROM_SLUGS, SOCKET_MESSAGES, NETWORK_IDS, NETWORK_TICKERS, MainNetworkSlugsType, MAX_MEMPOOL_TXS_TO_PROCESS_AT_A_TIME, MEMPOOL_PROCESS_DELAY, CHRONIK_INITIALIZATION_DELAY } from 'constants/index'
66
import { productionAddresses } from 'prisma/seeds/addresses'
77
import {
@@ -107,10 +107,10 @@ export function getNullDataScriptData (outputScript: string): OpReturnData | nul
107107
}
108108

109109
export class ChronikBlockchainClient {
110-
chronik: ChronikClientNode
110+
chronik: ChronikClient
111111
networkId: number
112112
networkSlug: string
113-
chronikWSEndpoint: WsEndpoint_InNode
113+
chronikWSEndpoint: WsEndpoint
114114
confirmedTxsHashesFromLastBlock: string[]
115115
wsEndpoint: Socket
116116
CHRONIK_MSG_PREFIX: string
@@ -127,7 +127,7 @@ export class ChronikBlockchainClient {
127127
this.mempoolTxsBeingProcessed = 0
128128
this.networkSlug = networkSlug
129129
this.networkId = NETWORK_IDS_FROM_SLUGS[networkSlug]
130-
this.chronik = new ChronikClientNode([config.networkBlockchainURLs[networkSlug]])
130+
this.chronik = new ChronikClient([config.networkBlockchainURLs[networkSlug]])
131131
this.chronikWSEndpoint = this.chronik.ws(this.getWsConfig())
132132
this.confirmedTxsHashesFromLastBlock = []
133133
void this.chronikWSEndpoint.waitForOpen()
@@ -197,14 +197,14 @@ export class ChronikBlockchainClient {
197197
return { height: blockchainInfo.tipHeight, hash: blockchainInfo.tipHash }
198198
}
199199

200-
async getBlockInfo (networkSlug: string, height: number): Promise<BlockInfo> {
200+
async getBlockInfo (networkSlug: string, height: number): Promise<SimpleBlockInfo> {
201201
this.validateNetwork(networkSlug)
202-
const blockInfo: BlockInfo_InNode = (await this.chronik.block(height)).blockInfo
202+
const blockInfo: BlockInfo = (await this.chronik.block(height)).blockInfo
203203
return { hash: blockInfo.hash, height: blockInfo.height, timestamp: blockInfo.timestamp }
204204
}
205205

206206
private txThesholdFilter (address: Address) {
207-
return (t: Tx_InNode, _index: number, _array: Tx_InNode[]): boolean => {
207+
return (t: Tx, _index: number, _array: Tx[]): boolean => {
208208
return (
209209
t.block === undefined ||
210210
(t.block?.timestamp >= XEC_TIMESTAMP_THRESHOLD && address.networkId === XEC_NETWORK_ID) ||
@@ -213,16 +213,16 @@ export class ChronikBlockchainClient {
213213
}
214214
}
215215

216-
private async getTransactionAmountAndData (transaction: Tx_InNode, addressString: string): Promise<{amount: Prisma.Decimal, opReturn: string}> {
217-
let totalOutput = 0
218-
let totalInput = 0
216+
private async getTransactionAmountAndData (transaction: Tx, addressString: string): Promise<{amount: Prisma.Decimal, opReturn: string}> {
217+
let totalOutput = 0n
218+
let totalInput = 0n
219219
const addressFormat = xecaddr.detectAddressFormat(addressString)
220220
const script = toHash160(addressString).hash160
221221
let opReturn = ''
222222

223223
for (const output of transaction.outputs) {
224224
if (output.outputScript.includes(script)) {
225-
totalOutput += output.value
225+
totalOutput += output.sats
226226
}
227227
if (opReturn === '') {
228228
const nullScriptData = getNullDataScriptData(output.outputScript)
@@ -235,17 +235,17 @@ export class ChronikBlockchainClient {
235235
}
236236
for (const input of transaction.inputs) {
237237
if (input?.outputScript?.includes(script) === true) {
238-
totalInput += input.value
238+
totalInput += input.sats
239239
}
240240
}
241-
const satoshis = new Prisma.Decimal(totalOutput).minus(totalInput)
241+
const satoshis = totalOutput - totalInput
242242
return {
243243
amount: await satoshisToUnit(satoshis, addressFormat),
244244
opReturn
245245
}
246246
}
247247

248-
private async getTransactionFromChronikTransaction (transaction: Tx_InNode, address: Address): Promise<Prisma.TransactionUncheckedCreateInput> {
248+
private async getTransactionFromChronikTransaction (transaction: Tx, address: Address): Promise<Prisma.TransactionUncheckedCreateInput> {
249249
const { amount, opReturn } = await this.getTransactionAmountAndData(transaction, address.address)
250250
return {
251251
hash: transaction.txid,
@@ -257,7 +257,7 @@ export class ChronikBlockchainClient {
257257
}
258258
}
259259

260-
public async getPaginatedTxs (addressString: string, page: number, pageSize: number): Promise<Tx_InNode[]> {
260+
public async getPaginatedTxs (addressString: string, page: number, pageSize: number): Promise<Tx[]> {
261261
const { type, hash160 } = toHash160(addressString)
262262
return (await this.chronik.script(type, hash160).history(page, pageSize)).txs
263263
}
@@ -314,15 +314,15 @@ export class ChronikBlockchainClient {
314314
await updateLastSynced(addressString)
315315
}
316316

317-
private async getUtxos (address: string): Promise<ScriptUtxo_InNode[]> {
317+
private async getUtxos (address: string): Promise<ScriptUtxo[]> {
318318
const { type, hash160 } = toHash160(address)
319319
const scriptsUtxos = await this.chronik.script(type, hash160).utxos()
320320
return scriptsUtxos.utxos
321321
}
322322

323-
public async getBalance (address: string): Promise<number> {
323+
public async getBalance (address: string): Promise<bigint> {
324324
const utxos = await this.getUtxos(address)
325-
return utxos.reduce((acc, utxo) => acc + utxo.value, 0)
325+
return utxos.reduce((acc, utxo) => acc + utxo.sats, 0n)
326326
}
327327

328328
async getTransactionDetails (hash: string): Promise<TransactionDetails> {
@@ -341,20 +341,20 @@ export class ChronikBlockchainClient {
341341
}
342342
for (const input of tx.inputs) {
343343
details.inputs.push({
344-
value: new Prisma.Decimal(input.value),
344+
value: input.sats,
345345
address: outputScriptToAddress(this.networkSlug, input.outputScript)
346346
})
347347
}
348348
for (const output of tx.outputs) {
349349
details.outputs.push({
350-
value: new Prisma.Decimal(output.value),
350+
value: output.sats,
351351
address: outputScriptToAddress(this.networkSlug, output.outputScript)
352352
})
353353
}
354354
return details
355355
}
356356

357-
private getWsConfig (): WsConfig_InNode {
357+
private getWsConfig (): WsConfig {
358358
return {
359359
onMessage: (msg: WsMsgClient) => { void this.processWsMessage(msg) },
360360
onError: (e: ws.ErrorEvent) => { console.log(`${this.CHRONIK_MSG_PREFIX}: Chronik webSocket error, type: ${e.type} | message: ${e.message} | error: ${e.error as string}`) },
@@ -365,19 +365,19 @@ export class ChronikBlockchainClient {
365365
}
366366
}
367367

368-
private getSortedInputAddresses (transaction: Tx_InNode): string[] {
369-
const addressValueMap = new Map<string, number>()
368+
private getSortedInputAddresses (transaction: Tx): string[] {
369+
const addressSatsMap = new Map<string, bigint>()
370370

371371
transaction.inputs.forEach((inp) => {
372372
const address = outputScriptToAddress(this.networkSlug, inp.outputScript)
373373
if (address !== undefined && address !== '') {
374-
const currentValue = addressValueMap.get(address) ?? 0
375-
addressValueMap.set(address, currentValue + inp.value)
374+
const currentValue = addressSatsMap.get(address) ?? 0n
375+
addressSatsMap.set(address, currentValue + inp.sats)
376376
}
377377
})
378378

379-
const sortedInputAddresses = Array.from(addressValueMap.entries())
380-
.sort(([, valueA], [, valueB]) => valueB - valueA)
379+
const sortedInputAddresses = Array.from(addressSatsMap.entries())
380+
.sort(([, valueA], [, valueB]) => Number(valueB - valueA))
381381
.map(([address]) => address)
382382

383383
return sortedInputAddresses
@@ -458,7 +458,7 @@ export class ChronikBlockchainClient {
458458
let page = 0
459459
const pageSize = 200
460460
let blockPageTxs = (await this.chronik.blockTxs(blockHash, page, pageSize)).txs
461-
let blockTxsToSync: Tx_InNode[] = []
461+
let blockTxsToSync: Tx[] = []
462462
while (blockPageTxs.length > 0 && blockTxsToSync.length !== this.confirmedTxsHashesFromLastBlock.length) {
463463
const thisBlockTxsToSync = blockPageTxs.filter(tx => this.confirmedTxsHashesFromLastBlock.includes(tx.txid))
464464
blockTxsToSync = [...blockTxsToSync, ...thisBlockTxsToSync]
@@ -481,13 +481,13 @@ export class ChronikBlockchainClient {
481481
}
482482
}
483483

484-
private getRelatedAddressesForTransaction (transaction: Tx_InNode): string[] {
484+
private getRelatedAddressesForTransaction (transaction: Tx): string[] {
485485
const inputAddresses = transaction.inputs.map(inp => outputScriptToAddress(this.networkSlug, inp.outputScript))
486486
const outputAddresses = transaction.outputs.map(out => outputScriptToAddress(this.networkSlug, out.outputScript))
487487
return [...inputAddresses, ...outputAddresses].filter(a => a !== undefined)
488488
}
489489

490-
private async getAddressesForTransaction (transaction: Tx_InNode): Promise<AddressWithTransaction[]> {
490+
private async getAddressesForTransaction (transaction: Tx): Promise<AddressWithTransaction[]> {
491491
const relatedAddresses = this.getRelatedAddressesForTransaction(transaction)
492492
const addressesFromStringArray = await fetchAddressesArray(relatedAddresses)
493493
const addressesWithTransactions: AddressWithTransaction[] = await Promise.all(addressesFromStringArray.map(
@@ -628,14 +628,14 @@ export function fromHash160 (networkSlug: string, type: string, hash160: string)
628628
)
629629
}
630630

631-
export function toHash160 (address: string): {type: ScriptType_InNode, hash160: string} {
631+
export function toHash160 (address: string): {type: ScriptType, hash160: string} {
632632
try {
633633
const { type, hash } = decode(address)
634634
const legacyAdress = bs58.encode(hash)
635635
const addrHash160 = Buffer.from(bs58.decode(legacyAdress)).toString(
636636
'hex'
637637
)
638-
return { type: type.toLowerCase() as ScriptType_InNode, hash160: addrHash160 }
638+
return { type: type.toLowerCase() as ScriptType, hash160: addrHash160 }
639639
} catch (err) {
640640
console.log('[CHRONIK]: Error converting address to hash160')
641641
throw err
@@ -781,7 +781,7 @@ class MultiBlockchainClient {
781781
return await this.clients[networkSlug as MainNetworkSlugsType].getLastBlockTimestamp()
782782
}
783783

784-
public async getBalance (address: string): Promise<number> {
784+
public async getBalance (address: string): Promise<bigint> {
785785
const networkSlug = getAddressPrefix(address)
786786
return await this.clients[networkSlug as MainNetworkSlugsType].getBalance(address)
787787
}

types/chronikTypes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Address, Prisma } from '@prisma/client'
22
import { KeyValueT } from 'constants/index'
33

44
interface InputOutput {
5-
value: Prisma.Decimal
5+
value: bigint
66
address?: string
77
}
88

@@ -18,7 +18,7 @@ export interface BlockchainInfo {
1818
hash: Uint8Array | string
1919
}
2020

21-
export interface BlockInfo extends BlockchainInfo {
21+
export interface SimpleBlockInfo extends BlockchainInfo {
2222
timestamp: number
2323
}
2424

utils/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,12 @@ export const getAddressPrefixed = function (addressString: string): string {
4040
return `${getAddressPrefix(addressString)}:${removeAddressPrefix(addressString)}`
4141
}
4242

43-
export async function satoshisToUnit (satoshis: Prisma.Decimal, networkFormat: string): Promise<Prisma.Decimal> {
43+
export async function satoshisToUnit (satoshis: bigint, networkFormat: string): Promise<Prisma.Decimal> {
44+
const decimal = new Prisma.Decimal(satoshis.toString())
4445
if (networkFormat === xecaddr.Format.Xecaddr) {
45-
return satoshis.dividedBy(1e2)
46+
return decimal.dividedBy(1e2)
4647
} else if (networkFormat === xecaddr.Format.Cashaddr) {
47-
return satoshis.dividedBy(1e8)
48+
return decimal.dividedBy(1e8)
4849
}
4950
throw new Error(RESPONSE_MESSAGES.INVALID_ADDRESS_400.message)
5051
}

yarn.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2807,14 +2807,14 @@ chokidar@^3.5.2:
28072807
optionalDependencies:
28082808
fsevents "~2.3.2"
28092809

2810-
chronik-client-cashtokens@^0.28.2-alpha:
2811-
version "0.28.2-alpha"
2812-
resolved "https://registry.yarnpkg.com/chronik-client-cashtokens/-/chronik-client-cashtokens-0.28.2-alpha.tgz#656a76202e821e68016a51ba039b1901fba91427"
2813-
integrity sha512-BPcXoKhm/wFIMge/NVbic7rgFCOudEqKOeW1IbNiKbtdqgLV+KmWTDOUjxDcJW9lEfclqwqOo/9qWL108vn6uQ==
2810+
chronik-client-cashtokens@^3.1.1-rc0:
2811+
version "3.1.1-rc0"
2812+
resolved "https://registry.yarnpkg.com/chronik-client-cashtokens/-/chronik-client-cashtokens-3.1.1-rc0.tgz#e5e4a3538e8010b70623974a731bf2712506c5e3"
2813+
integrity sha512-jnFnog+hVd9u8bik+sf2SRVwr4ETN8Gnq6HpFRdPkM5UtMu7boCjQVrKHOXKb9AyaCFKUnreK9mBEL/l9dAjMg==
28142814
dependencies:
28152815
"@types/ws" "^8.2.1"
28162816
axios "^1.6.3"
2817-
ecashaddrjs "file:../.cache/yarn/v6/npm-chronik-client-cashtokens-0.28.2-alpha-656a76202e821e68016a51ba039b1901fba91427-integrity/node_modules/ecashaddrjs"
2817+
ecashaddrjs "file:../.cache/yarn/v6/npm-chronik-client-cashtokens-3.1.1-rc0-e5e4a3538e8010b70623974a731bf2712506c5e3-integrity/node_modules/ecashaddrjs"
28182818
isomorphic-ws "^4.0.1"
28192819
protobufjs "^6.8.8"
28202820
ws "^8.3.0"
@@ -3281,7 +3281,7 @@ ecashaddrjs@^1.0.7:
32813281
dependencies:
32823282
big-integer "1.6.36"
32833283

3284-
ecashaddrjs@^1.5.8, "ecashaddrjs@file:../.cache/yarn/v6/npm-chronik-client-cashtokens-0.28.2-alpha-656a76202e821e68016a51ba039b1901fba91427-integrity/node_modules/ecashaddrjs":
3284+
ecashaddrjs@^1.5.8, "ecashaddrjs@file:../.cache/yarn/v6/npm-chronik-client-cashtokens-3.1.1-rc0-e5e4a3538e8010b70623974a731bf2712506c5e3-integrity/node_modules/ecashaddrjs":
32853285
version "1.5.8"
32863286
resolved "https://registry.yarnpkg.com/ecashaddrjs/-/ecashaddrjs-1.5.8.tgz#fff684d14a944cfd4bca56dd8dc3adbfce8016f9"
32873287
integrity sha512-EBL052a1Hd1+wwaBQr3Q+jXY4XfH0jXR1tK360P8GQ9YJUZ5zLG+0I7yee8/QgHY04zdoCzDOY0fRlwqtqDhRg==

0 commit comments

Comments
 (0)