Skip to content

Commit 191aded

Browse files
author
jsolman
committed
Fix login with Ledger on Windows. Upgrade neon-js and fix minor UTXO tracking bugs.
1 parent 9c51c7a commit 191aded

File tree

7 files changed

+116
-113
lines changed

7 files changed

+116
-113
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aphelion-desktop-wallet",
3-
"version": "3.3.7",
3+
"version": "3.4.2",
44
"author": "Aphelion <info@aphelion.org>",
55
"description": "Aphelion Desktop Wallet",
66
"license": "LicenseRef-LICENSE",
@@ -59,7 +59,7 @@
5959
}
6060
},
6161
"dependencies": {
62-
"@cityofzion/neon-js": "git+https://github.com/cityofzion/neon-js.git#3.8.1",
62+
"@cityofzion/neon-js": "^3.11.9",
6363
"@ionic/app-scripts": "^3.1.8",
6464
"@ledgerhq/hw-transport-node-hid": "^4.7.6",
6565
"@xkeshi/vue-qrcode": "^0.3.0",

src/renderer/components/login/Ledger.vue

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,32 +43,40 @@ export default {
4343
data() {
4444
return {
4545
connected: null,
46+
verifying: null,
4647
};
4748
},
4849
4950
methods: {
50-
checkLedgerStatus() {
51-
if (this.connected === true) {
51+
async checkLedgerStatus() {
52+
if (this.connected || this.verifying) {
5253
return;
5354
}
5455
55-
this.$store.dispatch('verifyLedgerConnection', {
56-
done: () => {
57-
this.connected = true;
58-
this.login();
59-
},
60-
failed: () => {
61-
this.connected = false;
62-
},
63-
});
56+
try {
57+
this.verifying = true;
58+
await new Promise(async (resolve, reject) => {
59+
this.$store.dispatch('verifyLedgerConnection', {
60+
done: async () => {
61+
this.connected = true;
62+
await this.login();
63+
resolve();
64+
},
65+
failed: () => reject(),
66+
});
67+
});
68+
} catch (e) {
69+
this.connected = false;
70+
}
71+
this.verifying = false;
6472
},
6573
66-
login() {
74+
async login() {
6775
if (!this.connected) {
6876
return;
6977
}
7078
71-
this.$store.dispatch('openLedger', {
79+
await this.$store.dispatch('openLedger', {
7280
done: () => {
7381
this.$router.push('/authenticated/dashboard');
7482
},

src/renderer/l10n/en.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@
171171
"nightMode": "Night Mode",
172172
"noContacts": "No contacts",
173173
"noDataAvailable": "No Data Available",
174-
"noLedgerDeviceFound": "No Ledger device found. Please plugin your Ledger in, unlock it and open the NEO application.",
174+
"noLedgerDeviceFound": "No Ledger device found. Please plug your Ledger in, unlock it and open the NEO application.",
175175
"noOptionSelected": "No Option Selected",
176176
"notRightNow": "No, Not Now",
177177
"noSavedWallets": "You do not have any saved wallets. Create one?",

src/renderer/services/dex.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,11 @@ export default {
446446
.then((transaction) => {
447447
// send the signed transactions to the api for relay
448448
const currentNetwork = network.getSelectedNetwork();
449+
const currentWallet = wallets.getCurrentWallet();
449450
axios.delete(`${currentNetwork.aph}/order/${order.marketName}/${order.offerId}/${tx.serializeTransaction(transaction.tx, true)}`)
450451
.then((res) => {
451452
if (res.data.result) {
453+
neo.applyTxToAddressSystemAssetBalance(currentWallet.address, transaction.tx, false);
452454
resolve('Order Cancelled');
453455
} else {
454456
reject('Cancel failed');
@@ -484,6 +486,7 @@ export default {
484486
alerts.success('Claim relayed, waiting for confirmation...');
485487
neo.monitorTransactionConfirmation(res.tx, true)
486488
.then(async () => {
489+
neo.applyTxToAddressSystemAssetBalance(wallets.getCurrentWallet().address, res.tx, true);
487490
alerts.success(`Claimed ${withdrawAmountAfterClaim.toString()} APH to Wallet Balance.`);
488491
try {
489492
await store.dispatch('fetchCommitState');
@@ -519,6 +522,7 @@ export default {
519522
alerts.success('Commit relayed, waiting for confirmation...');
520523
neo.monitorTransactionConfirmation(res.tx, true)
521524
.then(() => {
525+
neo.applyTxToAddressSystemAssetBalance(wallets.getCurrentWallet().address, res.tx, true);
522526
setTimeout(async () => {
523527
try {
524528
await store.dispatch('fetchCommitState');
@@ -605,6 +609,7 @@ export default {
605609
alerts.success('Compound relayed, waiting for confirmation...');
606610
neo.monitorTransactionConfirmation(res.tx, true)
607611
.then(() => {
612+
neo.applyTxToAddressSystemAssetBalance(wallets.getCurrentWallet().address, res.tx, true);
608613
setTimeout(async () => {
609614
try {
610615
await store.dispatch('fetchCommitState');
@@ -642,6 +647,7 @@ export default {
642647
let neoToSend = 0;
643648
let gasToSend = 0;
644649
let holding = null;
650+
const currentWallet = wallets.getCurrentWallet();
645651

646652
if (assetId === assets.NEO) {
647653
holding = neo.getHolding(assets.NEO);
@@ -671,6 +677,7 @@ export default {
671677
assetId, quantity);
672678
if (DBG_LOG) console.log(`Attempting approval of ${assetId}`);
673679
await neo.monitorTransactionConfirmation(res.tx, true);
680+
neo.applyTxToAddressSystemAssetBalance(currentWallet.address, res.tx, true);
674681
alerts.info(`Confirmed approval of ${quantity} ${holding.symbol} for deposit.`);
675682
// TODO: wait a few seconds before issuing deposit for UTXOs to settle.
676683
}
@@ -687,7 +694,7 @@ export default {
687694
alerts.success('Deposit relayed, waiting for confirmation...');
688695
neo.monitorTransactionConfirmation(res.tx, true)
689696
.then(() => {
690-
neo.applyTxToAddressSystemAssetBalance(wallets.getCurrentWallet().address, res.tx, true);
697+
neo.applyTxToAddressSystemAssetBalance(currentWallet.address, res.tx, true);
691698
resolve(res.tx);
692699
})
693700
.catch((e) => {
@@ -727,6 +734,7 @@ export default {
727734
return api.sendTx(configResponse);
728735
})
729736
.then((configResponse) => {
737+
neo.applyTxToAddressSystemAssetBalance(wallets.getCurrentWallet().address, configResponse.tx, false);
730738
resolve({
731739
success: configResponse.response.result,
732740
tx: configResponse.tx,
@@ -1832,6 +1840,7 @@ export default {
18321840
}
18331841

18341842
Vue.set(order, 'status', 'Submitting');
1843+
const currentWallet = wallets.getCurrentWallet();
18351844

18361845
// build all the order transactions
18371846
for (let i = 0; i < order.offersToTake.length; i += 1) {
@@ -1840,6 +1849,8 @@ export default {
18401849
// need to ignore this rule, each of these build operations has to happen in order
18411850
// that way they'll each select the right UTXO inputs
18421851
await this.buildAcceptOffer((order.side === 'Buy' ? 'Sell' : 'Buy'), order.orderType, order.market, offer);
1852+
// TODO: AcceptOffer has to be applied immediately in order to get different UTXO, in future wait to apply...
1853+
neo.applyTxToAddressSystemAssetBalance(currentWallet.address, offer.tx, false);
18431854
/* eslint-enable no-await-in-loop */
18441855
}
18451856

@@ -1876,6 +1887,7 @@ export default {
18761887
} else if (res.data.result.error) {
18771888
reject(`Order failed. Error: ${res.data.result.error}`);
18781889
} else {
1890+
if (order.makerTx) neo.applyTxToAddressSystemAssetBalance(currentWallet.address, order.makerTx, false);
18791891
const responseQuantityToTake = new BigNumber(res.data.quantityToTake);
18801892
const responseQuantityTaken = new BigNumber(res.data.quantityTaken);
18811893

@@ -2076,12 +2088,14 @@ export default {
20762088
return;
20772089
}
20782090
store.commit('setSystemWithdrawMergeState', { step: 2 });
2091+
const dexAddress = wallet.getAddressFromScriptHash(store.state.currentNetwork.dex_hash);
2092+
neo.applyTxToAddressSystemAssetBalance(dexAddress, res.tx, false);
20792093

20802094
alerts.success('Withdraw Mark Step Relayed. Waiting for confirmation.');
20812095
neo.monitorTransactionConfirmation(res.tx, true)
20822096
.then(() => {
20832097
store.commit('setSystemWithdrawMergeState', { step: 3 });
2084-
const dexAddress = wallet.getAddressFromScriptHash(store.state.currentNetwork.dex_hash);
2098+
20852099
// Must allow funds to be sent again by moving tx outputs to unspent.
20862100
neo.applyTxToAddressSystemAssetBalance(dexAddress, res.tx, true);
20872101

src/renderer/services/ledger.js

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,51 +7,32 @@ const VALID_STATUS = 0x9000;
77
let currentLedger = null;
88
let currentDevice = null;
99
export default {
10-
open() {
11-
return new Promise((resolve, reject) => {
12-
try {
13-
return LedgerNode.isSupported()
14-
.then((supported) => {
15-
if (!supported) {
16-
return reject('Your computer does not support the ledger!');
17-
}
1810

19-
return LedgerNode.list()
20-
.then((paths) => {
21-
if (paths.length === 0) {
22-
return reject('No Ledger device found. Please plugin your Ledger in, '
23-
+ 'unlock it and open the NEO application.');
24-
}
25-
26-
const path = paths[0];
27-
return LedgerNode.open(path)
28-
.then((res) => {
29-
currentDevice = res;
30-
this.getPublicKey()
31-
.then(() => {
32-
currentLedger = this;
33-
resolve(currentDevice);
34-
})
35-
.catch(() => {
36-
return reject('Please plugin your Ledger in, '
37-
+ 'unlock it and open the NEO application.');
38-
});
39-
})
40-
.catch(({ message }) => {
41-
return reject(message);
42-
});
43-
})
44-
.catch(({ message }) => {
45-
return reject(message);
46-
});
47-
})
48-
.catch(({ message }) => {
49-
return reject(message);
50-
});
51-
} catch ({ message }) {
52-
return reject(message);
11+
async open() {
12+
try {
13+
const supported = await LedgerNode.isSupported();
14+
if (!supported) {
15+
throw Error('Your computer does not support the ledger!');
5316
}
54-
});
17+
const paths = await LedgerNode.list();
18+
if (paths.length === 0) {
19+
throw Error('No Ledger device found. Please plug your Ledger in, '
20+
+ 'unlock it and open the NEO application.');
21+
}
22+
23+
const path = paths[0];
24+
currentDevice = await LedgerNode.open(path);
25+
try {
26+
await this.getPublicKey();
27+
} catch (e) {
28+
throw Error('Please plug your Ledger in, unlock it and open the NEO application.');
29+
}
30+
31+
currentLedger = this;
32+
return currentDevice;
33+
} catch ({ message }) {
34+
throw message;
35+
}
5536
},
5637

5738
close() {

src/renderer/services/neo.js

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
wallet,
33
api,
44
u,
5+
tx,
56
} from '@cityofzion/neon-js';
67
import _ from 'lodash';
78
import { BigNumber } from 'bignumber.js';
@@ -18,6 +19,7 @@ import { store } from '../store';
1819
import { timeouts, intervals } from '../constants';
1920
import { toBigNumber } from './formatting.js';
2021

22+
const { Transaction } = tx;
2123
const DBG_LOG = false;
2224

2325
const GAS_ASSET_ID = '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7';
@@ -844,8 +846,10 @@ export default {
844846
return this.monitorTransactionConfirmation(res.tx, checkRpcForDetails)
845847
.then(() => {
846848
if (isNep5 === false) {
847-
// Make change immediately available to spend.
848-
this.applyTxToAddressSystemAssetBalance(store.state.currentWallet.address, res.tx, true);
849+
// TODO: verify this only makes the change available to spend and doesn't try to add the other
850+
// TODO: utxo outputs too
851+
// this.applyTxToAddressSystemAssetBalance(store.state.currentWallet.address, res.tx, true);
852+
// Make change immediately available to spend
849853
}
850854
return resolve(res.tx);
851855
})
@@ -893,8 +897,11 @@ export default {
893897
config.signingFunction = ledger.signWithLedger;
894898
}
895899

900+
// TODO: this probably should happen as an action to update the balance without chance of race condition
896901
return api.sendAsset(config)
897902
.then((res) => {
903+
// api.sendAsset already applies the transaction to the balance, but if a block has passed and
904+
// fetchSystemAssetBalances() retrieved balance again the cached object changes, so we need to apply again.
898905
this.applyTxToAddressSystemAssetBalance(currentWallet.address, res.tx);
899906
return res;
900907
})
@@ -938,7 +945,12 @@ export default {
938945
config.address = currentWallet.address;
939946

940947
return api.doInvoke(config)
941-
.then(res => res)
948+
.then((res) => {
949+
// api.doInvoke already applies the transaction to the balance, but if a block has passed and
950+
// fetchSystemAssetBalances() retrieved balance again the cached object changes, so we need to apply again.
951+
this.applyTxToAddressSystemAssetBalance(currentWallet.address, res.tx, false);
952+
return res;
953+
})
942954
.catch((e) => {
943955
alerts.exception(e);
944956
});
@@ -948,7 +960,10 @@ export default {
948960
config.account = account;
949961

950962
return api.doInvoke(config)
951-
.then(res => res)
963+
.then((res) => {
964+
this.applyTxToAddressSystemAssetBalance(currentWallet.address, res.tx, false);
965+
return res;
966+
})
952967
.catch((e) => {
953968
alerts.exception(e);
954969
});
@@ -986,7 +1001,10 @@ export default {
9861001
config.address = currentWallet.address;
9871002

9881003
return api.doInvoke(config)
989-
.then(res => res)
1004+
.then((res) => {
1005+
this.applyTxToAddressSystemAssetBalance(currentWallet.address, res.tx, false);
1006+
return res;
1007+
})
9901008
.catch((e) => {
9911009
alerts.exception(e);
9921010
});
@@ -996,7 +1014,10 @@ export default {
9961014
config.account = account;
9971015

9981016
return api.doInvoke(config)
999-
.then(res => res)
1017+
.then((res) => {
1018+
this.applyTxToAddressSystemAssetBalance(currentWallet.address, res.tx, false);
1019+
return res;
1020+
})
10001021
.catch((e) => {
10011022
alerts.exception(e);
10021023
});
@@ -1259,6 +1280,7 @@ export default {
12591280
},
12601281

12611282
applyTxToAddressSystemAssetBalance(address, tx, confirmed) {
1283+
tx = tx instanceof Transaction ? tx : Transaction.deserialize(tx);
12621284
if (_.has(addressBalances, address)) {
12631285
const existingBalance = _.get(addressBalances, address);
12641286
existingBalance.balance.balance.applyTx(tx, confirmed);
@@ -1434,8 +1456,10 @@ export default {
14341456
return api.sendTx(config);
14351457
})
14361458
.then((config) => {
1459+
this.applyTxToAddressSystemAssetBalance(currentWallet.address, config.tx, false);
14371460
this.monitorTransactionConfirmation(config.tx, true)
14381461
.then(() => {
1462+
this.applyTxToAddressSystemAssetBalance(currentWallet.address, config.tx, true);
14391463
resolve({
14401464
success: config.response.result,
14411465
tx: config.tx,

0 commit comments

Comments
 (0)