Compare commits

...

266 Commits
master ... next

Author SHA1 Message Date
Justin Langston
389e752096 Merge pull request #806 from SonicWizard/next
added proxy to pull data from proper url
2017-08-29 16:12:32 -04:00
Justin Langston
9e2a875027 Merge pull request #805 from tenthirtyone/next-merge
Next-merge API updates
2017-08-29 16:12:00 -04:00
tenthirtyone
2146ff290b index block on tx model 2017-08-28 12:49:46 -04:00
tenthirtyone
ee0d5595b3 move models into lib 2017-08-28 00:38:48 -04:00
tenthirtyone
1a18a369c1 Save logic moved to models. Parsers removed 2017-08-27 23:44:08 -04:00
tenthirtyone
b836390b22 remove sockets 2017-08-27 22:53:39 -04:00
tenthirtyone
56078e2487 move cors to middleware 2017-08-27 22:38:40 -04:00
tenthirtyone
5f7e2b7613 removed old audit code 2017-08-27 22:30:41 -04:00
tenthirtyone
4ba24bba25 input sanitization moved to middleware 2017-08-27 21:58:04 -04:00
tenthirtyone
e7fd05afe9 Merge remote-tracking branch 'upstream/next' into next-merge 2017-08-27 21:55:41 -04:00
tenthirtyone
cbcd42c096 remove tx.size until bcoin pr is merged 2017-08-27 21:53:42 -04:00
tenthirtyone
df2beddf16 Better input handling. Huge increase in performance and accuracy. 2017-08-25 17:27:15 -04:00
tenthirtyone
afc063fb97 sync & async saving. Bleh 2017-08-25 10:47:03 -04:00
Darren Nelsen
45a8c809a3 added proxy to pull data from proper url 2017-08-24 16:48:22 -04:00
tenthirtyone
12cb8a0c29 Graceful Shutdown for mongodb 2017-08-24 15:26:57 -04:00
tenthirtyone
333eec3dd8 Reset Bcoin chain if blocks are missing from mongo. 2017-08-24 14:42:50 -04:00
tenthirtyone
2ccaf2fce0 Reliably update inputs. Self-healing. Audit Mongo blockheights 2017-08-24 14:28:21 -04:00
tenthirtyone
a3941f75ef Update inputs 2017-08-23 23:25:36 -04:00
Jason Dreyzehner
fbfd9ecb34 Merge pull request #804 from SonicWizard/next
Completed Latest Transactions
2017-08-23 13:43:56 -04:00
Darren Nelsen
ccf681dda7 added input parm for refresh timer seconds on latest-transactions component 2017-08-23 11:42:38 -04:00
tenthirtyone
c560ae3cff fix bestHeight bug 2017-08-23 11:17:49 -04:00
Darren Nelsen
2ac2822257 removed console logs; added a seconds var for latest transactions refresh 2017-08-23 10:41:10 -04:00
Darren Nelsen
07cd0cbd8f added refresh timer to latest transactions; styled latest transactions grid 2017-08-22 17:17:13 -04:00
Justin Langston
421d0ef8f4 Merge pull request #801 from tenthirtyone/next-merge
Next merge
2017-08-22 15:50:21 -04:00
Darren Nelsen
9848b17fc1 added call to new txs endpoint; changed html to reflect txid and valueOut in transactions grid 2017-08-22 14:34:24 -04:00
Darren Nelsen
b9de71862d Merge branch 'next-merge' of https://github.com/tenthirtyone/insight into next 2017-08-22 14:11:10 -04:00
tenthirtyone
52ebe7dde0 bugfix, return array instead of object 2017-08-22 14:10:19 -04:00
Darren Nelsen
b21e11b8fb Merge branch 'next-merge' of https://github.com/tenthirtyone/insight into next 2017-08-22 13:44:36 -04:00
Darren Nelsen
8a1d8e6df2 pull in transactions from new endpoint 2017-08-22 13:30:01 -04:00
tenthirtyone
d86cdd3678 Fix /txs default return to return the properly transformed response 2017-08-22 10:34:55 -04:00
Darren Nelsen
201a3871a0 Merge branch 'next-merge' of https://github.com/tenthirtyone/insight into next 2017-08-22 10:15:24 -04:00
Darren Nelsen
c6b0e66a42 Merge branch 'next' of https://github.com/bitpay/insight into next 2017-08-22 10:08:50 -04:00
tenthirtyone
067592df50 helmet and static expires header 2017-08-22 01:44:51 -04:00
tenthirtyone
a9493190c2 fix max tx 2017-08-22 01:23:12 -04:00
tenthirtyone
479d55de4a check for findOne null 2017-08-22 01:17:44 -04:00
tenthirtyone
c2c51e709a more cleaning up 2017-08-22 00:29:10 -04:00
tenthirtyone
e5ad52f55d fixed search by addr checking for address. Eventually move these to middleware 2017-08-21 22:57:43 -04:00
tenthirtyone
98164e4447 paging added back. Going over max config limit will default to config limit and still support paging. 2017-08-21 22:53:04 -04:00
tenthirtyone
cae4a45572 Massive debug/dev code cleanup. Most db logic moved to models. 2017-08-21 22:38:20 -04:00
tenthirtyone
050f45015a cleaned up tx db. Moved logic to models. API next 2017-08-21 21:55:09 -04:00
tenthirtyone
efe19444d5 getTxById added to model 2017-08-21 21:08:41 -04:00
Darren Nelsen
743c060463 added ion-grid to latest-transactions component 2017-08-21 18:00:39 -04:00
tenthirtyone
801fbf62e8 Change FE to relative request paths. 2017-08-21 14:01:08 -04:00
tenthirtyone
e3d6ef0039 Merge remote-tracking branch 'upstream/next' into next-merge 2017-08-21 10:19:52 -04:00
Justin Langston
a66573dbc1 Merge pull request #800 from SonicWizard/next
Added Home page with latest blocks and latest transactions (placeholder)
2017-08-20 10:54:48 -04:00
tenthirtyone
37744ec85a mongo fixed up 2017-08-19 21:03:54 -04:00
tenthirtyone
968ab3c103 merge mongo changes 2017-08-19 20:59:37 -04:00
tenthirtyone
46842c9cc5 tx by address wired up 2017-08-19 04:07:09 -04:00
tenthirtyone
697388f1ce pre cleanup. Running entirely on mongo. 2017-08-19 03:15:17 -04:00
Darren Nelsen
d4d5e500d6 hide the "mined by" column when in "portrait" mode 2017-08-18 18:00:17 -04:00
Darren Nelsen
d5adf90a9b added input parms for latest-blocks component; replaced block grid on blocks page with latest-blocks component 2017-08-18 17:08:58 -04:00
Darren Nelsen
5e79d1d4f3 wrapped setInterval in ngZone to make e2e tests work properly 2017-08-18 15:59:57 -04:00
Justin Langston
9026a3d27f Merge pull request #799 from tenthirtyone/next-merge
Changes for next branch
2017-08-18 15:31:14 -04:00
Darren Nelsen
44e85f0dec added See All Blocks button to latest-blocks component; created new BlocksPage with ionic convention; deprecated previous BlocksPage; fixed e2e tests 2017-08-18 15:08:36 -04:00
tenthirtyone
14cb4e3332 clean up console log and fix return statements 2017-08-18 14:19:10 -04:00
tenthirtyone
8231ed6a1e clean up console log and fix return statements 2017-08-18 14:17:15 -04:00
Darren Nelsen
722eb21cfb Added interval to get latest blocks and styled latest blocks grid 2017-08-18 11:33:41 -04:00
tenthirtyone
805e5ec0c3 top n txs setup 2017-08-17 17:49:54 -04:00
tenthirtyone
9b7336b066 New models and parser up 2017-08-17 17:44:47 -04:00
tenthirtyone
d2f68fefe9 need new mongo models from another branch 2017-08-17 17:41:07 -04:00
Darren Nelsen
cdbc84e93a added loading spinner and links to block detail 2017-08-17 16:42:09 -04:00
tenthirtyone
898e373b77 Add util to other routes for input validation. 2017-08-17 16:28:30 -04:00
Darren Nelsen
f2196bc297 added angular2-moment library; added a BlocksProvider; added latest blocks grid to home page 2017-08-17 16:20:40 -04:00
Alex
3f7ad54b2e Merge pull request #1 from unusualbob/feature/txEndpointValidation
transaction.js validation
2017-08-17 15:20:09 -04:00
Alex
5d91e48afa Merge branch 'next-merge' into feature/txEndpointValidation 2017-08-17 15:19:50 -04:00
tenthirtyone
d148b5ec77 updated readme instructions 2017-08-17 15:17:23 -04:00
tenthirtyone
4b6482e0ad add scriptsigs to txs for circle-plus info on tx lists 2017-08-17 14:37:08 -04:00
Darren Nelsen
879b87f2a6 added LatestTransactions and LatestBlocks components with simple placeholders 2017-08-17 11:47:31 -04:00
tenthirtyone
5a89cf17d2 All routes replaced. Stable but no tx inputs working. 2017-08-17 11:25:58 -04:00
Darren Nelsen
e2c69203ec Fixed e2e tests 2017-08-17 11:03:08 -04:00
tenthirtyone
31eecc5afe reduced block model and parsing. 2017-08-17 00:44:50 -04:00
tenthirtyone
8d733df278 Tx Parsing and updating input values 2017-08-17 00:26:32 -04:00
tenthirtyone
a5d74393d1 tx size, tx parser, mongo replies for tx by hash 2017-08-16 23:07:06 -04:00
tenthirtyone
1b0c1b1250 Bringing back other parsers 2017-08-16 22:49:13 -04:00
tenthirtyone
3e7f263e18 bestBlockHeight set by node now. Less cb Hell. 2017-08-16 21:56:56 -04:00
tenthirtyone
1cb0a6b385 indexes and experimenting with mem db 2017-08-16 21:23:29 -04:00
Darren Nelsen
1f974e5176 styled the About section 2017-08-16 17:23:21 -04:00
Darren Nelsen
05503371cf add "powered by" icons 2017-08-16 16:51:09 -04:00
Darren Nelsen
0cbff08f59 added HomePage 2017-08-16 16:33:45 -04:00
Rob Riddle
1218726ffc This adds some basic regex validation on query parameters to harden against attacks and reduce time to error. Address validation could likely be improved beyond just regex, but this will do for now 2017-08-16 16:31:57 -04:00
tenthirtyone
2ac70bc9a2 Fixed Bcoin error returned as data, fixed dead /txs endpoint missing error, added ttl to bcoin requests but large addrs still take too long 2017-08-16 16:30:33 -04:00
Darren Nelsen
c817f5e62c update ionic-cli 2017-08-16 15:10:18 -04:00
Jason Dreyzehner
9a80486227 Merge pull request #798 from SonicWizard/ionic
Added Search toggle and loading spinners for pages and transaction component
2017-08-16 14:13:44 -04:00
tenthirtyone
c47f58f8e8 Clean up eslint complaints 2017-08-16 14:13:18 -04:00
tenthirtyone
e5b608809b Fix Coinbase in blocks and address. Remove console log from compiled js (removed from temp previousl) 2017-08-16 12:49:37 -04:00
Darren Nelsen
c9a1b6b153 added spinners to transaction and address pages and transaction list component 2017-08-16 12:46:08 -04:00
tenthirtyone
515884bf63 Fix isCoinBase typo and add comments 2017-08-16 12:39:12 -04:00
Darren Nelsen
90379522fe added spinner to block detail 2017-08-16 11:11:20 -04:00
tenthirtyone
958fc79204 Fix return val in transactions.js for bestBlockHeight 2017-08-16 10:40:50 -04:00
tenthirtyone
ad39b6337c comment updates 2017-08-16 02:02:19 -04:00
tenthirtyone
06b0e108d5 socket reworking to reduce coupling 2017-08-16 01:47:30 -04:00
tenthirtyone
2f4533e057 getBestHeight added to db api 2017-08-16 01:13:30 -04:00
tenthirtyone
3b8b900405 More cleanup, naming fixes and comments 2017-08-16 01:08:05 -04:00
tenthirtyone
e3b8413eee Moved db configs to config file. Dropped time from log files. Simple commenting 2017-08-16 00:52:11 -04:00
tenthirtyone
2eac46fdb5 transactions added to db api 2017-08-16 00:17:45 -04:00
tenthirtyone
1d029fcf7f getBlocks completely in db api 2017-08-16 00:00:52 -04:00
tenthirtyone
b0f95d93ab All API but tx & socket cleaned up, blocks db api done 2017-08-15 23:14:24 -04:00
tenthirtyone
ecee54c10b Address API cleaned up. Unnecessary db calls removed 2017-08-15 21:55:48 -04:00
tenthirtyone
d278dbdb7c Blocks DB API up 2017-08-15 21:29:59 -04:00
tenthirtyone
1777be323c Message verification and bitcore-message added 2017-08-15 20:29:38 -04:00
tenthirtyone
0c04a55fd0 use app 404 page and clean up console log 2017-08-15 20:15:01 -04:00
Darren Nelsen
7d2b27be7d added toggle to searchbar; made text selectable 2017-08-15 16:36:11 -04:00
tenthirtyone
afd68116e7 broadcast tx 2017-08-15 15:41:25 -04:00
Justin Langston
ec208e93ab Merge pull request #797 from SonicWizard/ionic
Updates and bug fixes to TransactionComponent
2017-08-15 14:36:01 -04:00
tenthirtyone
358662fb84 add tx paging and protections 2017-08-15 11:38:40 -04:00
Darren Nelsen
cf4d45cf59 fixed responsiveness in the transaction grid 2017-08-15 11:15:10 -04:00
tenthirtyone
6659148d4b fix bad txid 2017-08-15 10:59:40 -04:00
tenthirtyone
bf26304746 Remove index from txs. Explicit return and fix spent and received in addr. 2017-08-15 10:42:36 -04:00
tenthirtyone
a3e4e19a9d address summary finished 2017-08-15 04:37:53 -04:00
tenthirtyone
17acbdda6d messiest yet, bump confs by 1 2017-08-15 04:11:22 -04:00
tenthirtyone
2b8eee6e03 Confirmations wired up for blocks txs and addr views 2017-08-15 04:09:28 -04:00
tenthirtyone
dd0e0bedf0 update tx fees div 1e8 2017-08-15 03:19:21 -04:00
tenthirtyone
69538704f6 sync, status and last block hash finished 2017-08-15 03:12:23 -04:00
tenthirtyone
4b71ae91ae moved rpc settings to config. Little confusing as is. Needs improvement 2017-08-15 02:24:30 -04:00
tenthirtyone
b1e540c8df RPC hookups fill the gaps way better than mongo in some places. See changes 2017-08-15 02:00:04 -04:00
tenthirtyone
90adbf3ece remove Block from status 2017-08-14 22:10:00 -04:00
Darren Nelsen
0fe359bd1f get scriptSigs working again in expanded view 2017-08-14 18:44:57 -04:00
tenthirtyone
9045eacccd Fixed txs per request to only save block w/ subdocs 2017-08-14 17:58:12 -04:00
tenthirtyone
e210e34dbc Merge branch 'txs-by-address' into next-merge 2017-08-14 17:19:14 -04:00
tenthirtyone
5a78d523a8 Merge branch 'turn-off-tx-saving' into next-merge 2017-08-14 17:19:10 -04:00
Darren Nelsen
a554e43c07 Added aggregateItems 2017-08-14 17:01:19 -04:00
tenthirtyone
ba1333f84f PR review catches and cleanups 2017-08-14 02:02:28 -04:00
Justin Langston
5e1e80a858 Merge pull request #793 from SonicWizard/ionic
Update CurrencyProvider with USD. Enable denomination changes on all the things.
2017-08-12 08:57:53 -04:00
Darren Nelsen
34792d5d65 fixed bug where block detail did not retain data after leaving view and coming back 2017-08-11 17:29:29 -04:00
Justin Langston
5b919a6dc5 Merge pull request #790 from tenthirtyone/next
Merging last commits & clean up logs/readme
2017-08-11 11:52:45 -04:00
Darren Nelsen
2226a2cc18 fixed lint warnings and tests 2017-08-11 10:42:34 -04:00
Darren Nelsen
1dfe384271 added USD conversion; added conversion to address page 2017-08-11 10:33:44 -04:00
tenthirtyone
e27c7bcf87 Address page working. Address details stubbed 2017-08-11 00:18:03 -04:00
tenthirtyone
741a234c76 Removing saving from tx parser. Only use for emitting block txs for now. Increase tx socket delay 2017-08-10 23:41:59 -04:00
tenthirtyone
4ef0949061 returning data 2017-08-10 23:39:08 -04:00
tenthirtyone
4a0138b666 Remove console logs. Fix cors 2017-08-10 23:05:48 -04:00
tenthirtyone
68af224331 Merge remote-tracking branch '1031/master' into next 2017-08-10 21:07:28 -04:00
tenthirtyone
301e36b5c4 CORS added 2017-08-10 17:56:57 -04:00
tenthirtyone
46c9027bdb Fixed tx value out on home page 2017-08-10 17:56:21 -04:00
Jason Dreyzehner
0ffef469df chore: rm the old, in with the new 2017-08-10 17:53:53 -04:00
Darren Nelsen
8ba0a07772 fixed tslint issues 2017-08-10 17:48:48 -04:00
Darren Nelsen
3bc5959075 Added currency conversion to transaction component 2017-08-10 17:44:51 -04:00
Darren Nelsen
db5bf4420a fixed e2e tests by adding provider dependencies 2017-08-10 17:35:17 -04:00
Darren Nelsen
ac656802c9 fixed lint warnings; renamed action sheet title 2017-08-10 17:30:46 -04:00
Darren Nelsen
5a551a5e3b add currency conversion button and action sheet 2017-08-10 17:19:31 -04:00
Jason Dreyzehner
2d1f504a3f Add 'server/' from commit 'eb7e5d10c97aafa302dfd4e7fd67a6bc2938c0a1'
git-subtree-dir: server
git-subtree-mainline: f35d7dd960
git-subtree-split: eb7e5d10c9
2017-08-10 17:08:14 -04:00
Darren Nelsen
1fc35956cb style the summary items and labels 2017-08-10 16:12:06 -04:00
Jason Dreyzehner
f35d7dd960 Merge pull request #787 from SonicWizard/ionic
Add Address and Transaction pages; Refactor TransactionsComponent to TransactionListComponent
2017-08-10 15:05:11 -04:00
Darren Nelsen
4c3a28c780 added CurrencyProvider and associated spec 2017-08-10 14:39:35 -04:00
tenthirtyone
eb7e5d10c9 block & tx throttling through the sockets. Blocks emits every 10s. Tx every 100 tx 2017-08-10 14:20:13 -04:00
tenthirtyone
bdbb086e10 socket moved to api level and socket block refresh signal set to 5s 2017-08-10 13:29:35 -04:00
tenthirtyone
923128de59 Socket architecture change. More maleable/easier to wire up events with the node 2017-08-10 13:16:55 -04:00
tenthirtyone
22c2642653 Added insight ui to sub folder, build there move to top level public - hack. Wired Socket listener 2017-08-10 12:33:11 -04:00
tenthirtyone
8d70c017ed update readme, config defaults 2017-08-10 00:00:02 -04:00
tenthirtyone
83a9388e99 Set bcoin prefix to cwd and add chain.ldb to gitignore 2017-08-09 23:18:13 -04:00
Darren Nelsen
5667e0b12e fix ellipsis on vin.scriptSig 2017-08-09 17:15:32 -04:00
Darren Nelsen
f6c4ff0990 move ellipsis to wrapping (block level) elements 2017-08-09 17:01:57 -04:00
Darren Nelsen
60914a1358 add qrcode generator 2017-08-09 16:38:50 -04:00
Darren Nelsen
402006f835 move ellipsis to global styles 2017-08-09 15:29:04 -04:00
tenthirtyone
7f87a3a9d7 Updated readme 2017-08-09 00:02:21 -04:00
tenthirtyone
7beb1867d7 block limits added, currency fixed, FE routes added 2017-08-08 23:52:39 -04:00
Darren Nelsen
4473bfd5df added Split pipe 2017-08-08 17:37:40 -04:00
Darren Nelsen
7e55c1b6f8 add vin expanded values 2017-08-08 14:08:51 -04:00
Darren Nelsen
269bbfe549 add expand toggle; add expanded output attributes 2017-08-08 13:11:36 -04:00
tenthirtyone
0174fd5226 socket added but not wired up with front ent 2017-08-08 01:40:12 -04:00
tenthirtyone
1ad21a667c block txs partially wired up 2017-08-08 00:58:09 -04:00
tenthirtyone
8d676886de Insight Ui wired up 2017-08-07 23:57:20 -04:00
tenthirtyone
fc1284b374 sync mocked readme updated. 2017-08-07 22:09:56 -04:00
tenthirtyone
5bf176485b logging out inputs and outputs for parsing & attaching to addresses 2017-08-07 15:28:58 -04:00
tenthirtyone
1143bd803a Move tx subdocs into their own files 2017-08-07 10:34:04 -04:00
tenthirtyone
3efd16c6af Stubbing status, prepping txs for blockhash and addr 2017-08-07 09:13:36 -04:00
tenthirtyone
23d858f4b3 Uncoupled tx parsing from block parsing inside the bcoin node 2017-08-06 20:53:43 -04:00
tenthirtyone
f7bdf8d0a9 removed test 2017-08-06 20:51:13 -04:00
tenthirtyone
d7a70d5456 blocks & tx routes mostly complete updating models for need 2017-08-05 20:36:17 -04:00
tenthirtyone
7948a63875 curren api finished. parser json var names normalized. Switched to express 4 router 2017-08-05 15:03:48 -04:00
tenthirtyone
b74e98c381 fix txJSON naming. 2017-08-05 13:26:59 -04:00
tenthirtyone
a038159526 Models updated to match bcoin data 2017-08-05 02:13:36 -04:00
tenthirtyone
d9a9b64650 block model mirroring bcoin toJson. Indexes removed for dev work. 2017-08-05 00:58:03 -04:00
tenthirtyone
b13d8df2de Parsers moved to their own files, full node added to config. 2017-08-05 00:41:26 -04:00
Darren Nelsen
3b873f4841 put vins and vouts into ion-lists; add fee, confirmation, and value data 2017-08-04 17:41:29 -04:00
Darren Nelsen
b48ff0adfa replace grids with lists in summaries 2017-08-04 17:11:07 -04:00
Alex
434b077467 Merge pull request #1 from tj-bitpay/new_branch
first alteration and find
2017-08-04 17:02:39 -04:00
Thomas Bright
1d160803c3
first alteration and find 2017-08-04 16:59:58 -04:00
Darren Nelsen
abb65a4394 put block data in ion-list 2017-08-04 16:45:36 -04:00
Darren Nelsen
dfccb2ea72 started putting data items in ion-grid 2017-08-04 15:56:45 -04:00
tenthirtyone
6e70484362 Block API dried up and mostly complete. Blocks still needs date params support 2017-08-04 15:39:04 -04:00
tenthirtyone
7afbdb41b1 Block API made more dry, rawblocks added to model 2017-08-04 14:29:10 -04:00
Darren Nelsen
0c7bb4d1f6 Added HeadNavComponent to use on all pages 2017-08-04 14:04:20 -04:00
tenthirtyone
e5ab809026 House cleaning, var names, package.json updates, config modifications 2017-08-04 12:35:59 -04:00
Darren Nelsen
aac27ff520 add more fields to blocksPage; add link to block 2017-08-04 11:23:58 -04:00
tenthirtyone
045c53accb Handling Mongo connection errors and starting bcoin once the db connects 2017-08-04 10:53:00 -04:00
tenthirtyone
63f60d06eb README formatting 2017-08-04 10:32:17 -04:00
tenthirtyone
857d56aa74 fixed first install and startup problem from logs folder not being stored in git 2017-08-04 10:31:38 -04:00
tenthirtyone
0c6868564f Cleaned up Readme and moved json spaces to config 2017-08-04 00:45:02 -04:00
tenthirtyone
0bbf9119e2 Prettied require statements 2017-08-03 23:10:03 -04:00
tenthirtyone
591d904212 Route functions named. Node & Parsers moved to their own files 2017-08-03 22:52:58 -04:00
tenthirtyone
836a2c4457 Config renamed to index.js for implicit importing. Moved routes to their own files 2017-08-03 22:18:12 -04:00
tenthirtyone
a5528e49d8 db connection moved to index.js to be a little more explicit. Cleaned up some comments and console logs 2017-08-03 21:45:35 -04:00
Darren Nelsen
b274b363ff added search by block hash 2017-08-03 18:24:48 -04:00
tenthirtyone
43b23b80dc Transaction, Input and Output models are wired or stubbed. Tomorrow/Tonight I wire up the API 2017-08-03 18:08:04 -04:00
Darren Nelsen
c1523966f8 added transaction and address search to blocksPage 2017-08-03 17:58:11 -04:00
Darren Nelsen
8a0d065296 Added ApiProvider to test.ts in order to make tests pass 2017-08-03 16:26:49 -04:00
tenthirtyone
7d5cade288 Transactions syncing, inputs and outputs mocked up. Bcoin data for tx, inputs and outputs varies depending on the vanilla object vs the object.toJSON() method Bcoin attaches to its primitives. Will likely need to redress this as Bcoin changes but for now this is how we move forward. 2017-08-03 16:19:53 -04:00
Darren Nelsen
440a007915 Moved apiPrefix into api provider; put transaction list into ion-grid 2017-08-03 15:43:47 -04:00
tenthirtyone
ea7e7aae34 Processing tx, input and output. About to refactor tx models to fit insight 2017-08-03 15:21:07 -04:00
Darren Nelsen
9f3a5d2bc8 fix lint warnings 2017-08-03 12:17:51 -04:00
tenthirtyone
8c5f296980 Input/Output moved back inside Transaction model file 2017-08-03 11:52:23 -04:00
tenthirtyone
3bf0fe7328 Transaction Models and updated config requires 2017-08-03 11:42:24 -04:00
Darren Nelsen
263933efcd Add transaction component to transaction page to show transaction details 2017-08-03 11:27:06 -04:00
Darren Nelsen
b656fb55d5 Moved transaction code from transaction-list to transaction component 2017-08-03 11:17:36 -04:00
Darren Nelsen
736b85e9df replaced TransactionsComponent with TransactionListComponent; added TransactionComponent placeholder 2017-08-03 10:45:55 -04:00
Darren Nelsen
a0930bd71b update versions of ionic-cli, cordova plugin, and ionic-angular 2017-08-03 10:23:10 -04:00
Darren Nelsen
3f1332ffca rename transaction object to tx in transaction page 2017-08-03 10:20:19 -04:00
tenthirtyone
5d7957c5fb updated configs and added nginx note in readme 2017-08-03 03:22:06 -04:00
tenthirtyone
06b24d85b7 node start wired up 2017-08-03 03:13:55 -04:00
tenthirtyone
aaef1c7273 bcoin node moved to its own file 2017-08-03 03:08:11 -04:00
tenthirtyone
3ee90bdbef Reverted async await to promise. 2017-08-03 01:46:47 -04:00
tenthirtyone
ad5c2dae93 Added Readme. 2 command install 2017-08-02 18:36:01 -04:00
tenthirtyone
71a24237f2 Stubbed insight API
Server changed to API
cleaned up some console.log

