@cityofzion/bs-neo3 1.15.3 → 1.16.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.
@@ -30,12 +30,13 @@ var __rest = (this && this.__rest) || function (s, e) {
30
30
  }
31
31
  return t;
32
32
  };
33
- var _DoraBDSNeo3_instances, _DoraBDSNeo3_supportedNep11Standards, _DoraBDSNeo3_nftDataService, _DoraBDSNeo3_explorerService, _DoraBDSNeo3_validateAddress, _DoraBDSNeo3_validateFullTransactionsByAddressParams, _DoraBDSNeo3_validateGetFullTransactionsByAddressParams;
33
+ var _DoraBDSNeo3_instances, _DoraBDSNeo3_supportedNep11Standards, _DoraBDSNeo3_nftDataService, _DoraBDSNeo3_explorerService, _DoraBDSNeo3_validateAddress, _DoraBDSNeo3_validateFullTransactionsByAddressParams, _DoraBDSNeo3_validateGetFullTransactionsByAddressParams, _DoraBDSNeo3_getBridgeNeo3NeoXDataByNotifications;
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
35
  exports.DoraBDSNeo3 = exports.DoraNeoRest = void 0;
36
36
  const blockchain_service_1 = require("@cityofzion/blockchain-service");
37
37
  const dora_ts_1 = require("@cityofzion/dora-ts");
38
38
  const neon_js_1 = require("@cityofzion/neon-js");
39
+ const BSNeo3Constants_1 = require("../../constants/BSNeo3Constants");
39
40
  const BSNeo3Helper_1 = require("../../helpers/BSNeo3Helper");
40
41
  const RpcBDSNeo3_1 = require("./RpcBDSNeo3");
