Skip to content

Commit

Permalink
Merge pull request #59 from dev-ptera/feat/2.8.0
Browse files Browse the repository at this point in the history
Feat/2.8.0
  • Loading branch information
dev-ptera authored Dec 21, 2024
2 parents 1d38851 + 597e6bc commit 693bc20
Show file tree
Hide file tree
Showing 13 changed files with 116 additions and 17 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change Log

## v2.8.0 (December 21, 2024)

- Added ability to search BNS addresses.

## v2.7.0 (April 28, 2024)

- Added birthday banner which displays every Apirl 1st.
Expand Down
5 changes: 4 additions & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,5 +151,8 @@
}
}
},
"defaultProject": "yellow-spyglass-client"
"defaultProject": "yellow-spyglass-client",
"cli": {
"analytics": false
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "yellow-spyglass-client",
"version": "2.7.0",
"version": "2.8.0",
"scripts": {
"ng": "ng",
"start": "ng serve -c development --open --host 0.0.0.0",
Expand Down Expand Up @@ -34,6 +34,7 @@
"@brightlayer-ui/colors-branding": "^3.2.1",
"@dev-ptera/nano-node-rpc": "^2.0.2",
"@ngneat/until-destroy": "^9.2.3",
"banani-bns": "^0.0.9",
"banano-unit-converter": "^0.1.0",
"core-js": "^2.5.4",
"file-saver": "^2.0.5",
Expand Down
8 changes: 6 additions & 2 deletions src/app/navigation/search-bar/search-bar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export let APP_SEARCH_BAR_ID = 0;
export class SearchBarComponent implements OnInit, AfterViewInit, AfterViewChecked {
@ViewChild(MatMenuTrigger) trigger: MatMenuTrigger;

@Input() placeholder: string = 'Search by Address, Block or Alias';
@Input() placeholder: string = 'Search by Address, Block, BNS, or Alias';
@Input() toolbarTitle: string;

/** This input is used to turn off the autofocus logic. Home page search does not need autofocus, but app-bar search does. */
Expand Down Expand Up @@ -127,7 +127,11 @@ export class SearchBarComponent implements OnInit, AfterViewInit, AfterViewCheck
return this.invalidSearch.emit();
}

if (this._searchService.isValidAddress(value) || this._searchService.isValidBlock(value)) {
if (
this._searchService.isValidAddress(value) ||
this._searchService.isValidBlock(value) ||
this._searchService.isValidBNSDomain(value)
) {
return this._emitSearch(value, controlKey);
}

Expand Down
25 changes: 21 additions & 4 deletions src/app/pages/account/account.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { OnlineRepsService } from '@app/services/online-reps/online-reps.service
import { NavigationEnd, Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { AliasService } from '@app/services/alias/alias.service';
import { APP_NAV_ITEMS, hashNavItem } from '../../navigation/nav-items';
import { APP_NAV_ITEMS, accountNavItem, hashNavItem } from '../../navigation/nav-items';
import { environment } from '../../../environments/environment';
import { DelegatorsTabService } from '@app/pages/account/tabs/delegators/delegators-tab.service';
import { InsightsTabService } from '@app/pages/account/tabs/insights/insights-tab.service';
Expand Down Expand Up @@ -64,12 +64,12 @@ export class AccountComponent implements OnDestroy {
private readonly _insightsTabService: InsightsTabService,
private readonly _delegatorsTabService: DelegatorsTabService
) {
this.routeListener = this._router.events.subscribe((route) => {
this.routeListener = this._router.events.subscribe(async (route) => {
if (route instanceof NavigationEnd) {
const splitUrl = this._router.url.replace('/history', '').split('/');
const path = splitUrl[splitUrl.length - 1];
const address = path.substring(0, 64);
this._searchAccount(address);
await this._searchAccount(address);
}
});

Expand Down Expand Up @@ -111,13 +111,30 @@ export class AccountComponent implements OnDestroy {
void this._router.navigate([`/${hashNavItem.route}/${hash}`], { replaceUrl: true });
}

/** Call this method whenever someone has enters a BNS domain, and it is resolved to a Banano address. */
private _redirectToAccountPage(account: string): void {
void this._router.navigate([`/${accountNavItem.route}/${account}`], { replaceUrl: true });
}

/** Given a ban address, searches for account. */
private _searchAccount(address): void {
private async _searchAccount(address): Promise<void> {
if (!address) {
return;
}

if (!address.startsWith('ban_')) {
//if not a banano address, and is in the format <string>.<string>, search in api
if (this._util.isValidBNSDomain(address)) {
//search in api
try {
const parts = address.split('.');
const domain = await this.apiService.fetchBNSDomain(parts[0], parts[1]);
if (domain.domain?.resolved_address) {
return this._redirectToAccountPage(domain.domain?.resolved_address);
}
} catch (_) {}
}
//if not in that format, or not found in api, assume it is a block hash
this._redirectToHashPage(address);
}

Expand Down
12 changes: 12 additions & 0 deletions src/app/services/api/api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
AliasDto,
BlockAtHeightDto,
BlockDtoV2,
BNSDomainDto,
ConfirmedTransactionDto,
DelegatorsOverviewDto,
DiscordResponseDto,
Expand Down Expand Up @@ -204,6 +205,17 @@ export class ApiService {
.toPromise();
}

/** Fetch/query BNS domain. */
async fetchBNSDomain(domain_name: string, tld: string): Promise<BNSDomainDto> {
await this._hasPingedApi();
return this._http
.post<BNSDomainDto>(`${this.httpApi}/v1/account/bns`, {
domain_name,
tld,
})
.toPromise();
}

/** Fetches monitored representatives stats. */
async fetchMonitoredRepresentatives(): Promise<MonitoredRepDto[]> {
await this._hasPingedApi();
Expand Down
11 changes: 8 additions & 3 deletions src/app/services/search/search.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Injectable } from '@angular/core';
import { UtilService } from '@app/services/util/util.service';
import { Observable, Subject } from 'rxjs';
import { APP_NAV_ITEMS } from '../../navigation/nav-items';
import { Router } from '@angular/router';
Expand All @@ -9,17 +10,17 @@ import { Router } from '@angular/router';
export class SearchService {
search$ = new Subject<{ search: string; openInNewWindow: boolean }>();

constructor(router: Router) {
constructor(router: Router, private readonly _utilService: UtilService) {
this.searchEvents().subscribe((data: { search: string; openInNewWindow: boolean }) => {
if (data.openInNewWindow) {
if (data.search.startsWith('ban_')) {
if (data.search.startsWith('ban_') || this.isValidBNSDomain(data.search)) {
const origin = window.location.origin;
window.open(`${origin}/${APP_NAV_ITEMS.account.route}/${data.search}`, '_blank');
} else {
window.open(`${origin}/${APP_NAV_ITEMS.hash.route}/${data.search}`, '_blank');
}
} else {
if (data.search.startsWith('ban_')) {
if (data.search.startsWith('ban_') || this.isValidBNSDomain(data.search)) {
void router.navigate([`${APP_NAV_ITEMS.account.route}/${data.search}`]);
} else {
void router.navigate([`${APP_NAV_ITEMS.hash.route}/${data.search}`]);
Expand Down Expand Up @@ -47,4 +48,8 @@ export class SearchService {
isValidBlock(block: string): boolean {
return block && block.length === 64;
}

isValidBNSDomain(bns: string): boolean {
return this._utilService.isValidBNSDomain(bns);
}
}
6 changes: 6 additions & 0 deletions src/app/services/util/util.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,10 @@ export class UtilService {
shortenAddress(addr: string): string {
return `${addr.substr(0, 12)}...${addr.substr(addr.length - 6, addr.length)}`;
}

isValidBNSDomain(bns: string): boolean {
const parts = bns.split('.');
//later, can also check for illegal characters once that is more settled
return parts.length === 2 && parts[0].length <= 32;
}
}
5 changes: 5 additions & 0 deletions src/app/types/dto/BNSDomainDto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Domain } from 'banani-bns';

export type BNSDomainDto = {
domain: Domain;
};
2 changes: 2 additions & 0 deletions src/app/types/dto/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from './AccountOverviewDto';
export * from './AliasDto';
export * from './BlockDto';
export * from './BlockAtHeightDto';
export * from './BNSDomainDto';
export * from './ConfirmedTransactionDto';
export * from './DelegatorDto';
export * from './DiscordResponseDto';
Expand All @@ -14,6 +15,7 @@ export * from './HostNodeStatsDto';
export * from './InsightsDto';
export * from './KnownAccountDto';
export * from './NakamotoCoefficientDto';
export * from './BNSDomainDto';
export * from './QuorumCoefficientDto';
export * from './MonitoredRepDto';
export * from './PeerVersionsDto';
Expand Down
8 changes: 4 additions & 4 deletions src/environments/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
export const environment = {
production: false,
brpd: false,
// api1: 'http://localhost:3001/banano',
// api2: 'http://localhost:3001/banano',
api1: 'https://api.spyglass.pw/banano',
api2: 'https://api.creeper.banano.cc/banano',
api1: 'http://localhost:3001/banano',
api2: 'http://localhost:3001/banano',
// api1: 'https://api.spyglass.pw/banano',
// api2: 'https://api.creeper.banano.cc/banano',
};
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"target": "es2020",
"module": "es2020",
"lib": [
"es2018",
"es2020",
"dom"
]
},
Expand Down
40 changes: 40 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2554,6 +2554,11 @@ axios@^0.21.1:
dependencies:
follow-redirects "^1.14.0"

b4a@^1.0.1:
version "1.6.7"
resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.7.tgz#a99587d4ebbfbd5a6e3b21bdb5d5fa385767abe4"
integrity sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==

babel-loader@8.2.5:
version "8.2.5"
resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz"
Expand Down Expand Up @@ -2611,6 +2616,20 @@ balanced-match@^1.0.0:
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==

banani-bns@^0.0.9:
version "0.0.9"
resolved "https://registry.yarnpkg.com/banani-bns/-/banani-bns-0.0.9.tgz#30eea4c94fbc3f1c9cf6e0282731c7a3edc3d550"
integrity sha512-G9eRXk24ykHLqSCr2LgqNHyUvuzye0VTpNMZdyD4/8HtZRU05Pv1Dbk1lbINkz0ZVf1Y2Jl6dF0ivXMLWBqIRA==
dependencies:
banani "^1.0.4"

banani@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/banani/-/banani-1.0.4.tgz#62a9102e70cefdbdb7826b0e66dca33ea8a64943"
integrity sha512-/W5cedmDLcrQ9T/Y17Yrk82t1EtJPf3sH14JAzgoHWgqsza2QC0YQallIOc51sY/WxEdnqLSSSoNk9hFkcd3og==
dependencies:
blake2b "^2.1.4"

banano-unit-converter@^0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/banano-unit-converter/-/banano-unit-converter-0.1.0.tgz"
Expand Down Expand Up @@ -2652,6 +2671,22 @@ bl@^4.1.0:
inherits "^2.0.4"
readable-stream "^3.4.0"

blake2b-wasm@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz#9115649111edbbd87eb24ce7c04b427e4e2be5be"
integrity sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==
dependencies:
b4a "^1.0.1"
nanoassert "^2.0.0"

blake2b@^2.1.4:
version "2.1.4"
resolved "https://registry.yarnpkg.com/blake2b/-/blake2b-2.1.4.tgz#817d278526ddb4cd673bfb1af16d1ad61e393ba3"
integrity sha512-AyBuuJNI64gIvwx13qiICz6H6hpmjvYS5DGkG6jbXMOT8Z3WUJ3V1X0FlhIoT1b/5JtHE3ki+xjtMvu1nn+t9A==
dependencies:
blake2b-wasm "^2.4.0"
nanoassert "^2.0.0"

body-parser@1.20.0, body-parser@^1.19.0:
version "1.20.0"
resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz"
Expand Down Expand Up @@ -5878,6 +5913,11 @@ mute-stream@0.0.8:
resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz"
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==

nanoassert@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/nanoassert/-/nanoassert-2.0.0.tgz#a05f86de6c7a51618038a620f88878ed1e490c09"
integrity sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==

nanoid@^3.3.3, nanoid@^3.3.4:
version "3.3.4"
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz"
Expand Down

0 comments on commit 693bc20

Please sign in to comment.