From 238250f35d6e1a5492a392d48eb5da984ada3138 Mon Sep 17 00:00:00 2001 From: Alex Barnsley <8069294+alexbarnsley@users.noreply.github.com> Date: Wed, 22 Sep 2021 10:21:12 +0100 Subject: [PATCH] refactor: core v3 upgrades (#705) --- .github/workflows/test.yml | 20 ------ config.xml | 5 +- package-lock.json | 22 ++++++- package.json | 7 ++- src/app/app.module.ts | 2 + .../custom-network-create.ts | 13 ++-- src/app/models/market.ts | 6 +- src/app/services/ark-api/ark-api.ts | 8 +-- src/app/services/neo-api/neo-api.ts | 2 +- src/app/utils/ark-client.ts | 30 ++++++--- src/app/utils/ark-http-client.ts | 61 +++++++++++++++++++ src/app/utils/ark-peer-discovery.ts | 16 ++--- 12 files changed, 137 insertions(+), 55 deletions(-) create mode 100644 src/app/utils/ark-http-client.ts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index deeeea21c..4bd28f73d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,23 +29,3 @@ jobs: run: npm run build -- --prod - name: Codecov run: ./node_modules/.bin/codecov --token=${{ secrets.CODECOV_TOKEN }} - - e2e: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [12.x] - - steps: - - uses: actions/checkout@v1 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - name: Install - run: npm install --ignore-scripts - - name: Pre Test - run: npx webdriver-manager update --versions.chrome=85.0.4183.83 - - name: Test - run: npm run test:e2e -- --prod --webdriver-update false diff --git a/config.xml b/config.xml index a498ed79f..c822636ec 100644 --- a/config.xml +++ b/config.xml @@ -1,5 +1,5 @@ <?xml version='1.0' encoding='utf-8'?> -<widget id="io.ark.wallet.mobile" version="1.8.6" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"> +<widget id="io.ark.wallet.mobile" version="1.9.2" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"> <name>Ark Mobile</name> <description>ARK</description> <author email="mobile@ark.io" href="http://ark.io/">Ark Ecosystem</author> @@ -30,6 +30,8 @@ <preference name="Orientation" value="portrait" /> <preference name="target-device" value="handset" /> <preference name="DisableDeploy" value="true" /> + <preference name="WKWebViewOnly" value="true" /> + <preference name="AndroidPersistentFileLocation" value="Compatibility" /> <platform name="android"> <edit-config file="AndroidManifest.xml" mode="merge" target="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android"> <application android:networkSecurityConfig="@xml/network_security_config" /> @@ -114,6 +116,7 @@ <splash height="2436" src="resources/ios/splash/Default-2436h.png" width="1125" /> <splash height="2732" src="resources/ios/splash/Default@2x~universal~anyany.png" width="2732" /> </platform> + <plugin name="cordova-plugin-advanced-http" spec="^3.2.0" /> <plugin name="cordova-plugin-whitelist" spec="1.3.3" /> <plugin name="cordova-plugin-statusbar" spec="2.4.2" /> <plugin name="cordova-plugin-device" spec="2.0.2" /> diff --git a/package-lock.json b/package-lock.json index 8acc6d4ee..e577a8455 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ark-mobile", - "version": "1.8.1", + "version": "1.9.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3445,6 +3445,21 @@ "@types/cordova": "^0.0.34" } }, + "@ionic-native/http": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@ionic-native/http/-/http-5.36.0.tgz", + "integrity": "sha512-3t7UhcqNxZuIX+HXuydlaDfA9AwDXiRFGs9GsHpJnXMTfbeKUcwzp0amqblrLslDA9tNfqSmJyFZFaMX6CRrog==", + "requires": { + "@types/cordova": "^0.0.34" + }, + "dependencies": { + "@types/cordova": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz", + "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=" + } + } + }, "@ionic-native/in-app-browser": { "version": "5.22.0", "resolved": "https://registry.npmjs.org/@ionic-native/in-app-browser/-/in-app-browser-5.22.0.tgz", @@ -9049,6 +9064,11 @@ } } }, + "cordova-plugin-advanced-http": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/cordova-plugin-advanced-http/-/cordova-plugin-advanced-http-3.2.1.tgz", + "integrity": "sha512-puQfmvGguo43Jf0dVtOjlNTpvdTA5NSCfnI+85LFzzcrZk/zpqawRQZbPS7c1A1Nmu+i+PWo3pP/YVOt586Ttw==" + }, "cordova-plugin-device": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/cordova-plugin-device/-/cordova-plugin-device-2.0.3.tgz", diff --git a/package.json b/package.json index 46bd86535..3e8b98aa5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ark-mobile", - "version": "1.8.6", + "version": "1.9.2", "author": "Ark Ecosystem <mobile@ark.io>", "homepage": "https://github.com/ArkEcosystem/mobile-wallet#readme", "scripts": { @@ -36,6 +36,7 @@ "@ionic-native/background-mode": "^5.22.0", "@ionic-native/clipboard": "^5.22.0", "@ionic-native/core": "^5.22.0", + "@ionic-native/http": "^5.36.0", "@ionic-native/in-app-browser": "^5.22.0", "@ionic-native/keyboard": "^5.22.0", "@ionic-native/local-notifications": "^5.22.0", @@ -63,6 +64,7 @@ "cordova-custom-config": "^5.1.0", "cordova-ios": "5.1.1", "cordova-plugin-add-swift-support": "^2.0.2", + "cordova-plugin-advanced-http": "^3.2.1", "cordova-plugin-device": "^2.0.3", "cordova-plugin-inappbrowser": "^3.2.0", "cordova-plugin-ionic": "^5.4.6", @@ -170,6 +172,9 @@ "cordova-plugin-ionic-webview": { "ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+" }, + "cordova-plugin-advanced-http": { + "ANDROIDBLACKLISTSECURESOCKETPROTOCOLS": "SSLv3,TLSv1" + }, "cordova-plugin-ionic-keyboard": {}, "cordova-plugin-ionic": { "APP_ID": "efb289f2", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index a1af03175..0ef585ea9 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -3,6 +3,7 @@ import { ErrorHandler, NgModule } from "@angular/core"; import { BrowserModule, HammerModule } from "@angular/platform-browser"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { RouteReuseStrategy } from "@angular/router"; +import { HTTP } from "@ionic-native/http/ngx"; import { Keyboard } from "@ionic-native/keyboard/ngx"; import { Network } from "@ionic-native/network/ngx"; import { QRScanner } from "@ionic-native/qr-scanner/ngx"; @@ -54,6 +55,7 @@ export function createTranslateLoader(http: HttpClient) { Network, ScreenOrientation, GlobalErrorHandlerService, + HTTP, { provide: UserDataService, useClass: UserDataServiceImpl }, { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, { provide: ErrorHandler, useClass: GlobalErrorHandlerService }, diff --git a/src/app/modals/custom-network-create/custom-network-create.ts b/src/app/modals/custom-network-create/custom-network-create.ts index f2ccaebe3..e6d18324a 100644 --- a/src/app/modals/custom-network-create/custom-network-create.ts +++ b/src/app/modals/custom-network-create/custom-network-create.ts @@ -1,13 +1,12 @@ -import { HttpClient } from "@angular/common/http"; import { Component } from "@angular/core"; import { LoadingController, ModalController } from "@ionic/angular"; import { Network, Peer } from "ark-ts"; -import lodash from "lodash"; import { finalize } from "rxjs/operators"; import { LoggerService } from "@/services/logger/logger.service"; import { ToastProvider } from "@/services/toast/toast"; import ArkClient from "@/utils/ark-client"; +import { HttpClient } from "@/utils/ark-http-client"; @Component({ selector: "customNetworkCreate", @@ -50,19 +49,15 @@ export class CustomNetworkCreateModal { this.network.version = response.version; this.network.type = null; - const apiConfig: any = lodash.find( - response.ports, - (_, key) => key.split("/").reverse()[0] === "core-api", - ); - if (!response.ports || !apiConfig) { + if (!response.ports || !seedServerUrl.port) { this.configureError(); return; } - this.network.apiPort = apiConfig; + this.network.apiPort = parseInt(seedServerUrl.port); this.network.activePeer = new Peer(); this.network.activePeer.ip = seedServerUrl.hostname; - this.network.activePeer.port = apiConfig; + this.network.activePeer.port = parseInt(seedServerUrl.port); if (seedServerUrl.protocol === "https:") { this.network.activePeer.port = 443; diff --git a/src/app/models/market.ts b/src/app/models/market.ts index 07a78f5cd..d7e497cd9 100644 --- a/src/app/models/market.ts +++ b/src/app/models/market.ts @@ -221,7 +221,11 @@ export class MarketHistory { getPriceByDate(currencyCode: string, date: Date): number { const timestampDate = date.setHours(0, 0, 0, 0); - return this.history[currencyCode.toUpperCase()][timestampDate]; + if (this.history[currencyCode.toUpperCase()]) { + return this.history[currencyCode.toUpperCase()][timestampDate]; + } + + return 0; } getLastWeekPrice(currencyCode: string): any { diff --git a/src/app/services/ark-api/ark-api.ts b/src/app/services/ark-api/ark-api.ts index 549768ef5..55e1a4bc6 100644 --- a/src/app/services/ark-api/ark-api.ts +++ b/src/app/services/ark-api/ark-api.ts @@ -1,4 +1,3 @@ -import { HttpClient } from "@angular/common/http"; import { Injectable } from "@angular/core"; import * as ArkCrypto from "@arkecosystem/crypto"; import * as arkts from "ark-ts"; @@ -25,11 +24,12 @@ import { FeeStatistic, StoredNetwork } from "@/models/stored-network"; import { StorageProvider } from "@/services/storage/storage"; import { ToastProvider } from "@/services/toast/toast"; import { UserDataService } from "@/services/user-data/user-data.interface"; +import ArkClient, { WalletResponse } from "@/utils/ark-client"; +import { HttpClient } from "@/utils/ark-http-client"; import { PeerDiscovery } from "@/utils/ark-peer-discovery"; +import { ArkUtility } from "@/utils/ark-utility"; import { SafeBigNumber as BigNumber } from "@/utils/bignumber"; -import ArkClient, { WalletResponse } from "../../utils/ark-client"; -import { ArkUtility } from "../../utils/ark-utility"; import { LoggerService } from "../logger/logger.service"; interface NodeFees { @@ -574,7 +574,7 @@ export class ArkApiProvider { return new Observable((observer) => { this.httpClient - .get(`${this._network.getPeerAPIUrl()}/api/v2/node/fees?days=7`) + .get(`${this._network.getPeerAPIUrl()}/api/node/fees?days=7`) .subscribe( (response: NodeFeesResponse) => { const data = response.data; diff --git a/src/app/services/neo-api/neo-api.ts b/src/app/services/neo-api/neo-api.ts index c819ea14a..b53adf421 100644 --- a/src/app/services/neo-api/neo-api.ts +++ b/src/app/services/neo-api/neo-api.ts @@ -1,9 +1,9 @@ -import { HttpClient } from "@angular/common/http"; import { Injectable } from "@angular/core"; import { Observable, of } from "rxjs"; import { map } from "rxjs/operators"; import { NetworkProvider } from "@/services/network/network"; +import { HttpClient } from "@/utils/ark-http-client"; @Injectable({ providedIn: "root" }) export class NeoApiProvider { diff --git a/src/app/utils/ark-client.ts b/src/app/utils/ark-client.ts index 00170474b..d8f1c05c8 100644 --- a/src/app/utils/ark-client.ts +++ b/src/app/utils/ark-client.ts @@ -1,4 +1,3 @@ -import { HttpClient } from "@angular/common/http"; import { AccountResponse, AccountVotesResponse, @@ -17,6 +16,7 @@ import { tap, timeout } from "rxjs/operators"; import { TRANSACTION_GROUPS } from "@/app/app.constants"; import { INodeConfiguration } from "@/models/node"; import { LoggerService } from "@/services/logger/logger.service"; +import { HttpClient } from "@/utils/ark-http-client"; export interface PeerApiResponse extends Peer { latency?: number; @@ -70,7 +70,8 @@ export default class ApiClient { const data = response.data; if (data.length) { - const lastVote = data[0].asset.votes[0]; + const lastVote = + data[0].asset.votes[data[0].asset.votes.length - 1]; if (lastVote.charAt(0) === "-") { observer.next({ @@ -80,9 +81,7 @@ export default class ApiClient { observer.complete(); } - const delegatePublicKey = data[0].asset.votes[0].substring( - 1, - ); + const delegatePublicKey = lastVote.substring(1); this.getDelegateByPublicKey( delegatePublicKey, ).subscribe( @@ -284,7 +283,24 @@ export default class ApiClient { observer.next(this.__formatDelegateResponse(data)); observer.complete(); }, - (error) => observer.error(error), + (error) => { + const response = + typeof error.error === "string" + ? JSON.parse(error.error) + : error.error; + if ( + response && + error.status === 404 && + response.message === "Delegate not found" + ) { + observer.next(null); + observer.complete(); + + return; + } + + observer.error(error); + }, ); }); } @@ -322,7 +338,7 @@ export default class ApiClient { ) { const url = `${host}/api/${path}`; return this.httpClient - .request("GET", url, { + .get(url, { ...options, headers: this.defaultHeaders, }) diff --git a/src/app/utils/ark-http-client.ts b/src/app/utils/ark-http-client.ts new file mode 100644 index 000000000..f39ab0eb8 --- /dev/null +++ b/src/app/utils/ark-http-client.ts @@ -0,0 +1,61 @@ +import { Injectable } from "@angular/core"; +import { HTTP } from "@ionic-native/http/ngx"; +import { from, Observable } from "rxjs"; +import { map } from "rxjs/operators"; + +@Injectable({ + providedIn: "root", +}) +export class HttpClient { + private defaultHeaders: any = { + "Content-Type": "application/json", + }; + + constructor(private http: HTTP) {} + + get<T>(url: string, options: any = {}): Observable<any> { + this.http.setDataSerializer("json"); + + return from( + this.http.get( + url, + {}, + { ...this.defaultHeaders, ...(options.headers || {}) }, + ), + ).pipe( + map(function (result): any { + return JSON.parse(result.data); + }), + ); + } + + post<T>(url: string, body: any = {}, options: any = {}): Observable<any> { + this.http.setDataSerializer("json"); + + return from( + this.http.post(url, body, { + ...this.defaultHeaders, + ...(options.headers || {}), + }), + ).pipe( + map(function (result): any { + return JSON.parse(result.data); + }), + ); + } + + put<T>(url: string, body: any = {}, options: any = {}): Observable<any> { + this.http.setDataSerializer("json"); + + return from( + this.http.put(url, body, { + ...this.defaultHeaders, + ...(options.headers || {}), + }), + ).pipe( + map(function (result): any { + return JSON.parse(result.data); + }), + ); + } +} diff --git a/src/app/utils/ark-peer-discovery.ts b/src/app/utils/ark-peer-discovery.ts index 79a897a46..30306c416 100644 --- a/src/app/utils/ark-peer-discovery.ts +++ b/src/app/utils/ark-peer-discovery.ts @@ -1,10 +1,10 @@ -import { HttpClient } from "@angular/common/http"; import isUrl from "is-url"; import orderBy from "lodash/orderBy"; import { Observable } from "rxjs/Observable"; import semver from "semver"; -import { PeerApiResponse } from "./ark-client"; +import { PeerApiResponse } from "@/utils/ark-client"; +import { HttpClient } from "@/utils/ark-http-client"; export class PeerDiscovery { private version: string | undefined; @@ -99,15 +99,11 @@ export class PeerDiscovery { ]; this.httpClient - .request( - "GET", - `http://${seed.ip}:${seed.port}/api/peers`, - { - headers: { - "API-Version": "2", - }, + .get(`http://${seed.ip}:${seed.port}/api/peers`, { + headers: { + "API-Version": "2", }, - ) + }) .subscribe( (body: any) => { let peers = body.data;