Insight UI does not use the entire API. Those are high priority
2017-08-02 18:23:27 -04:00
tenthirtyone
ee160d9e7b Added Utils, db, and updated block schema 2017-08-02 17:02:01 -04:00
Darren Nelsen
290e53f697 Added transaction page 2017-08-02 16:28:54 -04:00
tenthirtyone
6b7496e0c7 changed mongo config stanza. 2017-08-02 15:42:34 -04:00
tenthirtyone
767fc7e98a Bcoin config moved to config file 2017-08-02 14:55:55 -04:00
tenthirtyone
b028dead40 Initial Commit
Changelog:
Setup & Foundation
- bcoin
- express
- mongo
- eslint
- logging

Status: Bcoin syncs over network, uses a local leveldb to store blocks and checkpoints. Block event saves data to mongo. Express endpoint for block hashes, stubbed to reply with blockhashes until mongo models are finalized.

ToDo:
Move config out of code
2017-08-02 14:51:06 -04:00
Darren Nelsen
866b45457d replace address page placeholders with real data 2017-08-02 14:26:41 -04:00
Darren Nelsen
22351df704 refactored TransactionsComponent to allow for passed in query types and values 2017-08-02 11:20:16 -04:00
Alex
09804961c7 Initial commit 2017-08-02 00:40:46 -04:00
Darren Nelsen
f02fd3c01f refactored TransactionsComponent to accept blockHash or address 2017-07-31 17:54:32 -04:00
Darren Nelsen
25a83b546b put address fields and placeholders in ion-grid 2017-07-31 16:08:31 -04:00
Darren Nelsen
07d7fb3537 added address page 2017-07-31 15:38:47 -04:00
Jason Dreyzehner
8852924a14 Merge pull request #782 from SonicWizard/ionic
Ionic updates; block height search and block detail
2017-07-29 01:18:11 -04:00
Darren Nelsen
583139ca2c display transactions with vins/vouts 2017-07-28 17:05:25 -04:00
Darren Nelsen
6f99a2f881 Added TransactionsComponent 2017-07-27 16:38:56 -04:00
Darren Nelsen
de09b9056d pipe timestamp; add poolInfo; add block reward denomination 2017-07-27 15:06:33 -04:00
Darren Nelsen
877c5cfbc7 update ionic 2017-07-27 15:05:20 -04:00
Darren Nelsen
0d7e4783e7 took out some console logs and removed unneeded method 2017-07-26 17:05:38 -04:00
Darren Nelsen
04c4a71f14 cleaned up tslint warnings 2017-07-26 16:52:34 -04:00
Darren Nelsen
ccc5f8868a add loading indication 2017-07-26 16:05:10 -04:00
Darren Nelsen
2bc629cac5 added previous and next block links 2017-07-26 15:31:16 -04:00
Darren Nelsen
a3071d5ec6 added more block data 2017-07-26 14:26:40 -04:00
Darren Nelsen
9cfef6b834 use dynamic link for blockHash in block detail page; retrieve block data 2017-07-26 14:17:02 -04:00
Darren Nelsen
013358a69c pass blockHash to block detail page 2017-07-25 15:59:47 -04:00
Darren Nelsen
a6ab615a96 added block detail page (placeholder) 2017-07-25 15:21:58 -04:00
Darren Nelsen
b5a76aee44 Added addr and block-index searches 2017-07-25 13:04:37 -04:00
Darren Nelsen
9334b13a0d enabled search in blocksPage; removed package-lock.json from source control 2017-07-25 10:00:51 -04:00
Darren Nelsen
b8df8bcec4 added search field that accepts input 2017-07-14 17:07:11 -04:00
Darren Nelsen
a2c650b2a0 updated ionic cli and associated dependencies 2017-07-14 17:03:56 -04:00
Darren Nelsen
2f3207babe added spy in test to ensure coverage, even though send is a stub for now 2017-07-14 15:58:53 -04:00
Darren Nelsen
cf1ea86f7d cleaned up two e2e warnings 2017-07-14 13:12:26 -04:00
Darren Nelsen
53c9d82bd1 added package-lock.json, and added mynode to gitignore 2017-07-14 13:03:45 -04:00
Darren Nelsen
615ffc59db Added form validation to broadcast transaction 2017-07-13 17:20:29 -04:00
Jason Dreyzehner
7d21c310b1 Merge pull request #781 from SonicWizard/ionic
Headers and placeholders
2017-07-12 14:19:51 -04:00
Darren Nelsen
130b7a7022 Updated broadcast test to check for existance of input field 2017-07-12 14:12:15 -04:00
Darren Nelsen
8abeb5eb8e Added placeholder text and fields for verify and broadcast pages 2017-07-11 16:38:38 -04:00
Darren Nelsen
e9881777b2 Added fields to verify message page 2017-07-11 16:01:44 -04:00
Darren Nelsen
8f27d671f3 Added headers to blocks page 2017-07-11 15:29:13 -04:00
Jason Dreyzehner
f1994947b9 fix ci: avoid GitHub download, rate limit 2017-07-11 11:57:32 -04:00
Jason Dreyzehner
0608159096 convenience script to open coverage 2017-07-11 10:57:13 -04:00
Jason Dreyzehner
e624721fe3 lint corrections 2017-07-11 10:50:43 -04:00
Jason Dreyzehner
57ec79a46a continue scaffolding, add blocksService 2017-07-07 16:46:53 -04:00
Jason Dreyzehner
d784be5d7e scaffold top-level pages 2017-07-05 14:36:31 -04:00
Jason Dreyzehner
60d9d546a2 update to latest deps 2017-07-05 12:34:18 -04:00
Jason Dreyzehner
a801427e99 add package-lock 2017-06-16 14:01:34 -04:00
Jason Dreyzehner
f1fafaadf2 scaffold blocks view 2017-06-16 14:00:24 -04:00
Jason Dreyzehner
8f295786bc add ionic config 2017-06-15 17:59:07 -04:00
Jason Dreyzehner
95388ad451 fix chrome addon config for Travis 2017-06-15 17:46:19 -04:00
Jason Dreyzehner
8688f2fc80 remove extraneous 'npm install' from Travis build 2017-06-15 17:19:40 -04:00
Jason Dreyzehner
c979260395 add MIT license 2017-06-15 17:15:01 -04:00
Jason Dreyzehner
db4319d8e2 init Travis, add insight-ui to build matrix 2017-06-15 17:12:24 -04:00
Jason Dreyzehner
adf9376590 clicker -> insight-ui 2017-06-15 17:10:50 -04:00
Jason Dreyzehner
ff9f4cdae2 fork lathonez/clicker at b2c7d6a 2017-06-13 15:48:52 -04:00
770 changed files with 182015 additions and 6140 deletions

