Skip to content

Commit a094c46

Browse files
authored
Merge pull request #41 from nash-io/ts/movement-updates
Ts/movement updates
2 parents 5b1feb0 + a6423ca commit a094c46

File tree

4 files changed

+74
-50
lines changed

4 files changed

+74
-50
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5+
<a name="5.2.5"></a>
6+
## [5.2.5](https://github.com/nash-io/api-client-typescript/compare/v5.2.3...v5.2.5) (2020-08-22)
7+
8+
9+
510
<a name="5.2.3"></a>
611
## [5.2.3](https://github.com/nash-io/api-client-typescript/compare/v5.2.1...v5.2.3) (2020-08-12)
712

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@neon-exchange/api-client-typescript",
3-
"version": "5.2.3",
3+
"version": "5.2.5",
44
"description": "Official TypeScript client for interacting with the Nash exchange",
55
"main": "build/main/index.js",
66
"typings": "build/main/index.d.ts",

src/client/client.ts

Lines changed: 67 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ import {
206206
createAddMovementParams,
207207
createCancelOrderParams,
208208
createGetAssetsNoncesParams,
209-
createGetMovementParams,
210209
createListMovementsParams,
211210
createPlaceLimitOrderParams,
212211
createPlaceMarketOrderParams,
@@ -284,6 +283,16 @@ export const MISSING_NONCES = 'missing_asset_nonces'
284283
export const MAX_ORDERS_REACHED = 'Maximal number of orders have been reached'
285284
/** @internal */
286285
export const MAX_SIGN_STATE_RECURSION = 5
286+
/** @internal */
287+
export const BIG_NUMBER_FORMAT = {
288+
decimalSeparator: '.',
289+
groupSeparator: '',
290+
groupSize: 50,
291+
prefix: ''
292+
}
293+
294+
export const UNLIMITED_APPROVAL =
295+
'0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe'
287296

288297
export class Client {
289298
private _socket = null
@@ -352,7 +361,7 @@ export class Client {
352361
*/
353362
constructor(opts: EnvironmentConfig, clientOpts: ClientOptions = {}) {
354363
this.opts = {
355-
maxEthCostPrTransaction: '0.01',
364+
maxEthCostPrTransaction: '0.05',
356365
...opts
357366
}
358367
this.clientOpts = {
@@ -362,6 +371,7 @@ export class Client {
362371
...clientOpts
363372
}
364373
this.isMainNet = this.opts.host === EnvironmentConfiguration.production.host
374+
365375
this.web3 = new Web3(this.opts.ethNetworkSettings.nodes[0])
366376

367377
if (!opts.host || (opts.host.indexOf('.') === -1 && !opts.isLocal)) {
@@ -1534,8 +1544,14 @@ export class Client {
15341544
* console.log(movement)
15351545
* ```
15361546
*/
1537-
public async getMovement(movementID: number): Promise<Movement> {
1538-
const getMovemementParams = createGetMovementParams(movementID)
1547+
public async getMovement(movementID: string): Promise<Movement> {
1548+
const getMovemementParams = {
1549+
payload: {
1550+
movement_id: movementID,
1551+
timestamp: createTimestamp()
1552+
},
1553+
kind: SigningPayloadID.getMovementPayload
1554+
}
15391555
const signedPayload = await this.signPayload(getMovemementParams)
15401556

15411557
const result = await this.gql.query<{ getMovement: Movement }>({
@@ -2408,7 +2424,7 @@ export class Client {
24082424
order.ordersTillSignState < ORDERS_REMAINING_TO_AUTOSYNC_AT &&
24092425
!this.signStateInProgress
24102426
) {
2411-
console.info('Will auto sign state: ', order.ordersTillSignState)
2427+
// console.info('Will auto sign state: ', order.ordersTillSignState)
24122428
await this.getSignAndSyncStates()
24132429
}
24142430
}
@@ -2514,9 +2530,7 @@ export class Client {
25142530
}
25152531

25162532
private validateTransactionCost(gasPrice: string, estimate: number) {
2517-
const maxCost = new BigNumber(gasPrice)
2518-
.multipliedBy(2)
2519-
.multipliedBy(estimate)
2533+
const maxCost = new BigNumber(gasPrice).multipliedBy(estimate)
25202534
if (this.maxEthCostPrTransaction.lt(maxCost)) {
25212535
throw new Error(
25222536
'Transaction ETH cost larger than maxEthCostPrTransaction (' +
@@ -2529,7 +2543,7 @@ export class Client {
25292543
private async approveERC20Transaction(
25302544
asset: AssetData,
25312545
childKey: ChildKey,
2532-
amount: BigNumber
2546+
_amount: BigNumber
25332547
): Promise<TransactionReceipt> {
25342548
for (let i = 0; i < 5; i++) {
25352549
try {
@@ -2538,17 +2552,10 @@ export class Client {
25382552
Erc20ABI,
25392553
'0x' + asset.hash
25402554
)
2541-
25422555
const approveAbi = erc20Contract.methods
25432556
.approve(
25442557
this.opts.ethNetworkSettings.contracts.vault.contract,
2545-
this.web3.utils.numberToHex(
2546-
transferExternalGetAmount(
2547-
new BigNumber(amount),
2548-
asset,
2549-
this.isMainNet
2550-
)
2551-
)
2558+
UNLIMITED_APPROVAL
25522559
)
25532560
.encodeABI()
25542561

@@ -2569,28 +2576,29 @@ export class Client {
25692576
const approveTx = new EthTransaction({
25702577
nonce, // + movement.data.assetNonce,
25712578
gasPrice: '0x' + parseInt(gasPrice, 10).toString(16),
2572-
gasLimit: '0x' + (estimate * 2).toString(16),
2579+
gasLimit: '0x' + estimate.toString(16),
25732580
to: '0x' + asset.hash,
25742581
value: 0,
25752582
data: approveAbi
25762583
})
25772584
approveTx.getChainId = () => chainId
2578-
25792585
const approveSignature = await this.signEthTransaction(approveTx)
25802586
setEthSignature(approveTx, approveSignature)
25812587
const p = await this.web3.eth.sendSignedTransaction(
25822588
'0x' + approveTx.serialize().toString('hex')
25832589
)
25842590
return p
25852591
} catch (e) {
2592+
console.info('Error approving tx: ', e.message)
25862593
if (
25872594
e.message === 'Returned error: replacement transaction underpriced'
25882595
) {
25892596
// console.log('approve failed, retrying approve in 15 seconds')
25902597
await sleep(15000)
25912598
continue
2599+
} else if (e.message.inde) {
2600+
throw e
25922601
}
2593-
throw e
25942602
}
25952603
}
25962604
throw new Error('Failed to approve erc20 token')
@@ -2604,21 +2612,24 @@ export class Client {
26042612
const bnAmount = new BigNumber(amount)
26052613
const currentAllowance = await this.queryAllowance(assetData)
26062614
if (currentAllowance.lt(bnAmount)) {
2615+
console.info('Will approve allowance')
26072616
await this.approveERC20Transaction(
26082617
assetData,
26092618
childKey,
26102619
bnAmount.minus(currentAllowance)
26112620
)
26122621

2613-
// We will wait for allowance for up to 5 minutes. After which I think we should time out.
2614-
for (let i = 0; i < 5 * 12 * 4; i++) {
2622+
// We will wait for allowance for up to 20 minutes. After which I think we should time out.
2623+
for (let i = 0; i < 20 * 12 * 4; i++) {
26152624
const latestAllowance = await this.queryAllowance(assetData)
26162625
if (latestAllowance.gte(bnAmount)) {
26172626
return
26182627
}
26192628
await sleep(5000)
26202629
}
26212630
throw new Error('Eth approval timed out')
2631+
} else {
2632+
console.info('Already has enough approved')
26222633
}
26232634
}
26242635

@@ -2631,6 +2642,10 @@ export class Client {
26312642
quantity: { currency, amount },
26322643
address
26332644
} = params
2645+
console.info(
2646+
`Will try sending to address ${address}: ${amount} of ${currency}`
2647+
)
2648+
26342649
if (this.assetData == null) {
26352650
throw new Error('Asset data null')
26362651
}
@@ -2643,7 +2658,7 @@ export class Client {
26432658
const addrBlockchain = detectBlockchain(address)
26442659
if (addrBlockchain === null) {
26452660
throw new Error(
2646-
`We can infer blockchain type from address ${address}. If you think this is an error please report it.`
2661+
`We can't infer blockchain type from address ${address}. If you think this is an error please report it.`
26472662
)
26482663
}
26492664
if (addrBlockchain !== blockchain) {
@@ -2671,20 +2686,18 @@ export class Client {
26712686
Erc20ABI,
26722687
`0x${assetData.hash}`
26732688
)
2689+
const externalAmount = transferExternalGetAmount(
2690+
new BigNumber(amount),
2691+
assetData,
2692+
this.isMainNet
2693+
)
26742694
data = erc20Contract.methods
26752695
.transfer(
26762696
prefixWith0xIfNeeded(address),
2677-
this.web3.utils.numberToHex(
2678-
transferExternalGetAmount(
2679-
new BigNumber(amount),
2680-
assetData,
2681-
this.isMainNet
2682-
)
2683-
)
2697+
this.web3.utils.numberToHex(externalAmount)
26842698
)
26852699
.encodeABI()
26862700
}
2687-
26882701
const gasPrice = await this.web3.eth.getGasPrice()
26892702
const estimate = await this.web3.eth.estimateGas({
26902703
from: prefixWith0xIfNeeded(this.apiKey.child_keys[BIP44.ETH].address),
@@ -2699,10 +2712,11 @@ export class Client {
26992712
})
27002713

27012714
this.validateTransactionCost(gasPrice, estimate)
2715+
27022716
const ethTx = new EthTransaction({
27032717
nonce: '0x' + ethAccountNonce.toString(16),
27042718
gasPrice: '0x' + parseInt(gasPrice, 10).toString(16),
2705-
gasLimit: '0x' + (estimate * 2).toString(16),
2719+
gasLimit: '0x' + estimate.toString(16),
27062720
to: prefixWith0xIfNeeded(
27072721
currency !== CryptoCurrency.ETH ? assetData.hash : address
27082722
),
@@ -2793,6 +2807,7 @@ export class Client {
27932807
height: 0
27942808
}
27952809
})
2810+
27962811
const btcGasPrice = await calculateFeeRate()
27972812
const fee = calculateBtcFees(externalTransferAmount, btcGasPrice, utxos)
27982813
const net = networkFromName(this.opts.btcNetworkSettings.name)
@@ -2809,7 +2824,6 @@ export class Client {
28092824
const transferAmount = Math.round(
28102825
new BigNumber(amount).times(BTC_SATOSHI_MULTIPLIER).toNumber()
28112826
)
2812-
28132827
const p2wpkh = bitcoin.payments.p2wpkh({
28142828
network: net,
28152829
pubkey: pubKey
@@ -2945,12 +2959,13 @@ export class Client {
29452959
}
29462960
btcTx.finalizeAllInputs()
29472961
const signedRawBtcTx = btcTx.extractTransaction().toHex()
2948-
await this.sendBlockchainRawTransaction({
2962+
const btcTxResult = await this.sendBlockchainRawTransaction({
29492963
payload: signedRawBtcTx,
29502964
blockchain: Blockchain.BTC
29512965
})
2966+
29522967
return {
2953-
txId: uutx.getId()
2968+
txId: btcTxResult
29542969
}
29552970
default:
29562971
throw new Error('Unsupported blockchain ' + assetData.blockchain)
@@ -3040,7 +3055,6 @@ export class Client {
30403055
signature: signature.signature
30413056
}
30423057
})
3043-
30443058
return data.data.prepareMovement
30453059
}
30463060

@@ -3085,10 +3099,8 @@ export class Client {
30853099
}
30863100

30873101
public async isMovementCompleted(movementId: string): Promise<boolean> {
3088-
return (
3089-
(await this.getMovement((movementId as never) as number)).status ===
3090-
MovementStatus.COMPLETED
3091-
)
3102+
const movement = await this.getMovement(movementId)
3103+
return movement.status === MovementStatus.COMPLETED
30923104
}
30933105

30943106
private async _transferToTradingContract(
@@ -3115,15 +3127,19 @@ export class Client {
31153127
let preparedMovement: PrepareMovementData['prepareMovement']
31163128
let movementAmount = bnAmount
31173129
const prepareAMovement = async () => {
3118-
preparedMovement = await this.prepareMovement({
3130+
const params = {
31193131
address,
31203132
quantity: {
3121-
amount: bnAmount.toFormat(8),
3133+
amount: bnAmount.toFormat(
3134+
8,
3135+
BigNumber.ROUND_FLOOR,
3136+
BIG_NUMBER_FORMAT
3137+
),
31223138
currency: assetData.symbol
31233139
},
31243140
type: movementType
3125-
})
3126-
3141+
}
3142+
preparedMovement = await this.prepareMovement(params)
31273143
movementAmount = bnAmount
31283144
if (
31293145
quantity.currency === CryptoCurrency.BTC &&
@@ -3135,7 +3151,6 @@ export class Client {
31353151
}
31363152

31373153
await prepareAMovement()
3138-
31393154
let signedAddMovementPayload: PayloadSignature
31403155
let addMovementResult: GQLResp<{
31413156
addMovement: AddMovement
@@ -3146,7 +3161,11 @@ export class Client {
31463161
address: childKey.address,
31473162
nonce: preparedMovement.nonce,
31483163
quantity: {
3149-
amount: movementAmount.toFormat(8),
3164+
amount: movementAmount.toFormat(
3165+
8,
3166+
BigNumber.ROUND_FLOOR,
3167+
BIG_NUMBER_FORMAT
3168+
),
31503169
currency: assetData.symbol
31513170
},
31523171
type: movementType,
@@ -3203,7 +3222,6 @@ export class Client {
32033222
}
32043223
}
32053224
}
3206-
32073225
if (quantity.currency === CryptoCurrency.BTC) {
32083226
return {
32093227
txId: addMovementResult.data.addMovement.id.toString(),
@@ -3326,7 +3344,7 @@ export class Client {
33263344
movementType === MovementTypeDeposit &&
33273345
quantity.currency !== CryptoCurrency.ETH
33283346
) {
3329-
// console.log('approving erc02')
3347+
console.log('approving erc20')
33303348
await this.approveAndAwaitAllowance(
33313349
assetData,
33323350
childKey,
@@ -3757,6 +3775,7 @@ export class Client {
37573775
params.payload
37583776
)
37593777
)
3778+
37603779
const resp = await this.gql.mutate<
37613780
SendBlockchainRawTransactionResult,
37623781
SendBlockchainRawTransactionArgs

yarn.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6932,7 +6932,7 @@ performance-now@^2.1.0:
69326932
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
69336933
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
69346934

6935-
phoenix@^1.5.4:
6935+
phoenix@1.5.4:
69366936
version "1.5.4"
69376937
resolved "https://registry.yarnpkg.com/phoenix/-/phoenix-1.5.4.tgz#d42bb537f03f55076b4e7a6757fe29318a8439f0"
69386938
integrity sha512-mTxseCKWDgrBQRIriqzvxL+QH5xruu6KQPqFdDx0jrdu/nqWCo914MLihVksn7SV2Bol3T+e/VtovJgC5UZT+w==

0 commit comments

Comments
 (0)