Skip to content

Commit

Permalink
Add forced switch to nano prefix. Updates to pending tx detection.
Browse files Browse the repository at this point in the history
  • Loading branch information
cronoh committed Jul 29, 2019
1 parent 9c1fe98 commit c1dea2d
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
</div>
</div>

<div style="display: inline-block; text-align: right;" class="uk-text-muted" *ngIf="wallet.pending.gt(0)">
<div style="display: inline-block; text-align: right;" class="uk-text-muted" *ngIf="walletService.hasPendingTransactions()">
<span class="balance-text" style="display: inline-block; text-align: left; float: left; margin-top: 5px; color: #999;">Pending </span>
<span style="margin-left: 11px; display: inline-block; font-size: 12px; color: #999;">{{ wallet.pendingFiat | fiat: settings.settings.displayCurrency }}</span>
<span class="balance" style="clear: left; text-align: left; color: #999;">{{ wallet.pending | rai: settings.settings.displayDenomination }}</span>
Expand Down
22 changes: 21 additions & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,13 @@ export class AppComponent implements OnInit {
async ngOnInit() {
this.windowHeight = window.innerHeight;
this.settings.loadAppSettings();

// New for v19: Patch saved xrb_ prefixes to nano_
await this.patchXrbToNanoPrefixData();

this.addressBook.loadAddressBook();
this.workPool.loadWorkCache();

await this.walletService.loadStoredWallet();
this.websocket.connect();

Expand Down Expand Up @@ -107,6 +112,21 @@ export class AppComponent implements OnInit {

}

/*
This is important as it looks through saved data using hardcoded xrb_ prefixes
(Your wallet, address book, rep list, etc) and updates them to nano_ prefix for v19 RPC
*/
async patchXrbToNanoPrefixData() {
// If wallet is version 2, data has already been patched. Otherwise, patch all data
if (this.settings.settings.walletVersion >= 2) return;

await this.walletService.patchOldSavedData(); // Change saved xrb_ addresses to nano_
this.addressBook.patchXrbPrefixData();
this.representative.patchXrbPrefixData();

this.settings.setAppSetting('walletVersion', 2); // Update wallet version so we do not patch in the future.
}

toggleSearch(mobile = false) {
this.showSearchBar = !this.showSearchBar;
if (this.showSearchBar) {
Expand All @@ -118,7 +138,7 @@ export class AppComponent implements OnInit {
const searchData = this.searchData.trim();
if (!searchData.length) return;

if (searchData.startsWith('xrb_')) {
if (searchData.startsWith('xrb_') || searchData.startsWith('nano_')) {
this.router.navigate(['account', searchData]);
} else if (searchData.length === 64) {
this.router.navigate(['transaction', searchData]);
Expand Down
14 changes: 13 additions & 1 deletion src/app/components/send/send.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ <h2>Send Nano</h2>
<div class="uk-inline uk-width-1-1">
<span class="uk-form-icon uk-form-icon-flip" *ngIf="toAccountStatus === 0" uk-icon="icon: warning"></span>
<span class="uk-form-icon uk-form-icon-flip"*ngIf="toAccountStatus === 2" uk-icon="icon: check"></span>
<input (blur)="validateDestination()" (keyup)="searchAddressBook()" (focus)="searchAddressBook()" [(ngModel)]="toAccountID" [ngClass]="{ 'uk-form-success': toAccountStatus === 2, 'uk-form-danger': toAccountStatus === 0 }" class="uk-input" id="form-horizontal-text2" type="text" placeholder="Account to send to">
<input (blur)="validateDestination()" (keyup)="searchAddressBook()" (focus)="searchAddressBook()" [(ngModel)]="toAccountID" [ngClass]="{ 'uk-form-success': toAccountStatus === 2, 'uk-form-danger': toAccountStatus === 0 }" class="uk-input" id="form-horizontal-text2" type="text" placeholder="Account to send to" autocomplete="off">

<div *ngIf="(addressBookResults$ | async).length" [hidden]="!showAddressBook" class="uk-animation-slide-down-small uk-width-1-1 uk-card uk-card-default uk-card-body uk-position-absolute" style="z-index: 15000">
<ul class="uk-nav uk-nav-default">
Expand Down Expand Up @@ -184,6 +184,18 @@ <h2>Send Nano</h2>
</div>
<!-- End Confirmation Panel -->


<div uk-grid *ngIf="activePanel == 'status'" class="uk-animation-slide-left">
<div class="uk-width-1-1">
<div class="uk-card uk-card-default uk-width-1-1 uk-text-center">
<span style="display: block; padding-top: 8px;">You are sending</span>
<span style="display:block; font-size: 32px;">{{ rawAmount | rai: 'mnano' }}</span>
<span style="display:block; font-size: 12px;" *ngIf="amountRaw.gt(0)">+{{ amountRaw.toString(10) }} raw</span>
<span style="display:block; font-size: 16px; padding-bottom: 5px;" *ngIf="settings.settings.displayCurrency">{{ amountFiat | fiat: settings.settings.displayCurrency }} @ {{ price.price.lastPrice | fiat: settings.settings.displayCurrency }} / NANO</span>
</div>
</div>
</div>

</div>
</div>

Expand Down
9 changes: 8 additions & 1 deletion src/app/components/send/send.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export class SendComponent implements OnInit {

if (this.amount < 0 || rawAmount.lessThan(0)) return this.notificationService.sendWarning(`Amount is invalid`);
if (nanoAmount.lessThan(1)) return this.notificationService.sendWarning(`Transactions for less than 1 nano will be ignored by the node. Send raw amounts with at least 1 nano.`);
if (from.balanceBN.minus(rawAmount).lessThan(0)) return this.notificationService.sendError(`From account does not have enough XRB`);
if (from.balanceBN.minus(rawAmount).lessThan(0)) return this.notificationService.sendError(`From account does not have enough NANO`);

// Determine a proper raw amount to show in the UI, if a decimal was entered
this.amountRaw = this.rawAmount.mod(this.nano);
Expand All @@ -212,6 +212,13 @@ export class SendComponent implements OnInit {
this.confirmingTransaction = true;

try {
// New stuff to show status of each part of the transaction.
// console.log('Sending sub send command....');
// this.nanoBlock.subscribeSend(walletAccount, this.toAccountID, this.rawAmount, this.walletService.isLedgerWallet()).subscribe(value => {
// console.log('GOT VALUE!!! ', value)
// }, err => {
// console.log('GOT ERROR!!!: ', err);
// });
const newHash = await this.nanoBlock.generateSend(walletAccount, this.toAccountID, this.rawAmount, this.walletService.isLedgerWallet());
if (newHash) {
this.notificationService.sendSuccess(`Successfully sent ${this.amount} ${this.selectedAmount.shortName}!`);
Expand Down
18 changes: 18 additions & 0 deletions src/app/services/address-book.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,24 @@ export class AddressBookService {
return this.addressBook;
}

patchXrbPrefixData() {
const addressBookStore = localStorage.getItem(this.storeKey);
if (!addressBookStore) return;

const addressBook = JSON.parse(addressBookStore);

const newAddressBook = addressBook.map(entry => {
if (entry.account.indexOf('xrb_') !== -1) {
entry.account = entry.account.replace('xrb_', 'nano_');
}
return entry;
});

localStorage.setItem(this.storeKey, JSON.stringify(newAddressBook));

return true;
}

async saveAddress(account, name) {
const existingName = this.addressBook.find(a => a.name.toLowerCase() === name.toLowerCase());
if (existingName) throw new Error(`Name already exists in the address book`);
Expand Down
3 changes: 3 additions & 0 deletions src/app/services/app-settings.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ interface AppSettings {
serverNode: string | null;
serverWS: string | null;
minimumReceive: string | null;
walletVersion: number | null;
}

@Injectable()
Expand All @@ -38,6 +39,7 @@ export class AppSettingsService {
serverNode: null,
serverWS: null,
minimumReceive: null,
walletVersion: 1
};

constructor() { }
Expand Down Expand Up @@ -91,6 +93,7 @@ export class AppSettingsService {
serverAPI: null,
serverWS: null,
minimumReceive: null,
walletVersion: 1,
};
}

Expand Down
91 changes: 90 additions & 1 deletion src/app/services/nano-block.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import {NotificationService} from "./notification.service";
import {AppSettingsService} from "./app-settings.service";
import {WalletService} from "./wallet.service";
import {LedgerService} from "./ledger.service";
import {Observable} from "rxjs/Observable";
const nacl = window['nacl'];

const STATE_BLOCK_PREAMBLE = '0000000000000000000000000000000000000000000000000000000000000006';

@Injectable()
export class NanoBlockService {
representativeAccount = 'xrb_3rw4un6ys57hrb39sy1qx8qy5wukst1iiponztrz9qiz6qqa55kxzx4491or'; // NanoVault Representative
representativeAccount = 'nano_3rw4un6ys57hrb39sy1qx8qy5wukst1iiponztrz9qiz6qqa55kxzx4491or'; // NanoVault Representative

constructor(
private api: ApiService,
Expand Down Expand Up @@ -83,6 +84,94 @@ export class NanoBlockService {
}
}

// This might be used in the future to send state changes on the blocks instead of normal true/false
// subscribeSend(walletAccount, toAccountID, rawAmount, ledger = false): Observable {
// const doSend = async (observable) => {
// console.log(`OBS: Promise resolve, running main send logic.`);
// const startTime = Date.now();
//
// console.log(`Observable: Creation event run`);
// observable.next({ step: 0, startTime: startTime });
//
//
// const fromAccount = await this.api.accountInfo(walletAccount.id);
// if (!fromAccount) throw new Error(`Unable to get account information for ${walletAccount.id}`);
//
// const remaining = new BigNumber(fromAccount.balance).minus(rawAmount);
// const remainingDecimal = remaining.toString(10);
// let remainingPadded = remaining.toString(16);
// while (remainingPadded.length < 32) remainingPadded = '0' + remainingPadded; // Left pad with 0's
//
// let blockData;
// const representative = fromAccount.representative || (this.settings.settings.defaultRepresentative || this.representativeAccount);
//
// observable.next({ step: 1, startTime: startTime, eventTime: ((Date.now() - startTime) / 1000).toFixed(3) });
//
// let signature = null;
// if (ledger) {
// const ledgerBlock = {
// previousBlock: fromAccount.frontier,
// representative: representative,
// balance: remainingDecimal,
// recipient: toAccountID,
// };
// try {
// this.sendLedgerNotification();
// await this.ledgerService.updateCache(walletAccount.index, fromAccount.frontier);
// const sig = await this.ledgerService.signBlock(walletAccount.index, ledgerBlock);
// this.clearLedgerNotification();
// signature = sig.signature;
//
// observable.next({ step: 2, startTime: startTime, eventTime: ((Date.now() - startTime) / 1000).toFixed(3) });
// } catch (err) {
// this.clearLedgerNotification();
// this.sendLedgerDeniedNotification(err);
// return;
// }
// } else {
// signature = this.signSendBlock(walletAccount, fromAccount, representative, remainingPadded, toAccountID);
// observable.next({ step: 2, startTime: startTime, eventTime: ((Date.now() - startTime) / 1000).toFixed(3) });
// }
//
// if (!this.workPool.workExists(fromAccount.frontier)) {
// this.notifications.sendInfo(`Generating Proof of Work...`);
// }
//
// blockData = {
// type: 'state',
// account: walletAccount.id,
// previous: fromAccount.frontier,
// representative: representative,
// balance: remainingDecimal,
// link: this.util.account.getAccountPublicKey(toAccountID),
// work: await this.workPool.getWork(fromAccount.frontier),
// signature: signature,
// };
//
// observable.next({ step: 3, startTime: startTime, eventTime: ((Date.now() - startTime) / 1000).toFixed(3) });
//
// const processResponse = await this.api.process(blockData);
// if (!processResponse || !processResponse.hash) throw new Error(processResponse.error || `Node returned an error`);
//
// observable.next({ step: 4, startTime: startTime, eventTime: ((Date.now() - startTime) / 1000).toFixed(3) });
//
// walletAccount.frontier = processResponse.hash;
// this.workPool.addWorkToCache(processResponse.hash); // Add new hash into the work pool
// this.workPool.removeFromCache(fromAccount.frontier);
//
// observable.complete();
// };
//
//
// console.log(`Creating observable... on send...`);
// // Create an observable that can be returned instantly.
// return new Observable(observable => {
//
// doSend(observable).then(val => console.log(val));
// });
//
// }

async generateSend(walletAccount, toAccountID, rawAmount, ledger = false) {
const fromAccount = await this.api.accountInfo(walletAccount.id);
if (!fromAccount) throw new Error(`Unable to get account information for ${walletAccount.id}`);
Expand Down
18 changes: 18 additions & 0 deletions src/app/services/representative.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,24 @@ export class RepresentativeService {
return list;
}

patchXrbPrefixData() {
const representativeStore = localStorage.getItem(this.storeKey);
if (!representativeStore) return;

const list = JSON.parse(representativeStore);

const newRepList = list.map(entry => {
if (entry.id.indexOf('xrb_') !== -1) {
entry.id = entry.id.replace('xrb_', 'nano_');
}
return entry;
});

localStorage.setItem(this.storeKey, JSON.stringify(newRepList));

return true;
}

getRepresentative(id): StoredRepresentative | undefined {
return this.representatives.find(rep => rep.id == id);
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/services/util.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ function generateAccountKeyPair(accountSecretKeyBytes) {
return nacl.sign.keyPair.fromSecretKey(accountSecretKeyBytes);
}

function getPublicAccountID(accountPublicKeyBytes, prefix = 'xrb') {
function getPublicAccountID(accountPublicKeyBytes, prefix = 'nano') {
const accountHex = util.uint8.toHex(accountPublicKeyBytes);
const keyBytes = util.uint4.toUint8(util.hex.toUint4(accountHex)); // For some reason here we go from u, to hex, to 4, to 8??
const checksum = util.uint5.toString(util.uint4.toUint5(util.uint8.toUint4(blake.blake2b(keyBytes, null, 5).reverse())));
Expand Down
Loading

0 comments on commit c1dea2d

Please sign in to comment.