From 5313d61d8e239ff2954d65603163c33ca962a26d Mon Sep 17 00:00:00 2001 From: keeri Date: Wed, 10 May 2023 23:42:11 +0000 Subject: [PATCH 1/9] draft support for decentralized aliases (some features are still missing) --- .../account-details.component.ts | 12 +- .../address-book/address-book.component.ts | 4 + src/app/components/send/send.component.html | 36 +++-- src/app/components/send/send.component.ts | 144 ++++++++++++++++++ src/assets/i18n/en.json | 1 + src/less/nault-theme.less | 5 + 6 files changed, 189 insertions(+), 13 deletions(-) diff --git a/src/app/components/account-details/account-details.component.ts b/src/app/components/account-details/account-details.component.ts index 211f46e..359c9ed 100644 --- a/src/app/components/account-details/account-details.component.ts +++ b/src/app/components/account-details/account-details.component.ts @@ -744,14 +744,18 @@ export class AccountDetailsComponent implements OnInit, OnDestroy { const regexp = new RegExp('^(Account|' + this.translocoService.translate('general.account') + ') #\\d+$', 'g'); if ( regexp.test(this.addressBookModel) === true ) { - return this.notifications.sendError(`This name is reserved for wallet accounts without a label`); + return this.notifications.sendError(this.translocoService.translate('address-book.this-name-is-reserved-for-wallet-accounts-without-a-label')); + } + + if ( this.addressBookModel.startsWith('@') === true ) { + return this.notifications.sendError(this.translocoService.translate('address-book.this-name-is-reserved-for-decentralized-aliases')); } // Make sure no other entries are using that name const accountIdWithSameName = this.addressBook.getAccountIdByName(this.addressBookModel); if ( (accountIdWithSameName !== null) && (accountIdWithSameName !== this.accountID) ) { - return this.notifications.sendError(`This name is already in use! Please use a unique name`); + return this.notifications.sendError(this.translocoService.translate('address-book.this-name-is-already-in-use-please-use-a-unique-name')); } try { @@ -759,11 +763,11 @@ export class AccountDetailsComponent implements OnInit, OnDestroy { const currentTransactionTracking = this.addressBook.getTransactionTrackingById(this.accountID); await this.addressBook.saveAddress(this.accountID, this.addressBookModel, currentBalanceTracking, currentTransactionTracking); } catch (err) { - this.notifications.sendError(`Unable to save entry: ${err.message}`); + this.notifications.sendError(this.translocoService.translate('address-book.unable-to-save-entry', { message: err.message })); return; } - this.notifications.sendSuccess(`Address book entry saved successfully!`); + this.notifications.sendSuccess(this.translocoService.translate('address-book.address-book-entry-saved-successfully')); this.addressBookEntry = this.addressBookModel; this.showEditAddressBook = false; diff --git a/src/app/components/address-book/address-book.component.ts b/src/app/components/address-book/address-book.component.ts index 2962598..0c6ae61 100644 --- a/src/app/components/address-book/address-book.component.ts +++ b/src/app/components/address-book/address-book.component.ts @@ -281,6 +281,10 @@ export class AddressBookComponent implements OnInit, AfterViewInit, OnDestroy { return this.notificationService.sendError(this.translocoService.translate('address-book.this-name-is-reserved-for-wallet-accounts-without-a-label')); } + if ( this.newAddressName.startsWith('@') === true ) { + return this.notificationService.sendError(this.translocoService.translate('address-book.this-name-is-reserved-for-decentralized-aliases')); + } + // Remove spaces and convert to nano prefix this.newAddressAccount = this.newAddressAccount.replace(/ /g, '').replace('xrb_', 'nano_'); diff --git a/src/app/components/send/send.component.html b/src/app/components/send/send.component.html index e60f6b0..83614f7 100644 --- a/src/app/components/send/send.component.html +++ b/src/app/components/send/send.component.html @@ -32,24 +32,42 @@
- + -
+
-
-
+
+
+
+ +
diff --git a/src/app/components/send/send.component.ts b/src/app/components/send/send.component.ts index c3ed326..f209885 100644 --- a/src/app/components/send/send.component.ts +++ b/src/app/components/send/send.component.ts @@ -14,6 +14,7 @@ import {NanoBlockService} from '../../services/nano-block.service'; import { QrModalService } from '../../services/qr-modal.service'; import { environment } from 'environments/environment'; import { TranslocoService } from '@ngneat/transloco'; +import { HttpClient } from '@angular/common/http'; import * as nanocurrency from 'nanocurrency'; const nacl = window['nacl']; @@ -30,9 +31,23 @@ export class SendComponent implements OnInit { sendDestinationType = 'external-address'; accounts = this.walletService.wallet.accounts; + aliasLookup = { + fullText: '', + name: '', + domain: '', + } + aliasLookupLatestSuccessful = { + fullText: '', + name: '', + domain: '', + address: '', + } + aliasResults$ = new BehaviorSubject([]); addressBookResults$ = new BehaviorSubject([]); + isDestinationAccountAlias = false; showAddressBook = false; addressBookMatch = ''; + addressAliasMatch = ''; amounts = [ { name: 'XNO', shortName: 'XNO', value: 'mnano' }, @@ -70,6 +85,7 @@ export class SendComponent implements OnInit { public settings: AppSettingsService, private util: UtilService, private qrModalService: QrModalService, + private http: HttpClient, private translocoService: TranslocoService) { } async ngOnInit() { @@ -194,6 +210,10 @@ export class SendComponent implements OnInit { } onDestinationAddressInput() { + this.addressAliasMatch = ''; + this.addressBookMatch = ''; + + this.offerLookupIfDestinationIsAlias(); this.searchAddressBook(); const destinationAddress = this.toAccountID || ''; @@ -243,9 +263,117 @@ export class SendComponent implements OnInit { this.addressBookResults$.next(matches); } + offerLookupIfDestinationIsAlias() { + const destinationAddress = this.toAccountID || ''; + + const mayBeAnAlias = ( + ( destinationAddress.startsWith('@') === true ) + && ( destinationAddress.includes('.') === true ) + && ( destinationAddress.endsWith('.') === false ) + && ( destinationAddress.includes('/') === false ) + && ( destinationAddress.includes('?') === false ) + ); + + if (mayBeAnAlias === false) { + this.isDestinationAccountAlias = false; + this.aliasLookup = { + fullText: '', + name: '', + domain: '', + }; + this.aliasResults$.next([]); + return + } + + this.isDestinationAccountAlias = true; + + const aliasWithoutFirstSymbol = destinationAddress.slice(1); + const aliasSplitResults = aliasWithoutFirstSymbol.split('@'); + + let aliasName = '' + let aliasDomain = '' + + if (aliasSplitResults.length === 2) { + aliasName = aliasSplitResults[0] + aliasDomain = aliasSplitResults[1] + } else { + aliasDomain = aliasSplitResults[0] + } + + this.aliasLookup = { + fullText: destinationAddress, + name: aliasName, + domain: aliasDomain, + }; + + this.aliasResults$.next([{ ...this.aliasLookup }]); + + this.toAccountStatus = 1; // Neutral state + } + + async lookupAlias() { + if (this.aliasLookup.domain === '') { + return; + } + + this.toAccountStatus = 1; // Neutral state + + const aliasDomain = this.aliasLookup.domain; + + const aliasName = ( + (this.aliasLookup.name !== '') + ? this.aliasLookup.name + : '_' + ); + + const lookupUrl = + `https://${ aliasDomain }/.well-known/nano-currency.json?names=${ aliasName }`; + + await this.http.get(lookupUrl).toPromise() + .then(res => { + try { + const matchingAccount = + res.names.find( + (account) => + (account.name === aliasName) + ); + + if (matchingAccount == null) { + this.toAccountStatus = 0; // Error state + return; + } + + if (!this.util.account.isValidAccount(matchingAccount.address)) { + this.toAccountStatus = 0; // Error state + return; + } + + this.toAccountID = matchingAccount.address; + + this.aliasLookupLatestSuccessful = { + ...this.aliasLookup, + address: this.toAccountID, + } + + this.onDestinationAddressInput(); + this.validateDestination(); + + return; + } catch(err) { + this.toAccountStatus = 0; // Error state + return; + } + }) + .catch(err => { + this.toAccountStatus = 0; // Error state + return; + }); + } + selectBookEntry(account) { this.showAddressBook = false; this.toAccountID = account; + this.isDestinationAccountAlias = false; this.searchAddressBook(); this.validateDestination(); } @@ -261,6 +389,21 @@ export class SendComponent implements OnInit { // Remove spaces from the account id this.toAccountID = this.toAccountID.replace(/ /g, ''); + this.addressAliasMatch = ( + ( + (this.aliasLookupLatestSuccessful.address !== '') + && (this.aliasLookupLatestSuccessful.address === this.toAccountID) + ) + ? this.aliasLookupLatestSuccessful.fullText + : null + ); + + if (this.isDestinationAccountAlias === true) { + this.addressBookMatch = null; + this.toAccountStatus = 1; // Neutral state + return; + } + this.addressBookMatch = ( this.addressBookService.getAccountName(this.toAccountID) || this.getAccountLabel(this.toAccountID, null) @@ -426,6 +569,7 @@ export class SendComponent implements OnInit { this.fromAddressBook = ''; this.toAddressBook = ''; this.addressBookMatch = ''; + this.addressAliasMatch = ''; } else { if (!this.walletService.isLedgerWallet()) { this.notificationService.sendError(`There was an error sending your transaction, please try again.`); diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 2029c63..aa3859a 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -84,6 +84,7 @@ "the-balance-will-be-displayed-in-the-address-book": "The balance will be displayed in the address book.", "this-name-is-already-in-use-please-use-a-unique-name": "This name is already in use! Please use a unique name", "this-name-is-reserved-for-wallet-accounts-without-a-label": "This name is reserved for wallet accounts without a label", + "this-name-is-reserved-for-decentralized-aliases": "Names starting with @ are reserved for decentralized aliases", "track-balance": "Track Balance", "track-transactions": "Track Transactions", "unable-to-delete-entry": "Unable to delete entry: {{ message }}", diff --git a/src/less/nault-theme.less b/src/less/nault-theme.less index 646eefe..b4a0679 100644 --- a/src/less/nault-theme.less +++ b/src/less/nault-theme.less @@ -347,6 +347,11 @@ input[type=number] { background: @rep-label-color; color: #FFF; } + + &.alias { + text-transform: none; + font-family: 'Roboto Mono', monospace; + } } .rep-donation-icon { From 27489acbb35705cc8855eb90ca82306a0b8dbe39 Mon Sep 17 00:00:00 2001 From: keeri Date: Thu, 11 May 2023 10:58:04 +0000 Subject: [PATCH 2/9] opt-in setting for external requests to decentralized alias domains --- .../configure-app.component.html | 17 ++++++++++++++ .../configure-app/configure-app.component.ts | 12 ++++++++++ src/app/components/send/send.component.ts | 23 +++++++++++++++++++ src/app/services/app-settings.service.ts | 3 +++ src/assets/i18n/en.json | 7 ++++++ 5 files changed, 62 insertions(+) diff --git a/src/app/components/configure-app/configure-app.component.html b/src/app/components/configure-app/configure-app.component.html index b061f84..d9feaea 100644 --- a/src/app/components/configure-app/configure-app.component.html +++ b/src/app/components/configure-app/configure-app.component.html @@ -197,6 +197,23 @@
+
+
+ +
+ +
+ +
+ +
+
+
+
+
+
diff --git a/src/app/components/configure-app/configure-app.component.ts b/src/app/components/configure-app/configure-app.component.ts index 49fb9d8..007fa43 100644 --- a/src/app/components/configure-app/configure-app.component.ts +++ b/src/app/components/configure-app/configure-app.component.ts @@ -148,6 +148,12 @@ export class ConfigureAppComponent implements OnInit { ]; selectedPendingOption = this.pendingOptions[0].value; + decentralizedAliasesOptions = [ + { name: this.translocoService.translate('configure-app.decentralized-aliases-options.disabled'), value: 'disabled' }, + { name: this.translocoService.translate('configure-app.decentralized-aliases-options.enabled'), value: 'enabled' }, + ]; + selectedDecentralizedAliasesOption = this.decentralizedAliasesOptions[0].value; + // prefixOptions = [ // { name: 'xrb_', value: 'xrb' }, // { name: 'nano_', value: 'nano' }, @@ -282,6 +288,9 @@ export class ConfigureAppComponent implements OnInit { const matchingPendingOption = this.pendingOptions.find(d => d.value === settings.pendingOption); this.selectedPendingOption = matchingPendingOption ? matchingPendingOption.value : this.pendingOptions[0].value; + const matchingDecentralizedAliasesOption = this.decentralizedAliasesOptions.find(d => d.value === settings.decentralizedAliasesOption); + this.selectedDecentralizedAliasesOption = matchingDecentralizedAliasesOption ? matchingDecentralizedAliasesOption.value : this.decentralizedAliasesOptions[0].value; + this.serverOptions = this.appSettings.serverOptions; this.selectedServer = settings.serverName; this.serverAPI = settings.serverAPI; @@ -371,6 +380,8 @@ export class ConfigureAppComponent implements OnInit { minReceive = this.minimumReceive; } + const decentralizedAliasesOption = this.selectedDecentralizedAliasesOption; + // reload pending if threshold changes or if receive priority changes from manual to auto let reloadPending = this.appSettings.settings.minimumReceive !== this.minimumReceive || (pendingOption !== 'manual' && pendingOption !== this.appSettings.settings.pendingOption); @@ -432,6 +443,7 @@ export class ConfigureAppComponent implements OnInit { multiplierSource: Number(this.selectedMultiplierOption), customWorkServer: this.customWorkServer, pendingOption: pendingOption, + decentralizedAliasesOption: decentralizedAliasesOption, minimumReceive: minReceive, defaultRepresentative: this.defaultRepresentative || null, }; diff --git a/src/app/components/send/send.component.ts b/src/app/components/send/send.component.ts index f209885..c9ffc78 100644 --- a/src/app/components/send/send.component.ts +++ b/src/app/components/send/send.component.ts @@ -316,6 +316,29 @@ export class SendComponent implements OnInit { return; } + if (this.settings.settings.decentralizedAliasesOption === 'disabled') { + const UIkit = window['UIkit']; + try { + await UIkit.modal.confirm( + `


+ + ${ this.translocoService.translate('configure-app.decentralized-aliases-require-external-requests') } + `, + { + labels: { + cancel: this.translocoService.translate('general.cancel'), + ok: this.translocoService.translate('configure-app.allow-external-requests'), + } + } + ); + + this.settings.setAppSetting('decentralizedAliasesOption', 'enabled'); + } catch (err) { + // pressed cancel, or a different error + return; + } + } + this.toAccountStatus = 1; // Neutral state const aliasDomain = this.aliasLookup.domain; diff --git a/src/app/services/app-settings.service.ts b/src/app/services/app-settings.service.ts index fa5c1da..1a90b16 100644 --- a/src/app/services/app-settings.service.ts +++ b/src/app/services/app-settings.service.ts @@ -20,6 +20,7 @@ interface AppSettings { multiplierSource: number; customWorkServer: string; pendingOption: string; + decentralizedAliasesOption: string; serverName: string; serverAPI: string | null; serverWS: string | null; @@ -48,6 +49,7 @@ export class AppSettingsService { multiplierSource: 1, customWorkServer: '', pendingOption: 'amount', + decentralizedAliasesOption: 'disabled', serverName: 'random', serverAPI: null, serverWS: null, @@ -241,6 +243,7 @@ export class AppSettingsService { multiplierSource: 1, customWorkServer: '', pendingOption: 'amount', + decentralizedAliasesOption: 'disabled', serverName: 'random', serverAPI: null, serverWS: null, diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index aa3859a..ce5c7a4 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -134,6 +134,7 @@ }, "configure-app": { "advanced-options": "Advanced Options", + "allow-external-requests": "Allow External Requests", "api-server": "API Server", "app-display-settings-successfully-updated": "App display settings successfully updated!", "app-wallet-settings-successfully-updated": "App wallet settings successfully updated!", @@ -159,6 +160,12 @@ }, "custom-api-server-has-an-invalid-address": "Custom API Server has an invalid address.", "custom-update-server-has-an-invalid-address": "Custom Update Server has an invalid address.", + "decentralized-aliases": "Decentralized Aliases", + "decentralized-aliases-options": { + "disabled": "Disabled", + "enabled": "Enabled - Allow External Requests to Alias Domains" + }, + "decentralized-aliases-require-external-requests": "Decentralized aliases require external requests to alias domains. When you try to lookup the address of @madeline@example.com, the domain example.com may record your IP address.", "default-representative": "Default Representative", "default-representative-is-not-a-valid-account": "Default representative is not a valid account", "delete-all-data": "Delete ALL Data", From e4cc142eab5545d32b8e0e3505898f7858bf78fb Mon Sep 17 00:00:00 2001 From: keeri Date: Thu, 11 May 2023 11:23:18 +0000 Subject: [PATCH 3/9] decentralized alias fetch indication and handling of concurrent requests --- src/app/components/send/send.component.html | 19 +++++++--- src/app/components/send/send.component.ts | 41 +++++++++++++++++---- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/app/components/send/send.component.html b/src/app/components/send/send.component.html index 83614f7..5c7e7e1 100644 --- a/src/app/components/send/send.component.html +++ b/src/app/components/send/send.component.html @@ -39,14 +39,21 @@

  • Alias Lookup
  • -
  • - - Press Enter or click here to request alias from - - - {{ alias.domain }} +
  • + + Looking up {{ aliasLookupInProgress.fullText }}...
  • + +
  • + + Press Enter or click here to request alias from + + + {{ alias.domain }} + +
  • +
  • diff --git a/src/app/components/send/send.component.ts b/src/app/components/send/send.component.ts index c9ffc78..6f9de9f 100644 --- a/src/app/components/send/send.component.ts +++ b/src/app/components/send/send.component.ts @@ -31,15 +31,21 @@ export class SendComponent implements OnInit { sendDestinationType = 'external-address'; accounts = this.walletService.wallet.accounts; - aliasLookup = { + + ALIAS_LOOKUP_DEFAULT_STATE = { fullText: '', name: '', domain: '', } + + aliasLookup = { + ...this.ALIAS_LOOKUP_DEFAULT_STATE, + } + aliasLookupInProgress = { + ...this.ALIAS_LOOKUP_DEFAULT_STATE, + } aliasLookupLatestSuccessful = { - fullText: '', - name: '', - domain: '', + ...this.ALIAS_LOOKUP_DEFAULT_STATE, address: '', } aliasResults$ = new BehaviorSubject([]); @@ -277,9 +283,7 @@ export class SendComponent implements OnInit { if (mayBeAnAlias === false) { this.isDestinationAccountAlias = false; this.aliasLookup = { - fullText: '', - name: '', - domain: '', + ...this.ALIAS_LOOKUP_DEFAULT_STATE, }; this.aliasResults$.next([]); return @@ -341,6 +345,7 @@ export class SendComponent implements OnInit { this.toAccountStatus = 1; // Neutral state + const aliasFullText = this.aliasLookup.fullText; const aliasDomain = this.aliasLookup.domain; const aliasName = ( @@ -352,8 +357,25 @@ export class SendComponent implements OnInit { const lookupUrl = `https://${ aliasDomain }/.well-known/nano-currency.json?names=${ aliasName }`; + this.aliasLookupInProgress = { + ...this.aliasLookup, + }; + await this.http.get(lookupUrl).toPromise() .then(res => { + const isOutdatedRequest = ( + this.aliasLookupInProgress.fullText + !== aliasFullText + ); + + if (isOutdatedRequest === true) { + return; + } + + this.aliasLookupInProgress = { + ...this.ALIAS_LOOKUP_DEFAULT_STATE, + }; + try { const matchingAccount = res.names.find( @@ -374,7 +396,7 @@ export class SendComponent implements OnInit { this.toAccountID = matchingAccount.address; this.aliasLookupLatestSuccessful = { - ...this.aliasLookup, + ...this.aliasLookupInProgress, address: this.toAccountID, } @@ -388,6 +410,9 @@ export class SendComponent implements OnInit { } }) .catch(err => { + this.aliasLookupInProgress = { + ...this.ALIAS_LOOKUP_DEFAULT_STATE, + }; this.toAccountStatus = 0; // Error state return; }); From c911496716ac23b8609b881ed5ed3b3c93f2422b Mon Sep 17 00:00:00 2001 From: keeri Date: Thu, 11 May 2023 12:02:14 +0000 Subject: [PATCH 4/9] display error messages upon decentralized alias lookup failure --- src/app/components/send/send.component.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/app/components/send/send.component.ts b/src/app/components/send/send.component.ts index 6f9de9f..1a386a6 100644 --- a/src/app/components/send/send.component.ts +++ b/src/app/components/send/send.component.ts @@ -377,6 +377,18 @@ export class SendComponent implements OnInit { }; try { + const aliasesInJsonCount = ( + ( Array.isArray(res.names) === true ) + ? res.names.length + : 0 + ); + + if (aliasesInJsonCount === 0) { + this.toAccountStatus = 0; // Error state + this.notificationService.sendWarning(`No aliases found on ${aliasDomain}`); + return; + } + const matchingAccount = res.names.find( (account) => @@ -385,11 +397,13 @@ export class SendComponent implements OnInit { if (matchingAccount == null) { this.toAccountStatus = 0; // Error state + this.notificationService.sendWarning(`Alias @${aliasName} not found on ${aliasDomain}`); return; } if (!this.util.account.isValidAccount(matchingAccount.address)) { this.toAccountStatus = 0; // Error state + this.notificationService.sendWarning(`Alias ${aliasFullText} does not have a valid address`); return; } @@ -406,6 +420,7 @@ export class SendComponent implements OnInit { return; } catch(err) { this.toAccountStatus = 0; // Error state + this.notificationService.sendWarning(`Unknown error has occurred while trying to lookup ${aliasFullText}`); return; } }) @@ -414,6 +429,13 @@ export class SendComponent implements OnInit { ...this.ALIAS_LOOKUP_DEFAULT_STATE, }; this.toAccountStatus = 0; // Error state + + if (err.status === 404) { + this.notificationService.sendWarning(`No aliases found on ${aliasDomain}`); + } else { + this.notificationService.sendWarning(`Could not reach domain ${aliasDomain}`); + } + return; }); } From 7b31143828de99c3e75b1324fbd731c5aae59199 Mon Sep 17 00:00:00 2001 From: keeri Date: Thu, 11 May 2023 12:06:44 +0000 Subject: [PATCH 5/9] correctly store properties of the latest successful alias lookup --- src/app/components/send/send.component.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/app/components/send/send.component.ts b/src/app/components/send/send.component.ts index 1a386a6..1ade403 100644 --- a/src/app/components/send/send.component.ts +++ b/src/app/components/send/send.component.ts @@ -345,12 +345,14 @@ export class SendComponent implements OnInit { this.toAccountStatus = 1; // Neutral state - const aliasFullText = this.aliasLookup.fullText; - const aliasDomain = this.aliasLookup.domain; + const aliasLookup = { ...this.aliasLookup }; + + const aliasFullText = aliasLookup.fullText; + const aliasDomain = aliasLookup.domain; const aliasName = ( - (this.aliasLookup.name !== '') - ? this.aliasLookup.name + (aliasLookup.name !== '') + ? aliasLookup.name : '_' ); @@ -358,7 +360,7 @@ export class SendComponent implements OnInit { `https://${ aliasDomain }/.well-known/nano-currency.json?names=${ aliasName }`; this.aliasLookupInProgress = { - ...this.aliasLookup, + ...aliasLookup, }; await this.http.get(lookupUrl).toPromise() @@ -410,9 +412,9 @@ export class SendComponent implements OnInit { this.toAccountID = matchingAccount.address; this.aliasLookupLatestSuccessful = { - ...this.aliasLookupInProgress, + ...aliasLookup, address: this.toAccountID, - } + }; this.onDestinationAddressInput(); this.validateDestination(); From e42b848fa98e76879e34fcda6e2bac1126dc6141 Mon Sep 17 00:00:00 2001 From: keeri Date: Thu, 11 May 2023 12:14:32 +0000 Subject: [PATCH 6/9] if alias name is explicitly provided as underscore symbol, exclude it --- src/app/components/send/send.component.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/app/components/send/send.component.ts b/src/app/components/send/send.component.ts index 1ade403..c10789b 100644 --- a/src/app/components/send/send.component.ts +++ b/src/app/components/send/send.component.ts @@ -291,7 +291,12 @@ export class SendComponent implements OnInit { this.isDestinationAccountAlias = true; - const aliasWithoutFirstSymbol = destinationAddress.slice(1); + let aliasWithoutFirstSymbol = destinationAddress.slice(1); + + if (aliasWithoutFirstSymbol.startsWith('_@') === true ) { + aliasWithoutFirstSymbol = aliasWithoutFirstSymbol.slice(2); + } + const aliasSplitResults = aliasWithoutFirstSymbol.split('@'); let aliasName = '' @@ -305,7 +310,7 @@ export class SendComponent implements OnInit { } this.aliasLookup = { - fullText: destinationAddress, + fullText: `@${aliasWithoutFirstSymbol}`, name: aliasName, domain: aliasDomain, }; From 34ed82c4e84afe988f9659d10519a95a853ae3c4 Mon Sep 17 00:00:00 2001 From: keeri Date: Thu, 11 May 2023 12:22:19 +0000 Subject: [PATCH 7/9] handle /send?to=@alias url's --- src/app/components/send/send.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/components/send/send.component.ts b/src/app/components/send/send.component.ts index c10789b..fd57b12 100644 --- a/src/app/components/send/send.component.ts +++ b/src/app/components/send/send.component.ts @@ -156,6 +156,7 @@ export class SendComponent implements OnInit { if (params && params.to) { this.toAccountID = params.to; + this.offerLookupIfDestinationIsAlias(); this.validateDestination(); this.sendDestinationType = 'external-address'; } From df160644f6c9b8fbb999b1da94eba1cbcac493da Mon Sep 17 00:00:00 2001 From: keeri Date: Thu, 11 May 2023 13:12:51 +0000 Subject: [PATCH 8/9] make aliases non case sensitive --- src/app/components/send/send.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/components/send/send.component.ts b/src/app/components/send/send.component.ts index fd57b12..c2508d6 100644 --- a/src/app/components/send/send.component.ts +++ b/src/app/components/send/send.component.ts @@ -292,7 +292,7 @@ export class SendComponent implements OnInit { this.isDestinationAccountAlias = true; - let aliasWithoutFirstSymbol = destinationAddress.slice(1); + let aliasWithoutFirstSymbol = destinationAddress.slice(1).toLowerCase(); if (aliasWithoutFirstSymbol.startsWith('_@') === true ) { aliasWithoutFirstSymbol = aliasWithoutFirstSymbol.slice(2); From 1518915944485bebd2eda2fe8f1e1340c74010fc Mon Sep 17 00:00:00 2001 From: keeri Date: Fri, 12 May 2023 09:37:34 +0000 Subject: [PATCH 9/9] assuming dynamic json, 0 names returned merely means no match --- src/app/components/send/send.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/components/send/send.component.ts b/src/app/components/send/send.component.ts index c2508d6..7ad3f1c 100644 --- a/src/app/components/send/send.component.ts +++ b/src/app/components/send/send.component.ts @@ -393,7 +393,7 @@ export class SendComponent implements OnInit { if (aliasesInJsonCount === 0) { this.toAccountStatus = 0; // Error state - this.notificationService.sendWarning(`No aliases found on ${aliasDomain}`); + this.notificationService.sendWarning(`Alias @${aliasName} not found on ${aliasDomain}`); return; }