Skip to content

Commit 153dead

Browse files
Zcash client (#1373)
* Update licenses * Stable version zcash client * PR comments * Restore xchain-crypto dependency * Create changeset * Fix linter * Fix build
1 parent 6c30cb9 commit 153dead

File tree

40 files changed

+1918
-15
lines changed

40 files changed

+1918
-15
lines changed

.changeset/honest-points-drum.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@xchainjs/xchain-utxo-providers': patch
3+
'@xchainjs/xchain-zcash': patch
4+
---
5+
6+
Create zcash client

packages/xchain-binance/LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 THORChain
3+
Copyright (c) 2025 THORChain
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

packages/xchain-bitcoin/LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 THORChain
3+
Copyright (c) 2025 THORChain
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

packages/xchain-cosmos/LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 THORChain
3+
Copyright (c) 2025 THORChain
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

packages/xchain-crypto/LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 THORChain
3+
Copyright (c) 2025 THORChain
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

packages/xchain-kujira/LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 THORChain
3+
Copyright (c) 2025 THORChain
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

packages/xchain-litecoin/LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 THORChain
3+
Copyright (c) 2025 THORChain
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

packages/xchain-mayachain/LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 MAYAChain
3+
Copyright (c) 2025 MAYAChain
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

packages/xchain-thorchain/LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 THORChain
3+
Copyright (c) 2025 THORChain
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

packages/xchain-util/LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 THORChain
3+
Copyright (c) 2025 THORChain
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { AssetZEC, ZECChain } from '@xchainjs/xchain-zcash/src'
2+
import { NownodesProvider } from '../src/providers'
3+
4+
const nownodesProvider = new NownodesProvider(
5+
'https://zecbook.nownodes.io/api/v2',
6+
ZECChain,
7+
AssetZEC,
8+
8,
9+
process.env.NOWNODES_API_KEY as string
10+
)
11+
12+
describe('nownodes api tests', () => {
13+
it(`Should fetch the balance for an address`, async () => {
14+
const address = 't1aVCAJMxUNLNAJFPmbLfZWkPWopf8aMyu9'
15+
const bal = await nownodesProvider.getBalance(address)
16+
expect(bal[0].amount.amount().toString()).toBe("40000000")
17+
})
18+
it(`Should getConfirmedUnspentTxs for an address`, async () => {
19+
const address = 't1aVCAJMxUNLNAJFPmbLfZWkPWopf8aMyu9'
20+
const response = await nownodesProvider.getConfirmedUnspentTxs(address)
21+
console.log(response)
22+
})
23+
it(`Should nownodes getUnspentTxs for an address`, async () => {
24+
const address = 't1eiZYPXWurGMxFwoTu62531s8fAiExFh88'
25+
const response = await nownodesProvider.getUnspentTxs(address)
26+
console.log(JSON.stringify(response, null, 2))
27+
})
28+
it(`Should getTransactions for an address`, async () => {
29+
const address = 't1aVCAJMxUNLNAJFPmbLfZWkPWopf8aMyu9'
30+
const response = await nownodesProvider.getTransactions({ address })
31+
console.log(JSON.stringify(response, null, 2))
32+
})
33+
it(`Should getTransactionData for an address`, async () => {
34+
const hash = '540e2dd5759dee24dc799d9097bbff7aa7334e1516b216014b6561e2d58c29f8'
35+
const response = await nownodesProvider.getTransactionData(hash)
36+
console.log(JSON.stringify(response, null, 2))
37+
})
38+
it(`Should fetch fee rates`, async () => {
39+
await expect(nownodesProvider.getFeeRates()).rejects.toThrow('Zcash has flat fees. Fee rates not apply')
40+
})
41+
})

packages/xchain-utxo-providers/src/providers/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ export * from './blockcypher/blockcypher-data-provider'
3232
export { BlockcypherNetwork } from './blockcypher/blockcypher-api-types'
3333

3434
export { BitgoProvider } from './bitgo/bitgo-data-provider'
35+
36+
export { NownodesProvider } from './nownodes/nownodes-data-provider'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { TxHash } from '@xchainjs/xchain-client'
2+
3+
export type BalanceParams = {
4+
apiKey: string
5+
baseUrl: string
6+
address: string
7+
confirmedOnly: boolean
8+
assetDecimals: number
9+
}
10+
11+
export type TxHashParams = {
12+
apiKey: string
13+
baseUrl: string
14+
hash: TxHash
15+
}
16+
17+
export interface TxInput {
18+
txid: string
19+
vout?: number
20+
n: number
21+
sequence: number
22+
addresses: string[]
23+
isAddress: boolean
24+
value: string // zatoshis
25+
hex: string
26+
}
27+
export interface TxOutput {
28+
value: string
29+
n: number
30+
spent?: boolean
31+
hex: string
32+
addresses: string[]
33+
isAddress: boolean
34+
}
35+
export interface Transaction {
36+
txid: string
37+
version: number
38+
vin: TxInput[]
39+
vout: TxOutput[]
40+
blockHash: string
41+
blockHeight: number
42+
confirmations: number
43+
blockTime: number
44+
size: number
45+
value: string
46+
valueIn: string
47+
fees: string
48+
hex: string
49+
}
50+
51+
export type AddressUTXO = {
52+
txid: string
53+
vout: number
54+
value: string
55+
height: number
56+
confirmations: number
57+
}
58+
59+
export type GetAddressInfo= {
60+
page: number
61+
totalPages: number
62+
itemsOnPage: number
63+
address: string
64+
balance: string
65+
totalReceived: string
66+
totalSent: string
67+
unconfirmedBalance: string
68+
unconfirmedTxs: number
69+
txs: number
70+
txids?: string[]
71+
transactions?: Transaction[]
72+
}
73+
74+
export type BroadcastDTO = {
75+
result: string
76+
}
77+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import { TxHash } from '@xchainjs/xchain-client'
2+
import { BaseAmount, baseAmount } from '@xchainjs/xchain-util'
3+
import axios from 'axios'
4+
5+
import {
6+
GetAddressInfo,
7+
BalanceParams,
8+
BroadcastDTO,
9+
Transaction,
10+
TxHashParams,
11+
AddressUTXO,
12+
} from './nownodes-api-types'
13+
14+
/**
15+
* Get transaction by hash.
16+
*
17+
*
18+
* @param {string} baseUrl The sochain node url.
19+
* @param {string} hash The transaction hash.
20+
* @returns {Transactions}
21+
*/
22+
export const getTx = async ({ apiKey, baseUrl, hash }: TxHashParams): Promise<Transaction> => {
23+
const url = `${baseUrl}/tx/${hash}`
24+
const response = await axios.get(url, {
25+
headers: {
26+
'api-key': apiKey,
27+
}
28+
})
29+
const tx: Transaction = response.data
30+
return tx
31+
}
32+
33+
/**
34+
* Get transactions
35+
*
36+
*
37+
* @param {string} baseUrl The sochain node url.
38+
* @param {string} hash The transaction hash.
39+
* @returns {Transactions}
40+
*/
41+
export const getTxs = async ({
42+
apiKey,
43+
address,
44+
baseUrl,
45+
limit,
46+
}: {
47+
apiKey?: string
48+
address: string
49+
baseUrl: string
50+
limit: number
51+
}): Promise<Transaction[]> => {
52+
const url = `${baseUrl}/address/${address}`
53+
const response = await axios.get(url, {
54+
params: {
55+
details: 'txs',
56+
pageSize: limit
57+
},
58+
headers: {
59+
'api-key': apiKey,
60+
}
61+
})
62+
const txs: GetAddressInfo = response.data
63+
return txs.transactions as Transaction[]
64+
}
65+
66+
/**
67+
* Get UTXOs
68+
*
69+
* @param {string} baseUrl The nownodes blockbook URL.
70+
* @param {string} address address.
71+
* @returns {Transactions}
72+
*/
73+
74+
export const getUTXOs = async ({
75+
apiKey,
76+
address,
77+
baseUrl,
78+
isConfirmed = true,
79+
}: {
80+
apiKey: string
81+
address: string
82+
baseUrl: string
83+
isConfirmed: boolean,
84+
}): Promise<AddressUTXO[]> => {
85+
const url = `${baseUrl}/utxo/${address}`
86+
const response = await axios.get(url, {
87+
params: {
88+
confirmed: isConfirmed
89+
},
90+
headers: {
91+
'api-key': apiKey,
92+
}
93+
})
94+
const utxos: AddressUTXO[] = response.data
95+
return utxos
96+
}
97+
98+
/**
99+
* Get address balance.
100+
*
101+
*
102+
* @param {string} baseUrl The sochain node url.
103+
* @param {string} address Address
104+
* @param {boolean} confirmedOnly Flag whether to get balances of confirmed txs only or for all
105+
* @returns {number}
106+
*/
107+
export const getBalance = async ({
108+
apiKey,
109+
baseUrl,
110+
address,
111+
confirmedOnly = true,
112+
assetDecimals,
113+
}: BalanceParams): Promise<BaseAmount> => {
114+
const url = `${baseUrl}/address/${address}`
115+
const response = await axios.get(url, {
116+
headers: {
117+
'api-key': apiKey,
118+
}
119+
})
120+
const balanceResponse: GetAddressInfo = response.data
121+
const balance = confirmedOnly ? baseAmount(balanceResponse.balance, assetDecimals) : baseAmount(balanceResponse.balance).plus(balanceResponse.unconfirmedBalance, assetDecimals)
122+
return balance
123+
}
124+
125+
export const broadcastTx = async ({
126+
apiKey,
127+
baseUrl,
128+
txHex,
129+
}: {
130+
apiKey: string
131+
baseUrl: string
132+
txHex: string
133+
}): Promise<TxHash> => {
134+
const url = `${baseUrl}/sendtx/${txHex}`
135+
const response = await axios.get(url, {
136+
headers: {
137+
'api-key': apiKey,
138+
}
139+
})
140+
return (response.data as BroadcastDTO).result
141+
}

0 commit comments

Comments
 (0)