41
42
  exports.DoraNeoRest = new dora_ts_1.api.NeoRESTApi({
@@ -73,6 +74,7 @@ class DoraBDSNeo3 extends RpcBDSNeo3_1.RpcBDSNeo3 {
73
74
  fee: blockchain_service_1.BSBigNumberHelper.format(totalFee, { decimals: this._feeToken.decimals }),
74
75
  notifications: [],
75
76
  transfers: [],
77
+ type: 'default', // It's not possible to set the correct type because we don't have notifications here
76
78
  };
77
79
  }
78
80
  catch (_c) {
@@ -90,9 +92,10 @@ class DoraBDSNeo3 extends RpcBDSNeo3_1.RpcBDSNeo3 {
90
92
  }
91
93
  const data = yield exports.DoraNeoRest.addressTXFull(address, nextPageParams, this._network.id);
92
94
  const promises = data.items.map((item) => __awaiter(this, void 0, void 0, function* () {
93
- var _a, _b;
95
+ var _a, _b, _c;
94
96
  const transferPromises = [];
95
- item.notifications.forEach(({ contract: contractHash, state, event_name: eventName }) => {
97
+ const notifications = (_a = item.notifications) !== null && _a !== void 0 ? _a : [];
98
+ notifications.forEach(({ contract: contractHash, state, event_name: eventName }) => {
96
99
  var _a;
97
100
  const properties = Array.isArray(state) ? state : (_a = state === null || state === void 0 ? void 0 : state.value) !== null && _a !== void 0 ? _a : [];
98
101
  if (eventName !== 'Transfer' || (properties.length !== 3 && properties.length !== 4))
@@ -127,21 +130,25 @@ class DoraBDSNeo3 extends RpcBDSNeo3_1.RpcBDSNeo3 {
127
130
  transferPromises.push(promise());
128
131
  });
129
132
  const transfers = yield Promise.all(transferPromises);
130
- const notifications = item.notifications.map(notification => ({
131
- eventName: notification.event_name,
132
- state: notification.state,
133
- }));
134
- const systemFeeNumber = blockchain_service_1.BSBigNumberHelper.fromNumber((_a = item.sysfee) !== null && _a !== void 0 ? _a : 0);
135
- const networkFeeNumber = blockchain_service_1.BSBigNumberHelper.fromNumber((_b = item.netfee) !== null && _b !== void 0 ? _b : 0);
133
+ const systemFeeNumber = blockchain_service_1.BSBigNumberHelper.fromNumber((_b = item.sysfee) !== null && _b !== void 0 ? _b : 0);
134
+ const networkFeeNumber = blockchain_service_1.BSBigNumberHelper.fromNumber((_c = item.netfee) !== null && _c !== void 0 ? _c : 0);
136
135
  const totalFee = systemFeeNumber.plus(networkFeeNumber);
137
- return {
136
+ let transaction = {
138
137
  block: item.block,
139
138
  time: Number(item.time),
140
139
  hash: item.hash,
141
140
  fee: blockchain_service_1.BSBigNumberHelper.format(totalFee, { decimals: this._feeToken.decimals }),
142
141
  transfers,
143
- notifications,
142
+ notifications: notifications.map(notification => ({
143
+ eventName: notification.event_name,
144
+ state: notification.state,
145
+ })),
146
+ type: 'default',
144
147
  };
148
+ const bridgeNeo3NeoXData = __classPrivateFieldGet(this, _DoraBDSNeo3_instances, "m", _DoraBDSNeo3_getBridgeNeo3NeoXDataByNotifications).call(this, notifications);
149
+ if (bridgeNeo3NeoXData)
150
+ transaction = Object.assign(Object.assign({}, transaction), { type: 'bridgeNeo3NeoX', data: bridgeNeo3NeoXData });
151
+ return transaction;
145
152
  }));
146
153
  const transactions = yield Promise.all(promises);
147
154
  const limit = 15;
@@ -171,10 +178,10 @@ class DoraBDSNeo3 extends RpcBDSNeo3_1.RpcBDSNeo3 {
171
178
  const txTemplateUrl = __classPrivateFieldGet(this, _DoraBDSNeo3_explorerService, "f").getTxTemplateUrl();
172
179
  const nftTemplateUrl = __classPrivateFieldGet(this, _DoraBDSNeo3_explorerService, "f").getNftTemplateUrl();
173
180
  const contractTemplateUrl = __classPrivateFieldGet(this, _DoraBDSNeo3_explorerService, "f").getContractTemplateUrl();
174
- const itemPromises = items.map((_d) => __awaiter(this, void 0, void 0, function* () {
181
+ const itemPromises = items.map((_d, index) => __awaiter(this, void 0, void 0, function* () {
175
182
  var { networkFeeAmount, systemFeeAmount } = _d, item = __rest(_d, ["networkFeeAmount", "systemFeeAmount"]);
176
183
  const txId = item.transactionID;
177
- const newItem = {
184
+ let newItem = {
178
185
  txId,
179
186
  txIdUrl: txId ? txTemplateUrl === null || txTemplateUrl === void 0 ? void 0 : txTemplateUrl.replace('{txId}', txId) : undefined,
180
187
  block: item.block,
@@ -188,12 +195,13 @@ class DoraBDSNeo3 extends RpcBDSNeo3_1.RpcBDSNeo3 {
188
195
  ? blockchain_service_1.BSBigNumberHelper.format(systemFeeAmount, { decimals: this._feeToken.decimals })
189
196
  : undefined,
190
197
  events: [],
198
+ type: 'default',
191
199
  };
192
- const eventPromises = item.events.map((event) => __awaiter(this, void 0, void 0, function* () {
200
+ const eventPromises = item.events.map((event, eventIndex) => __awaiter(this, void 0, void 0, function* () {
193
201
  var _e, _f, _g, _h, _j, _k;
194
202
  let nftEvent;
195
203
  let assetEvent;
196
- const { methodName, tokenID: tokenId, contractHash: hash } = event;
204
+ const { methodName, tokenID: tokenId, contractHash: hash, contractName } = event;
197
205
  const from = (_e = event.from) !== null && _e !== void 0 ? _e : undefined;
198
206
  const to = (_f = event.to) !== null && _f !== void 0 ? _f : undefined;
199
207
  const fromUrl = from ? addressTemplateUrl === null || addressTemplateUrl === void 0 ? void 0 : addressTemplateUrl.replace('{address}', from) : undefined;
@@ -240,10 +248,18 @@ class DoraBDSNeo3 extends RpcBDSNeo3_1.RpcBDSNeo3 {
240
248
  tokenType: 'nep-17',
241
249
  };
242
250
  }
243
- newItem.events.push(isNft ? nftEvent : assetEvent);
251
+ if (newItem.type === 'default' && contractName === 'NeoXBridge') {
252
+ const [log] = yield blockchain_service_1.BSPromisesHelper.tryCatch(() => exports.DoraNeoRest.log(txId, this._network.id));
253
+ if (!!log && log.vmstate === 'HALT') {
254
+ const data = __classPrivateFieldGet(this, _DoraBDSNeo3_instances, "m", _DoraBDSNeo3_getBridgeNeo3NeoXDataByNotifications).call(this, log.notifications || []);
255
+ if (data)
256
+ newItem = Object.assign(Object.assign({}, newItem), { type: 'bridgeNeo3NeoX', data });
257
+ }
258
+ }
259
+ newItem.events.splice(eventIndex, 0, isNft ? nftEvent : assetEvent);
244
260
  }));
245
261
  yield Promise.allSettled(eventPromises);
246
- data.push(newItem);
262
+ data.splice(index, 0, newItem);
247
263
  }));
248
264
  yield Promise.allSettled(itemPromises);
249
265
  return { nextCursor: response.nextCursor, data };
@@ -357,4 +373,28 @@ _DoraBDSNeo3_supportedNep11Standards = new WeakMap(), _DoraBDSNeo3_nftDataServic
357
373
  if (typeof pageSize === 'number' && (isNaN(pageSize) || pageSize < 1 || pageSize > 500))
358
374
  throw new Error('Page size should be between 1 and 500');
359
375
  __classPrivateFieldGet(this, _DoraBDSNeo3_instances, "m", _DoraBDSNeo3_validateFullTransactionsByAddressParams).call(this, params);
376
+ }, _DoraBDSNeo3_getBridgeNeo3NeoXDataByNotifications = function _DoraBDSNeo3_getBridgeNeo3NeoXDataByNotifications(notifications) {
377
+ var _a, _b, _c;
378
+ const gasNotification = notifications.find(({ event_name }) => event_name === 'NativeDeposit');
379
+ const isNativeToken = !!gasNotification;
380
+ const neoNotification = !isNativeToken
381
+ ? notifications.find(({ event_name }) => event_name === 'TokenDeposit')
382
+ : undefined;
383
+ const notification = isNativeToken ? gasNotification : neoNotification;
384
+ const notificationStateValue = (_a = notification === null || notification === void 0 ? void 0 : notification.state) === null || _a === void 0 ? void 0 : _a.value;
385
+ if (!notificationStateValue)
386
+ return undefined;
387
+ const decimals = isNativeToken ? BSNeo3Constants_1.BSNeo3Constants.GAS_TOKEN.decimals : BSNeo3Constants_1.BSNeo3Constants.NEO_TOKEN.decimals;
388
+ const amountIndex = isNativeToken ? 2 : 4;
389
+ const amountWithDecimals = ((_b = notificationStateValue === null || notificationStateValue === void 0 ? void 0 : notificationStateValue[amountIndex]) === null || _b === void 0 ? void 0 : _b.value) || 0;
390
+ const amount = blockchain_service_1.BSBigNumberHelper.format(neon_js_1.u.BigInteger.fromNumber(amountWithDecimals).toDecimal(decimals), {
391
+ decimals,
392
+ });
393
+ const receiverAddressIndex = isNativeToken ? 1 : 3;
394
+ const byteStringReceiverAddress = ((_c = notificationStateValue === null || notificationStateValue === void 0 ? void 0 : notificationStateValue[receiverAddressIndex]) === null || _c === void 0 ? void 0 : _c.value) || '';
395
+ if (!byteStringReceiverAddress)
396
+ return undefined;
397
+ const receiverAddress = `0x${neon_js_1.u.HexString.fromBase64(byteStringReceiverAddress).toLittleEndian()}`;
398
+ const token = isNativeToken ? BSNeo3Constants_1.BSNeo3Constants.GAS_TOKEN : BSNeo3Constants_1.BSNeo3Constants.NEO_TOKEN;
399
+ return { amount, token, receiverAddress };
360
400
  };
@@ -39,6 +39,7 @@ class RpcBDSNeo3 {
39
39
  notifications: [],
40
40
  transfers: [],
41
41
  time: response.blocktime,
42
+ type: 'default', // It's not possible to set the correct type because we don't have notifications here
42
43
  };
43
44
  }
44
45
  catch (_c) {
@@ -3,11 +3,11 @@ import { BSNeo3 } from '../../BSNeo3';
3
3
  export declare class Neo3NeoXBridgeService<BSName extends string = string> implements INeo3NeoXBridgeService<BSName> {
4
4
  #private;
5
5
  readonly BRIDGE_SCRIPT_HASH = "0xbb19cfc864b73159277e1fd39694b3fd5fc613d2";
6
- tokens: TBridgeToken[];
6
+ tokens: TBridgeToken<BSName>[];
7
7
  constructor(service: BSNeo3<BSName>);
8
8
  getApprovalFee(): Promise<string>;
9
- getBridgeConstants(token: TBridgeToken): Promise<TNeo3NeoXBridgeServiceConstants>;
9
+ getBridgeConstants(token: TBridgeToken<BSName>): Promise<TNeo3NeoXBridgeServiceConstants>;
10
10
  bridge(params: TNeo3NeoXBridgeServiceBridgeParam<BSName>): Promise<string>;
11
- getNonce(params: TNeo3NeoXBridgeServiceGetNonceParams): Promise<string | null>;
12
- getTransactionHashByNonce(params: TNeo3NeoXBridgeServiceGetTransactionHashByNonceParams): Promise<string | null>;
11
+ getNonce(params: TNeo3NeoXBridgeServiceGetNonceParams<BSName>): Promise<string>;
12
+ getTransactionHashByNonce(params: TNeo3NeoXBridgeServiceGetTransactionHashByNonceParams<BSName>): Promise<string>;
13
13
  }
@@ -37,8 +37,8 @@ class Neo3NeoXBridgeService {
37
37
  _Neo3NeoXBridgeService_service.set(this, void 0);
38
38
  __classPrivateFieldSet(this, _Neo3NeoXBridgeService_service, service, "f");
39
39
  this.tokens = [
40
- Object.assign(Object.assign({}, BSNeo3Constants_1.BSNeo3Constants.GAS_TOKEN), { multichainId: 'gas' }),
41
- Object.assign(Object.assign({}, BSNeo3Constants_1.BSNeo3Constants.NEO_TOKEN), { multichainId: 'neo' }),
40
+ Object.assign(Object.assign({}, BSNeo3Constants_1.BSNeo3Constants.GAS_TOKEN), { multichainId: 'gas', blockchain: service.name }),
41
+ Object.assign(Object.assign({}, BSNeo3Constants_1.BSNeo3Constants.NEO_TOKEN), { multichainId: 'neo', blockchain: service.name }),
42
42
  ];
43
43
  }
44
44
  getApprovalFee() {
@@ -147,37 +147,62 @@ class Neo3NeoXBridgeService {
147
147
  getNonce(params) {
148
148
  var _a, _b;
149
149
  return __awaiter(this, void 0, void 0, function* () {
150
- const log = yield DoraBDSNeo3_1.DoraNeoRest.log(params.transactionHash, __classPrivateFieldGet(this, _Neo3NeoXBridgeService_service, "f").network.id);
151
- if (log.vmstate !== 'HALT') {
152
- return null;
150
+ let log;
151
+ try {
152
+ log = yield DoraBDSNeo3_1.DoraNeoRest.log(params.transactionHash, __classPrivateFieldGet(this, _Neo3NeoXBridgeService_service, "f").network.id);
153
+ }
154
+ catch (error) {
155
+ throw new blockchain_service_1.BSError('Failed to get nonce from transaction log', 'FAILED_TO_GET_NONCE', error);
156
+ }
157
+ if ((log === null || log === void 0 ? void 0 : log.vmstate) !== 'HALT') {
158
+ throw new blockchain_service_1.BSError('Transaction invalid', 'INVALID_TRANSACTION');
153
159
  }
154
160
  const isNativeToken = blockchain_service_1.BSTokenHelper.predicateByHash(params.token)(BSNeo3Constants_1.BSNeo3Constants.GAS_TOKEN);
161
+ let nonce = null;
155
162
  if (isNativeToken) {
156
163
  const notification = log.notifications.find(item => item.event_name === 'NativeDeposit');
157
- return (_a = notification === null || notification === void 0 ? void 0 : notification.state.value[0].value) !== null && _a !== void 0 ? _a : null;
164
+ nonce = (_a = notification === null || notification === void 0 ? void 0 : notification.state.value[0].value) !== null && _a !== void 0 ? _a : null;
165
+ }
166
+ else {
167
+ const notification = log.notifications.find(item => item.event_name === 'TokenDeposit');
168
+ nonce = (_b = notification === null || notification === void 0 ? void 0 : notification.state.value[2].value) !== null && _b !== void 0 ? _b : null;
169
+ }
170
+ if (!nonce) {
171
+ throw new blockchain_service_1.BSError('Nonce not found in transaction log', 'NONCE_NOT_FOUND');
158
172
  }
159
- const notification = log.notifications.find(item => item.event_name === 'TokenDeposit');
160
- return (_b = notification === null || notification === void 0 ? void 0 : notification.state.value[2].value) !== null && _b !== void 0 ? _b : null;
173
+ return nonce;
161
174
  });
162
175
  }
163
176
  getTransactionHashByNonce(params) {
164
- var _a;
165
177
  return __awaiter(this, void 0, void 0, function* () {
166
- const isNativeToken = blockchain_service_1.BSTokenHelper.predicateByHash(params.token)(BSNeo3Constants_1.BSNeo3Constants.GAS_TOKEN);
167
- const { data } = yield axios_1.default.post('https://neofura.ngd.network', {
168
- jsonrpc: '2.0',
169
- method: 'GetBridgeTxByNonce',
170
- params: {
171
- ContractHash: this.BRIDGE_SCRIPT_HASH,
172
- TokenHash: isNativeToken ? '' : BSNeo3Constants_1.BSNeo3Constants.NEO_TOKEN.hash,
173
- Nonce: Number(params.nonce),
174
- },
175
- id: 1,
176
- });
178
+ let data;
179
+ try {
180
+ const isNativeToken = blockchain_service_1.BSTokenHelper.predicateByHash(params.token)(BSNeo3Constants_1.BSNeo3Constants.GAS_TOKEN);
181
+ const response = yield axios_1.default.post('https://neofura.ngd.network', {
182
+ jsonrpc: '2.0',
183
+ method: 'GetBridgeTxByNonce',
184
+ params: {
185
+ ContractHash: this.BRIDGE_SCRIPT_HASH,
186
+ TokenHash: isNativeToken ? '' : BSNeo3Constants_1.BSNeo3Constants.NEO_TOKEN.hash,
187
+ Nonce: Number(params.nonce),
188
+ },
189
+ id: 1,
190
+ });
191
+ data = response.data;
192
+ }
193
+ catch (error) {
194
+ throw new blockchain_service_1.BSError('Failed to get transaction by nonce', 'FAILED_TO_GET_TRANSACTION_BY_NONCE', error);
195
+ }
177
196
  if (!(data === null || data === void 0 ? void 0 : data.result)) {
178
- throw new blockchain_service_1.BSError('Transaction not found', 'INVALID_RESPONSE');
197
+ throw new blockchain_service_1.BSError('Failed to get transaction by nonce', 'FAILED_TO_GET_TRANSACTION_BY_NONCE');
198
+ }
199
+ if (data.result.Vmstate !== 'HALT') {
200
+ throw new blockchain_service_1.BSError('Transaction invalid', 'INVALID_TRANSACTION');
201
+ }
202
+ if (!data.result.txid) {
203
+ throw new blockchain_service_1.BSError('Transaction ID not found in response', 'TXID_NOT_FOUND');
179
204
  }
180
- return data.result.Vmstate === 'HALT' ? (_a = data.result.txid) !== null && _a !== void 0 ? _a : null : null;
205
+ return data.result.txid;
181
206
  });
182
207
  }
183
208
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cityofzion/bs-neo3",
3
- "version": "1.15.3",
3
+ "version": "1.16.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "repository": "https://github.com/CityOfZion/blockchain-services",
@@ -21,7 +21,7 @@
21
21
  "isomorphic-ws": "^5.0.0",
22
22
  "lodash.clonedeep": "^4.5.0",
23
23
  "date-fns": "~4.1.0",
24
- "@cityofzion/blockchain-service": "1.19.2",
24
+ "@cityofzion/blockchain-service": "1.20.0",
25
25
  "@cityofzion/bs-asteroid-sdk": "0.9.1"
26
26
  },
27
27
  "devDependencies": {
@@ -35,7 +35,7 @@
35
35
  "eslint": "^8.48.0",
36
36
  "jest": "29.6.2",
37
37
  "ts-jest": "29.1.1",
38
- "ts-node": "10.9.1",
38
+ "ts-node": "~10.9.2",
39
39
  "typescript": "4.9.5",
40
40
  "typed-emitter": "^2.1.0"
41
41
  },