@cityofzion/bs-neo3 0.7.0 → 0.7.2
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/.rush/temp/package-deps_build.json +21 -16
- package/bs-neo3.build.log +2 -2
- package/dist/BSNeo3.d.ts +24 -37
- package/dist/BSNeo3.js +130 -198
- package/dist/DoraBDSNeo3.d.ts +12 -0
- package/dist/DoraBDSNeo3.js +169 -0
- package/dist/FlamingoEDSNeo3.d.ts +8 -0
- package/dist/FlamingoEDSNeo3.js +44 -0
- package/dist/GhostMarketNDSNeo3.d.ts +10 -0
- package/dist/GhostMarketNDSNeo3.js +75 -0
- package/dist/RpcBDSNeo3.d.ts +15 -0
- package/dist/RpcBDSNeo3.js +152 -0
- package/dist/assets/tokens/common.json +14 -0
- package/dist/assets/tokens/mainnet.json +116 -0
- package/dist/constants.d.ts +7 -10
- package/dist/constants.js +24 -9
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/package.json +3 -3
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"files": {
|
|
3
|
-
"packages/bs-neo3/
|
|
4
|
-
"packages/bs-neo3/
|
|
5
|
-
"packages/bs-neo3/
|
|
6
|
-
"packages/bs-neo3/src/
|
|
7
|
-
"packages/bs-neo3/src/
|
|
8
|
-
"packages/bs-neo3/src/
|
|
9
|
-
"packages/bs-neo3/src/
|
|
10
|
-
"packages/bs-neo3/src/
|
|
11
|
-
"packages/bs-neo3/src/
|
|
12
|
-
"packages/bs-neo3/src/
|
|
13
|
-
"packages/bs-neo3/src/
|
|
14
|
-
"packages/bs-neo3/src/
|
|
15
|
-
"packages/bs-neo3/
|
|
16
|
-
"packages/bs-neo3/
|
|
17
|
-
"packages/bs-neo3
|
|
3
|
+
"packages/bs-neo3/jest.config.ts": "d944475db93cbe41a9339187fd94b9962e411c43",
|
|
4
|
+
"packages/bs-neo3/jest.setup.ts": "9a1976a32050616d4d2ee95b1aa21041bc4daca3",
|
|
5
|
+
"packages/bs-neo3/package.json": "bba7849ac64221394efc7a7b35a9ad6ac81a7c08",
|
|
6
|
+
"packages/bs-neo3/src/BSNeo3.ts": "ac98a87cfd542ac1fdd1b2166ba2acb78a274126",
|
|
7
|
+
"packages/bs-neo3/src/DoraBDSNeo3.ts": "f94ef94afe666bc0991f5dd8e880d8fec8ade099",
|
|
8
|
+
"packages/bs-neo3/src/FlamingoEDSNeo3.ts": "f5fbb9ff405b02079c31493ae251aaea5defb77d",
|
|
9
|
+
"packages/bs-neo3/src/GhostMarketNDSNeo3.ts": "d7db2a624cf099fe550fa4a906f6127ca4815cac",
|
|
10
|
+
"packages/bs-neo3/src/RpcBDSNeo3.ts": "a548f689b39b42ce00452b1fb8f772b6ebbf7683",
|
|
11
|
+
"packages/bs-neo3/src/__tests__/BDSNeo3.spec.ts": "14bd204f3d4546c81b6ea37e16f3fe6e70102dd1",
|
|
12
|
+
"packages/bs-neo3/src/__tests__/BSNeo3.spec.ts": "edf56afc2efaa15d252eaaca0325cee364191699",
|
|
13
|
+
"packages/bs-neo3/src/__tests__/FlamingoEDSNeo3.spec.ts": "17e3b6f4dee4cb2222f3b4b1aed9d9a68ea037c0",
|
|
14
|
+
"packages/bs-neo3/src/__tests__/GhostMarketNDSNeo3.spec.ts": "1d583380b60112fb99426b4bf140c92898177b1e",
|
|
15
|
+
"packages/bs-neo3/src/__tests__/utils/sleep.ts": "c1eb515dad9f5c11eef5d5e77c85db4c3c8196a8",
|
|
16
|
+
"packages/bs-neo3/src/assets/tokens/common.json": "04691656019ba9234129b749553aa75828e77ef8",
|
|
17
|
+
"packages/bs-neo3/src/assets/tokens/mainnet.json": "f43f1a67f07c0b85977cf17dae825ae7fbb8eb21",
|
|
18
|
+
"packages/bs-neo3/src/constants.ts": "233a2c83f1829629865ace6fbf9c66cd39489c51",
|
|
19
|
+
"packages/bs-neo3/src/index.ts": "bad314a9ba14b57075684c9b823a934863bac6b2",
|
|
20
|
+
"packages/bs-neo3/tsconfig.build.json": "4dc23fb9c4c5e4d19a9bc3947a47c523f4bd967c",
|
|
21
|
+
"packages/bs-neo3/tsconfig.json": "77cf2b789e9c665b62792f9992cc81ae86296ef7",
|
|
22
|
+
"common/config/rush/npm-shrinkwrap.json": "c7f58d681afa54f5c08d809a1ace9947b56fb633"
|
|
18
23
|
},
|
|
19
|
-
"arguments": "tsc
|
|
24
|
+
"arguments": "tsc --project tsconfig.build.json "
|
|
20
25
|
}
|
package/bs-neo3.build.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Invoking: tsc
|
|
2
|
-
|
|
1
|
+
Invoking: tsc --project tsconfig.build.json
|
|
2
|
+
|
package/dist/BSNeo3.d.ts
CHANGED
|
@@ -1,40 +1,27 @@
|
|
|
1
|
-
import { BlockchainDataService, BlockchainService,
|
|
2
|
-
export declare class BSNeo3<BSCustomName extends string = string> implements BlockchainService,
|
|
3
|
-
blockchainName: BSCustomName;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
exchange: Exchange;
|
|
12
|
-
tokenClaim: {
|
|
13
|
-
hash: string;
|
|
14
|
-
symbol: string;
|
|
15
|
-
decimals: number;
|
|
16
|
-
};
|
|
1
|
+
import { BlockchainDataService, BlockchainService, BSClaimable, Account, ExchangeDataService, BDSClaimable, Token, BSWithNameService, Network, PartialBy, TransferParam, BSCalculableFee, NftDataService, BSWithNft, AccountWithDerivationPath } from '@cityofzion/blockchain-service';
|
|
2
|
+
export declare class BSNeo3<BSCustomName extends string = string> implements BlockchainService, BSClaimable, BSWithNameService, BSCalculableFee, BSWithNft {
|
|
3
|
+
readonly blockchainName: BSCustomName;
|
|
4
|
+
readonly feeToken: Token;
|
|
5
|
+
readonly claimToken: Token;
|
|
6
|
+
readonly burnToken: Token;
|
|
7
|
+
readonly derivationPath: string;
|
|
8
|
+
blockchainDataService: BlockchainDataService & BDSClaimable;
|
|
9
|
+
nftDataService: NftDataService;
|
|
10
|
+
exchangeDataService: ExchangeDataService;
|
|
17
11
|
tokens: Token[];
|
|
18
|
-
|
|
19
|
-
constructor(blockchainName: BSCustomName);
|
|
20
|
-
|
|
21
|
-
private buildTransfer;
|
|
22
|
-
private signTransfer;
|
|
23
|
-
generateMnemonic(): string;
|
|
24
|
-
generateWif(mnemonic: string, index: number): string;
|
|
25
|
-
generateAccount(mnemonic: string, index: number): Account;
|
|
26
|
-
generateAccountFromWif(wif: string): string;
|
|
27
|
-
decryptKey(encryptedKey: string, password: string): Promise<Account>;
|
|
12
|
+
network: Network;
|
|
13
|
+
constructor(blockchainName: BSCustomName, network: PartialBy<Network, 'url'>);
|
|
14
|
+
setNetwork(param: PartialBy<Network, 'url'>): void;
|
|
28
15
|
validateAddress(address: string): boolean;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
16
|
+
validateEncrypted(encryptedKey: string): boolean;
|
|
17
|
+
validateKey(key: string): boolean;
|
|
18
|
+
validateNameServiceDomainFormat(domainName: string): boolean;
|
|
19
|
+
generateAccountFromMnemonic(mnemonic: string[] | string, index: number): AccountWithDerivationPath;
|
|
20
|
+
generateAccountFromKey(key: string): Account;
|
|
21
|
+
decrypt(encryptedKey: string, password: string): Promise<Account>;
|
|
22
|
+
calculateTransferFee(param: TransferParam): Promise<string>;
|
|
23
|
+
transfer(param: TransferParam): Promise<string>;
|
|
24
|
+
claim(account: Account): Promise<string>;
|
|
25
|
+
resolveNameServiceDomain(domainName: string): Promise<any>;
|
|
26
|
+
private buildTransferInvocation;
|
|
40
27
|
}
|
package/dist/BSNeo3.js
CHANGED
|
@@ -1,27 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -31,220 +8,175 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
31
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
9
|
});
|
|
33
10
|
};
|
|
34
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
-
};
|
|
37
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
12
|
exports.BSNeo3 = void 0;
|
|
39
|
-
const blockchain_service_1 = require("@cityofzion/blockchain-service");
|
|
40
13
|
const neon_js_1 = require("@cityofzion/neon-js");
|
|
41
|
-
const AsteroidSDK = __importStar(require("@moonlight-io/asteroid-sdk-js"));
|
|
42
|
-
const constants_1 = require("./constants");
|
|
43
|
-
const exceptions_1 = require("./exceptions");
|
|
44
|
-
const explorer_1 = require("./explorer");
|
|
45
|
-
const tokens_json_1 = __importDefault(require("./assets/tokens.json"));
|
|
46
14
|
const neon_invoker_1 = require("@cityofzion/neon-invoker");
|
|
47
15
|
const neon_parser_1 = require("@cityofzion/neon-parser");
|
|
48
16
|
const neo3_parser_1 = require("@cityofzion/neo3-parser");
|
|
49
|
-
const
|
|
17
|
+
const RpcBDSNeo3_1 = require("./RpcBDSNeo3");
|
|
18
|
+
const DoraBDSNeo3_1 = require("./DoraBDSNeo3");
|
|
19
|
+
const constants_1 = require("./constants");
|
|
20
|
+
const FlamingoEDSNeo3_1 = require("./FlamingoEDSNeo3");
|
|
21
|
+
const GhostMarketNDSNeo3_1 = require("./GhostMarketNDSNeo3");
|
|
22
|
+
const bs_asteroid_sdk_1 = require("@cityofzion/bs-asteroid-sdk");
|
|
50
23
|
class BSNeo3 {
|
|
51
|
-
constructor(blockchainName) {
|
|
52
|
-
this.dataService = explorer_1.explorerOptions.dora;
|
|
53
|
-
this.derivationPath = "m/44'/888'/0'/0/?";
|
|
54
|
-
this.feeToken = constants_1.gasInfoNeo3;
|
|
55
|
-
this.exchange = blockchain_service_1.exchangeOptions.flamingo;
|
|
56
|
-
this.tokenClaim = constants_1.neoInfoNeo3;
|
|
57
|
-
this.tokens = tokens_json_1.default;
|
|
58
|
-
this.keychain = new AsteroidSDK.Keychain();
|
|
24
|
+
constructor(blockchainName, network) {
|
|
59
25
|
this.blockchainName = blockchainName;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
catch (error) {
|
|
73
|
-
throw error;
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
buildTransfer(transactionIntents, account) {
|
|
78
|
-
const intents = [];
|
|
79
|
-
const neoAccount = new neon_js_1.wallet.Account(account.wif);
|
|
80
|
-
for (const transactionIntent of transactionIntents) {
|
|
81
|
-
const { amount, receiverAddress, tokenHash } = transactionIntent;
|
|
82
|
-
intents.push({
|
|
83
|
-
to: receiverAddress,
|
|
84
|
-
contractHash: tokenHash,
|
|
85
|
-
from: neoAccount,
|
|
86
|
-
decimalAmt: amount,
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
return intents;
|
|
90
|
-
}
|
|
91
|
-
signTransfer(account) {
|
|
92
|
-
const neoAccount = new neon_js_1.wallet.Account(account.address);
|
|
93
|
-
const result = {
|
|
94
|
-
signingCallback: neon_js_1.api.signWithAccount(neoAccount)
|
|
26
|
+
this.tokens = constants_1.TOKENS[network.type];
|
|
27
|
+
this.derivationPath = constants_1.DERIVATION_PATH;
|
|
28
|
+
this.feeToken = this.tokens.find(token => token.symbol === 'GAS');
|
|
29
|
+
this.burnToken = this.tokens.find(token => token.symbol === 'NEO');
|
|
30
|
+
this.claimToken = this.tokens.find(token => token.symbol === 'GAS');
|
|
31
|
+
this.setNetwork(network);
|
|
32
|
+
}
|
|
33
|
+
setNetwork(param) {
|
|
34
|
+
var _a;
|
|
35
|
+
const network = {
|
|
36
|
+
type: param.type,
|
|
37
|
+
url: (_a = param.url) !== null && _a !== void 0 ? _a : constants_1.DEFAULT_URL_BY_NETWORK_TYPE[param.type],
|
|
95
38
|
};
|
|
96
|
-
|
|
39
|
+
this.network = network;
|
|
40
|
+
if (network.type === 'custom') {
|
|
41
|
+
this.blockchainDataService = new RpcBDSNeo3_1.RPCBDSNeo3(network, this.feeToken, this.claimToken);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this.blockchainDataService = new DoraBDSNeo3_1.DoraBDSNeo3(network, this.feeToken, this.claimToken);
|
|
45
|
+
}
|
|
46
|
+
this.exchangeDataService = new FlamingoEDSNeo3_1.FlamingoEDSNeo3(network.type);
|
|
47
|
+
this.nftDataService = new GhostMarketNDSNeo3_1.GhostMarketNDSNeo3(network.type);
|
|
97
48
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
this.keychain.generateMnemonic(128);
|
|
101
|
-
const list = (_a = this.keychain.mnemonic) === null || _a === void 0 ? void 0 : _a.toString();
|
|
102
|
-
if (!list)
|
|
103
|
-
throw new Error("Failed to generate mnemonic");
|
|
104
|
-
return list;
|
|
49
|
+
validateAddress(address) {
|
|
50
|
+
return neon_js_1.wallet.isAddress(address, 53);
|
|
105
51
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const childKey = this.keychain.generateChildKey('neo', this.derivationPath.replace('?', index.toString()));
|
|
109
|
-
return childKey.getWIF();
|
|
52
|
+
validateEncrypted(encryptedKey) {
|
|
53
|
+
return neon_js_1.wallet.isNEP2(encryptedKey);
|
|
110
54
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const { address } = new neon_js_1.wallet.Account(wif);
|
|
114
|
-
return { address, wif };
|
|
55
|
+
validateKey(key) {
|
|
56
|
+
return neon_js_1.wallet.isWIF(key) || neon_js_1.wallet.isPrivateKey(key);
|
|
115
57
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
58
|
+
validateNameServiceDomainFormat(domainName) {
|
|
59
|
+
if (!domainName.endsWith('.neo'))
|
|
60
|
+
return false;
|
|
61
|
+
return true;
|
|
119
62
|
}
|
|
120
|
-
|
|
63
|
+
generateAccountFromMnemonic(mnemonic, index) {
|
|
64
|
+
bs_asteroid_sdk_1.keychain.importMnemonic(Array.isArray(mnemonic) ? mnemonic.join(' ') : mnemonic);
|
|
65
|
+
const path = this.derivationPath.replace('?', index.toString());
|
|
66
|
+
const childKey = bs_asteroid_sdk_1.keychain.generateChildKey('neo', path);
|
|
67
|
+
const key = childKey.getWIF();
|
|
68
|
+
const { address } = new neon_js_1.wallet.Account(key);
|
|
69
|
+
return { address, key, type: 'wif', derivationPath: path };
|
|
70
|
+
}
|
|
71
|
+
generateAccountFromKey(key) {
|
|
72
|
+
const type = neon_js_1.wallet.isWIF(key) ? 'wif' : neon_js_1.wallet.isPrivateKey(key) ? 'privateKey' : undefined;
|
|
73
|
+
if (!type)
|
|
74
|
+
throw new Error('Invalid key');
|
|
75
|
+
const { address } = new neon_js_1.wallet.Account(key);
|
|
76
|
+
return { address, key, type };
|
|
77
|
+
}
|
|
78
|
+
decrypt(encryptedKey, password) {
|
|
121
79
|
return __awaiter(this, void 0, void 0, function* () {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
80
|
+
let BsReactNativeDecrypt;
|
|
81
|
+
try {
|
|
82
|
+
const { NativeModules } = require('react-native');
|
|
83
|
+
BsReactNativeDecrypt = NativeModules.BsReactNativeDecrypt;
|
|
84
|
+
}
|
|
85
|
+
catch (_a) {
|
|
86
|
+
const key = yield neon_js_1.wallet.decrypt(encryptedKey, password);
|
|
87
|
+
return this.generateAccountFromKey(key);
|
|
88
|
+
}
|
|
89
|
+
if (!BsReactNativeDecrypt) {
|
|
90
|
+
throw new Error('@CityOfZion/bs-react-native-decrypt is not installed');
|
|
91
|
+
}
|
|
92
|
+
const privateKey = yield BsReactNativeDecrypt.decryptNeo3(encryptedKey, password);
|
|
93
|
+
return this.generateAccountFromKey(privateKey);
|
|
125
94
|
});
|
|
126
95
|
}
|
|
127
|
-
validateAddress(address) {
|
|
128
|
-
return neon_js_1.wallet.isAddress(address);
|
|
129
|
-
}
|
|
130
|
-
validateEncryptedKey(encryptedKey) {
|
|
131
|
-
return neon_js_1.wallet.isNEP2(encryptedKey);
|
|
132
|
-
}
|
|
133
|
-
validateWif(wif) {
|
|
134
|
-
return neon_js_1.wallet.isWIF(wif);
|
|
135
|
-
}
|
|
136
96
|
calculateTransferFee(param) {
|
|
137
97
|
return __awaiter(this, void 0, void 0, function* () {
|
|
138
|
-
const
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
const txn = txBuilder.build();
|
|
151
|
-
const accountScriptHash = neon_js_1.wallet.getScriptHashFromAddress(param.senderAccount.address);
|
|
152
|
-
const invokeFunctionResponse = yield rpcClient.invokeScript(neon_js_1.u.HexString.fromHex(txn.script), [
|
|
153
|
-
{
|
|
154
|
-
account: accountScriptHash,
|
|
155
|
-
scopes: String(neon_js_1.tx.WitnessScope.CalledByEntry)
|
|
156
|
-
}
|
|
157
|
-
]);
|
|
158
|
-
const systemFee = neon_js_1.u.BigInteger.fromNumber(invokeFunctionResponse.gasconsumed).toDecimal(constants_1.gasInfoNeo3.decimals);
|
|
159
|
-
const networkFeeResponse = yield rpcClient.calculateNetworkFee(txn);
|
|
160
|
-
const networkFee = (Number(networkFeeResponse) / Math.pow(10, constants_1.gasInfoNeo3.decimals));
|
|
161
|
-
const sumFee = Number(systemFee) + networkFee;
|
|
162
|
-
const result = {
|
|
163
|
-
result: sumFee,
|
|
164
|
-
details: {
|
|
165
|
-
networkFee: networkFee.toString(),
|
|
166
|
-
systemFee
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
return result;
|
|
98
|
+
const account = new neon_js_1.wallet.Account(param.senderAccount.key);
|
|
99
|
+
const invoker = yield neon_invoker_1.NeonInvoker.init({
|
|
100
|
+
rpcAddress: this.network.url,
|
|
101
|
+
account,
|
|
102
|
+
});
|
|
103
|
+
const invocations = this.buildTransferInvocation(param, account);
|
|
104
|
+
const { networkFee, systemFee } = yield invoker.calculateFee({
|
|
105
|
+
invocations,
|
|
106
|
+
signers: [],
|
|
107
|
+
});
|
|
108
|
+
return networkFee.add(systemFee).toDecimal(this.feeToken.decimals);
|
|
170
109
|
});
|
|
171
110
|
}
|
|
172
|
-
|
|
173
|
-
claim(account) {
|
|
111
|
+
transfer(param) {
|
|
174
112
|
return __awaiter(this, void 0, void 0, function* () {
|
|
175
|
-
const
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const feeToClaim = yield this.calculateTransferFee(dataToClaim);
|
|
187
|
-
if (gasBalance.amount < feeToClaim.result) {
|
|
188
|
-
exceptions_1.claimGasExceptions.InsuficientGas(String(gasBalance.amount), String(feeToClaim.result));
|
|
189
|
-
}
|
|
190
|
-
const url = (yield this.dataService.getHigherNode()).url;
|
|
191
|
-
const facade = yield neon_js_1.api.NetworkFacade.fromConfig({ node: url });
|
|
192
|
-
const signing = this.signTransfer(account);
|
|
193
|
-
const txid = yield facade.claimGas(neoAccount, signing);
|
|
194
|
-
const result = {
|
|
195
|
-
hash: constants_1.gasInfoNeo3.hash,
|
|
196
|
-
symbol: constants_1.gasInfoNeo3.symbol,
|
|
197
|
-
txid
|
|
198
|
-
};
|
|
199
|
-
return result;
|
|
113
|
+
const account = new neon_js_1.wallet.Account(param.senderAccount.key);
|
|
114
|
+
const invoker = yield neon_invoker_1.NeonInvoker.init({
|
|
115
|
+
rpcAddress: this.network.url,
|
|
116
|
+
account,
|
|
117
|
+
});
|
|
118
|
+
const invocations = this.buildTransferInvocation(param, account);
|
|
119
|
+
const transactionHash = yield invoker.invokeFunction({
|
|
120
|
+
invocations,
|
|
121
|
+
signers: [],
|
|
122
|
+
});
|
|
123
|
+
return transactionHash;
|
|
200
124
|
});
|
|
201
125
|
}
|
|
202
|
-
|
|
203
|
-
getNNSRecord(domainName, type) {
|
|
204
|
-
var _a;
|
|
126
|
+
claim(account) {
|
|
205
127
|
return __awaiter(this, void 0, void 0, function* () {
|
|
206
|
-
const
|
|
207
|
-
const
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
invocations: [{
|
|
211
|
-
scriptHash: NEO_NS_HASH,
|
|
212
|
-
operation: "getRecord",
|
|
213
|
-
args: [{ type: "String", value: domainName }, { type: "Integer", value: type }]
|
|
214
|
-
}]
|
|
128
|
+
const neoAccount = new neon_js_1.wallet.Account(account.key);
|
|
129
|
+
const facade = yield neon_js_1.api.NetworkFacade.fromConfig({ node: this.network.url });
|
|
130
|
+
const transactionHash = yield facade.claimGas(neoAccount, {
|
|
131
|
+
signingCallback: neon_js_1.api.signWithAccount(neoAccount),
|
|
215
132
|
});
|
|
216
|
-
|
|
217
|
-
throw new Error((_a = response.exception) !== null && _a !== void 0 ? _a : 'unrecognized response');
|
|
218
|
-
}
|
|
219
|
-
const parsed = parser.parseRpcResponse(response.stack[0]);
|
|
220
|
-
return parsed;
|
|
133
|
+
return transactionHash;
|
|
221
134
|
});
|
|
222
135
|
}
|
|
223
|
-
|
|
136
|
+
resolveNameServiceDomain(domainName) {
|
|
224
137
|
var _a;
|
|
225
138
|
return __awaiter(this, void 0, void 0, function* () {
|
|
226
|
-
const higherNode = yield this.dataService.getHigherNode();
|
|
227
139
|
const parser = neon_parser_1.NeonParser;
|
|
228
|
-
const invoker = yield neon_invoker_1.NeonInvoker.init(
|
|
140
|
+
const invoker = yield neon_invoker_1.NeonInvoker.init({ rpcAddress: this.network.url });
|
|
229
141
|
const response = yield invoker.testInvoke({
|
|
230
|
-
invocations: [
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
142
|
+
invocations: [
|
|
143
|
+
{
|
|
144
|
+
scriptHash: constants_1.NEO_NS_HASH,
|
|
145
|
+
operation: 'ownerOf',
|
|
146
|
+
args: [{ type: 'String', value: domainName }],
|
|
147
|
+
},
|
|
148
|
+
],
|
|
235
149
|
});
|
|
236
150
|
if (response.stack.length === 0) {
|
|
237
151
|
throw new Error((_a = response.exception) !== null && _a !== void 0 ? _a : 'unrecognized response');
|
|
238
152
|
}
|
|
239
|
-
const parsed = parser.parseRpcResponse(response.stack[0], {
|
|
240
|
-
|
|
153
|
+
const parsed = parser.parseRpcResponse(response.stack[0], {
|
|
154
|
+
type: neo3_parser_1.ABI_TYPES.HASH160.name,
|
|
155
|
+
});
|
|
156
|
+
const address = parser.accountInputToAddress(parsed.replace('0x', ''));
|
|
241
157
|
return address;
|
|
242
158
|
});
|
|
243
159
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
160
|
+
buildTransferInvocation({ intent, tipIntent }, account) {
|
|
161
|
+
const intents = [intent, ...(tipIntent ? [tipIntent] : [])];
|
|
162
|
+
const invocations = intents.map(intent => {
|
|
163
|
+
return {
|
|
164
|
+
operation: 'transfer',
|
|
165
|
+
scriptHash: intent.tokenHash,
|
|
166
|
+
args: [
|
|
167
|
+
{ type: 'Hash160', value: account.address },
|
|
168
|
+
{ type: 'Hash160', value: intent.receiverAddress },
|
|
169
|
+
{
|
|
170
|
+
type: 'Integer',
|
|
171
|
+
value: intent.tokenDecimals
|
|
172
|
+
? neon_js_1.u.BigInteger.fromDecimal(intent.amount, intent.tokenDecimals).toString()
|
|
173
|
+
: intent.amount,
|
|
174
|
+
},
|
|
175
|
+
{ type: 'Any', value: '' },
|
|
176
|
+
],
|
|
177
|
+
};
|
|
178
|
+
});
|
|
179
|
+
return invocations;
|
|
248
180
|
}
|
|
249
181
|
}
|
|
250
182
|
exports.BSNeo3 = BSNeo3;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BalanceResponse, ContractResponse, TransactionsByAddressParams, TransactionsByAddressResponse, TransactionResponse, Network, Token } from '@cityofzion/blockchain-service';
|
|
2
|
+
import { RPCBDSNeo3 } from './RpcBDSNeo3';
|
|
3
|
+
export declare class DoraBDSNeo3 extends RPCBDSNeo3 {
|
|
4
|
+
readonly network: Network;
|
|
5
|
+
constructor(network: Network, feeToken: Token, claimToken: Token);
|
|
6
|
+
getTransaction(hash: string): Promise<TransactionResponse>;
|
|
7
|
+
getTransactionsByAddress({ address, page, }: TransactionsByAddressParams): Promise<TransactionsByAddressResponse>;
|
|
8
|
+
getContract(contractHash: string): Promise<ContractResponse>;
|
|
9
|
+
getTokenInfo(tokenHash: string): Promise<Token>;
|
|
10
|
+
getBalance(address: string): Promise<BalanceResponse[]>;
|
|
11
|
+
private convertByteStringToAddress;
|
|
12
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.DoraBDSNeo3 = void 0;
|
|
13
|
+
const neon_js_1 = require("@cityofzion/neon-js");
|
|
14
|
+
const api_1 = require("@cityofzion/dora-ts/dist/api");
|
|
15
|
+
const RpcBDSNeo3_1 = require("./RpcBDSNeo3");
|
|
16
|
+
const constants_1 = require("./constants");
|
|
17
|
+
const NeoRest = new api_1.NeoRESTApi({
|
|
18
|
+
doraUrl: 'https://dora.coz.io',
|
|
19
|
+
endpoint: '/api/v2/neo3',
|
|
20
|
+
});
|
|
21
|
+
class DoraBDSNeo3 extends RpcBDSNeo3_1.RPCBDSNeo3 {
|
|
22
|
+
constructor(network, feeToken, claimToken) {
|
|
23
|
+
if (network.type === 'custom') {
|
|
24
|
+
throw new Error('DoraBDSNeo3 does not support custom networks');
|
|
25
|
+
}
|
|
26
|
+
super(network, feeToken, claimToken);
|
|
27
|
+
this.network = network;
|
|
28
|
+
}
|
|
29
|
+
getTransaction(hash) {
|
|
30
|
+
var _a, _b;
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
try {
|
|
33
|
+
const data = yield NeoRest.transaction(hash, this.network.type);
|
|
34
|
+
return {
|
|
35
|
+
block: data.block,
|
|
36
|
+
time: Number(data.time),
|
|
37
|
+
hash: data.hash,
|
|
38
|
+
fee: neon_js_1.u.BigInteger.fromNumber((_a = data.netfee) !== null && _a !== void 0 ? _a : 0)
|
|
39
|
+
.add(neon_js_1.u.BigInteger.fromNumber((_b = data.sysfee) !== null && _b !== void 0 ? _b : 0))
|
|
40
|
+
.toDecimal(this.feeToken.decimals),
|
|
41
|
+
notifications: [],
|
|
42
|
+
transfers: [],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch (_c) {
|
|
46
|
+
throw new Error(`Transaction not found: ${hash}`);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
getTransactionsByAddress({ address, page = 1, }) {
|
|
51
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
const data = yield NeoRest.addressTXFull(address, page, this.network.type);
|
|
53
|
+
const transactions = yield Promise.all(data.items.map((item) => __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
const filteredTransfers = item.notifications.filter(item => item.event_name === 'Transfer' && (item.state.value.length === 3 || item.state.value.length === 4));
|
|
56
|
+
const transferPromises = filteredTransfers.map(({ contract: contractHash, state: { value: properties } }) => __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
var _c;
|
|
58
|
+
const isAsset = properties.length === 3;
|
|
59
|
+
const from = properties[0].value;
|
|
60
|
+
const to = properties[1].value;
|
|
61
|
+
const convertedFrom = from ? this.convertByteStringToAddress(from) : 'Mint';
|
|
62
|
+
const convertedTo = to ? this.convertByteStringToAddress(to) : 'Burn';
|
|
63
|
+
if (isAsset) {
|
|
64
|
+
const token = yield this.getTokenInfo(contractHash);
|
|
65
|
+
const [, , { value: amount }] = properties;
|
|
66
|
+
return {
|
|
67
|
+
amount: neon_js_1.u.BigInteger.fromNumber(amount).toDecimal((_c = token.decimals) !== null && _c !== void 0 ? _c : 0),
|
|
68
|
+
from: convertedFrom,
|
|
69
|
+
to: convertedTo,
|
|
70
|
+
contractHash,
|
|
71
|
+
type: 'token',
|
|
72
|
+
token,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
from: convertedFrom,
|
|
77
|
+
to: convertedTo,
|
|
78
|
+
tokenId: properties[3].value,
|
|
79
|
+
contractHash,
|
|
80
|
+
type: 'nft',
|
|
81
|
+
};
|
|
82
|
+
}));
|
|
83
|
+
const transfers = yield Promise.all(transferPromises);
|
|
84
|
+
const notifications = item.notifications.map(notification => ({
|
|
85
|
+
eventName: notification.event_name,
|
|
86
|
+
state: notification.state,
|
|
87
|
+
}));
|
|
88
|
+
return {
|
|
89
|
+
block: item.block,
|
|
90
|
+
time: Number(item.time),
|
|
91
|
+
hash: item.hash,
|
|
92
|
+
fee: neon_js_1.u.BigInteger.fromNumber((_a = item.netfee) !== null && _a !== void 0 ? _a : 0)
|
|
93
|
+
.add(neon_js_1.u.BigInteger.fromNumber((_b = item.sysfee) !== null && _b !== void 0 ? _b : 0))
|
|
94
|
+
.toDecimal(this.feeToken.decimals),
|
|
95
|
+
transfers,
|
|
96
|
+
notifications,
|
|
97
|
+
};
|
|
98
|
+
})));
|
|
99
|
+
return {
|
|
100
|
+
totalCount: data.totalCount,
|
|
101
|
+
transactions,
|
|
102
|
+
limit: 15,
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
getContract(contractHash) {
|
|
107
|
+
var _a, _b;
|
|
108
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
109
|
+
try {
|
|
110
|
+
const data = yield NeoRest.contract(contractHash, this.network.type);
|
|
111
|
+
return {
|
|
112
|
+
hash: data.hash,
|
|
113
|
+
methods: (_b = (_a = data.manifest.abi) === null || _a === void 0 ? void 0 : _a.methods) !== null && _b !== void 0 ? _b : [],
|
|
114
|
+
name: data.manifest.name,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
catch (_c) {
|
|
118
|
+
throw new Error(`Contract not found: ${contractHash}`);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
getTokenInfo(tokenHash) {
|
|
123
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
124
|
+
const localToken = constants_1.TOKENS[this.network.type].find(token => token.hash === tokenHash);
|
|
125
|
+
if (localToken)
|
|
126
|
+
return localToken;
|
|
127
|
+
if (this.tokenCache.has(tokenHash)) {
|
|
128
|
+
return this.tokenCache.get(tokenHash);
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const { decimals, symbol, name, scripthash } = yield NeoRest.asset(tokenHash, this.network.type);
|
|
132
|
+
const token = {
|
|
133
|
+
decimals: Number(decimals),
|
|
134
|
+
symbol,
|
|
135
|
+
name,
|
|
136
|
+
hash: scripthash,
|
|
137
|
+
};
|
|
138
|
+
this.tokenCache.set(tokenHash, token);
|
|
139
|
+
return token;
|
|
140
|
+
}
|
|
141
|
+
catch (_a) {
|
|
142
|
+
throw new Error(`Token not found: ${tokenHash}`);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
getBalance(address) {
|
|
147
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
148
|
+
const response = yield NeoRest.balance(address, this.network.type);
|
|
149
|
+
const promises = response.map((balance) => __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
try {
|
|
151
|
+
const token = yield this.getTokenInfo(balance.asset);
|
|
152
|
+
return {
|
|
153
|
+
amount: neon_js_1.u.BigInteger.fromNumber(balance.balance).toDecimal(token.decimals),
|
|
154
|
+
token,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
catch (_a) { }
|
|
158
|
+
}));
|
|
159
|
+
const balances = yield Promise.all(promises);
|
|
160
|
+
const filteredBalances = balances.filter(balance => balance !== undefined);
|
|
161
|
+
return filteredBalances;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
convertByteStringToAddress(byteString) {
|
|
165
|
+
const account = new neon_js_1.wallet.Account(neon_js_1.u.reverseHex(neon_js_1.u.HexString.fromBase64(byteString).toString()));
|
|
166
|
+
return account.address;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.DoraBDSNeo3 = DoraBDSNeo3;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Currency, ExchangeDataService, NetworkType, TokenPricesResponse } from '@cityofzion/blockchain-service';
|
|
2
|
+
export declare class FlamingoEDSNeo3 implements ExchangeDataService {
|
|
3
|
+
readonly networkType: NetworkType;
|
|
4
|
+
private axiosInstance;
|
|
5
|
+
constructor(networkType: NetworkType);
|
|
6
|
+
getTokenPrices(currency: Currency): Promise<TokenPricesResponse[]>;
|
|
7
|
+
private getCurrencyRatio;
|
|
8
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.FlamingoEDSNeo3 = void 0;
|
|
16
|
+
const axios_1 = __importDefault(require("axios"));
|
|
17
|
+
class FlamingoEDSNeo3 {
|
|
18
|
+
constructor(networkType) {
|
|
19
|
+
this.networkType = networkType;
|
|
20
|
+
this.axiosInstance = axios_1.default.create({ baseURL: 'https://api.flamingo.finance' });
|
|
21
|
+
}
|
|
22
|
+
getTokenPrices(currency) {
|
|
23
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
if (this.networkType !== 'mainnet')
|
|
25
|
+
throw new Error('Exchange is only available on mainnet');
|
|
26
|
+
const { data: prices } = yield this.axiosInstance.get('/token-info/prices');
|
|
27
|
+
let currencyRatio = 1;
|
|
28
|
+
if (currency !== 'USD') {
|
|
29
|
+
currencyRatio = yield this.getCurrencyRatio(currency);
|
|
30
|
+
}
|
|
31
|
+
return prices.map(price => ({
|
|
32
|
+
price: price.usd_price * currencyRatio,
|
|
33
|
+
symbol: price.symbol,
|
|
34
|
+
}));
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
getCurrencyRatio(currency) {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
const { data } = yield this.axiosInstance.get(`/fiat/exchange-rate?pair=USD_${currency}`);
|
|
40
|
+
return data;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.FlamingoEDSNeo3 = FlamingoEDSNeo3;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { NftResponse, NftsResponse, NetworkType, NftDataService, GetNftParam, GetNftsByAddressParams } from '@cityofzion/blockchain-service';
|
|
2
|
+
export declare class GhostMarketNDSNeo3 implements NftDataService {
|
|
3
|
+
private networkType;
|
|
4
|
+
constructor(networkType: NetworkType);
|
|
5
|
+
getNftsByAddress({ address, size, cursor, page }: GetNftsByAddressParams): Promise<NftsResponse>;
|
|
6
|
+
getNft({ contractHash, tokenId }: GetNftParam): Promise<NftResponse>;
|
|
7
|
+
private treatGhostMarketImage;
|
|
8
|
+
private getUrlWithParams;
|
|
9
|
+
private parse;
|
|
10
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.GhostMarketNDSNeo3 = void 0;
|
|
16
|
+
const query_string_1 = __importDefault(require("query-string"));
|
|
17
|
+
const axios_1 = __importDefault(require("axios"));
|
|
18
|
+
const constants_1 = require("./constants");
|
|
19
|
+
class GhostMarketNDSNeo3 {
|
|
20
|
+
constructor(networkType) {
|
|
21
|
+
this.networkType = networkType;
|
|
22
|
+
}
|
|
23
|
+
getNftsByAddress({ address, size = 18, cursor, page }) {
|
|
24
|
+
var _a;
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
const url = this.getUrlWithParams({
|
|
27
|
+
size,
|
|
28
|
+
owners: [address],
|
|
29
|
+
cursor: cursor,
|
|
30
|
+
});
|
|
31
|
+
const { data } = yield axios_1.default.get(url);
|
|
32
|
+
const nfts = (_a = data.assets) !== null && _a !== void 0 ? _a : [];
|
|
33
|
+
return { nextCursor: data.next, items: nfts.map(this.parse.bind(this)) };
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
getNft({ contractHash, tokenId }) {
|
|
37
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
const url = this.getUrlWithParams({
|
|
39
|
+
contract: contractHash,
|
|
40
|
+
tokenIds: [tokenId],
|
|
41
|
+
});
|
|
42
|
+
const { data } = yield axios_1.default.get(url);
|
|
43
|
+
return this.parse(data.assets[0]);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
treatGhostMarketImage(srcImage) {
|
|
47
|
+
if (!srcImage) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (srcImage.startsWith('ipfs://')) {
|
|
51
|
+
const [, imageId] = srcImage.split('://');
|
|
52
|
+
return `https://ghostmarket.mypinata.cloud/ipfs/${imageId}`;
|
|
53
|
+
}
|
|
54
|
+
return srcImage;
|
|
55
|
+
}
|
|
56
|
+
getUrlWithParams(params) {
|
|
57
|
+
const parameters = query_string_1.default.stringify(Object.assign({ chain: constants_1.GHOSTMARKET_CHAIN_BY_NETWORK_TYPE[this.networkType] }, params), { arrayFormat: 'bracket' });
|
|
58
|
+
return `${constants_1.GHOSTMARKET_URL_BY_NETWORK_TYPE[this.networkType]}/assets?${parameters}`;
|
|
59
|
+
}
|
|
60
|
+
parse(data) {
|
|
61
|
+
var _a, _b;
|
|
62
|
+
const nftResponse = {
|
|
63
|
+
collectionImage: this.treatGhostMarketImage((_a = data.collection) === null || _a === void 0 ? void 0 : _a.logoUrl),
|
|
64
|
+
id: data.tokenId,
|
|
65
|
+
contractHash: data.contract.hash,
|
|
66
|
+
symbol: data.contract.symbol,
|
|
67
|
+
collectionName: (_b = data.collection) === null || _b === void 0 ? void 0 : _b.name,
|
|
68
|
+
image: this.treatGhostMarketImage(data.metadata.mediaUri),
|
|
69
|
+
isSVG: String(data.metadata.mediaType).includes('svg+xml'),
|
|
70
|
+
name: data.metadata.name,
|
|
71
|
+
};
|
|
72
|
+
return nftResponse;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.GhostMarketNDSNeo3 = GhostMarketNDSNeo3;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BDSClaimable, BalanceResponse, BlockchainDataService, ContractResponse, Network, Token, TransactionResponse, TransactionsByAddressParams, TransactionsByAddressResponse } from '@cityofzion/blockchain-service';
|
|
2
|
+
export declare class RPCBDSNeo3 implements BlockchainDataService, BDSClaimable {
|
|
3
|
+
protected readonly tokenCache: Map<string, Token>;
|
|
4
|
+
protected readonly feeToken: Token;
|
|
5
|
+
protected readonly claimToken: Token;
|
|
6
|
+
readonly network: Network;
|
|
7
|
+
constructor(network: Network, feeToken: Token, claimToken: Token);
|
|
8
|
+
getTransaction(hash: string): Promise<TransactionResponse>;
|
|
9
|
+
getTransactionsByAddress(_params: TransactionsByAddressParams): Promise<TransactionsByAddressResponse>;
|
|
10
|
+
getContract(contractHash: string): Promise<ContractResponse>;
|
|
11
|
+
getTokenInfo(tokenHash: string): Promise<Token>;
|
|
12
|
+
getBalance(address: string): Promise<BalanceResponse[]>;
|
|
13
|
+
getBlockHeight(): Promise<number>;
|
|
14
|
+
getUnclaimed(address: string): Promise<string>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.RPCBDSNeo3 = void 0;
|
|
13
|
+
const neon_core_1 = require("@cityofzion/neon-core");
|
|
14
|
+
const neon_invoker_1 = require("@cityofzion/neon-invoker");
|
|
15
|
+
const constants_1 = require("./constants");
|
|
16
|
+
class RPCBDSNeo3 {
|
|
17
|
+
constructor(network, feeToken, claimToken) {
|
|
18
|
+
this.tokenCache = new Map();
|
|
19
|
+
this.network = network;
|
|
20
|
+
this.feeToken = feeToken;
|
|
21
|
+
this.claimToken = claimToken;
|
|
22
|
+
}
|
|
23
|
+
getTransaction(hash) {
|
|
24
|
+
var _a, _b;
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
try {
|
|
27
|
+
const rpcClient = new neon_core_1.rpc.RPCClient(this.network.url);
|
|
28
|
+
const response = yield rpcClient.getRawTransaction(hash, true);
|
|
29
|
+
return {
|
|
30
|
+
hash: response.hash,
|
|
31
|
+
block: response.validuntilblock,
|
|
32
|
+
fee: neon_core_1.u.BigInteger.fromNumber((_a = response.netfee) !== null && _a !== void 0 ? _a : 0)
|
|
33
|
+
.add(neon_core_1.u.BigInteger.fromNumber((_b = response.sysfee) !== null && _b !== void 0 ? _b : 0))
|
|
34
|
+
.toDecimal(this.feeToken.decimals),
|
|
35
|
+
notifications: [],
|
|
36
|
+
transfers: [],
|
|
37
|
+
time: response.blocktime,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
catch (_c) {
|
|
41
|
+
throw new Error(`Transaction not found: ${hash}`);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
getTransactionsByAddress(_params) {
|
|
46
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
throw new Error('Method not supported.');
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
getContract(contractHash) {
|
|
51
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
try {
|
|
53
|
+
const rpcClient = new neon_core_1.rpc.RPCClient(this.network.url);
|
|
54
|
+
const contractState = yield rpcClient.getContractState(contractHash);
|
|
55
|
+
const methods = contractState.manifest.abi.methods.map(method => ({
|
|
56
|
+
name: method.name,
|
|
57
|
+
parameters: method.parameters.map(parameter => ({
|
|
58
|
+
name: parameter.name,
|
|
59
|
+
type: parameter.type,
|
|
60
|
+
})),
|
|
61
|
+
}));
|
|
62
|
+
return {
|
|
63
|
+
hash: contractState.hash,
|
|
64
|
+
name: contractState.manifest.name,
|
|
65
|
+
methods,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (_a) {
|
|
69
|
+
throw new Error(`Contract not found: ${contractHash}`);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
getTokenInfo(tokenHash) {
|
|
74
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
75
|
+
const localToken = constants_1.TOKENS[this.network.type].find(token => token.hash === tokenHash);
|
|
76
|
+
if (localToken)
|
|
77
|
+
return localToken;
|
|
78
|
+
if (this.tokenCache.has(tokenHash)) {
|
|
79
|
+
return this.tokenCache.get(tokenHash);
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const rpcClient = new neon_core_1.rpc.RPCClient(this.network.url);
|
|
83
|
+
const contractState = yield rpcClient.getContractState(tokenHash);
|
|
84
|
+
const invoker = yield neon_invoker_1.NeonInvoker.init({
|
|
85
|
+
rpcAddress: this.network.url,
|
|
86
|
+
});
|
|
87
|
+
const response = yield invoker.testInvoke({
|
|
88
|
+
invocations: [
|
|
89
|
+
{
|
|
90
|
+
scriptHash: tokenHash,
|
|
91
|
+
operation: 'decimals',
|
|
92
|
+
args: [],
|
|
93
|
+
},
|
|
94
|
+
{ scriptHash: tokenHash, operation: 'symbol', args: [] },
|
|
95
|
+
],
|
|
96
|
+
});
|
|
97
|
+
const decimals = Number(response.stack[0].value);
|
|
98
|
+
const symbol = neon_core_1.u.base642utf8(response.stack[1].value);
|
|
99
|
+
const token = {
|
|
100
|
+
name: contractState.manifest.name,
|
|
101
|
+
symbol,
|
|
102
|
+
hash: contractState.hash,
|
|
103
|
+
decimals,
|
|
104
|
+
};
|
|
105
|
+
this.tokenCache.set(tokenHash, token);
|
|
106
|
+
return token;
|
|
107
|
+
}
|
|
108
|
+
catch (_a) {
|
|
109
|
+
throw new Error(`Token not found: ${tokenHash}`);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
getBalance(address) {
|
|
114
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
115
|
+
const rpcClient = new neon_core_1.rpc.RPCClient(this.network.url);
|
|
116
|
+
const response = yield rpcClient.getNep17Balances(address);
|
|
117
|
+
const promises = response.balance.map((balance) => __awaiter(this, void 0, void 0, function* () {
|
|
118
|
+
var _a;
|
|
119
|
+
let token = {
|
|
120
|
+
hash: balance.assethash,
|
|
121
|
+
name: '-',
|
|
122
|
+
symbol: '-',
|
|
123
|
+
decimals: 8,
|
|
124
|
+
};
|
|
125
|
+
try {
|
|
126
|
+
token = yield this.getTokenInfo(balance.assethash);
|
|
127
|
+
}
|
|
128
|
+
catch (_b) { }
|
|
129
|
+
return {
|
|
130
|
+
amount: neon_core_1.u.BigInteger.fromNumber(balance.amount).toDecimal((_a = token === null || token === void 0 ? void 0 : token.decimals) !== null && _a !== void 0 ? _a : 8),
|
|
131
|
+
token,
|
|
132
|
+
};
|
|
133
|
+
}));
|
|
134
|
+
const balances = yield Promise.all(promises);
|
|
135
|
+
return balances;
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
getBlockHeight() {
|
|
139
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
140
|
+
const rpcClient = new neon_core_1.rpc.RPCClient(this.network.url);
|
|
141
|
+
return yield rpcClient.getBlockCount();
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
getUnclaimed(address) {
|
|
145
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
146
|
+
const rpcClient = new neon_core_1.rpc.RPCClient(this.network.url);
|
|
147
|
+
const response = yield rpcClient.getUnclaimedGas(address);
|
|
148
|
+
return neon_core_1.u.BigInteger.fromNumber(response).toDecimal(this.claimToken.decimals);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
exports.RPCBDSNeo3 = RPCBDSNeo3;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"symbol": "LRB",
|
|
4
|
+
"name": "LyrebirdToken",
|
|
5
|
+
"hash": "0x8c07b4c9f5bc170a3922eac4f5bb7ef17b0acc8b",
|
|
6
|
+
"decimals": 8
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"symbol": "USDL",
|
|
10
|
+
"name": "LyrebirdUSDToken",
|
|
11
|
+
"hash": "0xa8c51aa0c177187aeed3db88bdfa908ccbc9b1a5",
|
|
12
|
+
"decimals": 8
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"symbol": "FLM",
|
|
16
|
+
"name": "FLM",
|
|
17
|
+
"hash": "0xf0151f528127558851b39c2cd8aa47da7418ab28",
|
|
18
|
+
"decimals": 8
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"symbol": "fCAKE",
|
|
22
|
+
"name": "fCAKE",
|
|
23
|
+
"hash": "0xe65b462b90516012826f8a9c4c285d8c750e3a77",
|
|
24
|
+
"decimals": 18
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"symbol": "WING",
|
|
28
|
+
"name": "WING",
|
|
29
|
+
"hash": "0xeeccd60ed722111f8400434dac3ba42c14d8beb1",
|
|
30
|
+
"decimals": 9
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"symbol": "fWETH",
|
|
34
|
+
"name": "fWETH",
|
|
35
|
+
"hash": "0xc14b601252aa5dfa6166cf35fe5ccd2e35f3fdf5",
|
|
36
|
+
"decimals": 18
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"symbol": "fWBTC",
|
|
40
|
+
"name": "fWBTC",
|
|
41
|
+
"hash": "0xd6abe115ecb75e1fa0b42f5e85934ce8c1ae2893",
|
|
42
|
+
"decimals": 8
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"symbol": "SWTH",
|
|
46
|
+
"name": "SWTHToken",
|
|
47
|
+
"hash": "0x78e1330db47634afdb5ea455302ba2d12b8d549f",
|
|
48
|
+
"decimals": 8
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"symbol": "pONT",
|
|
52
|
+
"name": "pONT",
|
|
53
|
+
"hash": "0x8122bc2212ec971690a044b37a6f52a9349b702b",
|
|
54
|
+
"decimals": 9
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"symbol": "fUSDT",
|
|
58
|
+
"name": "fUSDT",
|
|
59
|
+
"hash": "0xcd48b160c1bbc9d74997b803b9a7ad50a4bef020",
|
|
60
|
+
"decimals": 6
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"symbol": "FLUND",
|
|
64
|
+
"name": "FLUND",
|
|
65
|
+
"hash": "0xa9603a59e21d29e37ac39cf1b5f5abf5006b22a3",
|
|
66
|
+
"decimals": 8
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"symbol": "GM",
|
|
70
|
+
"name": "GhostMarketToken",
|
|
71
|
+
"hash": "0x9b049f1283515eef1d3f6ac610e1595ed25ca3e9",
|
|
72
|
+
"decimals": 8
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"symbol": "NUDES",
|
|
76
|
+
"name": "Nudes",
|
|
77
|
+
"hash": "0x340720c7107ef5721e44ed2ea8e314cce5c130fa",
|
|
78
|
+
"decimals": 8
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"symbol": "CANDY",
|
|
82
|
+
"name": "NeoCandy",
|
|
83
|
+
"hash": "0x88da18a5bca86ec8206d9b4960a7d0c4355a432f",
|
|
84
|
+
"decimals": 9
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"symbol": "DOGER",
|
|
88
|
+
"name": "DogeRift",
|
|
89
|
+
"hash": "0x322b5a366ca724801a1aa01e669b5f3d7f8c7f6f",
|
|
90
|
+
"decimals": 8
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"symbol": "DOGEF",
|
|
94
|
+
"name": "DogeFood",
|
|
95
|
+
"hash": "0xa3291b66f70d4687fc0e41977d8acb0699f235ae",
|
|
96
|
+
"decimals": 8
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"symbol": "SOM",
|
|
100
|
+
"name": "Som",
|
|
101
|
+
"hash": "0x2d4c6cf0417209a7eb410160344e224e74f87195",
|
|
102
|
+
"decimals": 8
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"symbol": "LAMBO",
|
|
106
|
+
"name": "BoomerFund",
|
|
107
|
+
"hash": "0xafdd6abedf066ff8c5fbc868cc89f80eac467142",
|
|
108
|
+
"decimals": 8
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"symbol": "bNEO",
|
|
112
|
+
"hash": "0x48c40d4666f93408be1bef038b6722404d9a4c2a",
|
|
113
|
+
"decimals": 8,
|
|
114
|
+
"name": "BurgerNEO"
|
|
115
|
+
}
|
|
116
|
+
]
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export declare const
|
|
7
|
-
|
|
8
|
-
symbol: string;
|
|
9
|
-
decimals: number;
|
|
10
|
-
};
|
|
1
|
+
import { NetworkType, Token } from '@cityofzion/blockchain-service';
|
|
2
|
+
export declare const TOKENS: Record<NetworkType, Token[]>;
|
|
3
|
+
export declare const NEO_NS_HASH = "0x50ac1c37690cc2cfc594472833cf57505d5f46de";
|
|
4
|
+
export declare const DEFAULT_URL_BY_NETWORK_TYPE: Record<NetworkType, string>;
|
|
5
|
+
export declare const GHOSTMARKET_URL_BY_NETWORK_TYPE: Partial<Record<NetworkType, string>>;
|
|
6
|
+
export declare const GHOSTMARKET_CHAIN_BY_NETWORK_TYPE: Partial<Record<NetworkType, string>>;
|
|
7
|
+
export declare const DERIVATION_PATH = "m/44'/888'/0'/0/?";
|
package/dist/constants.js
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
exports.DERIVATION_PATH = exports.GHOSTMARKET_CHAIN_BY_NETWORK_TYPE = exports.GHOSTMARKET_URL_BY_NETWORK_TYPE = exports.DEFAULT_URL_BY_NETWORK_TYPE = exports.NEO_NS_HASH = exports.TOKENS = void 0;
|
|
7
|
+
const common_json_1 = __importDefault(require("./assets/tokens/common.json"));
|
|
8
|
+
const mainnet_json_1 = __importDefault(require("./assets/tokens/mainnet.json"));
|
|
9
|
+
exports.TOKENS = {
|
|
10
|
+
mainnet: [...common_json_1.default, ...mainnet_json_1.default],
|
|
11
|
+
testnet: common_json_1.default,
|
|
12
|
+
custom: common_json_1.default,
|
|
13
|
+
};
|
|
14
|
+
exports.NEO_NS_HASH = '0x50ac1c37690cc2cfc594472833cf57505d5f46de';
|
|
15
|
+
exports.DEFAULT_URL_BY_NETWORK_TYPE = {
|
|
16
|
+
mainnet: 'https://mainnet1.neo.coz.io:443',
|
|
17
|
+
testnet: 'https://testnet1.neo.coz.io:443',
|
|
18
|
+
custom: 'http://127.0.0.1:50012',
|
|
19
|
+
};
|
|
20
|
+
exports.GHOSTMARKET_URL_BY_NETWORK_TYPE = {
|
|
21
|
+
mainnet: 'https://api.ghostmarket.io/api/v2',
|
|
22
|
+
testnet: 'https://api-testnet.ghostmarket.io/api/v2',
|
|
8
23
|
};
|
|
9
|
-
exports.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
decimals: 0
|
|
24
|
+
exports.GHOSTMARKET_CHAIN_BY_NETWORK_TYPE = {
|
|
25
|
+
mainnet: 'n3',
|
|
26
|
+
testnet: 'n3t',
|
|
13
27
|
};
|
|
28
|
+
exports.DERIVATION_PATH = "m/44'/888'/0'/0/?";
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -14,7 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./
|
|
17
|
+
__exportStar(require("./DoraBDSNeo3"), exports);
|
|
18
|
+
__exportStar(require("./RpcBDSNeo3"), exports);
|
|
18
19
|
__exportStar(require("./BSNeo3"), exports);
|
|
19
20
|
__exportStar(require("./constants"), exports);
|
|
20
|
-
__exportStar(require("./
|
|
21
|
+
__exportStar(require("./FlamingoEDSNeo3"), exports);
|
|
22
|
+
__exportStar(require("./GhostMarketNDSNeo3"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cityofzion/bs-neo3",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"repository": "https://github.com/CityOfZion/blockchain-services",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"@cityofzion/neo3-invoker": "1.6.0",
|
|
18
18
|
"@cityofzion/neon-parser": "1.6.2",
|
|
19
19
|
"@cityofzion/neo3-parser": "1.6.0",
|
|
20
|
-
"@cityofzion/blockchain-service": "0.7.
|
|
21
|
-
"@cityofzion/bs-asteroid-sdk": "0.7.
|
|
20
|
+
"@cityofzion/blockchain-service": "0.7.2",
|
|
21
|
+
"@cityofzion/bs-asteroid-sdk": "0.7.2",
|
|
22
22
|
"@cityofzion/dora-ts": "0.0.11",
|
|
23
23
|
"query-string": "7.1.3"
|
|
24
24
|
},
|