@cityofzion/bs-neo3 0.10.0 → 0.11.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.
- package/dist/BSNeo3.d.ts +3 -2
- package/dist/BSNeo3.js +23 -6
- package/dist/DoraBDSNeo3.d.ts +0 -1
- package/dist/DoraBDSNeo3.js +11 -12
- package/dist/DoraESNeo3.d.ts +1 -1
- package/dist/DoraESNeo3.js +19 -5
- package/dist/FlamingoEDSNeo3.d.ts +1 -2
- package/dist/FlamingoEDSNeo3.js +20 -5
- package/dist/GhostMarketNDSNeo3.d.ts +1 -1
- package/dist/GhostMarketNDSNeo3.js +17 -3
- package/dist/LedgerServiceNeo3.d.ts +3 -1
- package/dist/LedgerServiceNeo3.js +3 -0
- package/dist/RpcBDSNeo3.d.ts +4 -4
- package/dist/RpcBDSNeo3.js +17 -17
- package/package.json +6 -3
- package/.eslintignore +0 -13
- package/.eslintrc.cjs +0 -22
- package/.rush/temp/operation/build/all.log +0 -1
- package/.rush/temp/operation/build/state.json +0 -3
- package/.rush/temp/package-deps_build.json +0 -32
- package/.rush/temp/shrinkwrap-deps.json +0 -520
- package/CHANGELOG.json +0 -83
- package/CHANGELOG.md +0 -40
- package/bs-neo3.build.log +0 -1
- package/jest.config.ts +0 -13
- package/jest.setup.ts +0 -1
- package/src/BSNeo3.ts +0 -254
- package/src/DoraBDSNeo3.ts +0 -188
- package/src/DoraESNeo3.ts +0 -19
- package/src/FlamingoEDSNeo3.ts +0 -41
- package/src/GhostMarketNDSNeo3.ts +0 -121
- package/src/LedgerServiceNeo3.ts +0 -107
- package/src/RpcBDSNeo3.ts +0 -161
- package/src/__tests__/BDSNeo3.spec.ts +0 -124
- package/src/__tests__/BSNeo3.spec.ts +0 -175
- package/src/__tests__/DoraESNeo3.spec.ts +0 -23
- package/src/__tests__/FlamingoEDSNeo3.spec.ts +0 -48
- package/src/__tests__/GhostMarketNDSNeo3.spec.ts +0 -48
- package/src/__tests__/utils/sleep.ts +0 -1
- package/src/assets/tokens/common.json +0 -14
- package/src/assets/tokens/mainnet.json +0 -116
- package/src/constants.ts +0 -29
- package/src/index.ts +0 -6
- package/tsconfig.build.json +0 -4
- package/tsconfig.json +0 -14
package/CHANGELOG.json
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@cityofzion/bs-neo3",
|
|
3
|
-
"entries": [
|
|
4
|
-
{
|
|
5
|
-
"version": "0.10.0",
|
|
6
|
-
"tag": "@cityofzion/bs-neo3_v0.10.0",
|
|
7
|
-
"date": "Thu, 04 Apr 2024 19:52:20 GMT",
|
|
8
|
-
"comments": {
|
|
9
|
-
"minor": [
|
|
10
|
-
{
|
|
11
|
-
"comment": "Add ledger support"
|
|
12
|
-
}
|
|
13
|
-
],
|
|
14
|
-
"dependency": [
|
|
15
|
-
{
|
|
16
|
-
"comment": "Updating dependency \"@cityofzion/blockchain-service\" to `0.10.0`"
|
|
17
|
-
}
|
|
18
|
-
]
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"version": "0.9.3",
|
|
23
|
-
"tag": "@cityofzion/bs-neo3_v0.9.3",
|
|
24
|
-
"date": "Wed, 28 Feb 2024 17:43:01 GMT",
|
|
25
|
-
"comments": {
|
|
26
|
-
"patch": [
|
|
27
|
-
{
|
|
28
|
-
"comment": "Add creator infomations in nft methods return"
|
|
29
|
-
}
|
|
30
|
-
],
|
|
31
|
-
"dependency": [
|
|
32
|
-
{
|
|
33
|
-
"comment": "Updating dependency \"@cityofzion/blockchain-service\" to `0.9.1`"
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"version": "0.9.2",
|
|
40
|
-
"tag": "@cityofzion/bs-neo3_v0.9.2",
|
|
41
|
-
"date": "Tue, 30 Jan 2024 18:26:00 GMT",
|
|
42
|
-
"comments": {
|
|
43
|
-
"patch": [
|
|
44
|
-
{
|
|
45
|
-
"comment": "Fixed bug preventing decryption in dev mode in React Native"
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
"comment": "Fixed lint errors that were preventing the build"
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
"version": "0.9.1",
|
|
55
|
-
"tag": "@cityofzion/bs-neo3_v0.9.1",
|
|
56
|
-
"date": "Wed, 06 Dec 2023 21:51:30 GMT",
|
|
57
|
-
"comments": {
|
|
58
|
-
"patch": [
|
|
59
|
-
{
|
|
60
|
-
"comment": "Prevent the getAllTransaction method from breaking when Dora returns data from v1"
|
|
61
|
-
}
|
|
62
|
-
]
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
"version": "0.9.0",
|
|
67
|
-
"tag": "@cityofzion/bs-neo3_v0.9.0",
|
|
68
|
-
"date": "Tue, 05 Dec 2023 18:42:10 GMT",
|
|
69
|
-
"comments": {
|
|
70
|
-
"minor": [
|
|
71
|
-
{
|
|
72
|
-
"comment": "Inserted within the TokenPricesResponse type the token hash"
|
|
73
|
-
}
|
|
74
|
-
],
|
|
75
|
-
"dependency": [
|
|
76
|
-
{
|
|
77
|
-
"comment": "Updating dependency \"@cityofzion/blockchain-service\" to `0.9.0`"
|
|
78
|
-
}
|
|
79
|
-
]
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
]
|
|
83
|
-
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# Change Log - @cityofzion/bs-neo3
|
|
2
|
-
|
|
3
|
-
This log was last generated on Thu, 04 Apr 2024 19:52:20 GMT and should not be manually modified.
|
|
4
|
-
|
|
5
|
-
## 0.10.0
|
|
6
|
-
Thu, 04 Apr 2024 19:52:20 GMT
|
|
7
|
-
|
|
8
|
-
### Minor changes
|
|
9
|
-
|
|
10
|
-
- Add ledger support
|
|
11
|
-
|
|
12
|
-
## 0.9.3
|
|
13
|
-
Wed, 28 Feb 2024 17:43:01 GMT
|
|
14
|
-
|
|
15
|
-
### Patches
|
|
16
|
-
|
|
17
|
-
- Add creator infomations in nft methods return
|
|
18
|
-
|
|
19
|
-
## 0.9.2
|
|
20
|
-
Tue, 30 Jan 2024 18:26:00 GMT
|
|
21
|
-
|
|
22
|
-
### Patches
|
|
23
|
-
|
|
24
|
-
- Fixed bug preventing decryption in dev mode in React Native
|
|
25
|
-
- Fixed lint errors that were preventing the build
|
|
26
|
-
|
|
27
|
-
## 0.9.1
|
|
28
|
-
Wed, 06 Dec 2023 21:51:30 GMT
|
|
29
|
-
|
|
30
|
-
### Patches
|
|
31
|
-
|
|
32
|
-
- Prevent the getAllTransaction method from breaking when Dora returns data from v1
|
|
33
|
-
|
|
34
|
-
## 0.9.0
|
|
35
|
-
Tue, 05 Dec 2023 18:42:10 GMT
|
|
36
|
-
|
|
37
|
-
### Minor changes
|
|
38
|
-
|
|
39
|
-
- Inserted within the TokenPricesResponse type the token hash
|
|
40
|
-
|
package/bs-neo3.build.log
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Invoking: tsc --project tsconfig.build.json
|
package/jest.config.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { JestConfigWithTsJest } from 'ts-jest'
|
|
2
|
-
const config: JestConfigWithTsJest = {
|
|
3
|
-
preset: 'ts-jest',
|
|
4
|
-
testEnvironment: 'node',
|
|
5
|
-
clearMocks: true,
|
|
6
|
-
verbose: true,
|
|
7
|
-
bail: true,
|
|
8
|
-
testMatch: ['<rootDir>/**/*.spec.ts'],
|
|
9
|
-
setupFiles: ['<rootDir>/jest.setup.ts'],
|
|
10
|
-
detectOpenHandles: true,
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export default config
|
package/jest.setup.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import 'dotenv/config'
|
package/src/BSNeo3.ts
DELETED
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BlockchainDataService,
|
|
3
|
-
BlockchainService,
|
|
4
|
-
BSClaimable,
|
|
5
|
-
Account,
|
|
6
|
-
ExchangeDataService,
|
|
7
|
-
BDSClaimable,
|
|
8
|
-
Token,
|
|
9
|
-
BSWithNameService,
|
|
10
|
-
Network,
|
|
11
|
-
PartialBy,
|
|
12
|
-
TransferParam,
|
|
13
|
-
BSCalculableFee,
|
|
14
|
-
NftDataService,
|
|
15
|
-
BSWithNft,
|
|
16
|
-
AccountWithDerivationPath,
|
|
17
|
-
BSWithExplorerService,
|
|
18
|
-
ExplorerService,
|
|
19
|
-
BSWithLedger,
|
|
20
|
-
} from '@cityofzion/blockchain-service'
|
|
21
|
-
import { api, u, wallet } from '@cityofzion/neon-js'
|
|
22
|
-
import Neon from '@cityofzion/neon-core'
|
|
23
|
-
import { NeonInvoker, NeonParser } from '@cityofzion/neon-dappkit'
|
|
24
|
-
import { RPCBDSNeo3 } from './RpcBDSNeo3'
|
|
25
|
-
import { DoraBDSNeo3 } from './DoraBDSNeo3'
|
|
26
|
-
import { DEFAULT_URL_BY_NETWORK_TYPE, DERIVATION_PATH, NEO_NS_HASH, TOKENS } from './constants'
|
|
27
|
-
import { FlamingoEDSNeo3 } from './FlamingoEDSNeo3'
|
|
28
|
-
import { GhostMarketNDSNeo3 } from './GhostMarketNDSNeo3'
|
|
29
|
-
import { keychain } from '@cityofzion/bs-asteroid-sdk'
|
|
30
|
-
import { DoraESNeo3 } from './DoraESNeo3'
|
|
31
|
-
import { ContractInvocation } from '@cityofzion/neon-dappkit-types'
|
|
32
|
-
import { LedgerServiceNeo3 } from './LedgerServiceNeo3'
|
|
33
|
-
|
|
34
|
-
export class BSNeo3<BSCustomName extends string = string>
|
|
35
|
-
implements
|
|
36
|
-
BlockchainService,
|
|
37
|
-
BSClaimable,
|
|
38
|
-
BSWithNameService,
|
|
39
|
-
BSCalculableFee,
|
|
40
|
-
BSWithNft,
|
|
41
|
-
BSWithExplorerService,
|
|
42
|
-
BSWithLedger
|
|
43
|
-
{
|
|
44
|
-
readonly blockchainName: BSCustomName
|
|
45
|
-
readonly feeToken: Token
|
|
46
|
-
readonly claimToken: Token
|
|
47
|
-
readonly burnToken: Token
|
|
48
|
-
readonly derivationPath: string
|
|
49
|
-
|
|
50
|
-
blockchainDataService!: BlockchainDataService & BDSClaimable
|
|
51
|
-
nftDataService!: NftDataService
|
|
52
|
-
ledgerService: LedgerServiceNeo3 = new LedgerServiceNeo3()
|
|
53
|
-
exchangeDataService!: ExchangeDataService
|
|
54
|
-
explorerService!: ExplorerService
|
|
55
|
-
tokens: Token[]
|
|
56
|
-
network!: Network
|
|
57
|
-
|
|
58
|
-
constructor(blockchainName: BSCustomName, network: PartialBy<Network, 'url'>) {
|
|
59
|
-
this.blockchainName = blockchainName
|
|
60
|
-
this.tokens = TOKENS[network.type]
|
|
61
|
-
|
|
62
|
-
this.derivationPath = DERIVATION_PATH
|
|
63
|
-
this.feeToken = this.tokens.find(token => token.symbol === 'GAS')!
|
|
64
|
-
this.burnToken = this.tokens.find(token => token.symbol === 'NEO')!
|
|
65
|
-
this.claimToken = this.tokens.find(token => token.symbol === 'GAS')!
|
|
66
|
-
this.setNetwork(network)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
setNetwork(param: PartialBy<Network, 'url'>) {
|
|
70
|
-
const network = {
|
|
71
|
-
type: param.type,
|
|
72
|
-
url: param.url ?? DEFAULT_URL_BY_NETWORK_TYPE[param.type],
|
|
73
|
-
}
|
|
74
|
-
this.network = network
|
|
75
|
-
|
|
76
|
-
if (network.type === 'custom') {
|
|
77
|
-
this.blockchainDataService = new RPCBDSNeo3(network, this.feeToken, this.claimToken)
|
|
78
|
-
} else {
|
|
79
|
-
this.blockchainDataService = new DoraBDSNeo3(network, this.feeToken, this.claimToken)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
this.exchangeDataService = new FlamingoEDSNeo3(network.type)
|
|
83
|
-
this.nftDataService = new GhostMarketNDSNeo3(network.type)
|
|
84
|
-
this.explorerService = new DoraESNeo3(network.type)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
validateAddress(address: string): boolean {
|
|
88
|
-
return wallet.isAddress(address, 53)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
validateEncrypted(encryptedKey: string): boolean {
|
|
92
|
-
return wallet.isNEP2(encryptedKey)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
validateKey(key: string): boolean {
|
|
96
|
-
return wallet.isWIF(key) || wallet.isPrivateKey(key)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
validateNameServiceDomainFormat(domainName: string): boolean {
|
|
100
|
-
if (!domainName.endsWith('.neo')) return false
|
|
101
|
-
return true
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
generateAccountFromMnemonic(mnemonic: string[] | string, index: number): AccountWithDerivationPath {
|
|
105
|
-
keychain.importMnemonic(Array.isArray(mnemonic) ? mnemonic.join(' ') : mnemonic)
|
|
106
|
-
const path = this.derivationPath.replace('?', index.toString())
|
|
107
|
-
const childKey = keychain.generateChildKey('neo', path)
|
|
108
|
-
const key = childKey.getWIF()
|
|
109
|
-
const { address } = new wallet.Account(key)
|
|
110
|
-
return { address, key, type: 'wif', derivationPath: path }
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
generateAccountFromPublicKey(publicKey: string): Account {
|
|
114
|
-
if (!wallet.isPublicKey(publicKey)) throw new Error('Invalid public key')
|
|
115
|
-
|
|
116
|
-
const account = new wallet.Account(publicKey)
|
|
117
|
-
|
|
118
|
-
return {
|
|
119
|
-
address: account.address,
|
|
120
|
-
key: account.publicKey,
|
|
121
|
-
type: 'publicKey',
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
generateAccountFromKey(key: string): Account {
|
|
126
|
-
const type = wallet.isWIF(key) ? 'wif' : wallet.isPrivateKey(key) ? 'privateKey' : undefined
|
|
127
|
-
if (!type) throw new Error('Invalid key')
|
|
128
|
-
|
|
129
|
-
const { address } = new wallet.Account(key)
|
|
130
|
-
return { address, key, type }
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async decrypt(encryptedKey: string, password: string): Promise<Account> {
|
|
134
|
-
let BsReactNativeDecrypt: any
|
|
135
|
-
|
|
136
|
-
try {
|
|
137
|
-
const { NativeModules } = require('react-native')
|
|
138
|
-
BsReactNativeDecrypt = NativeModules.BsReactNativeDecrypt
|
|
139
|
-
|
|
140
|
-
if (!BsReactNativeDecrypt) {
|
|
141
|
-
throw new Error('@CityOfZion/bs-react-native-decrypt is not installed')
|
|
142
|
-
}
|
|
143
|
-
} catch {
|
|
144
|
-
const key = await wallet.decrypt(encryptedKey, password)
|
|
145
|
-
return this.generateAccountFromKey(key)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const privateKey = await BsReactNativeDecrypt.decryptNeo3(encryptedKey, password)
|
|
149
|
-
return this.generateAccountFromKey(privateKey)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
encrypt(key: string, password: string): Promise<string> {
|
|
153
|
-
return wallet.encrypt(key, password)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
async calculateTransferFee(param: TransferParam): Promise<string> {
|
|
157
|
-
const account = new wallet.Account(param.senderAccount.key)
|
|
158
|
-
|
|
159
|
-
const invoker = await NeonInvoker.init({
|
|
160
|
-
rpcAddress: this.network.url,
|
|
161
|
-
account,
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
const invocations = this.buildTransferInvocation(param, account)
|
|
165
|
-
|
|
166
|
-
const { total } = await invoker.calculateFee({
|
|
167
|
-
invocations,
|
|
168
|
-
signers: [],
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
return total.toString()
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
async transfer(param: TransferParam): Promise<string> {
|
|
175
|
-
const account = new wallet.Account(param.senderAccount.key)
|
|
176
|
-
|
|
177
|
-
const invoker = await NeonInvoker.init({
|
|
178
|
-
rpcAddress: this.network.url,
|
|
179
|
-
account,
|
|
180
|
-
signingCallback: param.isLedger ? this.ledgerService.getSigningCallback(param.ledgerTransport) : undefined,
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
const invocations = this.buildTransferInvocation(param, account)
|
|
184
|
-
|
|
185
|
-
const transactionHash = await invoker.invokeFunction({
|
|
186
|
-
invocations,
|
|
187
|
-
signers: [],
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
return transactionHash
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
async claim(account: Account): Promise<string> {
|
|
194
|
-
const neoAccount = new wallet.Account(account.key)
|
|
195
|
-
const facade = await api.NetworkFacade.fromConfig({ node: this.network.url })
|
|
196
|
-
|
|
197
|
-
const transactionHash = await facade.claimGas(neoAccount, {
|
|
198
|
-
signingCallback: api.signWithAccount(neoAccount),
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
return transactionHash
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
async resolveNameServiceDomain(domainName: string): Promise<any> {
|
|
205
|
-
const parser = NeonParser
|
|
206
|
-
const invoker = await NeonInvoker.init({ rpcAddress: this.network.url })
|
|
207
|
-
const response = await invoker.testInvoke({
|
|
208
|
-
invocations: [
|
|
209
|
-
{
|
|
210
|
-
scriptHash: NEO_NS_HASH,
|
|
211
|
-
operation: 'ownerOf',
|
|
212
|
-
args: [{ type: 'String', value: domainName }],
|
|
213
|
-
},
|
|
214
|
-
],
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
if (response.stack.length === 0) {
|
|
218
|
-
throw new Error(response.exception ?? 'unrecognized response')
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const parsed = parser.parseRpcResponse(response.stack[0] as any, {
|
|
222
|
-
type: 'Hash160',
|
|
223
|
-
})
|
|
224
|
-
const address = parser.accountInputToAddress(parsed.replace('0x', ''))
|
|
225
|
-
return address
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
private buildTransferInvocation(
|
|
229
|
-
{ intent, tipIntent }: TransferParam,
|
|
230
|
-
account: Neon.wallet.Account
|
|
231
|
-
): ContractInvocation[] {
|
|
232
|
-
const intents = [intent, ...(tipIntent ? [tipIntent] : [])]
|
|
233
|
-
|
|
234
|
-
const invocations: ContractInvocation[] = intents.map(intent => {
|
|
235
|
-
return {
|
|
236
|
-
operation: 'transfer',
|
|
237
|
-
scriptHash: intent.tokenHash,
|
|
238
|
-
args: [
|
|
239
|
-
{ type: 'Hash160', value: account.address },
|
|
240
|
-
{ type: 'Hash160', value: intent.receiverAddress },
|
|
241
|
-
{
|
|
242
|
-
type: 'Integer',
|
|
243
|
-
value: intent.tokenDecimals
|
|
244
|
-
? u.BigInteger.fromDecimal(intent.amount, intent.tokenDecimals).toString()
|
|
245
|
-
: intent.amount,
|
|
246
|
-
},
|
|
247
|
-
{ type: 'Any', value: '' },
|
|
248
|
-
],
|
|
249
|
-
}
|
|
250
|
-
})
|
|
251
|
-
|
|
252
|
-
return invocations
|
|
253
|
-
}
|
|
254
|
-
}
|
package/src/DoraBDSNeo3.ts
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BalanceResponse,
|
|
3
|
-
ContractResponse,
|
|
4
|
-
TransactionsByAddressParams,
|
|
5
|
-
TransactionsByAddressResponse,
|
|
6
|
-
TransactionResponse,
|
|
7
|
-
TransactionNotifications,
|
|
8
|
-
Network,
|
|
9
|
-
Token,
|
|
10
|
-
TransactionTransferNft,
|
|
11
|
-
TransactionTransferAsset,
|
|
12
|
-
} from '@cityofzion/blockchain-service'
|
|
13
|
-
import { wallet, u } from '@cityofzion/neon-js'
|
|
14
|
-
import { NeoRESTApi } from '@cityofzion/dora-ts/dist/api'
|
|
15
|
-
import { RPCBDSNeo3 } from './RpcBDSNeo3'
|
|
16
|
-
import { TOKENS } from './constants'
|
|
17
|
-
|
|
18
|
-
const NeoRest = new NeoRESTApi({
|
|
19
|
-
doraUrl: 'https://dora.coz.io',
|
|
20
|
-
endpoint: '/api/v2/neo3',
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
export class DoraBDSNeo3 extends RPCBDSNeo3 {
|
|
24
|
-
readonly network: Network
|
|
25
|
-
|
|
26
|
-
constructor(network: Network, feeToken: Token, claimToken: Token) {
|
|
27
|
-
if (network.type === 'custom') {
|
|
28
|
-
throw new Error('DoraBDSNeo3 does not support custom networks')
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
super(network, feeToken, claimToken)
|
|
32
|
-
this.network = network
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async getTransaction(hash: string): Promise<TransactionResponse> {
|
|
36
|
-
try {
|
|
37
|
-
const data = await NeoRest.transaction(hash, this.network.type)
|
|
38
|
-
return {
|
|
39
|
-
block: data.block,
|
|
40
|
-
time: Number(data.time),
|
|
41
|
-
hash: data.hash,
|
|
42
|
-
fee: u.BigInteger.fromNumber(data.netfee ?? 0)
|
|
43
|
-
.add(u.BigInteger.fromNumber(data.sysfee ?? 0))
|
|
44
|
-
.toDecimal(this.feeToken.decimals),
|
|
45
|
-
notifications: [],
|
|
46
|
-
transfers: [],
|
|
47
|
-
}
|
|
48
|
-
} catch {
|
|
49
|
-
throw new Error(`Transaction not found: ${hash}`)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async getTransactionsByAddress({
|
|
54
|
-
address,
|
|
55
|
-
page = 1,
|
|
56
|
-
}: TransactionsByAddressParams): Promise<TransactionsByAddressResponse> {
|
|
57
|
-
const data = await NeoRest.addressTXFull(address, page, this.network.type)
|
|
58
|
-
|
|
59
|
-
const promises = data.items.map(async (item): Promise<TransactionResponse> => {
|
|
60
|
-
const transferPromises: Promise<TransactionTransferAsset | TransactionTransferNft>[] = []
|
|
61
|
-
|
|
62
|
-
item.notifications.forEach(({ contract: contractHash, state, event_name: eventName }) => {
|
|
63
|
-
const properties = Array.isArray(state) ? state : state.value
|
|
64
|
-
if (eventName !== 'Transfer' || (properties.length !== 3 && properties.length !== 4)) return
|
|
65
|
-
|
|
66
|
-
const promise = async (): Promise<TransactionTransferAsset | TransactionTransferNft> => {
|
|
67
|
-
const isAsset = properties.length === 3
|
|
68
|
-
|
|
69
|
-
const from = properties[0].value
|
|
70
|
-
const to = properties[1].value
|
|
71
|
-
const convertedFrom = from ? this.convertByteStringToAddress(from) : 'Mint'
|
|
72
|
-
const convertedTo = to ? this.convertByteStringToAddress(to) : 'Burn'
|
|
73
|
-
|
|
74
|
-
if (isAsset) {
|
|
75
|
-
const token = await this.getTokenInfo(contractHash)
|
|
76
|
-
const [, , { value: amount }] = properties
|
|
77
|
-
return {
|
|
78
|
-
amount: u.BigInteger.fromNumber(amount).toDecimal(token.decimals ?? 0),
|
|
79
|
-
from: convertedFrom,
|
|
80
|
-
to: convertedTo,
|
|
81
|
-
contractHash,
|
|
82
|
-
type: 'token',
|
|
83
|
-
token,
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
from: convertedFrom,
|
|
89
|
-
to: convertedTo,
|
|
90
|
-
tokenId: properties[3].value,
|
|
91
|
-
contractHash,
|
|
92
|
-
type: 'nft',
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
transferPromises.push(promise())
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
const transfers = await Promise.all(transferPromises)
|
|
100
|
-
|
|
101
|
-
const notifications = item.notifications.map<TransactionNotifications>(notification => ({
|
|
102
|
-
eventName: notification.event_name,
|
|
103
|
-
state: notification.state as any,
|
|
104
|
-
}))
|
|
105
|
-
|
|
106
|
-
return {
|
|
107
|
-
block: item.block,
|
|
108
|
-
time: Number(item.time),
|
|
109
|
-
hash: item.hash,
|
|
110
|
-
fee: u.BigInteger.fromNumber(item.netfee ?? 0)
|
|
111
|
-
.add(u.BigInteger.fromNumber(item.sysfee ?? 0))
|
|
112
|
-
.toDecimal(this.feeToken.decimals),
|
|
113
|
-
transfers,
|
|
114
|
-
notifications,
|
|
115
|
-
}
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
const transactions = await Promise.all(promises)
|
|
119
|
-
|
|
120
|
-
return {
|
|
121
|
-
totalCount: data.totalCount,
|
|
122
|
-
transactions,
|
|
123
|
-
limit: 15,
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async getContract(contractHash: string): Promise<ContractResponse> {
|
|
128
|
-
try {
|
|
129
|
-
const data = await NeoRest.contract(contractHash, this.network.type)
|
|
130
|
-
return {
|
|
131
|
-
hash: data.hash,
|
|
132
|
-
methods: data.manifest.abi?.methods ?? [],
|
|
133
|
-
name: data.manifest.name,
|
|
134
|
-
}
|
|
135
|
-
} catch {
|
|
136
|
-
throw new Error(`Contract not found: ${contractHash}`)
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
async getTokenInfo(tokenHash: string): Promise<Token> {
|
|
141
|
-
const localToken = TOKENS[this.network.type].find(token => token.hash === tokenHash)
|
|
142
|
-
if (localToken) return localToken
|
|
143
|
-
|
|
144
|
-
if (this.tokenCache.has(tokenHash)) {
|
|
145
|
-
return this.tokenCache.get(tokenHash)!
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
-
const { decimals, symbol, name, scripthash } = await NeoRest.asset(tokenHash, this.network.type)
|
|
150
|
-
const token = {
|
|
151
|
-
decimals: Number(decimals),
|
|
152
|
-
symbol,
|
|
153
|
-
name,
|
|
154
|
-
hash: scripthash,
|
|
155
|
-
}
|
|
156
|
-
this.tokenCache.set(tokenHash, token)
|
|
157
|
-
|
|
158
|
-
return token
|
|
159
|
-
} catch {
|
|
160
|
-
throw new Error(`Token not found: ${tokenHash}`)
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
async getBalance(address: string): Promise<BalanceResponse[]> {
|
|
165
|
-
const response = await NeoRest.balance(address, this.network.type)
|
|
166
|
-
|
|
167
|
-
const promises = response.map<Promise<BalanceResponse | undefined>>(async balance => {
|
|
168
|
-
try {
|
|
169
|
-
const token = await this.getTokenInfo(balance.asset)
|
|
170
|
-
return {
|
|
171
|
-
amount: balance.balance.toString(),
|
|
172
|
-
token,
|
|
173
|
-
}
|
|
174
|
-
} catch {
|
|
175
|
-
// Empty block
|
|
176
|
-
}
|
|
177
|
-
})
|
|
178
|
-
const balances = await Promise.all(promises)
|
|
179
|
-
const filteredBalances = balances.filter(balance => balance !== undefined) as BalanceResponse[]
|
|
180
|
-
return filteredBalances
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
private convertByteStringToAddress(byteString: string): string {
|
|
184
|
-
const account = new wallet.Account(u.reverseHex(u.HexString.fromBase64(byteString).toString()))
|
|
185
|
-
|
|
186
|
-
return account.address
|
|
187
|
-
}
|
|
188
|
-
}
|
package/src/DoraESNeo3.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { ExplorerService, NetworkType, BuildNftUrlParams } from '@cityofzion/blockchain-service'
|
|
2
|
-
|
|
3
|
-
export class DoraESNeo3 implements ExplorerService {
|
|
4
|
-
private networkType: NetworkType
|
|
5
|
-
|
|
6
|
-
constructor(networkType: NetworkType) {
|
|
7
|
-
this.networkType = networkType
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
buildTransactionUrl(hash: string): string {
|
|
11
|
-
if (this.networkType === 'custom') throw new Error('DoraESNeo3 does not support custom network')
|
|
12
|
-
return `https://dora.coz.io/transaction/neo3/${this.networkType}/${hash}`
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
buildNftUrl({ contractHash, tokenId }: BuildNftUrlParams): string {
|
|
16
|
-
if (this.networkType === 'custom') throw new Error('DoraESNeo3 does not support custom network')
|
|
17
|
-
return `https://dora.coz.io/nft/neo3/${this.networkType}/${contractHash}/${tokenId}`
|
|
18
|
-
}
|
|
19
|
-
}
|
package/src/FlamingoEDSNeo3.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { Currency, ExchangeDataService, NetworkType, TokenPricesResponse } from '@cityofzion/blockchain-service'
|
|
2
|
-
import axios, { AxiosInstance } from 'axios'
|
|
3
|
-
|
|
4
|
-
type FlamingoTokenInfoPricesResponse = {
|
|
5
|
-
symbol: string
|
|
6
|
-
usd_price: number
|
|
7
|
-
hash: string
|
|
8
|
-
}[]
|
|
9
|
-
|
|
10
|
-
export class FlamingoEDSNeo3 implements ExchangeDataService {
|
|
11
|
-
readonly networkType: NetworkType
|
|
12
|
-
private axiosInstance: AxiosInstance
|
|
13
|
-
|
|
14
|
-
constructor(networkType: NetworkType) {
|
|
15
|
-
this.networkType = networkType
|
|
16
|
-
this.axiosInstance = axios.create({ baseURL: 'https://api.flamingo.finance' })
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async getTokenPrices(currency: Currency): Promise<TokenPricesResponse[]> {
|
|
20
|
-
if (this.networkType !== 'mainnet') throw new Error('Exchange is only available on mainnet')
|
|
21
|
-
|
|
22
|
-
const { data: prices } = await this.axiosInstance.get<FlamingoTokenInfoPricesResponse>('/token-info/prices')
|
|
23
|
-
|
|
24
|
-
let currencyRatio: number = 1
|
|
25
|
-
|
|
26
|
-
if (currency !== 'USD') {
|
|
27
|
-
currencyRatio = await this.getCurrencyRatio(currency)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return prices.map(price => ({
|
|
31
|
-
price: price.usd_price * currencyRatio,
|
|
32
|
-
symbol: price.symbol,
|
|
33
|
-
hash: price.hash,
|
|
34
|
-
}))
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
private async getCurrencyRatio(currency: Currency): Promise<number> {
|
|
38
|
-
const { data } = await this.axiosInstance.get<number>(`/fiat/exchange-rate?pair=USD_${currency}`)
|
|
39
|
-
return data
|
|
40
|
-
}
|
|
41
|
-
}
|