@cityofzion/bs-ethereum 0.8.2 → 0.9.1

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 (44) hide show
  1. package/.eslintignore +13 -0
  2. package/.eslintrc.cjs +22 -0
  3. package/.rush/temp/operation/build/all.log +1 -1
  4. package/.rush/temp/operation/build/state.json +1 -1
  5. package/.rush/temp/package-deps_build.json +12 -8
  6. package/.rush/temp/shrinkwrap-deps.json +84 -2
  7. package/CHANGELOG.json +39 -0
  8. package/CHANGELOG.md +22 -0
  9. package/bs-ethereum.build.log +1 -1
  10. package/dist/BSEthereum.d.ts +24 -23
  11. package/dist/BSEthereum.js +184 -178
  12. package/dist/BitqueryBDSEthereum.d.ts +14 -14
  13. package/dist/BitqueryBDSEthereum.js +198 -197
  14. package/dist/BitqueryEDSEthereum.d.ts +8 -8
  15. package/dist/BitqueryEDSEthereum.js +73 -73
  16. package/dist/GhostMarketNDSEthereum.d.ts +10 -10
  17. package/dist/GhostMarketNDSEthereum.js +77 -77
  18. package/dist/RpcBDSEthereum.d.ts +12 -12
  19. package/dist/RpcBDSEthereum.js +89 -89
  20. package/dist/assets/tokens/common.json +8 -8
  21. package/dist/constants.d.ts +16 -16
  22. package/dist/constants.js +33 -33
  23. package/dist/graphql.d.ts +124 -124
  24. package/dist/graphql.js +163 -163
  25. package/dist/index.d.ts +6 -6
  26. package/dist/index.js +22 -22
  27. package/jest.config.ts +13 -13
  28. package/jest.setup.ts +1 -1
  29. package/package.json +39 -34
  30. package/src/BSEthereum.ts +189 -184
  31. package/src/BitqueryBDSEthereum.ts +231 -230
  32. package/src/BitqueryEDSEthereum.ts +67 -67
  33. package/src/GhostMarketNDSEthereum.ts +121 -122
  34. package/src/RpcBDSEthereum.ts +88 -88
  35. package/src/__tests__/BDSEthereum.spec.ts +123 -123
  36. package/src/__tests__/BSEthereum.spec.ts +129 -123
  37. package/src/__tests__/BitqueryEDSEthereum.spec.ts +49 -49
  38. package/src/__tests__/GhostMarketNDSEthereum.spec.ts +45 -45
  39. package/src/assets/tokens/common.json +8 -8
  40. package/src/constants.ts +37 -37
  41. package/src/graphql.ts +291 -291
  42. package/src/index.ts +6 -6
  43. package/tsconfig.build.json +4 -4
  44. package/tsconfig.json +15 -15
@@ -1,122 +1,121 @@
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
+ NftResponse,
3
+ NftsResponse,
4
+ NetworkType,
5
+ NftDataService,
6
+ GetNftParam,
7
+ GetNftsByAddressParams,
8
+ } from '@cityofzion/blockchain-service'
9
+ import qs from 'query-string'
10
+
11
+ import { GHOSTMARKET_CHAIN_BY_NETWORK_TYPE, GHOSTMARKET_URL_BY_NETWORK_TYPE } from './constants'
12
+ import fetch from 'node-fetch'
13
+
14
+ type GhostMarketNFT = {
15
+ tokenId: string
16
+ contract: {
17
+ chain?: string
18
+ hash: string
19
+ symbol: string
20
+ }
21
+ creator: {
22
+ address?: string
23
+ offchainName?: string
24
+ }
25
+ apiUrl?: string
26
+ ownerships: {
27
+ owner: {
28
+ address?: string
29
+ }
30
+ }[]
31
+ collection: {
32
+ name?: string
33
+ logoUrl?: string
34
+ }
35
+ metadata: {
36
+ description: string
37
+ mediaType: string
38
+ mediaUri: string
39
+ mintDate: number
40
+ mintNumber: number
41
+ name: string
42
+ }
43
+ }
44
+
45
+ type GhostMarketAssets = {
46
+ assets: GhostMarketNFT[]
47
+ next: string
48
+ }
49
+ export class GhostMarketNDSEthereum implements NftDataService {
50
+ private networkType: NetworkType
51
+
52
+ constructor(networkType: NetworkType) {
53
+ this.networkType = networkType
54
+ }
55
+
56
+ async getNftsByAddress({ address, size = 18, cursor }: GetNftsByAddressParams): Promise<NftsResponse> {
57
+ const url = this.getUrlWithParams({
58
+ size,
59
+ owners: [address],
60
+ cursor: cursor,
61
+ })
62
+
63
+ const request = await fetch(url, { method: 'GET' })
64
+ const data = (await request.json()) as GhostMarketAssets
65
+ const nfts = data.assets ?? []
66
+
67
+ return { nextCursor: data.next, items: nfts.map(this.parse.bind(this)) }
68
+ }
69
+
70
+ async getNft({ contractHash, tokenId }: GetNftParam): Promise<NftResponse> {
71
+ const url = this.getUrlWithParams({
72
+ contract: contractHash,
73
+ tokenIds: [tokenId],
74
+ })
75
+
76
+ const request = await fetch(url, { method: 'GET' })
77
+ const data = (await request.json()) as GhostMarketAssets
78
+
79
+ return this.parse(data.assets[0])
80
+ }
81
+
82
+ private treatGhostMarketImage(srcImage?: string) {
83
+ if (!srcImage) {
84
+ return
85
+ }
86
+
87
+ if (srcImage.startsWith('ipfs://')) {
88
+ const [, imageId] = srcImage.split('://')
89
+
90
+ return `https://ghostmarket.mypinata.cloud/ipfs/${imageId}`
91
+ }
92
+
93
+ return srcImage
94
+ }
95
+
96
+ private getUrlWithParams(params: any) {
97
+ const parameters = qs.stringify(
98
+ {
99
+ chain: GHOSTMARKET_CHAIN_BY_NETWORK_TYPE[this.networkType],
100
+ ...params,
101
+ },
102
+ { arrayFormat: 'bracket' }
103
+ )
104
+ return `${GHOSTMARKET_URL_BY_NETWORK_TYPE[this.networkType]}/assets?${parameters}`
105
+ }
106
+
107
+ private parse(data: GhostMarketNFT) {
108
+ const nftResponse: NftResponse = {
109
+ collectionImage: this.treatGhostMarketImage(data.collection?.logoUrl),
110
+ id: data.tokenId,
111
+ contractHash: data.contract.hash,
112
+ symbol: data.contract.symbol,
113
+ collectionName: data.collection?.name,
114
+ image: this.treatGhostMarketImage(data.metadata.mediaUri),
115
+ isSVG: String(data.metadata.mediaType).includes('svg+xml'),
116
+ name: data.metadata.name,
117
+ }
118
+
119
+ return nftResponse
120
+ }
121
+ }
@@ -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 { 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
+ })