@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
package/package.json CHANGED
@@ -1,34 +1,34 @@
1
- {
2
- "name": "@cityofzion/bs-ethereum",
3
- "version": "0.8.2",
4
- "main": "dist/index.js",
5
- "types": "dist/index.d.ts",
6
- "repository": "https://github.com/CityOfZion/blockchain-services",
7
- "author": "Coz",
8
- "license": "MIT",
9
- "scripts": {
10
- "build": "tsc --project tsconfig.build.json",
11
- "test": "jest --config jest.config.ts"
12
- },
13
- "dependencies": {
14
- "@cityofzion/blockchain-service": "^0.8.0",
15
- "ethers": "5.7.2",
16
- "@urql/core": "~4.1.1",
17
- "graphql": "~16.8.0",
18
- "node-fetch": "2.6.4",
19
- "dayjs": "~1.11.9",
20
- "query-string": "7.1.3",
21
- "@ethersproject/json-wallets": "5.7.0",
22
- "@ethersproject/bytes": "5.7.0",
23
- "@ethersproject/bignumber": "5.7.0"
24
- },
25
- "devDependencies": {
26
- "@types/node-fetch": "2.6.4",
27
- "ts-node": "10.9.1",
28
- "typescript": "4.9.5",
29
- "jest": "29.6.2",
30
- "ts-jest": "29.1.1",
31
- "@types/jest": "29.5.3",
32
- "dotenv": "16.3.1"
33
- }
34
- }
1
+ {
2
+ "name": "@cityofzion/bs-ethereum",
3
+ "version": "0.9.0",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "repository": "https://github.com/CityOfZion/blockchain-services",
7
+ "author": "Coz",
8
+ "license": "MIT",
9
+ "dependencies": {
10
+ "ethers": "5.7.2",
11
+ "@urql/core": "~4.1.1",
12
+ "graphql": "~16.8.0",
13
+ "node-fetch": "2.6.4",
14
+ "dayjs": "~1.11.9",
15
+ "query-string": "7.1.3",
16
+ "@ethersproject/json-wallets": "5.7.0",
17
+ "@ethersproject/bytes": "5.7.0",
18
+ "@ethersproject/bignumber": "5.7.0",
19
+ "@cityofzion/blockchain-service": "0.9.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node-fetch": "2.6.4",
23
+ "ts-node": "10.9.1",
24
+ "typescript": "4.9.5",
25
+ "jest": "29.6.2",
26
+ "ts-jest": "29.1.1",
27
+ "@types/jest": "29.5.3",
28
+ "dotenv": "16.3.1"
29
+ },
30
+ "scripts": {
31
+ "build": "tsc --project tsconfig.build.json",
32
+ "test": "jest --config jest.config.ts"
33
+ }
34
+ }
package/src/BSEthereum.ts CHANGED
@@ -1,184 +1,189 @@
1
- import {
2
- Account,
3
- AccountWithDerivationPath,
4
- BSCalculableFee,
5
- BSWithNameService,
6
- BSWithNft,
7
- BlockchainDataService,
8
- BlockchainService,
9
- ExchangeDataService,
10
- Network,
11
- NftDataService,
12
- PartialBy,
13
- Token,
14
- TransferParam,
15
- } from '@cityofzion/blockchain-service'
16
- import { ethers } from 'ethers'
17
- import * as ethersJsonWallets from '@ethersproject/json-wallets'
18
- import * as ethersBytes from '@ethersproject/bytes'
19
- import * as ethersBigNumber from '@ethersproject/bignumber'
20
- import { DEFAULT_URL_BY_NETWORK_TYPE, DERIVATION_PATH, NATIVE_ASSETS, TOKENS } from './constants'
21
- import { BitqueryEDSEthereum } from './BitqueryEDSEthereum'
22
- import { GhostMarketNDSEthereum } from './GhostMarketNDSEthereum'
23
- import { RpcBDSEthereum } from './RpcBDSEthereum'
24
- import { BitqueryBDSEthereum } from './BitqueryBDSEthereum'
25
-
26
- export class BSEthereum<BSCustomName extends string = string>
27
- implements BlockchainService, BSWithNft, BSWithNameService, BSCalculableFee
28
- {
29
- readonly blockchainName: BSCustomName
30
- readonly feeToken: Token
31
- readonly derivationPath: string
32
-
33
- blockchainDataService!: BlockchainDataService
34
- exchangeDataService!: ExchangeDataService
35
- tokens: Token[]
36
- nftDataService!: NftDataService
37
- network!: Network
38
-
39
- constructor(blockchainName: BSCustomName, network: PartialBy<Network, 'url'>) {
40
- this.blockchainName = blockchainName
41
- this.derivationPath = DERIVATION_PATH
42
- this.tokens = TOKENS[network.type]
43
-
44
- this.feeToken = this.tokens.find(token => token.symbol === 'ETH')!
45
- this.setNetwork(network)
46
- }
47
-
48
- setNetwork(param: PartialBy<Network, 'url'>) {
49
- const network = {
50
- type: param.type,
51
- url: param.url ?? DEFAULT_URL_BY_NETWORK_TYPE[param.type],
52
- }
53
- this.network = network
54
-
55
- if (network.type === 'custom') {
56
- this.blockchainDataService = new RpcBDSEthereum(network)
57
- } else {
58
- this.blockchainDataService = new BitqueryBDSEthereum(network)
59
- }
60
-
61
- this.exchangeDataService = new BitqueryEDSEthereum(network.type)
62
- this.nftDataService = new GhostMarketNDSEthereum(network.type)
63
- }
64
-
65
- validateAddress(address: string): boolean {
66
- return ethers.utils.isAddress(address)
67
- }
68
-
69
- validateEncrypted(json: string): boolean {
70
- return ethersJsonWallets.isCrowdsaleWallet(json) || ethersJsonWallets.isKeystoreWallet(json)
71
- }
72
-
73
- validateKey(key: string): boolean {
74
- try {
75
- if (!key.startsWith('0x')) {
76
- key = '0x' + key
77
- }
78
- if (ethersBytes.hexDataLength(key) !== 32) return false
79
-
80
- return true
81
- } catch (error) {
82
- return false
83
- }
84
- }
85
-
86
- validateNameServiceDomainFormat(domainName: string): boolean {
87
- if (!domainName.endsWith('.eth')) return false
88
- return true
89
- }
90
-
91
- generateAccountFromMnemonic(mnemonic: string[] | string, index: number): AccountWithDerivationPath {
92
- const path = this.derivationPath.replace('?', index.toString())
93
- const wallet = ethers.Wallet.fromMnemonic(Array.isArray(mnemonic) ? mnemonic.join(' ') : mnemonic, path)
94
-
95
- return {
96
- address: wallet.address,
97
- key: wallet.privateKey,
98
- type: 'privateKey',
99
- derivationPath: path,
100
- }
101
- }
102
-
103
- generateAccountFromKey(key: string): Account {
104
- const wallet = new ethers.Wallet(key)
105
- return {
106
- address: wallet.address,
107
- key,
108
- type: 'privateKey',
109
- }
110
- }
111
-
112
- async decrypt(json: string, password: string): Promise<Account> {
113
- const wallet = await ethers.Wallet.fromEncryptedJson(json, password)
114
- return {
115
- address: wallet.address,
116
- key: wallet.privateKey,
117
- type: 'privateKey',
118
- }
119
- }
120
-
121
- async transfer({ senderAccount, intent }: TransferParam): Promise<string> {
122
- const provider = new ethers.providers.JsonRpcProvider(this.network.url)
123
- const wallet = new ethers.Wallet(senderAccount.key, provider)
124
-
125
- let transaction: ethers.providers.TransactionResponse
126
- const decimals = intent.tokenDecimals ?? 18
127
- const amount = ethersBigNumber.parseFixed(intent.amount, decimals)
128
-
129
- const isNative = NATIVE_ASSETS.some(asset => asset.hash === intent.tokenHash)
130
- if (!isNative) {
131
- const contract = new ethers.Contract(
132
- intent.tokenHash,
133
- ['function transfer(address to, uint amount) returns (bool)'],
134
- wallet
135
- )
136
- transaction = await contract.transfer(intent.receiverAddress, amount)
137
- } else {
138
- transaction = await wallet.sendTransaction({
139
- to: intent.receiverAddress,
140
- value: amount,
141
- })
142
- }
143
-
144
- const transactionMined = await transaction.wait()
145
- if (!transactionMined) throw new Error('Transaction not mined')
146
-
147
- return transactionMined.transactionHash
148
- }
149
-
150
- async calculateTransferFee({ senderAccount, intent }: TransferParam, details?: boolean | undefined): Promise<string> {
151
- const provider = new ethers.providers.JsonRpcProvider(this.network.url)
152
- const wallet = new ethers.Wallet(senderAccount.key, provider)
153
-
154
- let estimated: ethers.BigNumber
155
-
156
- const isNative = NATIVE_ASSETS.some(asset => asset.hash === intent.tokenHash)
157
- const decimals = intent.tokenDecimals ?? 18
158
- const amount = ethersBigNumber.parseFixed(intent.amount, decimals)
159
-
160
- if (!isNative) {
161
- const contract = new ethers.Contract(
162
- intent.tokenHash,
163
- ['function transfer(address to, uint amount) returns (bool)'],
164
- wallet
165
- )
166
-
167
- estimated = await contract.estimateGas.transfer(intent.receiverAddress, amount)
168
- } else {
169
- estimated = await wallet.estimateGas({
170
- to: intent.receiverAddress,
171
- value: amount,
172
- })
173
- }
174
-
175
- return ethers.utils.formatEther(estimated)
176
- }
177
-
178
- async resolveNameServiceDomain(domainName: string): Promise<string> {
179
- const provider = new ethers.providers.JsonRpcProvider(this.network.url)
180
- const address = await provider.resolveName(domainName)
181
- if (!address) throw new Error('No address found for domain name')
182
- return address
183
- }
184
- }
1
+ import {
2
+ Account,
3
+ AccountWithDerivationPath,
4
+ BSCalculableFee,
5
+ BSWithNameService,
6
+ BSWithNft,
7
+ BlockchainDataService,
8
+ BlockchainService,
9
+ ExchangeDataService,
10
+ Network,
11
+ NftDataService,
12
+ PartialBy,
13
+ Token,
14
+ TransferParam,
15
+ } from '@cityofzion/blockchain-service'
16
+ import { ethers } from 'ethers'
17
+ import * as ethersJsonWallets from '@ethersproject/json-wallets'
18
+ import * as ethersBytes from '@ethersproject/bytes'
19
+ import * as ethersBigNumber from '@ethersproject/bignumber'
20
+ import { DEFAULT_URL_BY_NETWORK_TYPE, DERIVATION_PATH, NATIVE_ASSETS, TOKENS } from './constants'
21
+ import { BitqueryEDSEthereum } from './BitqueryEDSEthereum'
22
+ import { GhostMarketNDSEthereum } from './GhostMarketNDSEthereum'
23
+ import { RpcBDSEthereum } from './RpcBDSEthereum'
24
+ import { BitqueryBDSEthereum } from './BitqueryBDSEthereum'
25
+
26
+ export class BSEthereum<BSCustomName extends string = string>
27
+ implements BlockchainService, BSWithNft, BSWithNameService, BSCalculableFee
28
+ {
29
+ readonly blockchainName: BSCustomName
30
+ readonly feeToken: Token
31
+ readonly derivationPath: string
32
+
33
+ blockchainDataService!: BlockchainDataService
34
+ exchangeDataService!: ExchangeDataService
35
+ tokens: Token[]
36
+ nftDataService!: NftDataService
37
+ network!: Network
38
+
39
+ constructor(blockchainName: BSCustomName, network: PartialBy<Network, 'url'>) {
40
+ this.blockchainName = blockchainName
41
+ this.derivationPath = DERIVATION_PATH
42
+ this.tokens = TOKENS[network.type]
43
+
44
+ this.feeToken = this.tokens.find(token => token.symbol === 'ETH')!
45
+ this.setNetwork(network)
46
+ }
47
+
48
+ setNetwork(param: PartialBy<Network, 'url'>) {
49
+ const network = {
50
+ type: param.type,
51
+ url: param.url ?? DEFAULT_URL_BY_NETWORK_TYPE[param.type],
52
+ }
53
+ this.network = network
54
+
55
+ if (network.type === 'custom') {
56
+ this.blockchainDataService = new RpcBDSEthereum(network)
57
+ } else {
58
+ this.blockchainDataService = new BitqueryBDSEthereum(network)
59
+ }
60
+
61
+ this.exchangeDataService = new BitqueryEDSEthereum(network.type)
62
+ this.nftDataService = new GhostMarketNDSEthereum(network.type)
63
+ }
64
+
65
+ validateAddress(address: string): boolean {
66
+ return ethers.utils.isAddress(address)
67
+ }
68
+
69
+ validateEncrypted(json: string): boolean {
70
+ return ethersJsonWallets.isCrowdsaleWallet(json) || ethersJsonWallets.isKeystoreWallet(json)
71
+ }
72
+
73
+ validateKey(key: string): boolean {
74
+ try {
75
+ if (!key.startsWith('0x')) {
76
+ key = '0x' + key
77
+ }
78
+ if (ethersBytes.hexDataLength(key) !== 32) return false
79
+
80
+ return true
81
+ } catch (error) {
82
+ return false
83
+ }
84
+ }
85
+
86
+ validateNameServiceDomainFormat(domainName: string): boolean {
87
+ if (!domainName.endsWith('.eth')) return false
88
+ return true
89
+ }
90
+
91
+ generateAccountFromMnemonic(mnemonic: string[] | string, index: number): AccountWithDerivationPath {
92
+ const path = this.derivationPath.replace('?', index.toString())
93
+ const wallet = ethers.Wallet.fromMnemonic(Array.isArray(mnemonic) ? mnemonic.join(' ') : mnemonic, path)
94
+
95
+ return {
96
+ address: wallet.address,
97
+ key: wallet.privateKey,
98
+ type: 'privateKey',
99
+ derivationPath: path,
100
+ }
101
+ }
102
+
103
+ generateAccountFromKey(key: string): Account {
104
+ const wallet = new ethers.Wallet(key)
105
+ return {
106
+ address: wallet.address,
107
+ key,
108
+ type: 'privateKey',
109
+ }
110
+ }
111
+
112
+ async decrypt(json: string, password: string): Promise<Account> {
113
+ const wallet = await ethers.Wallet.fromEncryptedJson(json, password)
114
+ return {
115
+ address: wallet.address,
116
+ key: wallet.privateKey,
117
+ type: 'privateKey',
118
+ }
119
+ }
120
+
121
+ async encrypt(key: string, password: string): Promise<string> {
122
+ const wallet = new ethers.Wallet(key)
123
+ return wallet.encrypt(password)
124
+ }
125
+
126
+ async transfer({ senderAccount, intent }: TransferParam): Promise<string> {
127
+ const provider = new ethers.providers.JsonRpcProvider(this.network.url)
128
+ const wallet = new ethers.Wallet(senderAccount.key, provider)
129
+
130
+ let transaction: ethers.providers.TransactionResponse
131
+ const decimals = intent.tokenDecimals ?? 18
132
+ const amount = ethersBigNumber.parseFixed(intent.amount, decimals)
133
+
134
+ const isNative = NATIVE_ASSETS.some(asset => asset.hash === intent.tokenHash)
135
+ if (!isNative) {
136
+ const contract = new ethers.Contract(
137
+ intent.tokenHash,
138
+ ['function transfer(address to, uint amount) returns (bool)'],
139
+ wallet
140
+ )
141
+ transaction = await contract.transfer(intent.receiverAddress, amount)
142
+ } else {
143
+ transaction = await wallet.sendTransaction({
144
+ to: intent.receiverAddress,
145
+ value: amount,
146
+ })
147
+ }
148
+
149
+ const transactionMined = await transaction.wait()
150
+ if (!transactionMined) throw new Error('Transaction not mined')
151
+
152
+ return transactionMined.transactionHash
153
+ }
154
+
155
+ async calculateTransferFee({ senderAccount, intent }: TransferParam, details?: boolean | undefined): Promise<string> {
156
+ const provider = new ethers.providers.JsonRpcProvider(this.network.url)
157
+ const wallet = new ethers.Wallet(senderAccount.key, provider)
158
+
159
+ let estimated: ethers.BigNumber
160
+
161
+ const isNative = NATIVE_ASSETS.some(asset => asset.hash === intent.tokenHash)
162
+ const decimals = intent.tokenDecimals ?? 18
163
+ const amount = ethersBigNumber.parseFixed(intent.amount, decimals)
164
+
165
+ if (!isNative) {
166
+ const contract = new ethers.Contract(
167
+ intent.tokenHash,
168
+ ['function transfer(address to, uint amount) returns (bool)'],
169
+ wallet
170
+ )
171
+
172
+ estimated = await contract.estimateGas.transfer(intent.receiverAddress, amount)
173
+ } else {
174
+ estimated = await wallet.estimateGas({
175
+ to: intent.receiverAddress,
176
+ value: amount,
177
+ })
178
+ }
179
+
180
+ return ethers.utils.formatEther(estimated)
181
+ }
182
+
183
+ async resolveNameServiceDomain(domainName: string): Promise<string> {
184
+ const provider = new ethers.providers.JsonRpcProvider(this.network.url)
185
+ const address = await provider.resolveName(domainName)
186
+ if (!address) throw new Error('No address found for domain name')
187
+ return address
188
+ }
189
+ }