diff --git a/packages/insight/src/app/app.scss b/packages/insight/src/app/app.scss index d2e5fa6a7c8..e3f5e7c4ce1 100644 --- a/packages/insight/src/app/app.scss +++ b/packages/insight/src/app/app.scss @@ -108,3 +108,12 @@ a.disabled-link{ color: #99a; pointer-events: none; } + +.no-txs { + background-color: #fcf8e3; + border: 1px solid #faebcc; + color: #8a6d3b; + border-radius: 3px; + margin: 5px; + padding: 5px; +} diff --git a/packages/insight/src/assets/img/currency_logos/eth.svg b/packages/insight/src/assets/img/currency_logos/eth.svg new file mode 100644 index 00000000000..09d4ac80a6c --- /dev/null +++ b/packages/insight/src/assets/img/currency_logos/eth.svg @@ -0,0 +1,8 @@ + + + Currency/Large/Ethereum + + + + + \ No newline at end of file diff --git a/packages/insight/src/assets/img/ethicon.svg b/packages/insight/src/assets/img/ethicon.svg new file mode 100644 index 00000000000..40e7d28df77 --- /dev/null +++ b/packages/insight/src/assets/img/ethicon.svg @@ -0,0 +1,13 @@ + + + + Artboard + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/packages/insight/src/components/block-summary-eth/block-summary-eth.html b/packages/insight/src/components/block-summary-eth/block-summary-eth.html new file mode 100644 index 00000000000..a110863e26f --- /dev/null +++ b/packages/insight/src/components/block-summary-eth/block-summary-eth.html @@ -0,0 +1,18 @@ + + Total Difficulty + + {{ block.totalDifficulty }} + + + + Gas Limit + + {{ block.gasLimit }} + + + + Gas Used + + {{ block.gasUsed }} + + \ No newline at end of file diff --git a/packages/insight/src/components/block-summary-eth/block-summary-eth.module.ts b/packages/insight/src/components/block-summary-eth/block-summary-eth.module.ts new file mode 100644 index 00000000000..27dbb8061d7 --- /dev/null +++ b/packages/insight/src/components/block-summary-eth/block-summary-eth.module.ts @@ -0,0 +1,10 @@ +import { NgModule } from '@angular/core'; +import { IonicModule } from 'ionic-angular'; +import { BlockSummaryEthComponent } from './block-summary-eth'; + +@NgModule({ + declarations: [BlockSummaryEthComponent], + imports: [IonicModule], + exports: [BlockSummaryEthComponent] +}) +export class BlockSummaryEthComponentModule {} diff --git a/packages/insight/src/components/block-summary-eth/block-summary-eth.scss b/packages/insight/src/components/block-summary-eth/block-summary-eth.scss new file mode 100644 index 00000000000..b051a665f26 --- /dev/null +++ b/packages/insight/src/components/block-summary-eth/block-summary-eth.scss @@ -0,0 +1,2 @@ +block-summary-eth { +} diff --git a/packages/insight/src/components/block-summary-eth/block-summary-eth.ts b/packages/insight/src/components/block-summary-eth/block-summary-eth.ts new file mode 100644 index 00000000000..1afd3a66431 --- /dev/null +++ b/packages/insight/src/components/block-summary-eth/block-summary-eth.ts @@ -0,0 +1,25 @@ +import { Component, Input } from '@angular/core'; +import { ChainNetwork } from '../../providers/api/api'; +import { CurrencyProvider } from '../../providers/currency/currency'; + +/** + * Generated class for the BlockSummaryEthComponent component. + * + * See https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html + * for more info on Angular Components. + */ +@Component({ + selector: 'block-summary-eth', + templateUrl: 'block-summary-eth.html' +}) +export class BlockSummaryEthComponent { + @Input() + public block: any = {}; + @Input() + public chainNetwork: ChainNetwork; + + constructor( + public currencyProvider: CurrencyProvider + ) { + } +} diff --git a/packages/insight/src/components/block-summary/block-summary.html b/packages/insight/src/components/block-summary/block-summary.html new file mode 100644 index 00000000000..97b883eb0f6 --- /dev/null +++ b/packages/insight/src/components/block-summary/block-summary.html @@ -0,0 +1,18 @@ + + Merkle Root + + {{ block.merkleroot }} + + + + Bits + + {{ block.bits }} + + + + Version + + {{ block.version }} + + \ No newline at end of file diff --git a/packages/insight/src/components/block-summary/block-summary.module.ts b/packages/insight/src/components/block-summary/block-summary.module.ts new file mode 100644 index 00000000000..8655fec917e --- /dev/null +++ b/packages/insight/src/components/block-summary/block-summary.module.ts @@ -0,0 +1,10 @@ +import { NgModule } from '@angular/core'; +import { IonicModule } from 'ionic-angular'; +import { BlockSummaryComponent } from './block-summary'; + +@NgModule({ + declarations: [BlockSummaryComponent], + imports: [IonicModule], + exports: [BlockSummaryComponent] +}) +export class BlockSummaryComponentModule {} diff --git a/packages/insight/src/components/block-summary/block-summary.scss b/packages/insight/src/components/block-summary/block-summary.scss new file mode 100644 index 00000000000..a993f4b7691 --- /dev/null +++ b/packages/insight/src/components/block-summary/block-summary.scss @@ -0,0 +1,2 @@ +block-summary { +} diff --git a/packages/insight/src/components/block-summary/block-summary.ts b/packages/insight/src/components/block-summary/block-summary.ts new file mode 100644 index 00000000000..9f37ca9190a --- /dev/null +++ b/packages/insight/src/components/block-summary/block-summary.ts @@ -0,0 +1,25 @@ +import { Component, Input } from '@angular/core'; +import { ChainNetwork } from '../../providers/api/api'; +import { CurrencyProvider } from '../../providers/currency/currency'; + +/** + * Generated class for the BlockSummaryComponent component. + * + * See https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html + * for more info on Angular Components. + */ +@Component({ + selector: 'block-summary', + templateUrl: 'block-summary.html' +}) +export class BlockSummaryComponent { + @Input() + public block: any = {}; + @Input() + public chainNetwork: ChainNetwork; + + constructor( + public currencyProvider: CurrencyProvider + ) { + } +} diff --git a/packages/insight/src/components/coin-list/coin-list.html b/packages/insight/src/components/coin-list/coin-list.html index 29a46800272..d68491d95eb 100644 --- a/packages/insight/src/components/coin-list/coin-list.html +++ b/packages/insight/src/components/coin-list/coin-list.html @@ -4,7 +4,8 @@ - + + diff --git a/packages/insight/src/components/coin-list/coin-list.module.ts b/packages/insight/src/components/coin-list/coin-list.module.ts index 5ed7e3420e2..105a07a4b08 100644 --- a/packages/insight/src/components/coin-list/coin-list.module.ts +++ b/packages/insight/src/components/coin-list/coin-list.module.ts @@ -1,12 +1,13 @@ import { NgModule } from '@angular/core'; import { IonicModule } from 'ionic-angular'; +import { TransactionDetailsEthComponentModule } from '../../components/transaction-details-eth/transaction-details-eth.module'; import { CoinComponentModule } from '../coin/coin.module'; import { LoaderComponentModule } from '../loader/loader.module'; import { CoinListComponent } from './coin-list'; @NgModule({ declarations: [CoinListComponent], - imports: [IonicModule, CoinComponentModule, LoaderComponentModule], + imports: [IonicModule, CoinComponentModule,TransactionDetailsEthComponentModule, LoaderComponentModule], exports: [CoinListComponent] }) export class CoinListComponentModule {} diff --git a/packages/insight/src/components/coin-list/coin-list.scss b/packages/insight/src/components/coin-list/coin-list.scss index d62450d4c1a..d485f4f55f1 100644 --- a/packages/insight/src/components/coin-list/coin-list.scss +++ b/packages/insight/src/components/coin-list/coin-list.scss @@ -1,10 +1,3 @@ coin-list { - .no-txs { - background-color: #fcf8e3; - border: 1px solid #faebcc; - color: #8a6d3b; - border-radius: 3px; - margin: 5px; - padding: 5px; - } + } diff --git a/packages/insight/src/components/coin-list/coin-list.ts b/packages/insight/src/components/coin-list/coin-list.ts index 5271e1407dd..7d0ea8ce872 100644 --- a/packages/insight/src/components/coin-list/coin-list.ts +++ b/packages/insight/src/components/coin-list/coin-list.ts @@ -3,7 +3,6 @@ import { Events } from 'ionic-angular'; import _ from 'lodash'; import { AddressProvider } from '../../providers/address/address'; import { ChainNetwork } from '../../providers/api/api'; -import { Logger } from '../../providers/logger/logger'; import { TxsProvider } from '../../providers/transactions/transactions'; @Component({ @@ -34,8 +33,9 @@ export class CoinListComponent implements OnInit { this.loading = true; this.addrProvider.getAddressActivity(this.addrStr).subscribe( data => { - const formattedData = data.map(this.txsProvider.toAppCoin); - this.txs = this.processData(formattedData); + const toAppCoin: any = this.chainNetwork.chain !== 'ETH' ? this.txsProvider.toAppCoin: this.txsProvider.toAppEthCoin; + const formattedData = data.map(toAppCoin); + this.txs = this.chainNetwork.chain !== 'ETH' ? this.processData(formattedData): formattedData; this.showTransactions = true; this.loading = false; this.events.publish('CoinList', { length: data.length }); diff --git a/packages/insight/src/components/coin/coin.html b/packages/insight/src/components/coin/coin.html index 60661a1b646..3db5ea9a06d 100644 --- a/packages/insight/src/components/coin/coin.html +++ b/packages/insight/src/components/coin/coin.html @@ -28,7 +28,7 @@ - {{ currencyProvider.getConvertedNumber(coin.value) | number:'1.0-8' }} + {{ currencyProvider.getConvertedNumber(coin.value, chainNetwork.chain) | number:'1.0-8' }} {{ currencyProvider.currencySymbol }} @@ -70,7 +70,7 @@ - - {{ currencyProvider.getConvertedNumber(coin.value) | number:'1.0-8' }} + - {{ currencyProvider.getConvertedNumber(coin.value, chainNetwork.chain) | number:'1.0-8' }} {{ currencyProvider.currencySymbol }} diff --git a/packages/insight/src/components/coin/coin.ts b/packages/insight/src/components/coin/coin.ts index 0e1c07dc57c..66bb9a4a42f 100644 --- a/packages/insight/src/components/coin/coin.ts +++ b/packages/insight/src/components/coin/coin.ts @@ -25,7 +25,9 @@ export class CoinComponent { // tslint:disable-next-line:use-life-cycle-interface ngAfterViewInit() { + if (this.chainNetwork.chain !== 'ETH') { this.getConfirmations(); + } } public getConfirmations() { diff --git a/packages/insight/src/components/components.module.ts b/packages/insight/src/components/components.module.ts index 4e7a58d5fb5..c9936ea10d1 100644 --- a/packages/insight/src/components/components.module.ts +++ b/packages/insight/src/components/components.module.ts @@ -1,9 +1,10 @@ import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { IonicModule } from 'ionic-angular'; +import { SplitPipe } from '../pipes/split/split'; @NgModule({ - declarations: [], + declarations: [SplitPipe], imports: [FormsModule, IonicModule, ReactiveFormsModule], exports: [], entryComponents: [], diff --git a/packages/insight/src/components/footer/footer.html b/packages/insight/src/components/footer/footer.html index 5adf5d7cc2b..6c257ff4418 100644 --- a/packages/insight/src/components/footer/footer.html +++ b/packages/insight/src/components/footer/footer.html @@ -6,7 +6,7 @@ Verify Message
- + v8.1.0 diff --git a/packages/insight/src/components/footer/footer.ts b/packages/insight/src/components/footer/footer.ts index 83f1136dbd2..565ce6c1ff4 100644 --- a/packages/insight/src/components/footer/footer.ts +++ b/packages/insight/src/components/footer/footer.ts @@ -9,7 +9,7 @@ import { ChainNetwork } from '../../providers/api/api'; }) export class FooterComponent { @Input() - private chainNetwork: ChainNetwork; + public chainNetwork: ChainNetwork; constructor(public nav: Nav) {} diff --git a/packages/insight/src/components/head-nav/head-nav.html b/packages/insight/src/components/head-nav/head-nav.html index fe8b5b4d759..9b5db75b402 100644 --- a/packages/insight/src/components/head-nav/head-nav.html +++ b/packages/insight/src/components/head-nav/head-nav.html @@ -5,14 +5,14 @@ -
- {{ currencyProvider.getConvertedNumber(vin.value) | number:'1.0-8' }} {{ currencyProvider.currencySymbol }} + {{ currencyProvider.getConvertedNumber(vin.value, chainNetwork.chain) | number:'1.0-8' }} {{ currencyProvider.currencySymbol }} +
+ + + + @@ -127,7 +135,7 @@
- {{ currencyProvider.getConvertedNumber(vout.value) | number:'1.0-8' }} {{ currencyProvider.currencySymbol }} + {{ currencyProvider.getConvertedNumber(vout.value, chainNetwork.chain) | number:'1.0-8' }} {{ currencyProvider.currencySymbol }} (S) (U)
@@ -137,6 +145,16 @@ + + +
+
+

+ {{ tx.to }} +

+
+
+
@@ -146,7 +164,7 @@
Fee - {{ currencyProvider.getConvertedNumber(tx.fee) | number:'1.0-8' }} + {{ currencyProvider.getConvertedNumber(tx.fee, chainNetwork.chain) | number:'1.0-8' }} {{ currencyProvider.currencySymbol }} @@ -167,7 +185,7 @@ - {{ currencyProvider.getConvertedNumber(tx.valueOut) | number:'1.0-8' }} + {{ currencyProvider.getConvertedNumber(tx.valueOut, chainNetwork.chain) | number:'1.0-8' }} {{ currencyProvider.currencySymbol }} diff --git a/packages/insight/src/components/transaction-details/transaction-details.module.ts b/packages/insight/src/components/transaction-details/transaction-details.module.ts new file mode 100644 index 00000000000..362b6e3e78d --- /dev/null +++ b/packages/insight/src/components/transaction-details/transaction-details.module.ts @@ -0,0 +1,10 @@ +import { NgModule } from '@angular/core'; +import { IonicModule } from 'ionic-angular'; +import { TransactionDetailsComponent } from './transaction-details'; + +@NgModule({ + declarations: [TransactionDetailsComponent], + imports: [IonicModule], + exports: [TransactionDetailsComponent] +}) +export class TransactionDetailsComponentModule {} diff --git a/packages/insight/src/components/transaction/transaction.scss b/packages/insight/src/components/transaction-details/transaction-details.scss similarity index 98% rename from packages/insight/src/components/transaction/transaction.scss rename to packages/insight/src/components/transaction-details/transaction-details.scss index 8b8b551a20d..ff5874c89f3 100644 --- a/packages/insight/src/components/transaction/transaction.scss +++ b/packages/insight/src/components/transaction-details/transaction-details.scss @@ -1,4 +1,4 @@ -transaction { +transaction-details { // TODO Customize the grid to have 13 columns so that we have 6-col inputs, 6-col outputs, 1 col arrow // See http://ionicframework.com/docs/api/components/grid/Grid/#customizing-the-grid diff --git a/packages/insight/src/components/transaction/transaction.ts b/packages/insight/src/components/transaction-details/transaction-details.ts similarity index 92% rename from packages/insight/src/components/transaction/transaction.ts rename to packages/insight/src/components/transaction-details/transaction-details.ts index e1a27a3a332..c084bc281ab 100644 --- a/packages/insight/src/components/transaction/transaction.ts +++ b/packages/insight/src/components/transaction-details/transaction-details.ts @@ -9,16 +9,16 @@ import { } from '../../providers/transactions/transactions'; /** - * Generated class for the TransactionComponent component. + * Generated class for the TransactionDetailsComponent component. * * See https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html * for more info on Angular Components. */ @Component({ - selector: 'transaction', - templateUrl: 'transaction.html' + selector: 'transaction-details', + templateUrl: 'transaction-details.html' }) -export class TransactionComponent implements OnInit { +export class TransactionDetailsComponent implements OnInit { public expanded = false; @Input() public tx: any = {}; @@ -36,10 +36,13 @@ export class TransactionComponent implements OnInit { public txProvider: TxsProvider, public redirProvider: RedirProvider, public blocksProvider: BlocksProvider - ) {} + ) { + } public ngOnInit(): void { - this.showCoins ? this.getCoins() : this.getConfirmations(); + if (this.chainNetwork.chain !== 'ETH') { + this.showCoins ? this.getCoins() : this.getConfirmations(); + } } public getCoins(): void { diff --git a/packages/insight/src/components/transaction-list/transaction-list.html b/packages/insight/src/components/transaction-list/transaction-list.html index 6a403f07f8e..567cc82ec3e 100644 --- a/packages/insight/src/components/transaction-list/transaction-list.html +++ b/packages/insight/src/components/transaction-list/transaction-list.html @@ -4,7 +4,7 @@ - + @@ -12,5 +12,10 @@ + + + There are no transactions involving this block. + +
\ No newline at end of file diff --git a/packages/insight/src/components/transaction-list/transaction-list.module.ts b/packages/insight/src/components/transaction-list/transaction-list.module.ts index 78d6b09f1ac..4797bcd1c9a 100644 --- a/packages/insight/src/components/transaction-list/transaction-list.module.ts +++ b/packages/insight/src/components/transaction-list/transaction-list.module.ts @@ -1,12 +1,13 @@ import { NgModule } from '@angular/core'; import { IonicModule } from 'ionic-angular'; import { LoaderComponentModule } from '../loader/loader.module'; -import { TransactionComponentModule } from '../transaction/transaction.module'; +import { TransactionDetailsEthComponentModule } from '../transaction-details-eth/transaction-details-eth.module'; +import { TransactionDetailsComponentModule } from '../transaction-details/transaction-details.module'; import { TransactionListComponent } from './transaction-list'; @NgModule({ declarations: [TransactionListComponent], - imports: [IonicModule, TransactionComponentModule, LoaderComponentModule], + imports: [IonicModule, TransactionDetailsEthComponentModule, TransactionDetailsComponentModule, LoaderComponentModule], exports: [TransactionListComponent] }) export class TransactionListComponentModule {} diff --git a/packages/insight/src/components/transaction-list/transaction-list.ts b/packages/insight/src/components/transaction-list/transaction-list.ts index 89ddae2a051..375b22bb002 100644 --- a/packages/insight/src/components/transaction-list/transaction-list.ts +++ b/packages/insight/src/components/transaction-list/transaction-list.ts @@ -1,9 +1,8 @@ import { Component, Input, OnInit } from '@angular/core'; -import { TxsProvider } from '../../providers/transactions/transactions'; +import { ChainNetwork } from '../../providers/api/api'; +import { ApiEthTx, ApiUtxoCoinTx, TxsProvider } from '../../providers/transactions/transactions'; import * as _ from 'lodash'; -import { ApiProvider, ChainNetwork } from '../../providers/api/api'; - @Component({ selector: 'transaction-list', templateUrl: 'transaction-list.html' @@ -28,9 +27,16 @@ export class TransactionListComponent implements OnInit { this.txProvider .getTxs(this.chainNetwork, { [this.queryType]: this.queryValue }) .subscribe( - response => { + response => { // Newly Generated Coins (Coinbase) First - const txs = response.map(tx => this.txProvider.toAppTx(tx)); + const txs = response.map((tx: ApiEthTx & ApiUtxoCoinTx) => { + if(this.chainNetwork.chain === "BTC" || this.chainNetwork.chain === "BCH") { + return this.txProvider.toUtxoCoinsAppTx(tx) + } + if(this.chainNetwork.chain === "ETH") { + return this.txProvider.toEthAppTx(tx) + } + }); const sortedTxs = _.sortBy(txs, (tx: any) => { return tx.isCoinBase ? 0 : 1; }); diff --git a/packages/insight/src/components/transaction-summary-eth/transaction-summary-eth.html b/packages/insight/src/components/transaction-summary-eth/transaction-summary-eth.html new file mode 100644 index 00000000000..5c189756e29 --- /dev/null +++ b/packages/insight/src/components/transaction-summary-eth/transaction-summary-eth.html @@ -0,0 +1,31 @@ + + Gas Limit + + {{ tx.gasLimit }} + + + + Gas Price + + {{ currencyProvider.getConvertedNumber(tx.gasPrice, chainNetwork.chain) | number:'1.0-8' }} + {{ currencyProvider.currencySymbol }} + + + + From + + {{ tx.from }} + + + + To + + {{ tx.to }} + + + + Mined Time + + {{ tx.blocktime * 1000 | date:'long' }} + + \ No newline at end of file diff --git a/packages/insight/src/components/transaction-summary-eth/transaction-summary-eth.module.ts b/packages/insight/src/components/transaction-summary-eth/transaction-summary-eth.module.ts new file mode 100644 index 00000000000..9f5bcbf54f0 --- /dev/null +++ b/packages/insight/src/components/transaction-summary-eth/transaction-summary-eth.module.ts @@ -0,0 +1,10 @@ +import { NgModule } from '@angular/core'; +import { IonicModule } from 'ionic-angular'; +import { TransactionSummaryEthComponent } from './transaction-summary-eth'; + +@NgModule({ + declarations: [TransactionSummaryEthComponent], + imports: [IonicModule], + exports: [TransactionSummaryEthComponent] +}) +export class TransactionSummaryEthComponentModule {} diff --git a/packages/insight/src/components/transaction-summary-eth/transaction-summary-eth.scss b/packages/insight/src/components/transaction-summary-eth/transaction-summary-eth.scss new file mode 100644 index 00000000000..2be1a2b20de --- /dev/null +++ b/packages/insight/src/components/transaction-summary-eth/transaction-summary-eth.scss @@ -0,0 +1,2 @@ +transaction-summary-eth { +} diff --git a/packages/insight/src/components/transaction-summary-eth/transaction-summary-eth.ts b/packages/insight/src/components/transaction-summary-eth/transaction-summary-eth.ts new file mode 100644 index 00000000000..5898a82757b --- /dev/null +++ b/packages/insight/src/components/transaction-summary-eth/transaction-summary-eth.ts @@ -0,0 +1,25 @@ +import { Component, Input } from '@angular/core'; +import { ChainNetwork } from '../../providers/api/api'; +import { CurrencyProvider } from '../../providers/currency/currency'; + +/** + * Generated class for the TransactionSummaryEthComponent component. + * + * See https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html + * for more info on Angular Components. + */ +@Component({ + selector: 'transaction-summary-eth', + templateUrl: 'transaction-summary-eth.html' +}) +export class TransactionSummaryEthComponent { + @Input() + public tx: any = {}; + @Input() + public chainNetwork: ChainNetwork; + + constructor( + public currencyProvider: CurrencyProvider + ) { + } +} diff --git a/packages/insight/src/components/transaction-summary/transaction-summary.html b/packages/insight/src/components/transaction-summary/transaction-summary.html new file mode 100644 index 00000000000..67d8325d895 --- /dev/null +++ b/packages/insight/src/components/transaction-summary/transaction-summary.html @@ -0,0 +1,12 @@ + + Size + + {{ tx.size }} (bytes) + + + + Fee Rate + + {{ (tx.fee / tx.size) | number:'1.0-2' }} sats/byte + + \ No newline at end of file diff --git a/packages/insight/src/components/transaction-summary/transaction-summary.module.ts b/packages/insight/src/components/transaction-summary/transaction-summary.module.ts new file mode 100644 index 00000000000..df5b8986421 --- /dev/null +++ b/packages/insight/src/components/transaction-summary/transaction-summary.module.ts @@ -0,0 +1,10 @@ +import { NgModule } from '@angular/core'; +import { IonicModule } from 'ionic-angular'; +import { TransactionSummaryComponent } from './transaction-summary'; + +@NgModule({ + declarations: [TransactionSummaryComponent], + imports: [IonicModule], + exports: [TransactionSummaryComponent] +}) +export class TransactionSummaryComponentModule {} diff --git a/packages/insight/src/components/transaction-summary/transaction-summary.scss b/packages/insight/src/components/transaction-summary/transaction-summary.scss new file mode 100644 index 00000000000..6758cb3a8be --- /dev/null +++ b/packages/insight/src/components/transaction-summary/transaction-summary.scss @@ -0,0 +1,2 @@ +transaction-summary { +} diff --git a/packages/insight/src/components/transaction-summary/transaction-summary.ts b/packages/insight/src/components/transaction-summary/transaction-summary.ts new file mode 100644 index 00000000000..5e4034fb981 --- /dev/null +++ b/packages/insight/src/components/transaction-summary/transaction-summary.ts @@ -0,0 +1,25 @@ +import { Component, Input } from '@angular/core'; +import { ChainNetwork } from '../../providers/api/api'; +import { CurrencyProvider } from '../../providers/currency/currency'; + +/** + * Generated class for the TransactionSummaryComponent component. + * + * See https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html + * for more info on Angular Components. + */ +@Component({ + selector: 'transaction-summary', + templateUrl: 'transaction-summary.html' +}) +export class TransactionSummaryComponent { + @Input() + public tx: any = {}; + @Input() + public chainNetwork: ChainNetwork; + + constructor( + public currencyProvider: CurrencyProvider + ) { + } +} diff --git a/packages/insight/src/components/transaction/transaction.module.ts b/packages/insight/src/components/transaction/transaction.module.ts deleted file mode 100644 index 7da3ba0ef03..00000000000 --- a/packages/insight/src/components/transaction/transaction.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { NgModule } from '@angular/core'; -import { IonicModule } from 'ionic-angular'; -import { SplitPipe } from '../../pipes/split/split'; -import { TransactionComponent } from './transaction'; - -@NgModule({ - declarations: [TransactionComponent, SplitPipe], - imports: [IonicModule], - exports: [TransactionComponent] -}) -export class TransactionComponentModule {} diff --git a/packages/insight/src/pages/address/address.html b/packages/insight/src/pages/address/address.html index 0ca5a5486bc..8a25087aa38 100644 --- a/packages/insight/src/pages/address/address.html +++ b/packages/insight/src/pages/address/address.html @@ -10,7 +10,7 @@
-

Address {{ getConvertedNumber(address.balance) | number:'1.0-8' }} +

Address {{ getConvertedNumber(address.balance, chainNetwork.chain) | number:'1.0-8' }} {{ currencyProvider.currencySymbol }}

{{ address.addrStr }}

diff --git a/packages/insight/src/pages/transaction/transaction.module.ts b/packages/insight/src/pages/transaction/transaction.module.ts index 84c066ab80c..61b8c4d7f15 100644 --- a/packages/insight/src/pages/transaction/transaction.module.ts +++ b/packages/insight/src/pages/transaction/transaction.module.ts @@ -4,7 +4,10 @@ import { ErrorComponentModule } from '../../components/error/error.module'; import { FooterComponentModule } from '../../components/footer/footer.module'; import { HeadNavComponentModule } from '../../components/head-nav/head-nav.module'; import { LoaderComponentModule } from '../../components/loader/loader.module'; -import { TransactionComponentModule } from '../../components/transaction/transaction.module'; +import { TransactionDetailsEthComponentModule } from '../../components/transaction-details-eth/transaction-details-eth.module'; +import { TransactionDetailsComponentModule } from '../../components/transaction-details/transaction-details.module'; +import { TransactionSummaryEthComponentModule } from '../../components/transaction-summary-eth/transaction-summary-eth.module'; +import { TransactionSummaryComponentModule } from '../../components/transaction-summary/transaction-summary.module'; import { CopyToClipboardModule } from '../../directives/copy-to-clipboard/copy-to-clipboard.module'; import { TransactionPage } from './transaction'; @@ -12,7 +15,10 @@ import { TransactionPage } from './transaction'; declarations: [TransactionPage], imports: [ IonicPageModule.forChild(TransactionPage), - TransactionComponentModule, + TransactionSummaryEthComponentModule, + TransactionSummaryComponentModule, + TransactionDetailsComponentModule, + TransactionDetailsEthComponentModule, FooterComponentModule, HeadNavComponentModule, LoaderComponentModule, diff --git a/packages/insight/src/pages/transaction/transaction.ts b/packages/insight/src/pages/transaction/transaction.ts index 6540ef1cc11..a0c915d077e 100644 --- a/packages/insight/src/pages/transaction/transaction.ts +++ b/packages/insight/src/pages/transaction/transaction.ts @@ -23,9 +23,9 @@ export class TransactionPage { public fromVout: boolean; public confirmations: number; public errorMessage: string; + public chainNetwork: ChainNetwork; private txId: string; - private chainNetwork: ChainNetwork; constructor( public navParams: NavParams, @@ -53,8 +53,15 @@ export class TransactionPage { public ionViewDidEnter(): void { this.txProvider.getTx(this.txId, this.chainNetwork).subscribe( - data => { - this.tx = this.txProvider.toAppTx(data); + response => { + let tx; + if(this.chainNetwork.chain === "BTC" || this.chainNetwork.chain === "BCH") { + tx = this.txProvider.toUtxoCoinsAppTx(response); + } + if(this.chainNetwork.chain === "ETH") { + tx = this.txProvider.toEthAppTx(response); + } + this.tx = tx; this.loading = false; this.txProvider .getConfirmations(this.tx.blockheight, this.chainNetwork) diff --git a/packages/insight/src/providers/address/address.ts b/packages/insight/src/providers/address/address.ts index 584853a5106..fa167d9d488 100644 --- a/packages/insight/src/providers/address/address.ts +++ b/packages/insight/src/providers/address/address.ts @@ -4,7 +4,7 @@ import { Observable } from 'rxjs'; import { ApiProvider, ChainNetwork } from '../../providers/api/api'; import { CurrencyProvider } from '../../providers/currency/currency'; import { BlocksProvider } from '../blocks/blocks'; -import { ApiCoin, TxsProvider } from '../transactions/transactions'; +import { ApiCoin, ApiEthCoin, TxsProvider } from '../transactions/transactions'; export interface ApiAddr { confirmed: number; @@ -33,8 +33,8 @@ export class AddressProvider { ); } - public getAddressActivity(addrStr?: string): Observable { - return this.httpClient.get( + public getAddressActivity(addrStr?: string): Observable { + return this.httpClient.get( `${this.apiProvider.getUrl()}/address/${addrStr}/txs?limit=1000` ); } diff --git a/packages/insight/src/providers/api/api.ts b/packages/insight/src/providers/api/api.ts index 5afe9ad24b9..4f633a4d941 100644 --- a/packages/insight/src/providers/api/api.ts +++ b/packages/insight/src/providers/api/api.ts @@ -28,7 +28,8 @@ export class ApiProvider { public ratesAPI = { btc: 'https://bitpay.com/api/rates', - bch: 'https://bitpay.com/api/rates/bch' + bch: 'https://bitpay.com/api/rates/bch', + eth: 'https://bitpay.com/api/rates/eth' }; constructor( diff --git a/packages/insight/src/providers/blocks/blocks.ts b/packages/insight/src/providers/blocks/blocks.ts index b460022fa42..9c068d0e8c0 100644 --- a/packages/insight/src/providers/blocks/blocks.ts +++ b/packages/insight/src/providers/blocks/blocks.ts @@ -7,30 +7,36 @@ import { CurrencyProvider } from '../../providers/currency/currency'; export interface ApiBlock { height: number; nonce: number; - bits: number; size: number; confirmations: number; hash: string; - merkleRoot: string; nextBlockHash: string; previousBlockHash: string; transactionCount: number; reward: number; minedBy: string; - version: number; time: Date; timeNormalized: Date; } +export interface ApiUtxoCoinBlock extends ApiBlock { + difficulty: number; + merkleRoot: string; + bits: number; + version: number; +} + +export interface ApiEthBlock extends ApiBlock { + difficulty: number; + totalDifficulty: number; + gasUsed: number; + gasLimit: number; +} export interface AppBlock { height: number; - merkleroot: string; nonce: number; size: number; confirmations: number; - version: number; - difficulty: number; - bits: string; virtualSize: number; hash: string; time: number; @@ -47,26 +53,44 @@ export interface AppBlock { reward: number; } +export interface AppUtxoCoinBlock extends AppBlock { + difficulty: number; + merkleroot: string; + bits: string; + version: number; +} + +export interface AppEthBlock extends AppBlock { + difficulty: number; + totalDifficulty: number; + gasUsed: number; + gasLimit: number; +} + @Injectable() export class BlocksProvider { constructor( public httpClient: HttpClient, public currency: CurrencyProvider, private api: ApiProvider - ) {} + ) { } - public toAppBlock(block: ApiBlock): AppBlock { + public toEthAppBlock(block: ApiEthBlock): AppEthBlock { + return { ...this.toAppBlock(block), gasLimit: block.gasLimit, gasUsed: block.gasUsed, difficulty: block.difficulty, totalDifficulty: block.totalDifficulty}; + } + + public toUtxoCoinAppBlock(block: ApiUtxoCoinBlock): AppUtxoCoinBlock { const difficulty: number = 0x1d00ffff / block.bits; + return { ...this.toAppBlock(block), merkleroot: block.merkleRoot, version: block.version, bits: block.bits.toString(16), difficulty}; + } + + public toAppBlock(block: ApiBlock): AppBlock { return { height: block.height, confirmations: block.confirmations, nonce: block.nonce, size: block.size, virtualSize: block.size, - merkleroot: block.merkleRoot, - version: block.version, - difficulty, - bits: block.bits.toString(16), hash: block.hash, time: new Date(block.time).getTime() / 1000, tx: { @@ -83,21 +107,21 @@ export class BlocksProvider { }; } - public getCurrentHeight(chainNetwork: ChainNetwork): Observable { + public getCurrentHeight(chainNetwork: ChainNetwork): Observable { const heightUrl = `${this.api.getUrlPrefix()}/${chainNetwork.chain}/${ chainNetwork.network - }/block/tip`; - return this.httpClient.get(heightUrl); + }/block/tip`; + return this.httpClient.get(heightUrl); } public getBlocks( chainNetwork: ChainNetwork, numBlocks: number = 10 - ): Observable { + ): Observable { const url = `${this.api.getUrlPrefix()}/${chainNetwork.chain}/${ chainNetwork.network - }/block?limit=${numBlocks}`; - return this.httpClient.get(url); + }/block?limit=${numBlocks}`; + return this.httpClient.get(url); } /** @@ -107,20 +131,20 @@ export class BlocksProvider { since: number, numBlocks: number = 10, chainNetwork: ChainNetwork - ): Observable { + ): Observable { const url = `${this.api.getUrlPrefix()}/${chainNetwork.chain}/${ chainNetwork.network - }/block?since=${since}&limit=${numBlocks}&paging=height&direction=-1`; - return this.httpClient.get(url); + }/block?since=${since}&limit=${numBlocks}&paging=height&direction=-1`; + return this.httpClient.get(url); } public getBlock( hash: string, chainNetwork: ChainNetwork - ): Observable { + ): Observable { const url = `${this.api.getUrlPrefix()}/${chainNetwork.chain}/${ chainNetwork.network - }/block/${hash}`; - return this.httpClient.get(url); + }/block/${hash}`; + return this.httpClient.get(url); } } diff --git a/packages/insight/src/providers/currency/currency.ts b/packages/insight/src/providers/currency/currency.ts index 7c7e3e018ca..a39c68854d6 100644 --- a/packages/insight/src/providers/currency/currency.ts +++ b/packages/insight/src/providers/currency/currency.ts @@ -35,13 +35,20 @@ export class CurrencyProvider { return this.currencySymbol; } - public getConvertedNumber(value: number): number { + public getConvertedNumber(value: number, chain): number { // TODO: Change this function to make use of satoshis so that we don't have to do all these roundabout conversions. - value = value * 1e-8; + switch (chain) { + case 'ETH': + value = value * 1e-18; + break; + default: + value = value * 1e-8; + break; + } if (value === 0.0) { return 0; } - + let response: number; if (this.currencySymbol === 'USD') { diff --git a/packages/insight/src/providers/price/price.ts b/packages/insight/src/providers/price/price.ts index 2df6f723053..4ddb51275b6 100644 --- a/packages/insight/src/providers/price/price.ts +++ b/packages/insight/src/providers/price/price.ts @@ -20,10 +20,18 @@ export class PriceProvider { } if (currency === 'USD') { - const ratesAPI = - this.api.getConfig().chain === 'BTC' - ? this.api.ratesAPI.btc - : this.api.ratesAPI.bch; + let ratesAPI; + switch (this.api.getConfig().chain) { + case 'BTC': + ratesAPI = this.api.ratesAPI.btc; + break; + case 'BCH': + ratesAPI = this.api.ratesAPI.bch; + break; + case 'ETH': + ratesAPI = this.api.ratesAPI.eth; + break; + } this.api.httpClient.get(ratesAPI).subscribe( (data: any) => { const currencyParsed: any = data; diff --git a/packages/insight/src/providers/search/search.ts b/packages/insight/src/providers/search/search.ts index 652bf493afb..d8d0cd9ac58 100644 --- a/packages/insight/src/providers/search/search.ts +++ b/packages/insight/src/providers/search/search.ts @@ -1,7 +1,5 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import * as bitcoreLib from 'bitcore-lib'; -import * as bitcoreLibCash from 'bitcore-lib-cash'; import * as _ from 'lodash'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -9,7 +7,6 @@ import { ApiProvider, ChainNetwork } from '../api/api'; @Injectable() export class SearchProvider { - private config: ChainNetwork; private apiURL: string; constructor( @@ -37,6 +34,14 @@ export class SearchProvider { } } + public isInputValid(inputValue, chainNetwork) { + return this.httpClient + .get<{isValid: boolean, type: string}>(`${this.apiProvider.getUrlPrefix()}/${chainNetwork.chain}/${ + chainNetwork.network + }/valid/${inputValue}`) + .pipe(map(res => ({ isValid: res.isValid , type: res.type}))); + } + private searchBlock(block: string): Observable<{ block: any }> { return this.httpClient .get<{ block: any }>(`${this.apiURL}/block/${block}`) @@ -53,66 +58,6 @@ export class SearchProvider { .get<{ addr: any }>(`${this.apiURL}/address/${address}`) .pipe(map(res => ({ addr: res }))); } - - public isInputValid(inputValue) { - if (this.isValidBlockOrTx(inputValue)) { - return { isValid: true, type: 'blockOrTx' }; - } else if (this.isValidAddress(inputValue)) { - return { isValid: true, type: 'addr' }; - } else if (this.isValidBlockIndex(inputValue)) { - return { isValid: true, type: 'blockOrTx' }; - } else { - return { isValid: false, type: 'invalid' }; - } - } - - private isValidBlockOrTx(inputValue): boolean { - const regexp = /^[0-9a-fA-F]{64}$/; - if (regexp.test(inputValue)) { - return true; - } else { - return false; - } - } - - private isValidAddress(inputValue): boolean { - this.config = this.apiProvider.getConfig(); - const coin = this.config.chain; - const network = this.config.network; - const addr = this.extractAddress(inputValue); - if (addr.charAt(0) === 'C' || addr.charAt(0) === 'H') { - return false; - } else if (coin.toLowerCase() === 'btc' && network === 'mainnet') { - return this.isValidBitcoinMainnetAddress(addr); - } else if (coin.toLowerCase() === 'btc' && network === 'testnet') { - return this.isValidBitcoinTestnetAddress(addr); - } else if (coin.toLowerCase() === 'bch' && network === 'mainnet') { - return ( - this.isValidBitcoinCashMainnetAddress(addr) || - this.isValidBitcoinCashLegacyMainnetAddress(addr) - ); - } - } - - private isValidBitcoinMainnetAddress(data: string): boolean { - return !!bitcoreLib.Address.isValid(data, 'mainnet'); - } - private isValidBitcoinTestnetAddress(data: string): boolean { - return !!bitcoreLib.Address.isValid(data, 'testnet'); - } - - private isValidBitcoinCashLegacyMainnetAddress(data: string): boolean { - return !!bitcoreLib.Address.isValid(data, 'mainnet'); - } - - private isValidBitcoinCashMainnetAddress(data: string): boolean { - return !!bitcoreLibCash.Address.isValid(data, 'mainnet'); - } - - private isValidBlockIndex(inputValue): boolean { - return isFinite(inputValue); - } - private extractAddress(address: string): string { const extractedAddress = address .replace(/^(bitcoincash:|bchtest:|bitcoin:)/i, '') diff --git a/packages/insight/src/providers/transactions/transactions.ts b/packages/insight/src/providers/transactions/transactions.ts index bf80ad1d282..8e70a821613 100644 --- a/packages/insight/src/providers/transactions/transactions.ts +++ b/packages/insight/src/providers/transactions/transactions.ts @@ -9,6 +9,7 @@ interface CoinsApiResponse { inputs: ApiCoin[]; outputs: ApiCoin[]; } + export interface ApiTx { address: string; chain: string; @@ -22,16 +23,29 @@ export interface ApiTx { size: number; confirmations: number; locktime: number; - inputs: ApiCoin[]; - outputs: ApiCoin[]; mintTxid: string; mintHeight: number; spentTxid: string; spentHeight: number; value: number; +} + +export interface ApiUtxoCoinTx extends ApiTx { + inputs: ApiCoin[]; + outputs: ApiCoin[]; version: number; } +export interface ApiEthTx extends ApiTx { + gasLimit: number; + gasPrice: number; + internal: any[]; + nonce: number; + to: string; + from: string; + fee: number; +} + export interface ApiCoin { txid: string; mintTxid: string; @@ -48,6 +62,23 @@ export interface ApiCoin { value: number; } +export interface ApiEthCoin { + blockHash: string; + blockHeight: string; + blockTime: string; + blockTimeNormalized: string; + chain: string; + fee: number; + from: string; + gasLimit: number; + gasPrice: number; + network: string; + nonce: string; + to: string; + txid:string; + value: number; +} + export interface AppCoin { txid: string; valueOut: number; @@ -58,6 +89,14 @@ export interface AppCoin { spentHeight: number; } +export interface AppEthCoin { + to: string, + from: string, + txid: string, + fee: number, + valueOut: number, +} + export interface AppInput { coinbase: boolean; sequence: number; @@ -96,11 +135,8 @@ export interface AppOutput { export interface AppTx { txid: string; blockhash: string; - version: number; locktime: number; isCoinBase: boolean; - vin: any[]; - vout: any[]; confirmations: number; time: number; valueOut: number; @@ -110,6 +146,19 @@ export interface AppTx { blocktime: number; } +export interface AppUtxoCoinsTx extends AppTx { + vin: any[]; + vout: any[]; + version: number; +} + +export interface AppEthTx extends AppTx { + gasLimit: number; + gasPrice: number; + to: string; + from: string; +} + @Injectable() export class TxsProvider { constructor( @@ -117,9 +166,9 @@ export class TxsProvider { public currency: CurrencyProvider, public blocksProvider: BlocksProvider, private apiProvider: ApiProvider - ) {} + ) { } - public getFee(tx: AppTx): number { + public getFee(tx: AppUtxoCoinsTx): number { const sumSatoshis: any = (arr: any): number => arr.reduce((prev, cur) => prev + cur.value, 0); const inputs: number = sumSatoshis(tx.vin); @@ -128,7 +177,20 @@ export class TxsProvider { return fee; } - public toAppTx(tx: ApiTx): AppTx { + public toEthAppTx(tx: ApiEthTx): AppEthTx { + return { ...this.toAppTx(tx), to: tx.to, from: tx.from, gasLimit: tx.gasLimit, gasPrice: tx.gasPrice }; + } + + public toUtxoCoinsAppTx(tx: ApiUtxoCoinTx): AppUtxoCoinsTx { + return { + ...this.toAppTx(tx), + vin: [], // populated when coins are retrieved + vout: [], // populated when coins are retrieved + version: tx.version + }; + } + + public toAppTx(tx: ApiUtxoCoinTx | ApiEthTx): AppTx { return { txid: tx.txid, fee: null, // calculated later, when coins are retrieved @@ -140,10 +202,17 @@ export class TxsProvider { isCoinBase: tx.coinbase, size: tx.size, locktime: tx.locktime, - vin: [], // populated when coins are retrieved - vout: [], // populated when coins are retrieved - valueOut: tx.value, - version: tx.version + valueOut: tx.value + }; + } + + public toAppEthCoin(coin: ApiEthCoin): AppEthCoin { + return { + to: coin.to, + from: coin.from, + txid: coin.txid, + fee: coin.fee, + valueOut: coin.value, }; } @@ -162,22 +231,22 @@ export class TxsProvider { public getTxs( chainNetwork: ChainNetwork, args?: { blockHash?: string } - ): Observable { + ): Observable { let queryString = ''; if (args.blockHash) { queryString += `?blockHash=${args.blockHash}`; } const url = `${this.apiProvider.getUrlPrefix()}/${chainNetwork.chain}/${ chainNetwork.network - }/tx/${queryString}`; - return this.httpClient.get(url); + }/tx/${queryString}`; + return this.httpClient.get(url); } - public getTx(hash: string, chainNetwork: ChainNetwork): Observable { + public getTx(hash: string, chainNetwork: ChainNetwork): Observable { const url = `${this.apiProvider.getUrlPrefix()}/${chainNetwork.chain}/${ chainNetwork.network - }/tx/${hash}`; - return this.httpClient.get(url); + }/tx/${hash}`; + return this.httpClient.get(url); } public getCoins( @@ -186,7 +255,7 @@ export class TxsProvider { ): Observable { const url = `${this.apiProvider.getUrlPrefix()}/${chainNetwork.chain}/${ chainNetwork.network - }/tx/${txId}/coins`; + }/tx/${txId}/coins`; return this.httpClient.get(url); }