@cityofzion/bs-neox 1.2.4 → 1.3.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.
- package/dist/services/blockchain-data/BlockscoutBDSNeoX.d.ts +1 -0
- package/dist/services/blockchain-data/BlockscoutBDSNeoX.js +164 -8
- package/dist/services/neo3neoXBridge/Neo3NeoXBridgeService.d.ts +5 -5
- package/dist/services/neo3neoXBridge/Neo3NeoXBridgeService.js +27 -21
- package/package.json +4 -4
|
@@ -2,6 +2,7 @@ import { BalanceResponse, ContractResponse, ExplorerService, ExportTransactionsB
|
|
|
2
2
|
import { DoraBDSEthereum } from '@cityofzion/bs-ethereum';
|
|
3
3
|
import { BSNeoXNetworkId } from '../../constants/BSNeoXConstants';
|
|
4
4
|
export declare class BlockscoutBDSNeoX extends DoraBDSEthereum<BSNeoXNetworkId> {
|
|
5
|
+
#private;
|
|
5
6
|
static BASE_URL_BY_CHAIN_ID: Partial<Record<BSNeoXNetworkId, string>>;
|
|
6
7
|
static getClient(network: Network<BSNeoXNetworkId>): import("axios").AxiosInstance;
|
|
7
8
|
constructor(network: Network<BSNeoXNetworkId>, nftDataService: NftDataService, explorerService: ExplorerService);
|
|
@@ -8,6 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
12
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
13
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
14
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
15
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
16
|
+
};
|
|
17
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
18
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
19
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
20
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
21
|
+
};
|
|
11
22
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
23
|
var t = {};
|
|
13
24
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -22,6 +33,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
22
33
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
34
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
35
|
};
|
|
36
|
+
var _BlockscoutBDSNeoX_instances, _BlockscoutBDSNeoX_nftDataService, _BlockscoutBDSNeoX_explorerService, _BlockscoutBDSNeoX_getBridgeNeo3NeoXDataByBlockscoutTransaction;
|
|
25
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
38
|
exports.BlockscoutBDSNeoX = void 0;
|
|
27
39
|
const blockchain_service_1 = require("@cityofzion/blockchain-service");
|
|
@@ -30,6 +42,9 @@ const ethers_1 = require("ethers");
|
|
|
30
42
|
const dora_ts_1 = require("@cityofzion/dora-ts");
|
|
31
43
|
const bs_ethereum_1 = require("@cityofzion/bs-ethereum");
|
|
32
44
|
const BSNeoXConstants_1 = require("../../constants/BSNeoXConstants");
|
|
45
|
+
const bridge_1 = require("../../assets/abis/bridge");
|
|
46
|
+
const Neo3NeoXBridgeService_1 = require("../neo3neoXBridge/Neo3NeoXBridgeService");
|
|
47
|
+
const neon_js_1 = require("@cityofzion/neon-js");
|
|
33
48
|
class BlockscoutBDSNeoX extends bs_ethereum_1.DoraBDSEthereum {
|
|
34
49
|
static getClient(network) {
|
|
35
50
|
const baseURL = BlockscoutBDSNeoX.BASE_URL_BY_CHAIN_ID[network.id];
|
|
@@ -41,10 +56,16 @@ class BlockscoutBDSNeoX extends bs_ethereum_1.DoraBDSEthereum {
|
|
|
41
56
|
});
|
|
42
57
|
}
|
|
43
58
|
constructor(network, nftDataService, explorerService) {
|
|
44
|
-
super(network, BSNeoXConstants_1.BSNeoXConstants.ALL_NETWORK_IDS
|
|
59
|
+
super(network, BSNeoXConstants_1.BSNeoXConstants.ALL_NETWORK_IDS);
|
|
60
|
+
_BlockscoutBDSNeoX_instances.add(this);
|
|
61
|
+
_BlockscoutBDSNeoX_nftDataService.set(this, void 0);
|
|
62
|
+
_BlockscoutBDSNeoX_explorerService.set(this, void 0);
|
|
45
63
|
this.maxTimeToConfirmTransactionInMs = 1000 * 60 * 5;
|
|
64
|
+
__classPrivateFieldSet(this, _BlockscoutBDSNeoX_nftDataService, nftDataService, "f");
|
|
65
|
+
__classPrivateFieldSet(this, _BlockscoutBDSNeoX_explorerService, explorerService, "f");
|
|
46
66
|
}
|
|
47
67
|
getTransaction(txid) {
|
|
68
|
+
var _a;
|
|
48
69
|
return __awaiter(this, void 0, void 0, function* () {
|
|
49
70
|
const client = BlockscoutBDSNeoX.getClient(this._network);
|
|
50
71
|
const { data } = yield client.get(`/transactions/${txid}`);
|
|
@@ -52,13 +73,14 @@ class BlockscoutBDSNeoX extends bs_ethereum_1.DoraBDSEthereum {
|
|
|
52
73
|
throw new Error('Transaction not found');
|
|
53
74
|
}
|
|
54
75
|
const nativeToken = BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET;
|
|
76
|
+
const to = (_a = data.to) === null || _a === void 0 ? void 0 : _a.hash;
|
|
55
77
|
const transfers = [];
|
|
56
78
|
const hasNativeTokenBeingTransferred = data.value !== '0';
|
|
57
79
|
if (hasNativeTokenBeingTransferred) {
|
|
58
80
|
transfers.push({
|
|
59
81
|
amount: ethers_1.ethers.utils.formatUnits(data.value, nativeToken.decimals),
|
|
60
82
|
from: data.from.hash,
|
|
61
|
-
to
|
|
83
|
+
to,
|
|
62
84
|
type: 'token',
|
|
63
85
|
contractHash: nativeToken.hash,
|
|
64
86
|
token: nativeToken,
|
|
@@ -94,14 +116,21 @@ class BlockscoutBDSNeoX extends bs_ethereum_1.DoraBDSEthereum {
|
|
|
94
116
|
}
|
|
95
117
|
}
|
|
96
118
|
}
|
|
97
|
-
|
|
119
|
+
let transaction = {
|
|
98
120
|
block: data.block,
|
|
99
121
|
hash: data.hash,
|
|
100
122
|
fee: ethers_1.ethers.utils.formatUnits(data.fee.value, nativeToken.decimals),
|
|
101
123
|
time: new Date(data.timestamp).getTime() / 1000,
|
|
102
124
|
notifications: [],
|
|
103
125
|
transfers,
|
|
126
|
+
type: 'default',
|
|
104
127
|
};
|
|
128
|
+
if (to === Neo3NeoXBridgeService_1.Neo3NeoXBridgeService.BRIDGE_SCRIPT_HASH) {
|
|
129
|
+
const [bridgeNeo3NeoXData] = yield blockchain_service_1.BSPromisesHelper.tryCatch(() => __classPrivateFieldGet(this, _BlockscoutBDSNeoX_instances, "m", _BlockscoutBDSNeoX_getBridgeNeo3NeoXDataByBlockscoutTransaction).call(this, data));
|
|
130
|
+
if (bridgeNeo3NeoXData)
|
|
131
|
+
transaction = Object.assign(Object.assign({}, transaction), { type: 'bridgeNeo3NeoX', data: bridgeNeo3NeoXData });
|
|
132
|
+
}
|
|
133
|
+
return transaction;
|
|
105
134
|
});
|
|
106
135
|
}
|
|
107
136
|
getTransactionsByAddress(params) {
|
|
@@ -118,13 +147,15 @@ class BlockscoutBDSNeoX extends bs_ethereum_1.DoraBDSEthereum {
|
|
|
118
147
|
const nativeToken = BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET;
|
|
119
148
|
const transactions = [];
|
|
120
149
|
const promises = data.items.map((item) => __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
var _a;
|
|
121
151
|
const transfers = [];
|
|
152
|
+
const to = (_a = item.to) === null || _a === void 0 ? void 0 : _a.hash;
|
|
122
153
|
const hasNativeTokenBeingTransferred = item.value !== '0';
|
|
123
154
|
if (hasNativeTokenBeingTransferred) {
|
|
124
155
|
transfers.push({
|
|
125
156
|
amount: ethers_1.ethers.utils.formatUnits(item.value, nativeToken.decimals),
|
|
126
157
|
from: item.from.hash,
|
|
127
|
-
to
|
|
158
|
+
to,
|
|
128
159
|
type: 'token',
|
|
129
160
|
contractHash: nativeToken.hash,
|
|
130
161
|
token: nativeToken,
|
|
@@ -153,14 +184,21 @@ class BlockscoutBDSNeoX extends bs_ethereum_1.DoraBDSEthereum {
|
|
|
153
184
|
/* empty */
|
|
154
185
|
}
|
|
155
186
|
}
|
|
156
|
-
|
|
187
|
+
let transaction = {
|
|
157
188
|
block: item.block,
|
|
158
189
|
hash: item.hash,
|
|
159
190
|
fee: ethers_1.ethers.utils.formatUnits(item.fee.value, nativeToken.decimals),
|
|
160
191
|
time: new Date(item.timestamp).getTime() / 1000,
|
|
161
192
|
notifications: [],
|
|
162
193
|
transfers,
|
|
163
|
-
|
|
194
|
+
type: 'default',
|
|
195
|
+
};
|
|
196
|
+
if (to === Neo3NeoXBridgeService_1.Neo3NeoXBridgeService.BRIDGE_SCRIPT_HASH) {
|
|
197
|
+
const [bridgeNeo3NeoXData] = yield blockchain_service_1.BSPromisesHelper.tryCatch(() => __classPrivateFieldGet(this, _BlockscoutBDSNeoX_instances, "m", _BlockscoutBDSNeoX_getBridgeNeo3NeoXDataByBlockscoutTransaction).call(this, item));
|
|
198
|
+
if (bridgeNeo3NeoXData)
|
|
199
|
+
transaction = Object.assign(Object.assign({}, transaction), { type: 'bridgeNeo3NeoX', data: bridgeNeo3NeoXData });
|
|
200
|
+
}
|
|
201
|
+
transactions.push(transaction);
|
|
164
202
|
}));
|
|
165
203
|
yield Promise.allSettled(promises);
|
|
166
204
|
return {
|
|
@@ -170,10 +208,11 @@ class BlockscoutBDSNeoX extends bs_ethereum_1.DoraBDSEthereum {
|
|
|
170
208
|
});
|
|
171
209
|
}
|
|
172
210
|
getFullTransactionsByAddress(_a) {
|
|
173
|
-
var _b;
|
|
211
|
+
var _b, _c;
|
|
174
212
|
var { nextCursor } = _a, params = __rest(_a, ["nextCursor"]);
|
|
175
213
|
return __awaiter(this, void 0, void 0, function* () {
|
|
176
214
|
this._validateGetFullTransactionsByAddressParams(params);
|
|
215
|
+
const data = [];
|
|
177
216
|
const response = yield dora_ts_1.api.NeoXREST.getFullTransactionsByAddress({
|
|
178
217
|
address: params.address,
|
|
179
218
|
timestampFrom: params.dateFrom,
|
|
@@ -182,7 +221,101 @@ class BlockscoutBDSNeoX extends bs_ethereum_1.DoraBDSEthereum {
|
|
|
182
221
|
cursor: nextCursor,
|
|
183
222
|
pageLimit: (_b = params.pageSize) !== null && _b !== void 0 ? _b : 50,
|
|
184
223
|
});
|
|
185
|
-
|
|
224
|
+
const items = (_c = response.data) !== null && _c !== void 0 ? _c : [];
|
|
225
|
+
const nativeToken = bs_ethereum_1.BSEthereumHelper.getNativeAsset(this._network);
|
|
226
|
+
const client = BlockscoutBDSNeoX.getClient(this._network);
|
|
227
|
+
const addressTemplateUrl = __classPrivateFieldGet(this, _BlockscoutBDSNeoX_explorerService, "f").getAddressTemplateUrl();
|
|
228
|
+
const txTemplateUrl = __classPrivateFieldGet(this, _BlockscoutBDSNeoX_explorerService, "f").getTxTemplateUrl();
|
|
229
|
+
const nftTemplateUrl = __classPrivateFieldGet(this, _BlockscoutBDSNeoX_explorerService, "f").getNftTemplateUrl();
|
|
230
|
+
const contractTemplateUrl = __classPrivateFieldGet(this, _BlockscoutBDSNeoX_explorerService, "f").getContractTemplateUrl();
|
|
231
|
+
const itemPromises = items.map((_d, index) => __awaiter(this, void 0, void 0, function* () {
|
|
232
|
+
var { networkFeeAmount, systemFeeAmount } = _d, item = __rest(_d, ["networkFeeAmount", "systemFeeAmount"]);
|
|
233
|
+
const txId = item.transactionID;
|
|
234
|
+
let newItem = {
|
|
235
|
+
txId,
|
|
236
|
+
txIdUrl: txId ? txTemplateUrl === null || txTemplateUrl === void 0 ? void 0 : txTemplateUrl.replace('{txId}', txId) : undefined,
|
|
237
|
+
block: item.block,
|
|
238
|
+
date: item.date,
|
|
239
|
+
invocationCount: item.invocationCount,
|
|
240
|
+
notificationCount: item.notificationCount,
|
|
241
|
+
networkFeeAmount: networkFeeAmount
|
|
242
|
+
? blockchain_service_1.BSBigNumberHelper.format(networkFeeAmount, { decimals: nativeToken.decimals })
|
|
243
|
+
: undefined,
|
|
244
|
+
systemFeeAmount: systemFeeAmount
|
|
245
|
+
? blockchain_service_1.BSBigNumberHelper.format(systemFeeAmount, { decimals: nativeToken.decimals })
|
|
246
|
+
: undefined,
|
|
247
|
+
events: [],
|
|
248
|
+
type: 'default',
|
|
249
|
+
};
|
|
250
|
+
const eventPromises = item.events.map((event, eventIndex) => __awaiter(this, void 0, void 0, function* () {
|
|
251
|
+
var _e, _f, _g, _h, _j, _k;
|
|
252
|
+
let nftEvent;
|
|
253
|
+
let assetEvent;
|
|
254
|
+
const { methodName, tokenID: tokenId, contractHash: hash } = event;
|
|
255
|
+
const from = (_e = event.from) !== null && _e !== void 0 ? _e : undefined;
|
|
256
|
+
const to = (_f = event.to) !== null && _f !== void 0 ? _f : undefined;
|
|
257
|
+
const standard = (_j = (_h = (_g = event.supportedStandards) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h.toLowerCase()) !== null && _j !== void 0 ? _j : '';
|
|
258
|
+
const isErc1155 = this._supportedErc1155Standards.includes(standard);
|
|
259
|
+
const isErc721 = this._supportedErc721Standards.includes(standard);
|
|
260
|
+
const isErc20 = this._supportedErc20Standards.includes(standard);
|
|
261
|
+
const isNft = (isErc1155 || isErc721) && !!tokenId;
|
|
262
|
+
const fromUrl = from ? addressTemplateUrl === null || addressTemplateUrl === void 0 ? void 0 : addressTemplateUrl.replace('{address}', from) : undefined;
|
|
263
|
+
const toUrl = to ? addressTemplateUrl === null || addressTemplateUrl === void 0 ? void 0 : addressTemplateUrl.replace('{address}', to) : undefined;
|
|
264
|
+
const hashUrl = hash ? contractTemplateUrl === null || contractTemplateUrl === void 0 ? void 0 : contractTemplateUrl.replace('{hash}', hash) : undefined;
|
|
265
|
+
if (isNft) {
|
|
266
|
+
const [nft] = yield blockchain_service_1.BSPromisesHelper.tryCatch(() => __classPrivateFieldGet(this, _BlockscoutBDSNeoX_nftDataService, "f").getNft({ contractHash: hash, tokenId }));
|
|
267
|
+
const nftUrl = hash ? nftTemplateUrl === null || nftTemplateUrl === void 0 ? void 0 : nftTemplateUrl.replace('{hash}', hash).replace('{tokenId}', tokenId) : undefined;
|
|
268
|
+
nftEvent = {
|
|
269
|
+
eventType: 'nft',
|
|
270
|
+
amount: undefined,
|
|
271
|
+
methodName,
|
|
272
|
+
from,
|
|
273
|
+
fromUrl,
|
|
274
|
+
to,
|
|
275
|
+
toUrl,
|
|
276
|
+
hash,
|
|
277
|
+
hashUrl,
|
|
278
|
+
tokenId,
|
|
279
|
+
tokenType: isErc1155 ? 'erc-1155' : 'erc-721',
|
|
280
|
+
nftImageUrl: nft === null || nft === void 0 ? void 0 : nft.image,
|
|
281
|
+
nftUrl,
|
|
282
|
+
name: nft === null || nft === void 0 ? void 0 : nft.name,
|
|
283
|
+
collectionName: nft === null || nft === void 0 ? void 0 : nft.collectionName,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
const [token] = yield blockchain_service_1.BSPromisesHelper.tryCatch(() => this.getTokenInfo(hash));
|
|
288
|
+
assetEvent = {
|
|
289
|
+
eventType: 'token',
|
|
290
|
+
amount: event.amount
|
|
291
|
+
? blockchain_service_1.BSBigNumberHelper.format(event.amount, { decimals: (_k = token === null || token === void 0 ? void 0 : token.decimals) !== null && _k !== void 0 ? _k : event.tokenDecimals })
|
|
292
|
+
: undefined,
|
|
293
|
+
methodName,
|
|
294
|
+
from,
|
|
295
|
+
fromUrl,
|
|
296
|
+
to,
|
|
297
|
+
toUrl,
|
|
298
|
+
hash,
|
|
299
|
+
hashUrl,
|
|
300
|
+
token: token !== null && token !== void 0 ? token : undefined,
|
|
301
|
+
tokenType: isErc20 ? 'erc-20' : 'generic',
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
if (newItem.type === 'default' && to === Neo3NeoXBridgeService_1.Neo3NeoXBridgeService.BRIDGE_SCRIPT_HASH) {
|
|
305
|
+
const [data] = yield blockchain_service_1.BSPromisesHelper.tryCatch(() => __awaiter(this, void 0, void 0, function* () {
|
|
306
|
+
const response = yield client.get(`/transactions/${txId}`);
|
|
307
|
+
return __classPrivateFieldGet(this, _BlockscoutBDSNeoX_instances, "m", _BlockscoutBDSNeoX_getBridgeNeo3NeoXDataByBlockscoutTransaction).call(this, response.data);
|
|
308
|
+
}));
|
|
309
|
+
if (data)
|
|
310
|
+
newItem = Object.assign(Object.assign({}, newItem), { type: 'bridgeNeo3NeoX', data });
|
|
311
|
+
}
|
|
312
|
+
newItem.events.splice(eventIndex, 0, isNft ? nftEvent : assetEvent);
|
|
313
|
+
}));
|
|
314
|
+
yield Promise.allSettled(eventPromises);
|
|
315
|
+
data.splice(index, 0, newItem);
|
|
316
|
+
}));
|
|
317
|
+
yield Promise.allSettled(itemPromises);
|
|
318
|
+
return { nextCursor: response.nextCursor, data };
|
|
186
319
|
});
|
|
187
320
|
}
|
|
188
321
|
exportFullTransactionsByAddress(params) {
|
|
@@ -311,6 +444,29 @@ class BlockscoutBDSNeoX extends bs_ethereum_1.DoraBDSEthereum {
|
|
|
311
444
|
}
|
|
312
445
|
}
|
|
313
446
|
exports.BlockscoutBDSNeoX = BlockscoutBDSNeoX;
|
|
447
|
+
_BlockscoutBDSNeoX_nftDataService = new WeakMap(), _BlockscoutBDSNeoX_explorerService = new WeakMap(), _BlockscoutBDSNeoX_instances = new WeakSet(), _BlockscoutBDSNeoX_getBridgeNeo3NeoXDataByBlockscoutTransaction = function _BlockscoutBDSNeoX_getBridgeNeo3NeoXDataByBlockscoutTransaction(blockscoutTransaction) {
|
|
448
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
449
|
+
const BridgeInterface = new ethers_1.ethers.utils.Interface(bridge_1.BRIDGE_ABI);
|
|
450
|
+
const input = BridgeInterface.parseTransaction({ data: blockscoutTransaction.raw_input });
|
|
451
|
+
const to = input.args._to;
|
|
452
|
+
const receiverAddress = neon_js_1.wallet.getAddressFromScriptHash(to.startsWith('0x') ? to.slice(2) : to);
|
|
453
|
+
if (input.name === 'withdrawNative') {
|
|
454
|
+
const token = BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET;
|
|
455
|
+
const amount = blockchain_service_1.BSBigNumberHelper.format(ethers_1.ethers.utils.formatUnits(blockscoutTransaction.value, token.decimals), {
|
|
456
|
+
decimals: token.decimals,
|
|
457
|
+
});
|
|
458
|
+
return { amount, token, receiverAddress };
|
|
459
|
+
}
|
|
460
|
+
if (input.name === 'withdrawToken') {
|
|
461
|
+
const token = BSNeoXConstants_1.BSNeoXConstants.NEO_TOKEN;
|
|
462
|
+
const amount = blockchain_service_1.BSBigNumberHelper.format(ethers_1.ethers.utils.formatUnits(input.args._amount, token.decimals), {
|
|
463
|
+
decimals: token.decimals,
|
|
464
|
+
});
|
|
465
|
+
return { amount, token, receiverAddress };
|
|
466
|
+
}
|
|
467
|
+
return undefined;
|
|
468
|
+
});
|
|
469
|
+
};
|
|
314
470
|
BlockscoutBDSNeoX.BASE_URL_BY_CHAIN_ID = {
|
|
315
471
|
'47763': `${blockchain_service_1.BSCommonConstants.DORA_URL}/api/neox/mainnet`,
|
|
316
472
|
'12227332': 'https://dora-stage.coz.io/api/neox/testnet',
|
|
@@ -2,13 +2,13 @@ import { INeo3NeoXBridgeService, TBridgeToken, TNeo3NeoXBridgeServiceBridgeParam
|
|
|
2
2
|
import { BSNeoX } from '../../BSNeoX';
|
|
3
3
|
export declare class Neo3NeoXBridgeService<BSName extends string> implements INeo3NeoXBridgeService<BSName> {
|
|
4
4
|
#private;
|
|
5
|
-
readonly BRIDGE_SCRIPT_HASH = "0x1212000000000000000000000000000000000004";
|
|
5
|
+
static readonly BRIDGE_SCRIPT_HASH = "0x1212000000000000000000000000000000000004";
|
|
6
6
|
readonly BRIDGE_BASE_CONFIRMATION_URL = "https://xexplorer.neo.org:8877/api/v1/transactions/deposits";
|
|
7
|
-
tokens: TBridgeToken[];
|
|
7
|
+
tokens: TBridgeToken<BSName>[];
|
|
8
8
|
constructor(service: BSNeoX<BSName>);
|
|
9
|
-
getBridgeConstants(token: TBridgeToken): Promise<TNeo3NeoXBridgeServiceConstants>;
|
|
9
|
+
getBridgeConstants(token: TBridgeToken<BSName>): Promise<TNeo3NeoXBridgeServiceConstants>;
|
|
10
10
|
getApprovalFee(params: TNeo3NeoXBridgeServiceGetApprovalParam<BSName>): Promise<string>;
|
|
11
11
|
bridge(params: TNeo3NeoXBridgeServiceBridgeParam<BSName>): Promise<string>;
|
|
12
|
-
getNonce(params: TNeo3NeoXBridgeServiceGetNonceParams): Promise<string
|
|
13
|
-
getTransactionHashByNonce(params: TNeo3NeoXBridgeServiceGetTransactionHashByNonceParams): Promise<string
|
|
12
|
+
getNonce(params: TNeo3NeoXBridgeServiceGetNonceParams<BSName>): Promise<string>;
|
|
13
|
+
getTransactionHashByNonce(params: TNeo3NeoXBridgeServiceGetTransactionHashByNonceParams<BSName>): Promise<string>;
|
|
14
14
|
}
|
|
@@ -37,20 +37,19 @@ const BSNeoXHelper_1 = require("../../helpers/BSNeoXHelper");
|
|
|
37
37
|
class Neo3NeoXBridgeService {
|
|
38
38
|
constructor(service) {
|
|
39
39
|
_Neo3NeoXBridgeService_instances.add(this);
|
|
40
|
-
this.BRIDGE_SCRIPT_HASH = '0x1212000000000000000000000000000000000004';
|
|
41
40
|
this.BRIDGE_BASE_CONFIRMATION_URL = 'https://xexplorer.neo.org:8877/api/v1/transactions/deposits';
|
|
42
41
|
_Neo3NeoXBridgeService_service.set(this, void 0);
|
|
43
42
|
__classPrivateFieldSet(this, _Neo3NeoXBridgeService_service, service, "f");
|
|
44
43
|
this.tokens = [
|
|
45
|
-
Object.assign(Object.assign({}, BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET), { multichainId: 'gas' }),
|
|
46
|
-
Object.assign(Object.assign({}, BSNeoXConstants_1.BSNeoXConstants.NEO_TOKEN), { multichainId: 'neo' }),
|
|
44
|
+
Object.assign(Object.assign({}, BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET), { multichainId: 'gas', blockchain: service.name }),
|
|
45
|
+
Object.assign(Object.assign({}, BSNeoXConstants_1.BSNeoXConstants.NEO_TOKEN), { multichainId: 'neo', blockchain: service.name }),
|
|
47
46
|
];
|
|
48
47
|
}
|
|
49
48
|
getBridgeConstants(token) {
|
|
50
49
|
return __awaiter(this, void 0, void 0, function* () {
|
|
51
50
|
try {
|
|
52
51
|
const provider = new ethers_1.ethers.providers.JsonRpcProvider(__classPrivateFieldGet(this, _Neo3NeoXBridgeService_service, "f").network.url);
|
|
53
|
-
const bridgeContract = new ethers_1.ethers.Contract(
|
|
52
|
+
const bridgeContract = new ethers_1.ethers.Contract(Neo3NeoXBridgeService.BRIDGE_SCRIPT_HASH, bridge_1.BRIDGE_ABI, provider);
|
|
54
53
|
const isNativeToken = blockchain_service_1.BSTokenHelper.predicateByHash(token)(BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET);
|
|
55
54
|
const response = isNativeToken
|
|
56
55
|
? yield bridgeContract.nativeBridge()
|
|
@@ -103,7 +102,7 @@ class Neo3NeoXBridgeService {
|
|
|
103
102
|
throw new blockchain_service_1.BSError('Bridging to Neo3 is only supported on mainnet', 'UNSUPPORTED_NETWORK');
|
|
104
103
|
const { account } = params;
|
|
105
104
|
const signer = yield __classPrivateFieldGet(this, _Neo3NeoXBridgeService_service, "f").generateSigner(account);
|
|
106
|
-
const bridgeContract = new ethers_1.ethers.Contract(
|
|
105
|
+
const bridgeContract = new ethers_1.ethers.Contract(Neo3NeoXBridgeService.BRIDGE_SCRIPT_HASH, bridge_1.BRIDGE_ABI);
|
|
107
106
|
const to = '0x' + neon_js_1.wallet.getScriptHashFromAddress(params.receiverAddress);
|
|
108
107
|
const bridgeFee = ethers_1.ethers.utils.parseUnits(params.bridgeFee, BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET.decimals);
|
|
109
108
|
const isNativeToken = blockchain_service_1.BSTokenHelper.predicateByHash(params.token)(BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET);
|
|
@@ -112,7 +111,7 @@ class Neo3NeoXBridgeService {
|
|
|
112
111
|
};
|
|
113
112
|
if (isNativeToken) {
|
|
114
113
|
const populatedTransaction = yield bridgeContract.populateTransaction.withdrawNative(to, bridgeFee);
|
|
115
|
-
bridgeTransactionParam = Object.assign(Object.assign(Object.assign({}, bridgeTransactionParam), populatedTransaction), { value: ethers_1.ethers.utils.parseUnits(params.amount, params.token.decimals) });
|
|
114
|
+
bridgeTransactionParam = Object.assign(Object.assign(Object.assign({}, bridgeTransactionParam), populatedTransaction), { value: ethers_1.ethers.utils.parseUnits(params.amount, params.token.decimals).add(bridgeFee) });
|
|
116
115
|
}
|
|
117
116
|
else {
|
|
118
117
|
const approveTransactionParam = yield __classPrivateFieldGet(this, _Neo3NeoXBridgeService_instances, "m", _Neo3NeoXBridgeService_buildApproveTransactionParam).call(this, params);
|
|
@@ -129,7 +128,7 @@ class Neo3NeoXBridgeService {
|
|
|
129
128
|
try {
|
|
130
129
|
gasLimit = yield signer.estimateGas(bridgeTransactionParam);
|
|
131
130
|
}
|
|
132
|
-
catch (
|
|
131
|
+
catch (error) {
|
|
133
132
|
gasLimit = bs_ethereum_1.BSEthereumConstants.DEFAULT_GAS_LIMIT;
|
|
134
133
|
}
|
|
135
134
|
const gasPrice = yield signer.getGasPrice();
|
|
@@ -146,30 +145,37 @@ class Neo3NeoXBridgeService {
|
|
|
146
145
|
data = response.data;
|
|
147
146
|
}
|
|
148
147
|
catch (error) {
|
|
149
|
-
throw new blockchain_service_1.BSError('
|
|
148
|
+
throw new blockchain_service_1.BSError('Failed to get nonce from transaction log', 'FAILED_TO_GET_NONCE', error);
|
|
150
149
|
}
|
|
151
150
|
if (!data.items || data.items.length === 0) {
|
|
152
|
-
throw new blockchain_service_1.BSError('Transaction
|
|
151
|
+
throw new blockchain_service_1.BSError('Transaction invalid', 'INVALID_TRANSACTION');
|
|
153
152
|
}
|
|
154
153
|
try {
|
|
155
154
|
const BridgeInterface = new ethers_1.ethers.utils.Interface(bridge_1.BRIDGE_ABI);
|
|
156
155
|
const isNativeToken = blockchain_service_1.BSTokenHelper.predicateByHash(params.token)(BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET);
|
|
156
|
+
let nonce;
|
|
157
157
|
if (isNativeToken) {
|
|
158
158
|
const item = data.items[0];
|
|
159
159
|
const parsedLog = BridgeInterface.parseLog({ data: item.data, topics: item.topics.filter(Boolean) });
|
|
160
|
-
|
|
160
|
+
nonce = parsedLog.args.nonce ? parsedLog.args.nonce.toString() : undefined;
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
const item = data.items[1];
|
|
164
|
+
const parsedLog = BridgeInterface.parseLog({ data: item.data, topics: item.topics.filter(Boolean) });
|
|
165
|
+
nonce = parsedLog.args.nonce ? parsedLog.args.nonce.toString() : undefined;
|
|
166
|
+
}
|
|
167
|
+
if (!nonce) {
|
|
168
|
+
throw new blockchain_service_1.BSError('Nonce not found in transaction log', 'NONCE_NOT_FOUND');
|
|
161
169
|
}
|
|
162
|
-
|
|
163
|
-
const parsedLog = BridgeInterface.parseLog({ data: item.data, topics: item.topics.filter(Boolean) });
|
|
164
|
-
return parsedLog.args.nonce ? parsedLog.args.nonce.toString() : null;
|
|
170
|
+
return nonce;
|
|
165
171
|
}
|
|
166
172
|
catch (error) {
|
|
167
|
-
|
|
173
|
+
throw new blockchain_service_1.BSError('Failed to get nonce from transaction log', 'FAILED_TO_GET_NONCE', error);
|
|
168
174
|
}
|
|
169
175
|
});
|
|
170
176
|
}
|
|
171
177
|
getTransactionHashByNonce(params) {
|
|
172
|
-
var _a
|
|
178
|
+
var _a;
|
|
173
179
|
return __awaiter(this, void 0, void 0, function* () {
|
|
174
180
|
try {
|
|
175
181
|
let url;
|
|
@@ -182,12 +188,12 @@ class Neo3NeoXBridgeService {
|
|
|
182
188
|
}
|
|
183
189
|
const response = yield axios_1.default.get(url);
|
|
184
190
|
if (!((_a = response.data) === null || _a === void 0 ? void 0 : _a.txid)) {
|
|
185
|
-
throw new blockchain_service_1.BSError('Transaction not found', '
|
|
191
|
+
throw new blockchain_service_1.BSError('Transaction ID not found in response', 'TXID_NOT_FOUND');
|
|
186
192
|
}
|
|
187
|
-
return
|
|
193
|
+
return response.data.txid;
|
|
188
194
|
}
|
|
189
195
|
catch (error) {
|
|
190
|
-
throw new blockchain_service_1.BSError('Transaction not found', '
|
|
196
|
+
throw new blockchain_service_1.BSError('Transaction ID not found in response', 'TXID_NOT_FOUND', error);
|
|
191
197
|
}
|
|
192
198
|
});
|
|
193
199
|
}
|
|
@@ -197,7 +203,7 @@ _Neo3NeoXBridgeService_service = new WeakMap(), _Neo3NeoXBridgeService_instances
|
|
|
197
203
|
return __awaiter(this, void 0, void 0, function* () {
|
|
198
204
|
const provider = new ethers_1.ethers.providers.JsonRpcProvider(__classPrivateFieldGet(this, _Neo3NeoXBridgeService_service, "f").network.url);
|
|
199
205
|
const erc20Contract = new ethers_1.ethers.Contract(params.token.hash, bs_ethereum_1.ERC20_ABI, provider);
|
|
200
|
-
const allowance = yield erc20Contract.allowance(params.account.address,
|
|
206
|
+
const allowance = yield erc20Contract.allowance(params.account.address, Neo3NeoXBridgeService.BRIDGE_SCRIPT_HASH);
|
|
201
207
|
const allowanceNumber = blockchain_service_1.BSBigNumberHelper.fromDecimals(allowance.toString(), BSNeoXConstants_1.BSNeoXConstants.NEO_TOKEN.decimals);
|
|
202
208
|
// We are using 0 as the decimals because the NEO token in Neo3 has 0 decimals
|
|
203
209
|
const fixedAmount = blockchain_service_1.BSBigNumberHelper.format(params.amount, { decimals: 0 });
|
|
@@ -205,7 +211,7 @@ _Neo3NeoXBridgeService_service = new WeakMap(), _Neo3NeoXBridgeService_instances
|
|
|
205
211
|
return null;
|
|
206
212
|
}
|
|
207
213
|
const amount = ethers_1.ethers.utils.parseUnits(fixedAmount, params.token.decimals);
|
|
208
|
-
|
|
209
|
-
return populatedApproveTransaction;
|
|
214
|
+
return yield erc20Contract.populateTransaction.approve(Neo3NeoXBridgeService.BRIDGE_SCRIPT_HASH, amount);
|
|
210
215
|
});
|
|
211
216
|
};
|
|
217
|
+
Neo3NeoXBridgeService.BRIDGE_SCRIPT_HASH = '0x1212000000000000000000000000000000000004';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cityofzion/bs-neox",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"repository": "https://github.com/CityOfZion/blockchain-services",
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"axios": "1.8.2",
|
|
17
17
|
"ethers": "5.7.2",
|
|
18
18
|
"date-fns": "~4.1.0",
|
|
19
|
-
"@cityofzion/blockchain-service": "1.
|
|
20
|
-
"@cityofzion/bs-ethereum": "2.
|
|
19
|
+
"@cityofzion/blockchain-service": "1.20.0",
|
|
20
|
+
"@cityofzion/bs-ethereum": "2.13.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@ledgerhq/hw-transport-node-hid": "~6.29.9",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"eslint": "^8.48.0",
|
|
30
30
|
"jest": "29.6.2",
|
|
31
31
|
"ts-jest": "29.1.1",
|
|
32
|
-
"ts-node": "10.9.
|
|
32
|
+
"ts-node": "~10.9.2",
|
|
33
33
|
"typescript": "4.9.5"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|