View File

@ -1,3 +0,0 @@
{
"directory": "public/lib"
}

49
.gitignore vendored
View File

@ -1,49 +1,4 @@
# from https://github.com/github/gitignore/blob/master/Node.gitignore
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
*.swp
tags
pids
logs
results
build
node_modules node_modules
package-lock.json
# extras *.log
*.swp
*.swo
*~
.project
peerdb.json
npm-debug.log
.nodemonignore
.DS_Store .DS_Store
public/lib/*
!public/lib/zeroclipboard/ZeroClipboard.swf
db/txs/*
db/txs
db/testnet/txs/*
db/testnet/txs
db/blocks/*
db/blocks
db/testnet/blocks/*
db/testnet/blocks
public/js/angularjs-all.js
public/js/main.js
public/js/vendors.js
public/css/main.css
README.html
po/*
!po/*.po

View File

@ -1,43 +0,0 @@
{
"node": true, // Enable globals available when code is running inside of the NodeJS runtime environment.
"browser": true, // Standard browser globals e.g. `window`, `document`.
"esnext": true, // Allow ES.next specific features such as `const` and `let`.
"bitwise": false, // Prohibit bitwise operators (&, |, ^, etc.).
"camelcase": false, // Permit only camelcase for `var` and `object indexes`.
"curly": false, // Require {} for every new block or scope.
"eqeqeq": true, // Require triple equals i.e. `===`.
"immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`
"latedef": true, // Prohibit variable use before definition.
"newcap": true, // Require capitalization of all constructor functions e.g. `new F()`.
"noarg": true, // Prohibit use of `arguments.caller` and `arguments.callee`.
"quotmark": "single", // Define quotes to string values.
"regexp": true, // Prohibit `.` and `[^...]` in regular expressions.
"undef": true, // Require all non-global variables be declared before they are used.
"unused": true, // Warn unused variables.
"strict": true, // Require `use strict` pragma in every file.
"trailing": true, // Prohibit trailing whitespaces.
"smarttabs": false, // Suppresses warnings about mixed tabs and spaces
"globals": { // Globals variables.
"angular": true
},
"predef": [ // Extra globals.
"define",
"require",
"exports",
"module",
"describe",
"before",
"beforeEach",
"after",
"afterEach",
"it",
"inject",
"$",
"io",
"app",
"moment"
],
"indent": false, // Specify indentation spacing
"devel": true, // Allow development statements e.g. `console.log();`.
"noempty": true // Prohibit use of empty blocks.
}

View File

@ -1,39 +0,0 @@
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
*.swp
tags
pids
logs
results
build
node_modules
# extras
*.swp
*.swo
*~
.project
peerdb.json
npm-debug.log
.nodemonignore
.DS_Store
db/txs/*
db/txs
db/testnet/txs/*
db/testnet/txs
db/blocks/*
db/blocks
db/testnet/blocks/*
db/testnet/blocks
README.html
k*

6
.travis.yml Normal file
View File

@ -0,0 +1,6 @@
sudo: false
language: node_js
node_js:
- 8
after_success:
- yarn send-coverage

View File

@ -1,148 +0,0 @@
'use strict';
// var config = require('insight-config.json');
module.exports = function(grunt) {
//Load NPM tasks
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-css');
grunt.loadNpmTasks('grunt-markdown');
grunt.loadNpmTasks('grunt-macreload');
grunt.loadNpmTasks('grunt-angular-gettext');
grunt.loadNpmTasks('grunt-replace');
// Project Configuration
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
replace: {
dist: {
options: {
patterns: [
{
match: 'INSIGHT_API_PREFIX',
replacement: '<%= pkg.insightConfig.apiPrefix %>'
}
],
usePrefix: false
},
files: [
{src: ['public/src/templates/api.js'], dest: 'public/src/js/services/api.js'}
]
}
},
concat: {
options: {
process: function(src, filepath) {
if (filepath.substr(filepath.length - 2) === 'js') {
return '// Source: ' + filepath + '\n' +
src.replace(/(^|\n)[ \t]*('use strict'|"use strict");?\s*/g, '$1');
} else {
return src;
}
}
},
vendors: {
src: ['public/src/js/ios-imagefile-megapixel/megapix-image.js', 'public/lib/qrcode-generator/js/qrcode.js', 'public/src/js/jsqrcode/grid.js', 'public/src/js/jsqrcode/version.js', 'public/src/js/jsqrcode/detector.js', 'public/src/js/jsqrcode/formatinf.js', 'public/src/js/jsqrcode/errorlevel.js', 'public/src/js/jsqrcode/bitmat.js', 'public/src/js/jsqrcode/datablock.js', 'public/src/js/jsqrcode/bmparser.js', 'public/src/js/jsqrcode/datamask.js', 'public/src/js/jsqrcode/rsdecoder.js', 'public/src/js/jsqrcode/gf256poly.js', 'public/src/js/jsqrcode/gf256.js', 'public/src/js/jsqrcode/decoder.js', 'public/src/js/jsqrcode/qrcode.js', 'public/src/js/jsqrcode/findpat.js', 'public/src/js/jsqrcode/alignpat.js', 'public/src/js/jsqrcode/databr.js', 'public/lib/momentjs/min/moment.min.js', 'public/lib/moment/lang/es.js', 'public/lib/zeroclipboard/ZeroClipboard.min.js'],
dest: 'public/js/vendors.js'
},
angular: {
src: ['public/lib/angular/angular.min.js', 'public/lib/angular-resource/angular-resource.min.js', 'public/lib/angular-route/angular-route.min.js', 'public/lib/angular-qrcode/qrcode.js', 'public/lib/angular-animate/angular-animate.min.js', 'public/lib/angular-bootstrap/ui-bootstrap.js', 'public/lib/angular-bootstrap/ui-bootstrap-tpls.js', 'public/lib/angular-ui-utils/ui-utils.min.js', 'public/lib/ngprogress/build/ngProgress.min.js', 'public/lib/angular-gettext/dist/angular-gettext.min.js', 'public/lib/angular-moment/angular-moment.min.js'],
dest: 'public/js/angularjs-all.js'
},
main: {
src: ['public/src/js/app.js', 'public/src/js/controllers/*.js', 'public/src/js/services/*.js', 'public/src/js/directives.js', 'public/src/js/filters.js', 'public/src/js/config.js', 'public/src/js/init.js', 'public/src/js/translations.js'],
dest: 'public/js/main.js'
},
css: {
src: ['public/lib/bootstrap/dist/css/bootstrap.min.css', 'public/src/css/**/*.css'],
dest: 'public/css/main.css'
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= pkg.version %> */\n',
mangle: false
},
vendors: {
src: 'public/js/vendors.js',
dest: 'public/js/vendors.min.js'
},
angular: {
src: 'public/js/angularjs-all.js',
dest: 'public/js/angularjs-all.min.js'
},
main: {
src: 'public/js/main.js',
dest: 'public/js/main.min.js'
}
},
cssmin: {
css: {
src: 'public/css/main.css',
dest: 'public/css/main.min.css'
}
},
markdown: {
all: {
files: [
{
expand: true,
src: 'README.md',
dest: '.',
ext: '.html'
}
]
}
},
macreload: {
chrome: {
browser: 'chrome',
editor: 'macvim'
}
},
watch: {
main: {
files: ['public/src/js/**/*.js'],
tasks: ['concat:main', 'uglify:main'],
},
css: {
files: ['public/src/css/**/*.css'],
tasks: ['concat:css', 'cssmin'],
},
},
nggettext_extract: {
pot: {
files: {
'po/template.pot': ['public/views/*.html', 'public/views/**/*.html']
}
},
},
nggettext_compile: {
all: {
options: {
module: 'insight'
},
files: {
'public/src/js/translations.js': ['po/*.po']
}
},
}
});
//Making grunt default to force in order not to break the project.
grunt.option('force', true);
//Default task(s).
grunt.registerTask('default', ['replace', 'watch']);
//Update .pot file
grunt.registerTask('translate', ['nggettext_extract']);
//Compile task (concat + minify)
grunt.registerTask('compile', ['replace', 'nggettext_compile', 'concat', 'uglify', 'cssmin']);
};

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2013-2017 BitPay, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

