@cityofzion/bs-ethereum 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.rush/temp/operation/build/all.log +1 -1
  2. package/.rush/temp/operation/build/state.json +1 -1
  3. package/.rush/temp/package-deps_build.json +6 -4
  4. package/.rush/temp/shrinkwrap-deps.json +1 -2
  5. package/CHANGELOG.json +27 -0
  6. package/CHANGELOG.md +15 -0
  7. package/bs-ethereum.build.log +1 -1
  8. package/dist/BSEthereum.d.ts +24 -23
  9. package/dist/BSEthereum.js +184 -178
  10. package/dist/BitqueryBDSEthereum.d.ts +14 -14
  11. package/dist/BitqueryBDSEthereum.js +197 -197
  12. package/dist/BitqueryEDSEthereum.d.ts +8 -8
  13. package/dist/BitqueryEDSEthereum.js +73 -73
  14. package/dist/GhostMarketNDSEthereum.d.ts +10 -10
  15. package/dist/GhostMarketNDSEthereum.js +77 -77
  16. package/dist/RpcBDSEthereum.d.ts +12 -12
  17. package/dist/RpcBDSEthereum.js +89 -89
  18. package/dist/assets/tokens/common.json +8 -8
  19. package/dist/constants.d.ts +16 -16
  20. package/dist/constants.js +33 -33
  21. package/dist/graphql.d.ts +124 -124
  22. package/dist/graphql.js +163 -163
  23. package/dist/index.d.ts +6 -6
  24. package/dist/index.js +22 -22
  25. package/jest.config.ts +13 -13
  26. package/jest.setup.ts +1 -1
  27. package/package.json +34 -34
  28. package/src/BSEthereum.ts +189 -184
  29. package/src/BitqueryBDSEthereum.ts +230 -230
  30. package/src/BitqueryEDSEthereum.ts +67 -67
  31. package/src/GhostMarketNDSEthereum.ts +122 -122
  32. package/src/RpcBDSEthereum.ts +88 -88
  33. package/src/__tests__/BDSEthereum.spec.ts +123 -123
  34. package/src/__tests__/BSEthereum.spec.ts +129 -123
  35. package/src/__tests__/BitqueryEDSEthereum.spec.ts +49 -49
  36. package/src/__tests__/GhostMarketNDSEthereum.spec.ts +45 -45
  37. package/src/assets/tokens/common.json +7 -7
  38. package/src/constants.ts +37 -37
  39. package/src/graphql.ts +291 -291
  40. package/src/index.ts +6 -6
  41. package/tsconfig.build.json +4 -4
  42. package/tsconfig.json +15 -15
