@cityofzion/bs-neox 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -16,13 +16,13 @@ BSNeoXConstants.TESTNET_NETWORK_IDS = ['12227332'];
|
|
|
16
16
|
BSNeoXConstants.ALL_NETWORK_IDS = [..._a.MAINNET_NETWORK_IDS, ..._a.TESTNET_NETWORK_IDS];
|
|
17
17
|
BSNeoXConstants.MAINNET_NETWORK = {
|
|
18
18
|
id: '47763',
|
|
19
|
-
name: 'NeoX
|
|
19
|
+
name: 'NeoX Mainnet',
|
|
20
20
|
url: _a.RPC_LIST_BY_NETWORK_ID['47763'][0],
|
|
21
21
|
};
|
|
22
22
|
BSNeoXConstants.TESTNET_NETWORK = {
|
|
23
23
|
id: '12227332',
|
|
24
|
-
name: 'NeoX
|
|
24
|
+
name: 'NeoX Testnet',
|
|
25
25
|
url: _a.RPC_LIST_BY_NETWORK_ID['12227332'][0],
|
|
26
26
|
};
|
|
27
|
-
BSNeoXConstants.ALL_NETWORK = [_a.
|
|
27
|
+
BSNeoXConstants.ALL_NETWORK = [_a.MAINNET_NETWORK, _a.TESTNET_NETWORK];
|
|
28
28
|
BSNeoXConstants.DEFAULT_NETWORK = _a.MAINNET_NETWORK;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cityofzion/bs-neox",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
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/
|
|
20
|
-
"@cityofzion/
|
|
19
|
+
"@cityofzion/blockchain-service": "1.18.0",
|
|
20
|
+
"@cityofzion/bs-ethereum": "2.12.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@ledgerhq/hw-transport-node-hid": "~6.28.5",
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { Account, BalanceResponse, Token } from '@cityofzion/blockchain-service';
|
|
2
|
-
import { BSNeoX } from '../../BSNeoX';
|
|
3
|
-
export type TValidateBridgeToNeo3Param<BSName extends string> = {
|
|
4
|
-
account: Account<BSName>;
|
|
5
|
-
neo3Address: string;
|
|
6
|
-
amount: string;
|
|
7
|
-
token: Token;
|
|
8
|
-
balances: BalanceResponse[];
|
|
9
|
-
};
|
|
10
|
-
export type TValidateBridgeToNeo3 = {
|
|
11
|
-
amount: string;
|
|
12
|
-
receiveAmount: string;
|
|
13
|
-
token: Token;
|
|
14
|
-
isGasToken?: boolean;
|
|
15
|
-
isNeoToken?: boolean;
|
|
16
|
-
};
|
|
17
|
-
export type TBridgeToNeo3Param<BSName extends string> = {
|
|
18
|
-
account: Account<BSName>;
|
|
19
|
-
neo3Address: string;
|
|
20
|
-
validateResult: TValidateBridgeToNeo3;
|
|
21
|
-
};
|
|
22
|
-
export type TCalculateMaxAmountToBridgeToNeo3Param<BSName extends string> = {
|
|
23
|
-
account: Account<BSName>;
|
|
24
|
-
neo3Address: string;
|
|
25
|
-
token: Token;
|
|
26
|
-
balances: BalanceResponse[];
|
|
27
|
-
};
|
|
28
|
-
export declare class BridgeNeoXService<BSName extends string> {
|
|
29
|
-
#private;
|
|
30
|
-
constructor(service: BSNeoX<BSName>);
|
|
31
|
-
calculateBridgeToNeo3Fee(params: TBridgeToNeo3Param<BSName>): Promise<string>;
|
|
32
|
-
validateBridgeToNeo3({ amount, balances, token, account, neo3Address, }: TValidateBridgeToNeo3Param<BSName>): Promise<TValidateBridgeToNeo3>;
|
|
33
|
-
calculateMaxAmountToBridgeToNeoX({ account, balances, neo3Address, token, }: TCalculateMaxAmountToBridgeToNeo3Param<BSName>): Promise<any>;
|
|
34
|
-
}
|
|
@@ -1,177 +0,0 @@
|
|
|
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 __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
|
-
};
|
|
22
|
-
var _BridgeNeoXService_instances, _BridgeNeoXService_service, _BridgeNeoXService_buildBridgeParams;
|
|
23
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.BridgeNeoXService = void 0;
|
|
25
|
-
const blockchain_service_1 = require("@cityofzion/blockchain-service");
|
|
26
|
-
const BSNeoXConstants_1 = require("../../constants/BSNeoXConstants");
|
|
27
|
-
const ethers_1 = require("ethers");
|
|
28
|
-
const neon_js_1 = require("@cityofzion/neon-js");
|
|
29
|
-
const bridge_1 = require("../../assets/abis/bridge");
|
|
30
|
-
const bs_ethereum_1 = require("@cityofzion/bs-ethereum");
|
|
31
|
-
class BridgeNeoXService {
|
|
32
|
-
constructor(service) {
|
|
33
|
-
_BridgeNeoXService_instances.add(this);
|
|
34
|
-
_BridgeNeoXService_service.set(this, void 0);
|
|
35
|
-
__classPrivateFieldSet(this, _BridgeNeoXService_service, service, "f");
|
|
36
|
-
}
|
|
37
|
-
calculateBridgeToNeo3Fee(params) {
|
|
38
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
-
try {
|
|
40
|
-
const signer = yield __classPrivateFieldGet(this, _BridgeNeoXService_service, "f").generateSigner(params.account);
|
|
41
|
-
const { gasPrice, approveTransactionParams, bridgeTransactionParam } = yield __classPrivateFieldGet(this, _BridgeNeoXService_instances, "m", _BridgeNeoXService_buildBridgeParams).call(this, params);
|
|
42
|
-
let fee = ethers_1.ethers.utils.parseEther('0');
|
|
43
|
-
if (params.validateResult.isGasToken) {
|
|
44
|
-
const estimated = yield signer.estimateGas(bridgeTransactionParam);
|
|
45
|
-
fee = gasPrice.mul(estimated);
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
let approvedEstimated = ethers_1.ethers.utils.parseEther('0');
|
|
49
|
-
if (approveTransactionParams) {
|
|
50
|
-
approvedEstimated = yield signer.estimateGas(approveTransactionParams);
|
|
51
|
-
}
|
|
52
|
-
// We can't estimate the gas for the bridge transaction because it requires the approve transaction to be done first
|
|
53
|
-
// if not the gas estimation of bridge transaction will fail so we add a fixed value
|
|
54
|
-
const neoBridgeFee = ethers_1.ethers.utils.parseUnits(BSNeoXConstants_1.BSNeoXConstants.BRIDGE_NEO_BRIDGE_TRANSACTION_FEE.toString(), BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET.decimals);
|
|
55
|
-
fee = gasPrice.mul(approvedEstimated).add(neoBridgeFee);
|
|
56
|
-
}
|
|
57
|
-
return ethers_1.ethers.utils.formatEther(fee);
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
throw new blockchain_service_1.BSError(error.message, 'FEE_CALCULATION_ERROR');
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
validateBridgeToNeo3({ amount, balances, token, account, neo3Address, }) {
|
|
65
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
-
const normalizedSelectedToken = blockchain_service_1.BSTokenHelper.normalizeToken(token);
|
|
67
|
-
const isGasToken = normalizedSelectedToken.hash === BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET.hash;
|
|
68
|
-
const isNeoToken = normalizedSelectedToken.hash === BSNeoXConstants_1.BSNeoXConstants.NEO_TOKEN.hash;
|
|
69
|
-
if (!isGasToken && !isNeoToken) {
|
|
70
|
-
throw new blockchain_service_1.BSError('Only GAS and NEO tokens are supported for bridging', 'UNSUPPORTED_TOKEN');
|
|
71
|
-
}
|
|
72
|
-
const gasBalance = balances.find(balance => blockchain_service_1.BSTokenHelper.normalizeHash(balance.token.hash) === BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET.hash);
|
|
73
|
-
if (!gasBalance) {
|
|
74
|
-
throw new blockchain_service_1.BSError('GAS is necessary to bridge', 'GAS_BALANCE_NOT_FOUND');
|
|
75
|
-
}
|
|
76
|
-
const amountNumber = blockchain_service_1.BSBigNumberHelper.fromNumber(amount);
|
|
77
|
-
const gasBalanceNumber = blockchain_service_1.BSBigNumberHelper.fromNumber(gasBalance.amount);
|
|
78
|
-
if (isGasToken) {
|
|
79
|
-
const receiveAmount = amountNumber.minus(BSNeoXConstants_1.BSNeoXConstants.BRIDGE_GAS_FEE).toString();
|
|
80
|
-
if (amountNumber.isLessThan(BSNeoXConstants_1.BSNeoXConstants.BRIDGE_MIN_AMOUNT + BSNeoXConstants_1.BSNeoXConstants.BRIDGE_GAS_FEE)) {
|
|
81
|
-
throw new blockchain_service_1.BSError('Amount is less than the minimum amount plus bridge fee', 'AMOUNT_TOO_LOW');
|
|
82
|
-
}
|
|
83
|
-
if (amountNumber.isGreaterThan(gasBalanceNumber)) {
|
|
84
|
-
throw new blockchain_service_1.BSError('Amount is greater than your balance', 'INSUFFICIENT_GAS_BALANCE');
|
|
85
|
-
}
|
|
86
|
-
const validateResult = { receiveAmount, token, isGasToken, isNeoToken, amount };
|
|
87
|
-
const fee = yield this.calculateBridgeToNeo3Fee({
|
|
88
|
-
account,
|
|
89
|
-
neo3Address,
|
|
90
|
-
validateResult,
|
|
91
|
-
});
|
|
92
|
-
if (amountNumber.plus(fee).isGreaterThan(gasBalanceNumber)) {
|
|
93
|
-
throw new blockchain_service_1.BSError('Amount is greater than your balance plus fee', 'INSUFFICIENT_GAS_BALANCE_FEE');
|
|
94
|
-
}
|
|
95
|
-
return validateResult;
|
|
96
|
-
}
|
|
97
|
-
const neoBalance = balances.find(balance => blockchain_service_1.BSTokenHelper.normalizeHash(balance.token.hash) === BSNeoXConstants_1.BSNeoXConstants.NEO_TOKEN.hash);
|
|
98
|
-
if (!neoBalance) {
|
|
99
|
-
throw new blockchain_service_1.BSError('NEO balance not found', 'NEO_BALANCE_NOT_FOUND');
|
|
100
|
-
}
|
|
101
|
-
if (amountNumber.isLessThan(BSNeoXConstants_1.BSNeoXConstants.BRIDGE_MIN_AMOUNT)) {
|
|
102
|
-
throw new blockchain_service_1.BSError('Amount is less than the minimum amount', 'AMOUNT_TOO_LOW');
|
|
103
|
-
}
|
|
104
|
-
if (amountNumber.isGreaterThan(neoBalance.amount)) {
|
|
105
|
-
throw new blockchain_service_1.BSError('Amount is greater than your balance', 'INSUFFICIENT_NEO_BALANCE');
|
|
106
|
-
}
|
|
107
|
-
const minGasBalanceNumber = blockchain_service_1.BSBigNumberHelper.fromNumber(BSNeoXConstants_1.BSNeoXConstants.BRIDGE_GAS_FEE);
|
|
108
|
-
if (gasBalanceNumber.isLessThan(minGasBalanceNumber)) {
|
|
109
|
-
throw new blockchain_service_1.BSError('GAS balance is less than bridge fee', 'INSUFFICIENT_GAS_BALANCE_BRIDGE_FEE');
|
|
110
|
-
}
|
|
111
|
-
const receiveAmount = amount;
|
|
112
|
-
const validateResult = { receiveAmount, token, isNeoToken, amount };
|
|
113
|
-
const fee = yield this.calculateBridgeToNeo3Fee({
|
|
114
|
-
account,
|
|
115
|
-
neo3Address,
|
|
116
|
-
validateResult,
|
|
117
|
-
});
|
|
118
|
-
if (minGasBalanceNumber.plus(blockchain_service_1.BSBigNumberHelper.fromNumber(fee)).isGreaterThan(gasBalanceNumber)) {
|
|
119
|
-
throw new blockchain_service_1.BSError('GAS balance is less than fees', 'INSUFFICIENT_GAS_BALANCE_FEES');
|
|
120
|
-
}
|
|
121
|
-
return validateResult;
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
calculateMaxAmountToBridgeToNeoX({ account, balances, neo3Address, token, }) {
|
|
125
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
126
|
-
const normalizedSelectedToken = blockchain_service_1.BSTokenHelper.normalizeToken(token);
|
|
127
|
-
const selectedTokenBalance = balances.find(balance => blockchain_service_1.BSTokenHelper.normalizeHash(balance.token.hash) === normalizedSelectedToken.hash);
|
|
128
|
-
if (!selectedTokenBalance) {
|
|
129
|
-
throw new blockchain_service_1.BSError('Token balance not found', 'TOKEN_BALANCE_NOT_FOUND');
|
|
130
|
-
}
|
|
131
|
-
const selectedTokenBalanceNumber = blockchain_service_1.BSBigNumberHelper.fromNumber(selectedTokenBalance.amount);
|
|
132
|
-
const amount = blockchain_service_1.BSBigNumberHelper.fromNumber(BSNeoXConstants_1.BSNeoXConstants.BRIDGE_MIN_AMOUNT).toString();
|
|
133
|
-
const receiveAmount = selectedTokenBalanceNumber.minus(amount).toString();
|
|
134
|
-
const isGasToken = normalizedSelectedToken.hash === BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET.hash;
|
|
135
|
-
const isNeoToken = normalizedSelectedToken.hash === BSNeoXConstants_1.BSNeoXConstants.NEO_TOKEN.hash;
|
|
136
|
-
const fee = yield this.calculateBridgeToNeo3Fee({
|
|
137
|
-
account,
|
|
138
|
-
neo3Address,
|
|
139
|
-
validateResult: { receiveAmount, token, isGasToken, isNeoToken, amount },
|
|
140
|
-
});
|
|
141
|
-
const maxAmount = selectedTokenBalanceNumber.minus(blockchain_service_1.BSBigNumberHelper.fromNumber(fee)).toString();
|
|
142
|
-
return maxAmount;
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
exports.BridgeNeoXService = BridgeNeoXService;
|
|
147
|
-
_BridgeNeoXService_service = new WeakMap(), _BridgeNeoXService_instances = new WeakSet(), _BridgeNeoXService_buildBridgeParams = function _BridgeNeoXService_buildBridgeParams(params) {
|
|
148
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
-
const { validateResult } = params;
|
|
150
|
-
const provider = new ethers_1.ethers.providers.JsonRpcProvider(__classPrivateFieldGet(this, _BridgeNeoXService_service, "f").network.url);
|
|
151
|
-
const gasPrice = yield provider.getGasPrice();
|
|
152
|
-
let bridgeTransactionParam;
|
|
153
|
-
let approveTransactionParams;
|
|
154
|
-
const to = '0x' + neon_js_1.wallet.getScriptHashFromAddress(params.neo3Address);
|
|
155
|
-
const bridgeContract = new ethers_1.ethers.Contract(BSNeoXConstants_1.BSNeoXConstants.BRIDGE_SCRIPT_HASH, bridge_1.BRIDGE_ABI);
|
|
156
|
-
const bridgeFee = ethers_1.ethers.utils.parseUnits(BSNeoXConstants_1.BSNeoXConstants.BRIDGE_GAS_FEE.toString(), BSNeoXConstants_1.BSNeoXConstants.NATIVE_ASSET.decimals);
|
|
157
|
-
if (validateResult.isGasToken) {
|
|
158
|
-
const populatedTransaction = yield bridgeContract.populateTransaction.withdrawNative(to, bridgeFee);
|
|
159
|
-
bridgeTransactionParam = Object.assign(Object.assign({}, populatedTransaction), { value: ethers_1.ethers.utils.parseUnits(validateResult.amount, params.validateResult.token.decimals), type: 2 });
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
const amount = ethers_1.ethers.utils.parseUnits(blockchain_service_1.BSBigNumberHelper.format(params.validateResult.amount, 0), params.validateResult.token.decimals);
|
|
163
|
-
const erc20Contract = new ethers_1.ethers.Contract(BSNeoXConstants_1.BSNeoXConstants.NEO_TOKEN.hash, bs_ethereum_1.ERC20_ABI);
|
|
164
|
-
const populatedApproveTransaction = yield erc20Contract.populateTransaction.approve(BSNeoXConstants_1.BSNeoXConstants.BRIDGE_SCRIPT_HASH, amount);
|
|
165
|
-
approveTransactionParams = Object.assign(Object.assign({}, populatedApproveTransaction), { type: 2 });
|
|
166
|
-
const populatedTransaction = yield bridgeContract.populateTransaction.withdrawToken(validateResult.token.hash, to,
|
|
167
|
-
// We are using 0 as the decimals because the NEO token in Neo3 has 0 decimals
|
|
168
|
-
amount);
|
|
169
|
-
bridgeTransactionParam = Object.assign(Object.assign({}, populatedTransaction), { type: 2, value: bridgeFee });
|
|
170
|
-
}
|
|
171
|
-
return {
|
|
172
|
-
bridgeTransactionParam,
|
|
173
|
-
approveTransactionParams,
|
|
174
|
-
gasPrice,
|
|
175
|
-
};
|
|
176
|
-
});
|
|
177
|
-
};
|