121
README.md
View File

@ -1,118 +1,17 @@
# Insight UI # Insight
A Bitcoin blockchain explorer web application service for [Bitcore Node](https://github.com/bitpay/bitcore-node) using the [Insight API](https://github.com/bitpay/insight-api). **A bitcoin blockchain explorer and API.**
## Requirements
Insight requires [Node.js](https://nodejs.org) 8.2 and [MongoDB](https://www.mongodb.com/). Consider using [n](https://github.com/tj/n) and [m](https://github.com/aheckmann/m) to install the latest versions.
## Quick Start ## Quick Start
Please see the guide at [https://bitcore.io/guides/full-node](https://bitcore.io/guides/full-node) for information about getting a block explorer running. This is only the front-end component of the block explorer, and is packaged together with all of the necessary components in [Bitcore](https://github.com/bitpay/bitcore). To get started, clone this repository, then with `mongod` running install and run insight:
## Getting Started
To manually install all of the necessary components, you can run these commands:
```bash ```bash
npm install -g bitcore-node git clone -b next https://github.com/bitpay/insight.git && cd insight/server
bitcore-node create mynode npm install
cd mynode npm start
bitcore-node install insight-api
bitcore-node install insight-ui
bitcore-node start
``` ```
Open a web browser to `http://localhost:3001/insight/`
## Development
To build Insight UI locally:
```
$ npm run build
```
A watch task is also available:
```
$ npm run watch
```
## Changing routePrefix and apiPrefix
By default, the `insightConfig` in `package.json` is:
```json
"insightConfig": {
"apiPrefix": "insight-api",
"routePrefix": "insight"
}
```
To change these routes, first make your changes to `package.json`, for example:
```json
"insightConfig": {
"apiPrefix": "api",
"routePrefix": ""
}
```
Then rebuild the `insight-ui` service:
```
$ npm run build
```
## Multilanguage support
Insight UI uses [angular-gettext](http://angular-gettext.rocketeer.be) for multilanguage support.
To enable a text to be translated, add the ***translate*** directive to html tags. See more details [here](http://angular-gettext.rocketeer.be/dev-guide/annotate/). Then, run:
```
grunt compile
```
This action will create a template.pot file in ***po/*** folder. You can open it with some PO editor ([Poedit](http://poedit.net)). Read this [guide](http://angular-gettext.rocketeer.be/dev-guide/translate/) to learn how to edit/update/import PO files from a generated POT file. PO file will be generated inside po/ folder.
If you make new changes, simply run **grunt compile** again to generate a new .pot template and the angular javascript ***js/translations.js***. Then (if use Poedit), open .po file and choose ***update from POT File*** from **Catalog** menu.
Finally changes your default language from ***public/src/js/config***
```
gettextCatalog.currentLanguage = 'es';
```
This line will take a look at any *.po files inside ***po/*** folder, e.g.
**po/es.po**, **po/nl.po**. After any change do not forget to run ***grunt
compile***.
## Note
For more details about the [Insight API](https://github.com/bitpay/insight-api) configuration and end-points, go to [Insight API GitHub repository](https://github.com/bitpay/insight-api).
## Contribute
Contributions and suggestions are welcomed at the [Insight UI GitHub repository](https://github.com/bitpay/insight-ui).
## License
(The MIT License)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

62
app/.angular-cli.json Normal file
View File

@ -0,0 +1,62 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "insight-ui"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"favicon.ico"
],
"index": "index.html",
"main": "app/main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/tsconfig.app.json"
},
{
"project": "src/tsconfig.spec.json"
},
{
"project": "e2e/tsconfig.e2e.json"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
},
"codeCoverage": {
"exclude": [
"src/polyfills.ts",
"src/test.ts",
"src/mocks.ts",
"**/*.mock.ts"
]
}
},
"defaults": {
"styleExt": "css",
"component": {}
}
}

38
app/.gitignore vendored Normal file
View File

@ -0,0 +1,38 @@
# Specifies intentionally untracked files to ignore when using Git
# http://git-scm.com/docs/gitignore
*~
*.sw[mnpcod]
*.log
*.tmp
*.tmp.*
log.txt
*.sublime-project
*.sublime-workspace
.vscode/
npm-debug.log*
.idea/
.sass-cache/
.tmp/
.versions/
coverage/
dist/
node_modules/
tmp/
temp/
hooks/
platforms/
plugins/
plugins/android.json
plugins/ios.json
www/
$RECYCLE.BIN/
# e2e
/e2e/*.js
/e2e/*.map
.DS_Store
Thumbs.db
UserInterfaceState.xcuserstate

24
app/README.md Normal file
View File

@ -0,0 +1,24 @@
[![Build Status](https://travis-ci.org/bitpay/insight-ui.svg?branch=ionic)](https://travis-ci.org/bitpay/insight-ui)
[![codecov.io](https://codecov.io/github/bitpay/insight-ui/coverage.svg?branch=ionic)](https://codecov.io/github/bitpay/insight-ui?branch=ionic)
# Insight UI
## Install & Start
You need to be running [the latest node LTS](https://nodejs.org/en/download/) or newer.
```bash
git clone https://github.com/bitpay/insight-ui.git
cd insight-ui/app
npm install
npm start
```
## Run Unit Tests
```bash
npm test
```
## Run E2E
```
npm run e2e
```

32
app/e2e/app.e2e-spec.ts Normal file
View File

@ -0,0 +1,32 @@
import { browser, element, by } from 'protractor';
describe('InsightApp', () => {
beforeEach(() => {
browser.get('');
});
it('should have a title', () => {
expect(browser.getTitle()).toEqual('Home');
});
it('should have {nav}', () => {
expect(element(by.css('ion-navbar')).isPresent()).toEqual(true);
});
it('has a menu button that displays the left menu', () => {
element(by.css('.bar-button-menutoggle')).click()
.then(() => {
browser.driver.sleep(2000); // wait for the animation
expect(element(by.css('ion-menu')).isPresent()).toEqual(true);
});
});
it('the left menu has a link with title Home', () => {
element(by.css('.bar-button-menutoggle')).click()
.then(() => {
browser.driver.sleep(2000); // wait for the animation
expect(element.all(by.css('ion-label')).first().getText()).toEqual('Home');
});
});
});

View File

@ -0,0 +1,22 @@
import { browser, element, by, ElementFinder } from 'protractor';
describe('BroadcastTxPage', () => {
beforeEach(() => {
browser.get('');
});
it('should have an input field', () => {
element(by.css('.bar-button-menutoggle')).click().then(() => {
browser.driver.sleep(2000); // wait for the animation
element.all(by.className('input-wrapper')).then((items) => {
items[2].click();
browser.driver.sleep(2000); // wait for the animation
let theElem = element.all(by.css('ion-label')).first;
console.log(theElem);
expect(element.all(by.css('ion-input')).first().isPresent()).toEqual(true);
return items[1];
});
});
});
});

12
app/e2e/tsconfig.e2e.json Normal file
View File

@ -0,0 +1,12 @@
{
"extends": "../tsconfig.ng-cli.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"node"
]
}
}

12
app/ionic.config.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "insight-ui",
"app_id": "",
"type": "ionic-angular",
"integrations": {
"cordova": {}
},
"proxies": [{
"path": "/api",
"proxyUrl": "http://localhost:3000/api"
}]
}

44
app/karma.conf.js Normal file
View File

@ -0,0 +1,44 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/0.13/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular/cli'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular/cli/plugins/karma')
],
client:{
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
files: [
{ pattern: './src/test.ts', watched: false }
],
preprocessors: {
'./src/test.ts': ['@angular/cli']
},
mime: {
'text/x-typescript': ['ts','tsx']
},
coverageIstanbulReporter: {
reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
angularCli: {
environment: 'dev'
},
reporters: config.angularCli && config.angularCli.codeCoverage
? ['progress', 'coverage-istanbul']
: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};

65
app/package.json Normal file
View File

@ -0,0 +1,65 @@
{
"name": "insight-ui",
"private": true,
"scripts": {
"clean": "ionic-app-scripts clean",
"build": "ionic-app-scripts build",
"ionic:build": "ionic-app-scripts build",
"ionic:serve": "ionic-app-scripts serve",
"e2e": "ionic-app-scripts build && protractor",
"postinstall": "webdriver-manager update --gecko false",
"start": "ionic serve",
"test": "ng test --code-coverage",
"cov": "opn coverage/index.html",
"test-ci": "ng test --watch=false --code-coverage && npm run e2e"
},
"dependencies": {
"@angular/common": "4.1.3",
"@angular/compiler": "4.1.3",
"@angular/compiler-cli": "4.1.3",
"@angular/core": "4.1.3",
"@angular/forms": "4.1.3",
"@angular/http": "4.1.3",
"@angular/platform-browser": "4.1.3",
"@angular/platform-browser-dynamic": "4.1.3",
"@angular/router": "4.1.3",
"@ionic-native/core": "3.10.2",
"@ionic-native/splash-screen": "3.10.2",
"@ionic-native/status-bar": "3.10.2",
"@ionic/storage": "2.0.1",
"angular2-moment": "^1.6.0",
"angular2-qrcode": "^2.0.1",
"ionic-angular": "3.4.2",
"ionicons": "3.0.0",
"rxjs": "5.4.0",
"sw-toolbox": "3.6.0",
"zone.js": "0.8.12"
},
"devDependencies": {
"@angular/cli": "1.1.2",
"@ionic/app-scripts": "1.3.7",
"@types/jasmine": "2.5.41",
"@types/node": "7.0.4",
"codecov": "2.2.0",
"ionic": "3.9.2",
"jasmine-core": "2.5.2",
"jasmine-spec-reporter": "3.2.0",
"karma": "1.4.1",
"karma-chrome-launcher": "2.1.1",
"karma-cli": "1.0.1",
"karma-coverage-istanbul-reporter": "1.2.1",
"karma-jasmine": "1.1.0",
"karma-jasmine-html-reporter": "0.2.2",
"opn-cli": "^3.1.0",
"protractor": "5.1.2",
"serve-static": "1.12.3",
"ts-node": "3.0.4",
"tslint": "5.3.2",
"tslint-eslint-rules": "4.1.1",
"typescript": "2.3.3"
},
"engines": {
"node": ">=8"
},
"license": "MIT"
}

33
app/protractor.conf.js Normal file
View File

@ -0,0 +1,33 @@
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./e2e/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
useAllAngular2AppRoots: true,
beforeLaunch: function() {
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
});
require('connect')().use(require('serve-static')('www')).listen(4200);
},
onPrepare() {
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
app/resources/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
app/resources/splash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -0,0 +1,63 @@
import { Component, ViewChild } from '@angular/core';
import { Platform, MenuController, Nav } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import {
HomePage,
BlocksPage,
BroadcastTxPage,
NodeStatusPage,
VerifyMessagePage
} from '../pages';
@Component({
templateUrl: './app.html'
})
export class InsightApp {
@ViewChild(Nav) public nav: Nav;
private menu: MenuController;
private platform: Platform;
private splash: SplashScreen;
private status: StatusBar;
public rootPage: any;
public pages: Array<{ title: string, component: any }>;
constructor(platform: Platform, menu: MenuController, splash: SplashScreen, status: StatusBar) {
this.menu = menu;
this.platform = platform;
this.splash = splash;
this.status = status;
this.rootPage = HomePage;
this.initializeApp();
// set our app's pages
this.pages = [
{ title: 'Home', component: HomePage },
{ title: 'Blocks', component: BlocksPage },
{ title: 'Broadcast Transaction', component: BroadcastTxPage },
{ title: 'Verify Signed Message', component: VerifyMessagePage },
{ title: 'Node Status', component: NodeStatusPage }
];
}
private initializeApp(): void {
this.platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
this.status.styleDefault();
this.splash.hide();
});
}
public openPage(page: any): void {
// close the menu when clicking a link from the menu
this.menu.close();
// navigate to the new page if it is not the current page
this.nav.setRoot(page.component);
}
}

13
app/src/app/app.html Normal file
View File

@ -0,0 +1,13 @@
<ion-menu [content]="content">
<ion-content>
<ion-list>
<button ion-item *ngFor="let p of pages" (click)="openPage(p)">
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>

45
app/src/app/app.module.ts Normal file
View File

@ -0,0 +1,45 @@
import { HttpModule } from '@angular/http';
import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { InsightApp } from './app.component';
import { PagesModule, HomePage, BlocksPage, BroadcastTxPage, NodeStatusPage, VerifyMessagePage } from '../pages';
import { BlocksService, StorageService } from '../services';
import { ApiProvider } from '../providers/api/api';
import { CurrencyProvider } from '../providers/currency/currency';
import { BlocksProvider } from '../providers/blocks/blocks';
@NgModule({
declarations: [
InsightApp
],
imports: [
BrowserModule,
HttpModule,
PagesModule,
IonicModule.forRoot(InsightApp)
],
bootstrap: [IonicApp],
entryComponents: [
InsightApp,
HomePage,
BlocksPage,
BroadcastTxPage,
NodeStatusPage,
VerifyMessagePage
],
providers: [
StatusBar,
SplashScreen,
StorageService,
BlocksService,
{provide: ErrorHandler, useClass: IonicErrorHandler},
ApiProvider,
CurrencyProvider,
BlocksProvider
]
})
export class AppModule {}

37
app/src/app/app.scss Normal file
View File

@ -0,0 +1,37 @@
// http://ionicframework.com/docs/v2/theming/
// App Global Sass
// --------------------------------------------------
// Put style rules here that you want to apply globally. These
// styles are for the entire app and not just one component.
// Additionally, this file can be also used as an entry point
// to import other Sass files to be included in the output CSS.
.ellipsis {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.summary ion-label {
color: #333;
font-weight: bold;
}
.summary ion-item {
color: #999;
font-size: 1.4rem;
}
body {
user-select: text;
}
// Shared Sass variables, which can be used to adjust Ionic's
// default Sass variables, belong in "theme/variables.scss".
//
// To declare rules for a specific mode, create a child rule
// for the .md, .ios, or .wp mode classes. The mode class is
// automatically applied to the <body> element in the app.

29
app/src/app/app.spec.ts Normal file
View File

@ -0,0 +1,29 @@
import { InsightApp } from './app.component';
import { MenuMock, NavMock, PlatformMock, SplashMock, StatusMock } from '../mocks';
import { BroadcastTxPage } from '../pages';
let instance: InsightApp = null;
describe('InsightApp', () => {
beforeEach(() => {
instance = new InsightApp((<any> new PlatformMock), (<any> new MenuMock), (<any>new SplashMock()), (<any>new StatusMock()));
instance['nav'] = (<any>new NavMock());
});
it('initializes with four possible pages', () => {
expect(instance['pages'].length).toEqual(4);
});
it('initializes with a root page', () => {
expect(instance['rootPage']).not.toBe(null);
});
it('opens a page', () => {
spyOn(instance['menu'], 'close');
spyOn(instance['nav'], 'setRoot');
instance.openPage(instance['pages'][1]);
expect(instance['menu']['close']).toHaveBeenCalled();
expect(instance['nav'].setRoot).toHaveBeenCalledWith(BroadcastTxPage);
});
});

5
app/src/app/main.ts Normal file
View File

@ -0,0 +1,5 @@
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,19 @@
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { IonicModule } from 'ionic-angular';
@NgModule({
declarations: [
],
imports: [
FormsModule,
IonicModule,
ReactiveFormsModule
],
exports: [
],
entryComponents: [],
providers: []
})
export class ComponentsModule {}

View File

@ -0,0 +1,15 @@
<ion-navbar color="primary">
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>{{title}}</ion-title>
<ion-buttons end>
<button ion-button (click)="changeCurrency()">
<ion-icon name="logo-bitcoin" *ngIf="currency.currencySymbol !== 'USD'"></ion-icon><ion-icon name="logo-usd" *ngIf="currency.currencySymbol === 'USD'"></ion-icon>&nbsp;{{ currency.currencySymbol }}
</button>
<button ion-button icon-only (click)="toggleSearch()">
<ion-icon name="search"></ion-icon>
</button>
</ion-buttons>
</ion-navbar>
<ion-searchbar [hidden]="!showSearch" (ionInput)="search($event)" placeholder="{{ 'Search for block, transaction or address' }}" [(ngModel)]="q" [debounce]="1500"></ion-searchbar>

View File

@ -0,0 +1,16 @@
import { NgModule } from '@angular/core';
import { IonicModule } from 'ionic-angular';
import { HeadNavComponent } from './head-nav';
@NgModule({
declarations: [
HeadNavComponent
],
imports: [
IonicModule
],
exports: [
HeadNavComponent
]
})
export class HeadNavComponentModule {}

View File

@ -0,0 +1,3 @@
head-nav {
}

View File

@ -0,0 +1,145 @@
import { Component } from '@angular/core';
import { Input } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Http } from '@angular/http';
import { ApiProvider } from '../../providers/api/api';
import { CurrencyProvider } from '../../providers/currency/currency';
import { ActionSheetController } from 'ionic-angular';
/**
* Generated class for the HeadNavComponent component.
*
* See https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html
* for more info on Angular Components.
*/
@Component({
selector: 'head-nav',
templateUrl: 'head-nav.html'
})
export class HeadNavComponent {
public showSearch: boolean = false;
public loading: boolean;
@Input() public title: string;
public q: string;
public badQuery: boolean = false;
constructor(private navCtrl: NavController, private http: Http, private api: ApiProvider, public currency: CurrencyProvider, public actionSheetCtrl: ActionSheetController) {
}
public search(): void {
this.showSearch = false;
let apiPrefix: string = this.api.apiPrefix;
this.http.get(apiPrefix + 'block/' + this.q).subscribe(
function (data: any): void {
this.resetSearch();
console.log('block', data);
let parsedData: any = JSON.parse(data._body);
this.navCtrl.push('block-detail', {
'blockHash': parsedData.hash
});
}.bind(this),
() => {
this.http.get(apiPrefix + 'tx/' + this.q).subscribe(
function (data: any): void {
this.resetSearch();
console.log('tx', data);
let parsedData: any = JSON.parse(data._body);
this.navCtrl.push('transaction', {
'txId': parsedData.txid
});
}.bind(this),
() => {
this.http.get(apiPrefix + 'addr/' + this.q).subscribe(
function (data: any): void {
this.resetSearch();
console.log('addr', data);
let parsedData: any = JSON.parse(data._body);
this.navCtrl.push('address', {
'addrStr': parsedData.addrStr
});
}.bind(this),
() => {
this.http.get(apiPrefix + 'block-index/' + this.q).subscribe(
function (data: any): void {
this.resetSearch();
let parsedData: any = JSON.parse(data._body);
this.navCtrl.push('block-detail', {
'blockHash': parsedData.blockHash
});
}.bind(this),
function (): void {
this.loading = false;
this.reportBadQuery();
}.bind(this)
);
}
);
}
);
}
);
}
/* tslint:disable:no-unused-variable */
private reportBadQuery(): void {
this.badQuery = true;
console.log('badQuery', this.badQuery);
setTimeout(
function (): void {
this.badQuery = false;
console.log('badQuery', this.badQuery);
}.bind(this),
2000
);
};
private resetSearch(): void {
this.q = '';
this.loading = false;
}
/* tslint:enable:no-unused-variable */
public changeCurrency(): void {
let actionSheet: any = this.actionSheetCtrl.create({
title: 'Change Denomination',
buttons: [
{
text: 'USD',
handler: () => {
this.currency.setCurrency('USD');
}
},
{
text: 'BTC',
handler: () => {
this.currency.setCurrency('BTC');
}
},
{
text: 'mBTC',
handler: () => {
this.currency.setCurrency('mBTC');
}
},
{
text: 'bits',
handler: () => {
this.currency.setCurrency('bits');
}
},
{
text: 'Cancel',
role: 'cancel'
}
]
});
actionSheet.present();
}
public toggleSearch(): void {
this.showSearch = !this.showSearch;
}
}

View File

@ -0,0 +1 @@
export * from './components.module';

View File

@ -0,0 +1,45 @@
<!-- Generated template for the LatestBlocksComponent component -->
<div>
<div *ngIf="loading">
<ion-spinner name="crescent"></ion-spinner>
</div>
<div *ngIf="!loading">
<ion-grid>
<ion-row>
<ion-col><b>Height</b></ion-col>
<ion-col *ngIf="showTimeAs === 'age'"><b>Age</b></ion-col>
<ion-col *ngIf="showTimeAs === 'timestamp'"><b>Timestamp</b></ion-col>
<ion-col text-right><b>Transactions</b></ion-col>
<ion-col hideWhen="portrait"><b>Mined By</b></ion-col>
<ion-col text-right><b>Size</b></ion-col>
</ion-row>
<ion-row *ngFor="let block of getBlocks()">
<ion-col>
<a (click)="goToBlock(block.hash)">{{block.height}}</a>
</ion-col>
<ion-col *ngIf="showTimeAs === 'age'">
{{ block.time | amFromUnix | amTimeAgo }}
</ion-col>
<ion-col *ngIf="showTimeAs === 'timestamp'">
{{ block.time * 1000 | date:'medium' }}
</ion-col>
<ion-col text-right>
{{block.txlength}}
</ion-col>
<ion-col hideWhen="portrait">
<a *ngIf="block.poolInfo.poolName" href="{{block.poolInfo.url}}">{{block.poolInfo.poolName}}</a>
</ion-col>
<ion-col text-right>
{{ block.size }}
</ion-col>
</ion-row>
<ion-row *ngIf="showAllBlocksButton">
<ion-col text-center>
<button ion-button (click)="goToBlocks()">See all blocks</button>
</ion-col>
</ion-row>
</ion-grid>
</div>
</div>

View File

@ -0,0 +1,18 @@
import { NgModule } from '@angular/core';
import { IonicModule } from 'ionic-angular';
import { LatestBlocksComponent } from './latest-blocks';
import { MomentModule } from 'angular2-moment';
@NgModule({
declarations: [
LatestBlocksComponent
],
imports: [
IonicModule,
MomentModule
],
exports: [
LatestBlocksComponent
]
})
export class LatestBlocksComponentModule {}

View File

@ -0,0 +1,23 @@
latest-blocks {
ion-grid {
// border: 2px solid green;
margin: 10px 0 20px;
ion-row {
border-top: 1px solid #ccc;
}
ion-row:nth-child(even) {
background-color: #f4f4f4;
}
ion-row:first-child {
background-color: white;
border-top: none;
}
ion-row:last-child {
background-color: white;
}
}
}

View File

@ -0,0 +1,65 @@
import { Component, NgZone, Input } from '@angular/core';
import { BlocksProvider } from '../../providers/blocks/blocks';
import { NavController } from 'ionic-angular';
/**
* Generated class for the LatestBlocksComponent component.
*
* See https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html
* for more info on Angular Components.
*/
@Component({
selector: 'latest-blocks',
templateUrl: 'latest-blocks.html'
})
export class LatestBlocksComponent {
public loading: boolean = true;
public blocks: Array<any> = [];
@Input() public numBlocks: number;
@Input() public showAllBlocksButton: boolean;
@Input() public showTimeAs: string;
constructor(private blocksProvider: BlocksProvider, private navCtrl: NavController, ngZone: NgZone) {
this.loadBlocks();
ngZone.runOutsideAngular(() => {
setInterval(
function (): void {
ngZone.run(function (): void {
this.loadBlocks.call(this);
}.bind(this));
}.bind(this),
1000 * 30
);
});
}
private loadBlocks(): void {
this.blocksProvider.getBlocks().subscribe(
(data) => {
this.blocks = JSON.parse(data['_body']).blocks;
this.loading = false;
},
(err) => {
console.log('err', err);
this.loading = false;
}
);
}
public goToBlock(blockHash: string): void {
this.navCtrl.push('block-detail', {
'blockHash': blockHash
});
}
public getBlocks(): Array<any> {
/* tslint:disable:no-unused-variable */
return this.blocks.filter((block, index) => index < this.numBlocks);
/* tslint:enable:no-unused-variable */
}
public goToBlocks(): void {
this.navCtrl.push('blocks');
}
}

View File

@ -0,0 +1,27 @@
<div>
<div *ngIf="loading">
<ion-spinner name="crescent"></ion-spinner>
</div>
<div *ngIf="!loading">
<ion-grid>
<ion-row>
<ion-col><b>Hash</b></ion-col>
<ion-col text-right><b>Value Out</b></ion-col>
</ion-row>
<ion-row *ngFor="let tx of transactions">
<ion-col col-9>
<div class="ellipsis">
<a (click)="goToTx(tx.txid)">{{ tx.txid }}</a>
</div>
</ion-col>
<ion-col col-3 text-right>
{{ currency.getConversion(tx.valueOut) }}
</ion-col>
</ion-row>
</ion-grid>
</div>
</div>

View File

@ -0,0 +1,16 @@
import { NgModule } from '@angular/core';
import { IonicModule } from 'ionic-angular';
import { LatestTransactionsComponent } from './latest-transactions';
@NgModule({
declarations: [
LatestTransactionsComponent
],
imports: [
IonicModule
],
exports: [
LatestTransactionsComponent
]
})
export class LatestTransactionsComponentModule {}

View File

@ -0,0 +1,23 @@
latest-transactions {
ion-grid {
// border: 2px solid green;
margin: 10px 0 20px;
ion-row {
border-top: 1px solid #ccc;
}
ion-row:nth-child(even) {
background-color: #f4f4f4;
}
ion-row:first-child {
background-color: white;
border-top: none;
}
ion-row:last-child {
background-color: white;
}
}
}

View File

@ -0,0 +1,65 @@
import { Component, NgZone, Input } from '@angular/core';
import { Http } from '@angular/http';
import { NavController } from 'ionic-angular';
import { ApiProvider } from '../../providers/api/api';
import { CurrencyProvider } from '../../providers/currency/currency';
/**
* Generated class for the LatestTransactionsComponent component.
*
* See https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html
* for more info on Angular Components.
*/
@Component({
selector: 'latest-transactions',
templateUrl: 'latest-transactions.html'
})
export class LatestTransactionsComponent {
private loading: boolean = true;
private transactions: Array<any> = [];
@Input() public refreshSeconds: number = 10;
private timer: number;
constructor(private http: Http, private navCtrl: NavController, private api: ApiProvider, public currency: CurrencyProvider, private ngZone: NgZone) {
this.loadTransactions();
}
public ngOnChanges(): void {
if (this.timer) {
clearInterval(this.timer);
}
this.ngZone.runOutsideAngular(() => {
this.timer = setInterval(
function (): void {
this.ngZone.run(function (): void {
this.loadTransactions.call(this);
}.bind(this));
}.bind(this),
1000 * this.refreshSeconds
);
});
}
private loadTransactions(): void {
let url: string = this.api.apiPrefix + 'txs';
this.http.get(url).subscribe(
(data) => {
this.transactions = JSON.parse(data['_body']);
this.loading = false;
},
(err) => {
console.log('err is', err);
this.loading = false;
}
);
}
public goToTx(txId: string): void {
this.navCtrl.push('transaction', {
'txId': txId
});
}
}

View File

@ -0,0 +1,14 @@
<div *ngIf="loading">
<ion-spinner name="crescent"></ion-spinner>
</div>
<div *ngIf="!loading">
<ion-grid>
<ion-row *ngFor="let tx of transactions.txs">
<ion-col col-12>
<transaction [tx]="tx"></transaction>
</ion-col>
</ion-row>
</ion-grid>
</div>

View File

@ -0,0 +1,18 @@
import { NgModule } from '@angular/core';
import { IonicModule } from 'ionic-angular';
import { TransactionListComponent } from './transaction-list';
import { TransactionComponentModule } from '../transaction/transaction.module';
@NgModule({
declarations: [
TransactionListComponent
],
imports: [
IonicModule,
TransactionComponentModule
],
exports: [
TransactionListComponent
]
})
export class TransactionListComponentModule {}

View File

@ -0,0 +1,3 @@
transaction-list {
}

View File

@ -0,0 +1,40 @@
import { Component } from '@angular/core';
import { Input } from '@angular/core';
import { Http } from '@angular/http';
import { ApiProvider } from '../../providers/api/api';
/**
* Generated class for the TransactionListComponent component.
*
* See https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html
* for more info on Angular Components.
*/
@Component({
selector: 'transaction-list',
templateUrl: 'transaction-list.html'
})
export class TransactionListComponent {
public loading: boolean = true;
@Input() public queryType: string;
@Input() public queryValue: string;
public transactions: any = [];
constructor(private http: Http, private api: ApiProvider) {
}
private ngOnInit(): void {
let url: string = this.api.apiPrefix + 'txs?' + this.queryType + '=' + this.queryValue;
this.http.get(url).subscribe(
(data) => {
this.transactions = JSON.parse(data['_body']);
this.loading = false;
},
(err) => {
console.log('err is', err);
this.loading = false;
}
);
}
}

View File

@ -0,0 +1,99 @@
<ion-grid>
<ion-row>
<ion-col col-8>
<div class="ellipsis">
<ion-icon name="add-circle" [hidden]="expanded" (click)="toggleExpanded()"></ion-icon><ion-icon name="remove-circle" [hidden]="!expanded" (click)="toggleExpanded()"></ion-icon> <span><a (click)="goToTx(tx.txid)">{{ tx.txid }}</a></span>
</div>
</ion-col>
<ion-col col-4 text-right>
<div [hidden]="!tx.firstSeenTs">
<span translate>first seen at</span>
<time>{{tx.firstSeenTs * 1000 | date:'medium'}}</time>
</div>
<div [hidden]="!tx.blocktime && tx.firstSeenTs">
<span translate>mined</span>
<time>{{tx.time * 1000 | date:'medium'}}</time>
</div>
</ion-col>
</ion-row>
<ion-row>
<ion-col col-12 col-md-5>
<ion-list [hidden]="!tx.isCoinBase">
<ion-item>
No Inputs (Newly Generated Coins)
</ion-item>
</ion-list>
<ion-list [hidden]="tx.isCoinBase">
<ion-item *ngFor="let vin of aggregateItems(tx.vin)">
<div>
<div class="ellipsis">
<p><a (click)="goToAddress(vin.addr)">{{ vin.addr }}</a></p>
</div>
<div [hidden]="!expanded">
<p *ngIf="vin.confirmations"><b>Confirmations</b> {{vin.confirmations}}</p>
<p><b>scriptSig</b></p>
<div *ngFor="let item of vin.items">
<div *ngIf="item.scriptSig">
<div *ngFor="let scriptSig of item.scriptSig.asm | split:' '">
<div class="ellipsis">
<p>{{ scriptSig }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div item-end>
{{ currency.getConversion(vin.value) }}
</div>
</ion-item>
</ion-list>
</ion-col>
<ion-col col-12 col-md-1 text-center>
<ion-icon name="arrow-forward"></ion-icon>
</ion-col>
<ion-col col-12 col-md-6>
<ion-list>
<ion-item *ngFor="let vout of tx.vout">
<div>
<div class="ellipsis">
<p><a (click)="goToAddress(getAddress(vout))">{{ getAddress(vout) }}</a></p>
</div>
<div [hidden]="!expanded">
<p><b>Type</b> {{vout.scriptPubKey.type}}</p>
<p><b>scriptPubKey</b></p>
<div class="ellipsis">
<p>{{vout.scriptPubKey.asm}}</p>
</div>
</div>
</div>
<div item-end>
{{ currency.getConversion(vout.value) }}
<span [hidden]="!vout.spentTxId">(S)</span>
<span [hidden]="vout.spentTxId">(U)</span>
</div>
</ion-item>
</ion-list>
</ion-col>
</ion-row>
<ion-row>
<ion-col col-3>
<span [hidden]="tx.isCoinBase">Fee {{ currency.getConversion(tx.fees) }}</span>
</ion-col>
<ion-col col-6 text-center>
{{ tx.confirmations }} Confirmations
</ion-col>
<ion-col col-3 text-right>
<span class="">{{ currency.getConversion(tx.valueOut) }}</span>
</ion-col>
</ion-row>
</ion-grid>

View File

@ -0,0 +1,18 @@
import { NgModule } from '@angular/core';
import { IonicModule } from 'ionic-angular';
import { TransactionComponent } from './transaction';
import { SplitPipe } from '../../pipes/split/split';
@NgModule({
declarations: [
TransactionComponent,
SplitPipe
],
imports: [
IonicModule
],
exports: [
TransactionComponent
]
})
export class TransactionComponentModule {}

View File

@ -0,0 +1,14 @@
transaction {
// 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
ion-grid {
background-color: #F4F4F4;
border: 1px solid #eee;
border-radius: 2px;
ion-row {
border: 1px solid #eee;
}
}
}

View File

@ -0,0 +1,115 @@
import { Component } from '@angular/core';
import { Input } from '@angular/core';
import { NavController } from 'ionic-angular';
import { CurrencyProvider } from '../../providers/currency/currency';
/**
* Generated class for the TransactionComponent 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'
})
export class TransactionComponent {
private COIN: number = 100000000;
public expanded: boolean = false;
@Input() public tx: any = {};
constructor(private navCtrl: NavController, public currency: CurrencyProvider) {
}
public getAddress(vout: any): string {
if (vout.scriptPubKey && vout.scriptPubKey.addresses) {
return vout.scriptPubKey.addresses[0];
} else {
return 'Unparsed address';
}
}
public goToTx(txId: string): void {
this.navCtrl.push('transaction', {
'txId': txId
});
}
public goToAddress(addrStr: string): void {
this.navCtrl.push('address', {
'addrStr': addrStr
});
}
public toggleExpanded(): void {
this.expanded = !this.expanded;
}
public aggregateItems(items: Array<any>): Array<any> {
if (!items) return [];
let l: number = items.length;
let ret: Array<any> = [];
let tmp: any = {};
let u: number = 0;
for (let i: number = 0; i < l; i++) {
let notAddr: boolean = false;
// non standard input
if (items[i].scriptSig && !items[i].addr) {
items[i].addr = 'Unparsed address [' + u++ + ']';
items[i].notAddr = true;
notAddr = true;
}
// non standard output
if (items[i].scriptPubKey && !items[i].scriptPubKey.addresses) {
items[i].scriptPubKey.addresses = ['Unparsed address [' + u++ + ']'];
items[i].notAddr = true;
notAddr = true;
}
// multiple addr at output
if (items[i].scriptPubKey && items[i].scriptPubKey.addresses.length > 1) {
items[i].addr = items[i].scriptPubKey.addresses.join(',');
ret.push(items[i]);
continue;
}
let addr: string = items[i].addr || (items[i].scriptPubKey && items[i].scriptPubKey.addresses[0]);
if (!tmp[addr]) {
tmp[addr] = {};
tmp[addr].valueSat = 0;
tmp[addr].count = 0;
tmp[addr].addr = addr;
tmp[addr].items = [];
}
tmp[addr].isSpent = items[i].spentTxId;
tmp[addr].doubleSpentTxID = tmp[addr].doubleSpentTxID || items[i].doubleSpentTxID;
tmp[addr].doubleSpentIndex = tmp[addr].doubleSpentIndex || items[i].doubleSpentIndex;
tmp[addr].dbError = tmp[addr].dbError || items[i].dbError;
tmp[addr].valueSat += Math.round(items[i].value * this.COIN);
tmp[addr].items.push(items[i]);
tmp[addr].notAddr = notAddr;
if (items[i].unconfirmedInput)
tmp[addr].unconfirmedInput = true;
tmp[addr].count++;
}
for (let v in tmp) {
let obj: any = tmp[v];
obj.value = obj.value || parseInt(obj.valueSat) / this.COIN;
ret.push(obj);
}
return ret;
};
}

14
app/src/declarations.d.ts vendored Normal file
View File

@ -0,0 +1,14 @@
/*
Declaration files are how the Typescript compiler knows about the type information(or shape) of an object.
They're what make intellisense work and make Typescript know all about your code.
A wildcard module is declared below to allow third party libraries to be used in an app even if they don't
provide their own type declarations.
To learn more about using third party libraries in an Ionic app, check out the docs here:
http://ionicframework.com/docs/v2/resources/third-party-libs/
For more info on type definition files, check out the Typescript docs here:
https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html
*/
declare module '*';

Some files were not shown because too many files have changed in this diff Show More