@@ -1,122 +1,122 @@
1
- import {
2
- BlockchainService,
3
- NftResponse,
4
- NftsResponse,
5
- NetworkType,
6
- NftDataService,
7
- GetNftParam,
8
- GetNftsByAddressParams,
9
- } from '@cityofzion/blockchain-service'
10
- import qs from 'query-string'
11
-
12
- import { GHOSTMARKET_CHAIN_BY_NETWORK_TYPE, GHOSTMARKET_URL_BY_NETWORK_TYPE } from './constants'
13
- import fetch from 'node-fetch'
14
-
15
- type GhostMarketNFT = {
16
- tokenId: string
17
- contract: {
18
- chain?: string
19
- hash: string
20
- symbol: string
21
- }
22
- creator: {
23
- address?: string
24
- offchainName?: string
25
- }
26
- apiUrl?: string
27
- ownerships: {
28
- owner: {
29
- address?: string
30
- }
31
- }[]
32
- collection: {
33
- name?: string
34
- logoUrl?: string
35
- }
36
- metadata: {
37
- description: string
38
- mediaType: string
39
- mediaUri: string
40
- mintDate: number
41
- mintNumber: number
42
- name: string
43
- }
44
- }
45
-
46
- type GhostMarketAssets = {
47
- assets: GhostMarketNFT[]
48
- next: string
49
- }
50
- export class GhostMarketNDSEthereum implements NftDataService {
51
- private networkType: NetworkType
52
-
53
- constructor(networkType: NetworkType) {
54
- this.networkType = networkType
55
- }
56
-
57
- async getNftsByAddress({ address, size = 18, cursor, page }: GetNftsByAddressParams): Promise<NftsResponse> {
58
- const url = this.getUrlWithParams({
59
- size,
60
- owners: [address],
61
- cursor: cursor,
62
- })
63
-
64
- const request = await fetch(url, { method: 'GET' })
65
- const data = (await request.json()) as GhostMarketAssets
66
- const nfts = data.assets ?? []
67
-
68
- return { nextCursor: data.next, items: nfts.map(this.parse.bind(this)) }
69
- }
70
-
71
- async getNft({ contractHash, tokenId }: GetNftParam): Promise<NftResponse> {
72
- const url = this.getUrlWithParams({
73
- contract: contractHash,
74
- tokenIds: [tokenId],
75
- })
76
-
77
- const request = await fetch(url, { method: 'GET' })
78
- const data = (await request.json()) as GhostMarketAssets
79
-
80
- return this.parse(data.assets[0])
81
- }
82
-
83
- private treatGhostMarketImage(srcImage?: string) {
84
- if (!srcImage) {
85
- return
86
- }
87
-
88
- if (srcImage.startsWith('ipfs://')) {
89
- const [, imageId] = srcImage.split('://')
90
-
91
- return `https://ghostmarket.mypinata.cloud/ipfs/${imageId}`
92
- }
93
-
94
- return srcImage
95
- }
96
-
97
- private getUrlWithParams(params: any) {
98
- const parameters = qs.stringify(
99
- {
100
- chain: GHOSTMARKET_CHAIN_BY_NETWORK_TYPE[this.networkType],
101
- ...params,
102
- },
103
- { arrayFormat: 'bracket' }
104
- )
105
- return `${GHOSTMARKET_URL_BY_NETWORK_TYPE[this.networkType]}/assets?${parameters}`
106
- }
107
-
108
- private parse(data: GhostMarketNFT) {
109
- const nftResponse: NftResponse = {
110
- collectionImage: this.treatGhostMarketImage(data.collection?.logoUrl),
111
- id: data.tokenId,
112
- contractHash: data.contract.hash,
113
- symbol: data.contract.symbol,
114
- collectionName: data.collection?.name,
115
- image: this.treatGhostMarketImage(data.metadata.mediaUri),
116
- isSVG: String(data.metadata.mediaType).includes('svg+xml'),
117
- name: data.metadata.name,
118
- }
119
-
120
- return nftResponse
121
- }
122
- }
1
+ import {
2
+ BlockchainService,
3
+ NftResponse,
4
+ NftsResponse,
5
+ NetworkType,
6
+ NftDataService,
7
+ GetNftParam,
8
+ GetNftsByAddressParams,
9
+ } from '@cityofzion/blockchain-service'
10
+ import qs from 'query-string'
11
+
12
+ import { GHOSTMARKET_CHAIN_BY_NETWORK_TYPE, GHOSTMARKET_URL_BY_NETWORK_TYPE } from './constants'
13
+ import fetch from 'node-fetch'
14
+
15
+ type GhostMarketNFT = {
16
+ tokenId: string
17
+ contract: {
18
+ chain?: string
19
+ hash: string
20
+ symbol: string
21
+ }
22
+ creator: {
23
+ address?: string
24
+ offchainName?: string
25
+ }
26
+ apiUrl?: string
27
+ ownerships: {
28
+ owner: {
29
+ address?: string
30
+ }
31
+ }[]
32
+ collection: {
33
+ name?: string
34
+ logoUrl?: string
35
+ }
36
+ metadata: {
37
+ description: string
38
+ mediaType: string
39
+ mediaUri: string
40
+ mintDate: number
41
+ mintNumber: number
42
+ name: string
43
+ }
44
+ }
45
+
46
+ type GhostMarketAssets = {
47
+ assets: GhostMarketNFT[]
48
+ next: string
49
+ }
50
+ export class GhostMarketNDSEthereum implements NftDataService {
51
+ private networkType: NetworkType
52
+
53
+ constructor(networkType: NetworkType) {
54
+ this.networkType = networkType
55
+ }
56
+
57
+ async getNftsByAddress({ address, size = 18, cursor, page }: GetNftsByAddressParams): Promise<NftsResponse> {
58
+ const url = this.getUrlWithParams({
59
+ size,
60
+ owners: [address],
61
+ cursor: cursor,
62
+ })
63
+
64
+ const request = await fetch(url, { method: 'GET' })
65
+ const data = (await request.json()) as GhostMarketAssets
66
+ const nfts = data.assets ?? []
67
+
68
+ return { nextCursor: data.next, items: nfts.map(this.parse.bind(this)) }
69
+ }
70
+
71
+ async getNft({ contractHash, tokenId }: GetNftParam): Promise<NftResponse> {
72
+ const url = this.getUrlWithParams({
73
+ contract: contractHash,
74
+ tokenIds: [tokenId],
75
+ })
76
+
77
+ const request = await fetch(url, { method: 'GET' })
78
+ const data = (await request.json()) as GhostMarketAssets
79
+
80
+ return this.parse(data.assets[0])
81
+ }
82
+
83
+ private treatGhostMarketImage(srcImage?: string) {
84
+ if (!srcImage) {
85
+ return
86
+ }
87
+
88
+ if (srcImage.startsWith('ipfs://')) {
89
+ const [, imageId] = srcImage.split('://')
90
+
91
+ return `https://ghostmarket.mypinata.cloud/ipfs/${imageId}`
92
+ }
93
+
94
+ return srcImage
95
+ }
96
+
97
+ private getUrlWithParams(params: any) {
98
+ const parameters = qs.stringify(
99
+ {
100
+ chain: GHOSTMARKET_CHAIN_BY_NETWORK_TYPE[this.networkType],
101
+ ...params,
102
+ },
103
+ { arrayFormat: 'bracket' }
104
+ )
105
+ return `${GHOSTMARKET_URL_BY_NETWORK_TYPE[this.networkType]}/assets?${parameters}`
106
+ }
107
+
108
+ private parse(data: GhostMarketNFT) {
109
+ const nftResponse: NftResponse = {
110
+ collectionImage: this.treatGhostMarketImage(data.collection?.logoUrl),
111
+ id: data.tokenId,
112
+ contractHash: data.contract.hash,
113
+ symbol: data.contract.symbol,
114
+ collectionName: data.collection?.name,
115
+ image: this.treatGhostMarketImage(data.metadata.mediaUri),
116
+ isSVG: String(data.metadata.mediaType).includes('svg+xml'),
117
+ name: data.metadata.name,
118
+ }
119
+
120
+ return nftResponse
121
+ }
122
+ }
@@ -1,88 +1,88 @@
1
- import {
2
- BalanceResponse,
3
- BlockchainDataService,
4
- ContractResponse,
5
- Network,
6
- Token,
7
- TransactionResponse,
8
- TransactionsByAddressParams,
9
- TransactionsByAddressResponse,
10
- } from '@cityofzion/blockchain-service'
11
- import { ethers } from 'ethers'
12
- import { TOKENS } from './constants'
13
-
14
- export class RpcBDSEthereum implements BlockchainDataService {
15
- private readonly network: Network
16
-
17
- maxTimeToConfirmTransactionInMs: number = 1000 * 60 * 5
18
-
19
- constructor(network: Network) {
20
- this.network = network
21
- }
22
-
23
- async getTransaction(hash: string): Promise<TransactionResponse> {
24
- const provider = new ethers.providers.JsonRpcProvider(this.network.url)
25
-
26
- const transaction = await provider.getTransaction(hash)
27
- if (!transaction || !transaction.blockHash || !transaction.to) throw new Error('Transaction not found')
28
-
29
- const block = await provider.getBlock(transaction.blockHash)
30
- if (!block) throw new Error('Block not found')
31
-
32
- const tokens = TOKENS[this.network.type]
33
- const token = tokens.find(token => token.symbol === 'ETH')!
34
-
35
- return {
36
- block: block.number,
37
- time: block.timestamp,
38
- hash: transaction.hash,
39
- transfers: [
40
- {
41
- type: 'token',
42
- amount: ethers.utils.formatEther(transaction.value),
43
- contractHash: '-',
44
- from: transaction.from,
45
- to: transaction.to,
46
- token,
47
- },
48
- ],
49
- notifications: [],
50
- }
51
- }
52
-
53
- async getTransactionsByAddress(_params: TransactionsByAddressParams): Promise<TransactionsByAddressResponse> {
54
- throw new Error("RPC doesn't support get transactions history of address")
55
- }
56
-
57
- async getContract(): Promise<ContractResponse> {
58
- throw new Error("RPC doesn't support contract info")
59
- }
60
-
61
- async getTokenInfo(hash: string): Promise<Token> {
62
- const tokens = TOKENS[this.network.type]
63
- const token = tokens.find(token => token.hash === hash)
64
- if (!token) throw new Error('Token not found')
65
-
66
- return token
67
- }
68
-
69
- async getBalance(address: string): Promise<BalanceResponse[]> {
70
- const provider = new ethers.providers.JsonRpcProvider(this.network.url)
71
- const balance = await provider.getBalance(address)
72
-
73
- const tokens = TOKENS[this.network.type]
74
- const token = tokens.find(token => token.symbol === 'ETH')!
75
-
76
- return [
77
- {
78
- amount: ethers.utils.formatEther(balance),
79
- token,
80
- },
81
- ]
82
- }
83
-
84
- async getBlockHeight(): Promise<number> {
85
- const provider = new ethers.providers.JsonRpcProvider(this.network.url)
86
- return await provider.getBlockNumber()
87
- }
88
- }
1
+ import {
2
+ BalanceResponse,
3
+ BlockchainDataService,
4
+ ContractResponse,
5
+ Network,
6
+ Token,
7
+ TransactionResponse,
8
+ TransactionsByAddressParams,
9
+ TransactionsByAddressResponse,
10
+ } from '@cityofzion/blockchain-service'
11
+ import { ethers } from 'ethers'
12
+ import { TOKENS } from './constants'
13
+
14
+ export class RpcBDSEthereum implements BlockchainDataService {
15
+ private readonly network: Network
16
+
17
+ maxTimeToConfirmTransactionInMs: number = 1000 * 60 * 5
18
+
19
+ constructor(network: Network) {
20
+ this.network = network
21
+ }
22
+
23
+ async getTransaction(hash: string): Promise<TransactionResponse> {
24
+ const provider = new ethers.providers.JsonRpcProvider(this.network.url)
25
+
26
+ const transaction = await provider.getTransaction(hash)
27
+ if (!transaction || !transaction.blockHash || !transaction.to) throw new Error('Transaction not found')
28
+
29
+ const block = await provider.getBlock(transaction.blockHash)
30
+ if (!block) throw new Error('Block not found')
31
+
32
+ const tokens = TOKENS[this.network.type]
33
+ const token = tokens.find(token => token.symbol === 'ETH')!
34
+
35
+ return {
36
+ block: block.number,
37
+ time: block.timestamp,
38
+ hash: transaction.hash,
39
+ transfers: [
40
+ {
41
+ type: 'token',
42
+ amount: ethers.utils.formatEther(transaction.value),
43
+ contractHash: '-',
44
+ from: transaction.from,
45
+ to: transaction.to,
46
+ token,
47
+ },
48
+ ],
49
+ notifications: [],
50
+ }
51
+ }
52
+
53
+ async getTransactionsByAddress(_params: TransactionsByAddressParams): Promise<TransactionsByAddressResponse> {
54
+ throw new Error("RPC doesn't support get transactions history of address")
55
+ }
56
+
57
+ async getContract(): Promise<ContractResponse> {
58
+ throw new Error("RPC doesn't support contract info")
59
+ }
60
+
61
+ async getTokenInfo(hash: string): Promise<Token> {
62
+ const tokens = TOKENS[this.network.type]
63
+ const token = tokens.find(token => token.hash === hash)
64
+ if (!token) throw new Error('Token not found')
65
+
66
+ return token
67
+ }
68
+
69
+ async getBalance(address: string): Promise<BalanceResponse[]> {
70
+ const provider = new ethers.providers.JsonRpcProvider(this.network.url)
71
+ const balance = await provider.getBalance(address)
72
+
73
+ const tokens = TOKENS[this.network.type]
74
+ const token = tokens.find(token => token.symbol === 'ETH')!
75
+
76
+ return [
77
+ {
78
+ amount: ethers.utils.formatEther(balance),
79
+ token,
80
+ },
81
+ ]
82
+ }
83
+
84
+ async getBlockHeight(): Promise<number> {
85
+ const provider = new ethers.providers.JsonRpcProvider(this.network.url)
86
+ return await provider.getBlockNumber()
87
+ }
88
+ }
@@ -1,123 +1,123 @@
1
- import { BDSClaimable, BlockchainDataService } from '@cityofzion/blockchain-service'
2
- import { BitqueryBDSEthereum } from '../BitqueryBDSEthereum'
3
- import { RpcBDSEthereum } from '../RpcBDSEthereum'
4
- import { DEFAULT_URL_BY_NETWORK_TYPE } from '../constants'
5
-
6
- const bitqueryBDSEthereum = new BitqueryBDSEthereum({ type: 'testnet', url: DEFAULT_URL_BY_NETWORK_TYPE.testnet })
7
- const rpcBDSEthereum = new RpcBDSEthereum({ type: 'testnet', url: DEFAULT_URL_BY_NETWORK_TYPE.testnet })
8
-
9
- describe('BDSEthereum', () => {
10
- it.each([rpcBDSEthereum, bitqueryBDSEthereum])(
11
- 'Should be able to get transaction - %s',
12
- async (BDSEthereum: BlockchainDataService) => {
13
- const hash = '0x43fa3015d077a13888409cfbd6228df8900abcd5314ff11ea6ce0c49e8b7c94d'
14
- const transaction = await BDSEthereum.getTransaction(hash)
15
-
16
- expect(transaction).toEqual(
17
- expect.objectContaining({
18
- block: expect.any(Number),
19
- hash,
20
- notifications: [],
21
- time: expect.any(Number),
22
- })
23
- )
24
- transaction.transfers.forEach(transfer => {
25
- expect(transfer).toEqual(
26
- expect.objectContaining({
27
- from: expect.any(String),
28
- to: expect.any(String),
29
- contractHash: expect.any(String),
30
- amount: expect.any(String),
31
- type: expect.any(String),
32
- })
33
- )
34
- })
35
- },
36
- 10000
37
- )
38
-
39
- it.each([bitqueryBDSEthereum])(
40
- 'Should be able to get transactions of address - %s',
41
- async (BDSEthereum: BlockchainDataService) => {
42
- const address = '0x82B5Cd984880C8A821429cFFf89f36D35BaeBE89'
43
- const response = await BDSEthereum.getTransactionsByAddress({ address: address, page: 1 })
44
- expect(response.totalCount).toBeGreaterThan(0)
45
- response.transactions.forEach(transaction => {
46
- expect(transaction).toEqual(
47
- expect.objectContaining({
48
- block: expect.any(Number),
49
- hash: expect.any(String),
50
- notifications: [],
51
- time: expect.any(Number),
52
- fee: expect.any(String),
53
- })
54
- )
55
-
56
- transaction.transfers.forEach(transfer => {
57
- expect(transfer).toEqual(
58
- expect.objectContaining({
59
- from: expect.any(String),
60
- to: expect.any(String),
61
- contractHash: expect.any(String),
62
- amount: expect.any(String),
63
- type: expect.any(String),
64
- })
65
- )
66
- })
67
- })
68
- },
69
- 10000
70
- )
71
-
72
- it.each([bitqueryBDSEthereum, rpcBDSEthereum])(
73
- 'Should be able to get eth info - %s',
74
- async (BDSEthereum: BlockchainDataService) => {
75
- const hash = '-'
76
- const token = await BDSEthereum.getTokenInfo(hash)
77
-
78
- expect(token).toEqual({
79
- symbol: 'ETH',
80
- name: 'Ethereum',
81
- hash: '-',
82
- decimals: 16,
83
- })
84
- }
85
- )
86
-
87
- it.each([bitqueryBDSEthereum])(
88
- 'Should be able to get token info - %s',
89
- async (BDSEthereum: BlockchainDataService) => {
90
- const hash = '0xBA62BCfcAaFc6622853cca2BE6Ac7d845BC0f2Dc'
91
- const token = await BDSEthereum.getTokenInfo(hash)
92
-
93
- expect(token).toEqual({
94
- hash: '0xba62bcfcaafc6622853cca2be6ac7d845bc0f2dc',
95
- name: 'FaucetToken',
96
- symbol: 'FAU',
97
- decimals: 18,
98
- })
99
- }
100
- )
101
-
102
- it.each([bitqueryBDSEthereum, rpcBDSEthereum])(
103
- 'Should be able to get balance - %s',
104
- async (BDSEthereum: BlockchainDataService) => {
105
- const address = '0x82B5Cd984880C8A821429cFFf89f36D35BaeBE89'
106
- const balance = await BDSEthereum.getBalance(address)
107
-
108
- balance.forEach(balance => {
109
- expect(balance).toEqual(
110
- expect.objectContaining({
111
- amount: expect.any(String),
112
- token: {
113
- hash: expect.any(String),
114
- name: expect.any(String),
115
- symbol: expect.any(String),
116
- decimals: expect.any(Number),
117
- },
118
- })
119
- )
120
- })
121
- }
122
- )
123
- })
1
+ import { BDSClaimable, BlockchainDataService } from '@cityofzion/blockchain-service'
2
+ import { BitqueryBDSEthereum } from '../BitqueryBDSEthereum'
3
+ import { RpcBDSEthereum } from '../RpcBDSEthereum'
4
+ import { DEFAULT_URL_BY_NETWORK_TYPE } from '../constants'
5
+
6
+ const bitqueryBDSEthereum = new BitqueryBDSEthereum({ type: 'testnet', url: DEFAULT_URL_BY_NETWORK_TYPE.testnet })
7
+ const rpcBDSEthereum = new RpcBDSEthereum({ type: 'testnet', url: DEFAULT_URL_BY_NETWORK_TYPE.testnet })
8
+
9
+ describe('BDSEthereum', () => {
10
+ it.each([rpcBDSEthereum, bitqueryBDSEthereum])(
11
+ 'Should be able to get transaction - %s',
12
+ async (BDSEthereum: BlockchainDataService) => {
13
+ const hash = '0x43fa3015d077a13888409cfbd6228df8900abcd5314ff11ea6ce0c49e8b7c94d'
14
+ const transaction = await BDSEthereum.getTransaction(hash)
15
+
16
+ expect(transaction).toEqual(
17
+ expect.objectContaining({
18
+ block: expect.any(Number),
19
+ hash,
20
+ notifications: [],
21
+ time: expect.any(Number),
22
+ })
23
+ )
24
+ transaction.transfers.forEach(transfer => {
25
+ expect(transfer).toEqual(
26
+ expect.objectContaining({
27
+ from: expect.any(String),
28
+ to: expect.any(String),
29
+ contractHash: expect.any(String),
30
+ amount: expect.any(String),
31
+ type: expect.any(String),
32
+ })
33
+ )
34
+ })
35
+ },
36
+ 10000
37
+ )
38
+
39
+ it.each([bitqueryBDSEthereum])(
40
+ 'Should be able to get transactions of address - %s',
41
+ async (BDSEthereum: BlockchainDataService) => {
42
+ const address = '0x82B5Cd984880C8A821429cFFf89f36D35BaeBE89'
43
+ const response = await BDSEthereum.getTransactionsByAddress({ address: address, page: 1 })
44
+ expect(response.totalCount).toBeGreaterThan(0)
45
+ response.transactions.forEach(transaction => {
46
+ expect(transaction).toEqual(
47
+ expect.objectContaining({
48
+ block: expect.any(Number),
49
+ hash: expect.any(String),
50
+ notifications: [],
51
+ time: expect.any(Number),
52
+ fee: expect.any(String),
53
+ })
54
+ )
55
+
56
+ transaction.transfers.forEach(transfer => {
57
+ expect(transfer).toEqual(
58
+ expect.objectContaining({
59
+ from: expect.any(String),
60
+ to: expect.any(String),
61
+ contractHash: expect.any(String),
62
+ amount: expect.any(String),
63
+ type: expect.any(String),
64
+ })
65
+ )
66
+ })
67
+ })
68
+ },
69
+ 10000
70
+ )
71
+
72
+ it.each([bitqueryBDSEthereum, rpcBDSEthereum])(
73
+ 'Should be able to get eth info - %s',
74
+ async (BDSEthereum: BlockchainDataService) => {
75
+ const hash = '-'
76
+ const token = await BDSEthereum.getTokenInfo(hash)
77
+
78
+ expect(token).toEqual({
79
+ symbol: 'ETH',
80
+ name: 'Ethereum',
81
+ hash: '-',
82
+ decimals: 16,
83
+ })
84
+ }
85
+ )
86
+
87
+ it.each([bitqueryBDSEthereum])(
88
+ 'Should be able to get token info - %s',
89
+ async (BDSEthereum: BlockchainDataService) => {
90
+ const hash = '0xBA62BCfcAaFc6622853cca2BE6Ac7d845BC0f2Dc'
91
+ const token = await BDSEthereum.getTokenInfo(hash)
92
+
93
+ expect(token).toEqual({
94
+ hash: '0xba62bcfcaafc6622853cca2be6ac7d845bc0f2dc',
95
+ name: 'FaucetToken',
96
+ symbol: 'FAU',
97
+ decimals: 18,
98
+ })
99
+ }
100
+ )
101
+
102
+ it.each([bitqueryBDSEthereum, rpcBDSEthereum])(
103
+ 'Should be able to get balance - %s',
104
+ async (BDSEthereum: BlockchainDataService) => {
105
+ const address = '0x82B5Cd984880C8A821429cFFf89f36D35BaeBE89'
106
+ const balance = await BDSEthereum.getBalance(address)
107
+
108
+ balance.forEach(balance => {
109
+ expect(balance).toEqual(
110
+ expect.objectContaining({
111
+ amount: expect.any(String),
112
+ token: {
113
+ hash: expect.any(String),
114
+ name: expect.any(String),
115
+ symbol: expect.any(String),
116
+ decimals: expect.any(Number),
117
+ },
118
+ })
119
+ )
120
+ })
121
+ }
122
+ )
123
+ })