-
Notifications
You must be signed in to change notification settings - Fork 2
/
DYORassistant.user.js
1826 lines (1454 loc) · 153 KB
/
DYORassistant.user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// ==UserScript==
// @name DYORassistant
// @namespace https://apopheniapays.com/
// @version ALPHA-2020.10.03s2
// @description Adds some research tools and visual niceties to popular DeFi utilities and sites. Does not interfere with existing functionality, just adds cosmetics for user convenience.
// @author @ApopheniaPays
// @updateURL https://github.com/ApopheniaPays/DYORassistant/raw/master/DYORassistant.user.js
// @downloadURL https://github.com/ApopheniaPays/DYORassistant/raw/master/DYORassistant.user.js
// @match *://etherscan.io/*
// @match *://www.dextools.io/app/*
// @match *://app.astrotools.io/*
// @match *://dapp.trendering.com/*
// @match *://unitradebeta.com/*
// @match *://chartex.pro/*
// @match *://twitter.com/*
// @grant GM_addStyle
// @grant GM.xmlHttpRequest
// @connect github.com
// @connect githubusercontent.com
// @run-at document-start
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAASCAYAAABfJS4tAAAD7ElEQVQ4EY2TXUyTVxiAC5hlm3E/LmxZzK7MbsyWLO73wsvdLLvaxZYsLrucf3NTyRZ1uhD3YxB/yaYzm04HToEJgmBhCFQopbICpUBpqRaKqJSClA/o9533KzzLV8NsdS47ycn7c855zvue9z02W9oAlvgGVEe5XzjjM7TqUFJzRtEu9opWFFba0duiufpEuxQUrSYkWu010cq6hbaImnBjvJiGuqcC2X0+1dV8RagLClHAFJ3RyCjWqAY+0hVlMaEvKDjCQt2QEBpRmHqCiNJnGg1j5T2izWYDHuvvUb6GNqHRLSgdgv6/+P3kzxw7dJjiE8cIuNtoAj6eUZyOCR1BoaZPGIoZMG9way7Btbk5o1mpl1Jw4Mlgl/K1tpo42hWzAl6Pi00b12Gvs+Pt8fLjT8fI37yZ2TvTHALWInw7I5T7BO+owkBnbG6GyVmNWGJOH1DqZZs3pH6r9prU9Cs6R1JZc/BgAfZLdlwuF3a7nUgkwv7C/ZSeOkkcOOVTnA4LYzM6iWmdyrjB+bjBhbhBraZTcUcFbP6bsvpcQObPhhWDSbju7+ebPXtSkTY1NdHQ0EAoFGLv3r0Ul5xI3dzZqPC3CPNjBvWGYv2kydYpky/iJmunTI5H1e7Uc/SG1QdnugUr4EB3D+++/Q67du/C7XbT299LWXk5G9d/wnD4OiMxaPYofO1CZVD4TBfyNeG7aWHLtHB0QoozCljnTeQNKLhce4miwiMMhfxs3/o5G9ZtYueOnfT5PMSmodYhODpMupyKopiwLSHkx4U8Cx6TjgzoomFC5YU/Kig9fSaVsn94jJuRGyndTMLIOCTn79ZhQmCbJmyJC1/NJfl63IiFZ2efW2RlSCC/5NcSupxtGMAMMBWNsq+ggAsV5xExuVhdzoGCfG6FB1O97l9Y4I4ujKnkhxmwdMMCOx1OCr/fRzgYIDwYxGpzay7JWULuM8uxZd21c7JsBDyd+FucVBWftdL4NJ2VoVvgpvomqiqqeOP1V/+BWuCcnGxyn11OVnZ2hn/Z40uJRFJ9+lYGLN2wwKUlpQxfH16IjscW1qx5k2VLs1jx/BP8cvyH1OMeOVDA6pUv8EiOjdWvvYLD0WL5D6dzHtAtcGVZJV6P9zbwfjKJczSmMT2rp6CTWkoQVYqRSc1kfr7X+ogPgO53LEbc7my3aveotd4zSW37OLS4Ta42GpQMmuSBmoRV959/qG2BzxWfw9XqSgIrrI1DQ1NPlfZJsHFAGGwXCm+YnJ1KvPdQyL8tLII9Vz1WxLmLe0K31aorHcKfPUJtXG1f9P9vCWxwXG6m39c/DjydfnAwoL5sjKj6dN9/6X8D6mKWJnFSJqUAAAAASUVORK5CYII=
// @require https://code.jquery.com/jquery-3.3.1.min.js
// @require https://gist.github.com/raw/2625891/waitForKeyElements.js
// @require https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js
// @require https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js
// @require https://piyolab.github.io/sushiether/web3.js/libs/web3.js_v1.0.0-beta.33/web3.min.js
// @resource FONTAWESOME https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css
// @license MIT
// ==/UserScript==
// Follow t.me/ApopheniaProjects for announcements.
// A block of user-configurable options are further down in the script, if you want to tinker.
/*
# DYORassistant (formerly "DEXTassistant")
An independently developed userscript bringing new UI features and embedded research tools to popular DEX- &
DeFi-related websites, to give you an edge and help avoid scams. Follow
[http://t.me/ApopheniaProjects](http://t.me/ApopheniaProjects) on Telegram for announcements.
# BACKGROUND
## I. Origins
The website [http://DEXTools.io](http://DEXTools.io) started out as the most popular info explorer
for Uniswap. However, I found that as I explored the information it gave me, I had to do far too
much clicking around to other websites to do my own research on the coins listed. I wanted a quicker
way to gather information and determine which coins might be worth investing in, and more importantly,
which look like scams and should be avoided. So I took all the research I was doing by hand, and coded
an add-on tool that set on top of DEXTools but gave quicker access to all that information, and in
some cases, embedded it right in the page without having to leave DEXTools. Once it was written, it
struck me that this was a good way to lend a hand to beginning traders and newbies, and I decided to
make it available on Github for that purpose.
Since then, script development has begun to shift focus away from DEXTools to other popular sites.
Which I believe are more in keeping with my original intent of helping the beginning traders who need
this most and may not necessarily be in profit yet... traders very much like I was, literally only weeks
ago.
## II. From DextAssistant to DYORassistant: Change of focus and rebranding
As of 1 September 2020, going forward, this script has been rebranded from "DextAssistant" to
"DYORassistant" ("Do Your Own Reasearch" Assistant) to reflect a broader emphasis on helping fledgling
DEX traders research new tokens, rather than just focusing exclusively on enhancing DEXTools. For the
next month, I will be shifting focus to helping new traders by providing information and enhancements
on sites that do not charge the subscription fees that DEXTools will be instituting by the end of September.
The transition will be gradual. But I hope to shift focus before too long completely away from DEXTools, to
whatever tools show the most promising combination of usefulness, accessibility, and value to beginning or
intermediate traders in the months to come. DEXTools is an amazing service run by a great team, and likely
to only get better as it develops; however, I cannot justify volunteering time and development skills for
free to support what now looks like an exclusive service aimed at catering to traders who are already
succesfully enough to be able to afford to pay quite a lot of money for the tools they need. I think it's
terrific that DEXTools is offering an awesome toolset to those traders, I just don't see any reason to
support that myself.
At the same time, I plan on concurrently transitioning away from using DEXTools in my own trading. But I'll
make an effort to support the existing DEXTools-related features, and even continue to add new ones that were
already in the planning stages, for as long as possible.
UPDATE, September 20 2020: Following major under-the-hood changes to DEXTools's UI that are too difficult
to be worth dealing with, some of the script functionality no longer works on that site. The above notes will
be updated shortly. The next major revision of this script will bring full functionality to other sites.
# DISCLAIMER
## TO BE READ IN A STERN, GRUFF VOICE:
Despite my efforts to give it an easy-to-understand GUI, this is an advanced tool for technically
advanced traders.
If you are trading on Uniswap or other DEXs, you need to have a certain level of general knowledge in
order to avoid the high risks, and I'm not going to enable anyone to jump in and lose money. If there's
anything in this you don't understand, then you probably shouldn't be trading on Uniswap yet, so this
tool is not for you.
What's more, as this is under active development, you may find bugs, though I try hard to avoid that.
## Support? Support is for _closers_.
As I'm sharing this for free, I won't give you any support or any guarantees, and if you choose to use
it I don't owe you anything for any reason. It's presented as-is, use it only at your own risk. What
you see is what you get. If you have questions you'll have to do your own research and figure out the
answers yourself. I'm grouchy, don't bother me.
## The murky depths from whence this came
This is an independent project that bubbled up out of a single developer's needs. It's not affiliated
with DEXTools.io or its development team in any way, please *never bother them with questions about it*.
## In not so many words:
Essentially, YOU'RE ON YOUR OWN with this.
Do you think Indiana Jones needed someone holding his hand? No, never. When you're fighting for your
life in a remote jungle or far-flung desert outpost, there's no support, no instruction manual, no second
chances... just your own ingenuity, will to live, and the rich rewards that will come if you can figure
out on your own how to succeed.
As of right now, _that is your life._
(Metaphorically speaking.)
Enjoy!
# INSTRUCTIONS
## Installation
This script *requires a browser plugin that allows you to install and manage user scripts, such as
Greasemonkey, Tampermonkey, or Violentmonkey.* I chose to go with a userscript instead of a browser plugin
because it would allow the code to remain 100% open source and cross-platform.
(Here's where you need to bring a little knowledge to the table. If you're unfamiliar with userscripts or
Tampermonkey, Greasemonkey, Violentmonkey, etc, you should educate yourself from a page like
[https://simply-how.com/enhance-and-fine-tune-any-web-page-the-complete-user-scripts-guide](https://simply-how.com/enhance-and-fine-tune-any-web-page-the-complete-user-scripts-guide)
before you try to use this. BTW I use Tampermonkey [https://www.tampermonkey.net/](https://www.tampermonkey.net/)
myself, on Firefox, Brave, and Chrome, so I know for sure that this script works with that. But you'll
need to decide for yourself which userscript manager is right for you. Consult your doctor.)
*BONUS!* For users that already have a userscript manager extension installed in their browser, you can
install DextAssistant simply by clicking this link: [https://github.com/ApopheniaPays/dextassistant/raw/master/dextAssistant.user.js](https://github.com/ApopheniaPays/dextassistant/raw/master/dextAssistant.user.js).
This script is also hosted at [https://openuserjs.org/scripts/ApopheniaPays/DextAssistant](https://openuserjs.org/scripts/ApopheniaPays/DextAssistant)
for one-click install if you prefer to get a minified version. Supposedly that will stay current as I update
it here, but I haven't checked.
## Features
Global enhancements (currently works on DEXTools.io, Astrotools.io, Trendering.com, Etherscan.io, and Unitradebeta.com):
1.) In any table that has a header row, columns are now sortable.
2.) Ethereum addresses in table columns (indicated by links to Etherscan.io address pages) can be filtered to show only
the rows for that address.
3.) Any links to Etherscan.io now also have a button added to look that address up on Zerion. Ethereum addresses
are color coded to make repeated transactions from the same address more noticeable in tables.
### NOTE: as of 2020 sep 20, not all features listed below may work on DEXTools.io anymore, due to radical
under-the-hood changes to how DEXTools displays information. Most basic functionality has been restored, but not
all. This is the last version of this script that any features are guaranteed to work on DEXTools.
DEXTools.io enhancements:
1.) The most prominent addition is a new icon under the Pool Explorer's Actions column, which opens a
"research assistant" popup that will allow you to view data from other websites pertaining to the token Name,
Contract Address, and Uniswap.info Pair Address for the token on that row. Next to the Contract addresses you
will see a little circled arrow that will show you Google search results for those contract addresses, embedded
right in the popup, when you hover your mouse over it.
2.) For tokens with a particularly low DEXT score or which are auto-generated by a lazy website token-generator
script, the distinguished monocle and handlebar mustache on the "research assistant" gear button are replaced
with a "poop" emoji.
3.) Rows in the the Pool Explorer are color-coded to indicate liquidity adds, removes, and new pools. 100%
liquidity removals are now labeled as "rugpull" instead of just "remove", to make sure you know to feel
extra-bitter.
6.) DEXTools "Dark mode" is now supported, because I was too lazy to attempt any real work tonight.
7.) Rather than rely on the various browser plugins' hinky auto-update mechanism, the script adds an unobtrusive
"update available" link to the footer of the screen after a new version has been pushed to this repo, for
convenient one-click upgrading. (Some extremely nerdy people will notice the script phones home to github on page
load. This update check is why.)
As this script makes cosmetic changes only, there's no harm you can do by poking around. Explore it.
## Usage Tips
Ok, if you need to be told how to use this, you probably aren't ready to be doing this kind of trading. But here's my
basic routine for checking out a token and deciding if it's real or a scam: Check an see any the existing search results
for the contract address, check if liquidity is locked, look at the pair explorer and see if there is website/telegram/
discord referenced and look at those to get an impression. Takes no time at all.
Oh, yeah, and, be extra skeptical if the liquidity pool is less than 1000 ETH. I've seen real coins with pools as small as
20 ETH, but I've never (yet) seen a scam with a pool over 1000 ETH.
# KNOWN ISSUES
1.) Right now the list filtering and sorting only acts on existing rows. As new transactions or pools appear, they
come in at the top, exactly as if the list wasn't filtered or sorted. I'll get around to it. Hey, it's an open
source script, you don't like it, fix it yourself.
# FUTURE PLANS
In keeping with this tool's mission of helping beginning and small traders get a leg up, in an upcoming version this userscript
may begin asking for read-only permission to connect to your wallet (exactly as all dApps currently do.) If you hold enough wealth to
qualify for the premium-level subscriptions to some popular websites, such as holding 20k DEXT for DEXTools 2nd-tier subscription
or holding enough TRND to qualify for Trendering's exclusive 300-member telegram, you may be prevented from further use of this
script. If you wish to avoid these restrictions you may wish not to upgrade the script.
*/
/* ******** USER-CONFIGURABLE OPTIONS *************/
// * Feel free to change any of the values after the equals signs in this block. Don't remove the semicolon from the end of the lines.
// * If you don't understand what they do, then you probably don't need to worry about them.
// *
var ShowAssistantOnHover = true;
//Show the Research Assistant popover immediately on hover, without needing to click the icon.
var ethplorerkey="freekey";
//NOT YET IN USE. When activatory, if you run into hourly limits on some of the EthPlorer info (not yet included) because you have looked at more than 50 tokens in an hour, you can sign up for an API key at https://ethplorer.io/wallet/#register, get an API key from https://ethplorer.io/wallet/#screen=api, and replace "freekey" with it to raise your limits.
var scamWallets= {scammer:{wallet:"0x408f2ff726aae56ea7382b8676d8db43d624df7c",
reason:"yfking.link scammer",
url:"https://www.dextools.io/app/uniswap/pair-explorer/0x9ad1c11fd75c4c29e414bbc5c8cce83765c19911"}};
//NOT YET IN USE. Would like to eventually track wallets that I've verified are involved in scams
// *
/****** END USER-CONFIGURABLE OPTIONS ***********/
/************** DEV TO-DOs *********************/
// Live coingecko prices
// show how many people in pool
// show POL score
// incorporate https://thegraph.com/explorer/subgraph/graphprotocol/uniswap
// incorporate https://github.com/EverexIO/Ethplorer/wiki/Ethplorer-API
// color-code eth addresses so can see wash trades more easily
// option to always open Pair Explorer in new tab
// "star" favorite tokens so get alerts when something happens
// make column filtering and sort order persist for new rows
// alerts for adds with over a certain amount of liquidity
// view maker contract addresses on Zerion
// show % increase in pool over initial
// Maybe gray out any row with no pool left. This requires keeping the ontimer() live, so, think about it.
// maybe provision to enter your own wellet addresses and hilight them to find your own transactions easily
// maybe switch to using mutationobservers per https://stackoverflow.com/questions/32233895/using-waitForKeyElementsWrapper-is-it-possible-to-prevent-the-key-element-from-being-d
// show when liquidity has grown by a certain amount from initial add
// make mouse pointer into finger over all clickabl elements
// expand functions to work on other frequently used sites, like etherscan, Zerion
// total columns in pair explorer
// add an identifier as TD values are evaluated and screen for it so don't keep selecting same TD's over and over again
// alert if new pool doubles in size.
// user option to open Zerion in private window
/**/
/**/
/**/
/**/
/**/
/**/
/******************************************************************************/
/****** TOUCH NOTHING BELOW THIS LINE. IF YOU BREAK IT, YOU BOUGHT IT. ********/
/******************************************************************************/
/**/
/**/
/**/
/**/
/**/
/**/
var currentVersion="ALPHA-2020.10.03s2";
var thisHistory= encodeURIComponent(`
VERSION HISTORY
===============
2020.10.03s2 - I promised that the earlier update tonight contained bugs, and I delivered! This fixes
them. Also began adding DYORassistant niceties to Etherscan.io
2020.10.03s - "Stealth update". Major improvements to integration with Astrotools, most features
previously developed for DEXTools now work with Astrotools, although there still may be bugs.
Ethplorer integration begun. Internal conversion to store all page specifications in a hash rather
than hardcoded, so can much more easily adapt & extend functionality on new sites, which is totally fun.
2020.09.25 - Beginnings of integration with Chartex. Add buy/sell row coloring to transaction
lists on Chartex.
2020.09.20 - Fixes to restore some usability to Dextools after major UI overhaul that stopped
using table tags. Remove filtering on Dextools, as it is no longer possible. Squash some minor
bugs that were polluting the consol. THIS IS THE LAST VERSION THAT WILL OFFICIALLY SUPPORT
DEXTOOLS.IO. Some functionality will work but it will no longer be considered officially supported.
2020.09.15c - Minor upgrade, fix incorrect text and broken icon or Astrotools linkage
2020.09.15b - security upgrade only. Remove wildcard @match in favor of whitelisting specific
websites.
2020.09.15 - INSECURE VERSION, DO NOT USE - Change background row coloring to use transparency
and lighten hex address coloring so also works with stupid "dark themes". Another minor change
to logo icon for maximal visual prettiness. Resize Zerion icon and table sort arrows for extra
layoutical betterness. Under-the-hood changes in preparation for pseudopluginization & increased
ease of incorporating new sites.
2020.09.14t - INSECURE VERSION, DO NOT USE - Fix regression errors introduced in 2020.09.13t
causing research assistant popover to be added multiple times on DEXTools Pool Explorer page.
Introduce object property arrays to store page codes and page-specific values. Store page codes
in attribute in body tag so can be used in selectors to create page-specific selectors in the
global scope. Prevent filtering and Zerion from appearing on Etherscan links Pool Explorer page
because DEXTools has their own filtering and Zerion is in the research assistant popover.
2020.09.13t - INSECURE VERSION, DO NOT USE - transitional version while I work on code
refactoring for greater portability. Remove page restrictions so table features appear on all
sites where there are ethereum addresses. Finally fix button for Reasearch Assistant popover
not appearing on pair page. Get Zerion links, address coloring, and table sorting working on
all sites instead of just DEXTools. Add footer popovers for credits and version history. Color
rows that contain cells labeled "buy" or "sell". Add classes and functions to remove additions
if element that triggered their creation is gone. Spiffy new icon.
2020.09.02 - add popover Research Assistant menu to Pair Explorer page, fixes to contact info
indication, preparation for moving repository and begin rebrand to DYORa, titles to DYORa and
version links, show version history when click on version link, begin prepping to show new
version history before upgrade, rename functions to avoid potential conflicts [old version]
2020.08.28 - add visual higlight and prominent indication when there's contact info on pair page,
add hover effects and pointer cursor for all clickable elements, color code pair explorer page
totals red/green for sell/buy
020.08.27 - make compatible with DEXTools dark theme, because that's more important than
working on real features. Add icon. Add functionality to display "updateavailalable" link. Update
Pair Explorer filter icon to match default Pool Explorer one.
2020.08.25 - Alpha development. Color pool rows for added liquidity or new pools, popover menu
of extra research tools, token icons from Trustwallet repo, mark 100% removes as "rugpull",
integrate custom crypto search engine results into Research Assistant popover, integrate live
CryptoCompare pricing info, soooooperfast table sorting, color-coding and filtering hex addresses
`);
this.$ = this.jQuery = jQuery.noConflict(true);
//required for compatilibilty in case they start using jQuery on Dextools
try{
(function() {'use strict';
//Hey ho, let's go
var logErrors=false;
var thisPage="all";
var pageCodes = {pair:
{url:"www.dextools.io/app/uniswap/pair-explorer",
features:["noListFilter"],
onlySortColumns:"",
addDisclaimerAnchor:"span.copyright.ml-auto.my-auto.mr-2",
researchAsstAnchor:"body[ap_dajs_pagetype=pair] h3.page-title + small",
researchAsstPlacement:function(jNode) {return jNode;},
theAbbreviation:function(jNode){return jNode.prev().find("strong").text().split(" ")[4];},
theContract:function(jNode){var thisHREF=jNode.prev().children("a:first-of-type").attr('href');return thisHREF.substring(thisHREF.lastIndexOf("/")+1);},
thePair:function(jNode) {var thisHREF=document.location.href;return thisHREF.substring(thisHREF.lastIndexOf("/")+1);},
customWaitElements:
{ ".circle":addLogo}
},
pool:
{url:"www.dextools.io/app/uniswap/pool-explorer",
features:["noListFilter","noZerion"],
onlySortColumns:"",
addDisclaimerAnchor:"span.copyright.ml-auto.my-auto.mr-2",
researchAsstAnchor:"body[ap_dajs_pagetype=pool] datatable-body-cell:nth-child(3) a > i.fa-wpexplorer.pools-icon-warning:not(i.gAdded)",
researchAsstPlacement: function(jNode) {return jNode.parent().parent();},
theAbbreviation:function(jNode){return jNode.closest("TD,datatable-body-cell").siblings().first().children(0).children(0).text();},
theContract:function(jNode){ var thisHREF=jNode.closest("TD,datatable-body-cell").siblings().first().children(0).children(0).attr('href');return thisHREF.substring(thisHREF.lastIndexOf("/")+1);},
thePair:function(jNode) {var thisHREF=jNode.closest("TD,datatable-body-cell").next().children(0).children(0).attr('href');return thisHREF.substring(thisHREF.lastIndexOf("/")+1);},
customWaitElements:
{ ".circle":addLogo,
"body[ap_dajs_pagetype=pool] datatable-body-cell:nth-child(4) a.badge-danger":makeRed,
"body[ap_dajs_pagetype=pool] datatable-body-cell:nth-child(4) a.badge-success":makeGreen,
"body[ap_dajs_pagetype=pool] datatable-body-cell:nth-child(4) i.fa-info-circle.pools-icon-warning":poolWarning,
"body[ap_dajs_pagetype=pool] datatable-body-cell:nth-child(9) a.badge.badge-danger":rugPull}
},
astropair:
{url:"app.astrotools.io/pair-explorer",
features:["noZerion","noListFilter"],
onlySortColumns:"TH:nth-child(7)",
addDisclaimerAnchor:"li.ant-pagination-prev", /* "div.ant-layout-sider-children", */
researchAsstAnchor:"div.symbol div.icons-list",
researchAsstPlacement: function(jNode) {return jNode;},
theAbbreviation:function(jNode){var thisHREF= $("#chart-header section.chart-options a:first-child").attr("href"); return thisHREF.substring(thisHREF.lastIndexOf(":")+1);},
theContract:function(jNode){var thisHREF= jNode.children("a:first-child").attr('href'); return thisHREF.substring(thisHREF.lastIndexOf("/")+1);},
thePair:function(jNode) {var thisHREF=document.location.href; return thisHREF.substring(thisHREF.lastIndexOf("/")+1);},
customWaitElements:
{ ".circle":addLogo}
},
etherscan:
{url:"etherscan.io",
addDisclaimerAnchor:"footer > div.container > div:last-child",
customWaitElements: {
"td a[href*='0x']:not(.AP_DAJS_ethPrepared):not(.AP_DAJS_element):not(:has(i.fas.fa-chart-line)), a[href*='0x'][id^='spanTarget']:not(.AP_DAJS_ethPrepared):not(.AP_DAJS_element)": prepareEtherscanLink /*any link in a TD or id starting with "spanTarget" with an address will get parsed on etherscan*/
}
}
};
var newVersionAvail="";
var newVersionHistory="";
var newVersionURL = "https://github.com/ApopheniaPays/DYORassistant/raw/master/DYORassistant.user.js";
GM.xmlHttpRequest({
method: "GET",
url:newVersionURL,
onload: function(scrptTxt) {
var versionMtch = scrptTxt.response.match(/\/\/\s+@version\s+(.+)/i);
newVersionHistory = encodeURIComponent(scrptTxt.response.match(/var thisHistory= encodeURIComponent\(\`([\s\S]+?)\`/i)[1]);
if (versionMtch && versionMtch.length > 1) {
newVersionAvail = encodeURIComponent(versionMtch[1]);
if(newVersionAvail!=currentVersion) {waitForKeyElementsWrapper('span#newVersion',addNewVersion);}
};
}
});
function addNewVersion (jNode) {
jNode.html('<a title="update DYORassistant" href="'+newVersionURL+'" class="AP_DAJS_element">v '+newVersionAvail.replace(/ALPHA-/gi,'')+' available</a>');
//yeah, it's hinky. This runs asynchronously so there's two different places this can happen: here, or synchronously down below.
}
var IDcounter=1
// Hash any string into an integer value
// Then we'll use the int and convert to hex.
function hashCode(str) {
var hash = 0;
for (var i = 0; i < str.length; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash);
}
return hash;
}
// Convert an int to hexadecimal with a max length
// of six characters.
function intToARGB(i) {
var hex = (((i>>24)&0xCC)+0x33).toString(16) +
(((i>>16)&0x9E)+0x33).toString(16) +
(((i>>8)&0x9E)+0x33).toString(16) +
((i&0x9E)+0x33).toString(16);
// Sometimes the string returned will be too short so we
// add zeros to pad it out, which later get removed if
// the length is greater than six.
hex += '000000';
var theReturn = hex.substring(0, 6).replace("b","3").replace("c","5").replace("d","7").replace("e","9").replace("f","a"); //make a little darker
// theReturn = (((theReturn & 0x7E7E7E) >> 1) | (col & 0x808080)) ;//darken it
return theReturn;
}
// Extend the string type to allow converting to hex for quick access.
String.prototype.toHexColour = function() {
return intToARGB(hashCode(this));
}
window.thisHistory=thisHistory;
function quoteFunction(funcCall){
//from https://coursesweb.net/javascript/replace-javascript-variable-name-from-string-with-value_cs
var str=funcCall.toString();
// JavaScript & jQuery Courses - https://coursesweb.net/javascript/
str = str.replace(/\$\{(.*?)\}/gi, function(a,b) {
// if token is an array item, else, is object property, or variable
if(b.match(/[a-z0-9_]+\[[a-z0-9_]+\]/i)) {
var arritm = b.match(/([a-z0-9_]+)\[([a-z0-9_]+)\]/i); // gets an array with the matched items
return window[arritm[1]][arritm[2]];
}
else {
var voitm = b.split('.');
return (voitm.length == 2) ? window[voitm[0]][voitm[1]] : window[voitm[0]];
}
});
return str;
}
function addJS_Node (text, s_URL, funcToRun) {
var D = document;
var scriptNode = D.createElement ('script');
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = quoteFunction(funcToRun);
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}
/********************** Functions to include in pages **********************/
function AP_DAJS_displayHistory(){
win=window.open("", 'DYORa Version History', 'width=700, height=700, right=24, top=24, scrollbars, resizable');
win.document.write('<html><body><pre>'+decodeURIComponent(`${thisHistory}`)+'</pre></body></html>');return false;
}
addJS_Node(null, null, AP_DAJS_displayHistory);
function AP_DAJS_upgradeVersion(){
win=window.open("", 'DYORa Version Upgrade', 'width=700, height=700, right=24, top=24, scrollbars, resizable');
win.document.write('<html><body>Installed version: '+decodeURIComponent(`${currentVersion}`)+'<br>Available version: '+decodeURIComponent(`${newVersionAvail}`)+'< a href="'+decodeURIComponent(`${newVersionAvail}`)+'">click to install upgrade</a> (<a href="'+decodeURIComponent(`${newVersionAvail}.replace(/\/raw\//i,'/blob/')`)+'">source</a>)<br><small>After upgrading, please close this window and refresh the browser page you came from.</small><p><pre>'+decodeURIComponent(`${thisHistory}`)+'</pre></body></html>');return false;
}
addJS_Node(null, null, AP_DAJS_upgradeVersion);
function AP_DAJS_sortTable(n,tableId) {
var table = document.getElementById(tableId);
document.getElementById("AP_DAJS_th"+tableId+n).classList.toggle(".sorting");
window.setTimeout(AP_DAJS_sortTableMain(n,tableId), 100);
return;}
addJS_Node(null, null, AP_DAJS_sortTable);
function AP_DAJS_sortTableMain(n,tableId) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById(tableId);
try { document.getElementById("AP_DAJS_th"+tableId+table.getAttribute("lastSortedBy")).textContent="⇅";
document.getElementById("AP_DAJS_th"+tableId+table.getAttribute("lastSortedBy")).classList.toggle("text-info");
} catch(e) {};
try { table.setAttribute("lastSortedBy",n); } catch (e) {errorLog("line 471 failure ",e);}
switching = true;
// Set the sorting direction to ascending:
dir = "asc";
/* Make a loop that will continue until no switching has been done: */
while (switching) {
// Start by saying: no switching is done:
switching = false;
rows = table.rows;
/* Loop through all table rows (except the
first, which contains table headers): */
for (i = 1; i < (rows.length - 1); i++) {
// Start by saying there should be no switching:
shouldSwitch = false;
/* Get the two elements you want to compare,
one from current row and one from the next: */
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
/* Check if the two rows should switch place,
based on the direction, asc or desc: */
xValue=isNaN(x.getAttribute('AP_DAJS_valueCalc'))?x.getAttribute('AP_DAJS_valueCalc') :(+x.getAttribute('AP_DAJS_valueCalc') );
yValue=isNaN(y.getAttribute('AP_DAJS_valueCalc'))?y.getAttribute('AP_DAJS_valueCalc') :(+y.getAttribute('AP_DAJS_valueCalc') );
if (dir == "asc") {
if (xValue < yValue) {
// If so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (xValue > yValue) {
// If so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
/* If a switch has been marked, make the switch
and mark that a switch has been done: */
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
// Each time a switch is done, increase this count by 1:
switchcount ++;
} else {
/* If no switching has been done AND the direction is "asc",
set the direction to "desc" and run the while loop again. */
if (switchcount == 0 && dir == "asc") {
dir = "desc";
switching = true;
}
}
}
document.getElementById("AP_DAJS_th"+tableId+n).textContent=(dir=="desc"?"↓":"↑");
document.getElementById("AP_DAJS_th"+tableId+n).classList.toggle("text-info");
document.getElementById("AP_DAJS_th"+tableId+n).classList.toggle(".sorting");
}
addJS_Node(null, null, AP_DAJS_sortTableMain);
function AP_DAJS_previewToggle (thisCounter,url,section){
if(document.getElementById('AP_DAJS_previewResults'+thisCounter).style.display=='block'
&& document.getElementById('AP_DAJS_results'+thisCounter).src==decodeURIComponent(url))
{document.getElementById('AP_DAJS_previewResults'+thisCounter).style.display='none';
document.getElementById('AP_DAJS_floaterlink'+section+thisCounter).innerHTML='>🔎'}
else
{document.getElementById('AP_DAJS_results'+thisCounter).src=decodeURIComponent(url);
document.getElementById('AP_DAJS_previewResults'+thisCounter).style.display='block';
document.getElementById('AP_DAJS_floaterlink'+section+thisCounter).innerHTML='<🔍'}
}
addJS_Node(null, null, AP_DAJS_previewToggle);
function AP_DAJS_filterFunction(filterOn,tableId,theColor) {
var filterAddr=filterOn;//filterOn.parentNode.getAttribute("ap_dajs_valuecalc");
var thisIndex = Array.from(filterOn.parentNode.parentNode.children).indexOf(filterOn.parentNode);
if (typeof window.filterState === 'undefined') {window.filterState="";}
var filter= (window.filterState=="")?filterAddr:"";
window.filterState=filter;
var table, tr, td, i, txtValue;
table = document.getElementById(tableId);
tr = table.getElementsByTagName("tr");
var hTD = table.getElementsByTagName("th")[thisIndex];
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[thisIndex];
if (td) {
txtValue = td.getAttribute("ap_dajs_valuecalc"); //td.textContent || td.innerText;
if (txtValue.indexOf(filter) > -1 || filter=="" ) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
if (filter == "") {hTD.innerHTML = hTD.getAttribute("oldText");} else {
try {hTD.setAttribute("oldText",hTD.innerHTML);} catch (e) {errorLog("line 569 failure ",e);}
hTD.innerHTML = 'Maker <span style="color:#'+theColor+' !important" class="AP_DAJS_element">'+filter+' only</span>';}
}
addJS_Node(null, null, AP_DAJS_filterFunction);
/********************** end Functions to include in pages **********************/
function timeStringToSeconds (timeString) {
var hms = timeString.replace(/ *[hmdHMD] */g,":").replace(/ *[s] *$/g,""); // your input string
var a = hms.split(':'); // split it at the colons
// minutes are worth 60 seconds. Hours are worth 60 minutes.
var seconds = (typeof a[3] !== "undefined")?(+a[0]) * 60 * 60 * 60 + (+a[1]) * 60 + (+a[2])*60+(+a[3]):(typeof a[2] !== "undefined")?(+a[0]) * 60 * 60 + (+a[1]) * 60 + (+a[2]):
(typeof a[1] !== "undefined")?(+a[0]) * 60+ (+a[1]):(+a[0]);
return(seconds);
}
/* general */
waitForKeyElementsWrapper ("body[ap_dajs_pagetype]",pageSpecificElements);
waitForKeyElementsWrapper ( "thead>tr>th, ngx-datatable", prepareTable);
waitForKeyElementsWrapper ("td,datatable-body-cell", setTDvalue);
errorLog(JSON.parse(JSON.stringify(thisPageOptions())));
waitForKeyElementsWrapper ( "a[href*='/address/0x']:not(.AP_DAJS_ethPrepared):not(.AP_DAJS_element)", prepareEtherscanLink);
waitForKeyElementsWrapper ( ".AP_DAJS_dependentElement:not(.AP_DAJS_dependency+.AP_DAJS_dependentElement)",removeDependency)
waitForKeyElementsWrapper ( "#AP_DAJS_popupframe[src='']", togglePreview);
errorLog("RAA");
errorLog(thisPageOptions());
function pageSpecificElements() {
waitForKeyElementsWrapper ( thisPageOptions().researchAsstAnchor, addGoog);
waitForKeyElementsWrapper ( thisPageOptions().addDisclaimerAnchor, addDisclaimer);
}
/* DT pool */
/* end DT pool */
function waitForKeyElementsWrapper(theSelector,theFunc) {
try {
if(typeof theSelector != "undefined") {
// errorLog("Starting WFKE "+theSelector+theFunc.name);
waitForKeyElements (theSelector,theFunc);
errorLog("ENDINg WFKE "+theSelector+' '+theFunc.name);
} } catch(e) {errorLog(e);}
}
function removeDependency(jNode) {
jNode.remove();
}
function prepareEtherscanLink(jNode) {
jNode.addClass("AP_DAJS_ethPrepared");
var thisNode = jNode;
try { var thisHREF = thisNode.attr('href'); } catch (e) {errorLog("href not found"); return false}
//really stupid, but somehow waitForKeyElementsWrapper is sometimes passing empty nodes
/* errorLog (JSON.parse(JSON.stringify(jNode)));
errorLog (typeof jNode.attr('href'));
errorLog("a");
errorLog ( jNode.attr('href'));
errorLog("b");
errorLog (thisHREF);
errorLog("c");
errorLog(/0\x[0-9a-f]+/i.exec(thisHREF));
errorLog("d");
errorLog(/0\x[0-9a-f]+/i.exec(thisHREF)[0]);
errorLog("e"); */
var theHex= /0\x[0-9a-f]+(?!.*0\x[0-9a-f]+)/i.exec(thisHREF)[0]; /* get last match with ?! negative lookahead */
/* errorLog("f");
errorLog(theHex); */
// try {
var theTest=theHex.length;
thisNode.attr('style','color: #'+theHex.toHexColour()+' !important');
try {
if( thisNode.closest("TD,datatable-body-cell").length && !pageHasFeature("noListFilter")) {
var thisIndex=thisNode.closest("TD,datatable-body-cell").index();
var theTable=thisNode.closest("table,ngx-datatable").attr('id');
var theDupeCount=$("#"+theTable+" a[href='"+thisHREF+"']").length;
if (theDupeCount>1 )
/* we're not going to do this on DEXtools pair page anymore, the dynamically generated data table rows are bogus. */
{
thisNode.parent().prepend('<i title="filter on this address" class="AP_DAJS_element AP_DAJS_clickable filterbutton fa fa-filter pools-icon-warning" onclick="AP_DAJS_filterFunction('+thisNode.closest("table,ngx-datatable").attr("ap_dajs_valuecalc")+',\''+thisNode.closest("table,ngx-datatable").attr("id")+'\',\''+theHex.toHexColour()+'\')"><sup style="font-size:.5em;">'+theDupeCount+'</sup></i>'); }
}} catch (e) {console.log("ERROR - theHex",theHex);console.log(e);}
//style="background:#'+theHex.toHexColour()+' !important"
// jNode.closest("td").next().attr('style','background: #'+theHex.toHexColsorttour()+' !important');
jNode.after(zerionLink (theHex));
jNode.addClass('AP_DAJS_dependency');
// } catch(e) {errorLog("605 error fail",e);}
}
function zerionLink (theHex) {
var output="";
if (!pageHasFeature("noZerion")){
output=output+ ('<a title="Zerion address overview" onclick="window.open(this.href, \'windowName\', \'width=1000, height=700, right=24, top=24, scrollbars, resizable\'); return false;" class="AP_DAJS_element AP_DAJS_dependentElement AP_DAJS_dependency AP_DAJS_popupItem AP_DAJS_popupWin"'
+' href="https://app.zerion.io/'+theHex+'/overview">'
+' <div class="AP_DAJS_element backImgSmol zeriImg hide"></div></a>');
}
if (!pageHasFeature("noEthplorer")){
output=output+ ('<a title="Ethplorer address overview" onclick="window.open(this.href, \'windowName\', \'width=1000, height=700, right=24, top=24, scrollbars, resizable\'); return false;" class="AP_DAJS_element AP_DAJS_dependentElement AP_DAJS_popupItem AP_DAJS_popupWin"'
+' href="https://ethplorer.io/address/'+theHex+'">'
+' <div class="AP_DAJS_element backImgSmol ethpImg hide"></div></a>');
}
return output;
}
function setTDvalue(jNode) {
var rightNow = (new Date().getTime()/1000 );
var thisTD=jNode.clone();
thisTD.find(".AP_DAJS_element").remove();
jNode.attr("AP_DAJS_valueCalc",
( thisTD.text()!="" && thisTD.text().replace(/[ 0-9hdmsHDMS]*/g,"")=="" )?
timeStringToSeconds(thisTD.text()):
(isNaN(thisTD.text().replace(/[$,]/g,"")))?thisTD.text().toLowerCase().replace(/ /g,""):parseFloat(thisTD.text().replace(/[$,]/g,""))
); /*convert relative times to epoch time so don't have to worry about cell relative value updating, as it does. */
/* now some special general formatting */
if (jNode.attr("AP_DAJS_valueCalc")=="sell") {makeRed(jNode);}
if (jNode.attr("AP_DAJS_valueCalc")=="buy") {makeGreen(jNode);}
return true;
/* jNode.on('DOMSubtreeModified', setTDvalue(jNode)); NOPE! Infinit loop */
}
function prepareTable (jNode) {
if (!jNode.closest("table,ngx-datatable").attr("id"))
{ jNode.closest("table,ngx-datatable").attr("id",Math.floor(Math.random() * Math.floor(Math.random() * Date.now())));}
if ((typeof thisPageOptions().onlySortColumns=="undefined" && jNode.prop("tagName")=="TH") || jNode.is(thisPageOptions().onlySortColumns) ) {
jNode.addClass("AP_DAJS_clickable");
jNode.attr("onclick","AP_DAJS_sortTable("+jNode.index()+","+jNode.closest("table,ngx-datatable").attr("id")+")");
jNode.append('<span class="AP_DAJS_element DAsorter" id="AP_DAJS_th'+jNode.closest("table,ngx-datatable").attr("id")+jNode.index()+'">⇅</span>');
}}
/* Watch for window URL change: */
history.pushState = ( function (f) {return function pushState(){
var ret = f.apply(this, arguments);
window.dispatchEvent(new Event('pushstate'));
window.dispatchEvent(new Event('locationchange'));
return ret;
}})(history.pushState);
history.replaceState = ( function (f) { return function replaceState(){
var ret = f.apply(this, arguments);
window.dispatchEvent(new Event('replacestate'));
window.dispatchEvent(new Event('locationchange'));
return ret;
}})(history.replaceState);
window.addEventListener('popstate',function(){ return function(){
window.dispatchEvent(new Event('locationchange'))
}});
window.addEventListener('locationchange', function(){
initPage();
})
/* End Watch for window URL change. from https://stackoverflow.com/questions/6390341/how-to-detect-if-url-has-changed-after-hash-in-javascript/52809105#52809105 */
window.addEventListener('popstate', function (event) {
// back and forward buttons, etc.
initPage();
});
function pageHasFeature (featureCode) {
try {
var pageFeatures = pageCodes[thisPage].features.includes(featureCode);
return pageFeatures;}
catch(e) {return false;}
}
function errorLog(thisText) {
if(logErrors) {console.log(thisText);}
}
function thisPageOptions() {
errorLog("thisPage");
errorLog(thisPage);
try{
return pageCodes[thisPage] || {};
} catch(e){errorLog("Body not ready");return {};}
}
function setupPageType() {
for (const prop in pageCodes) {
errorLog("prop");
errorLog(prop);
errorLog("URL "+document.location.href);
errorLog("PROP URL "+pageCodes[prop].url);
if(document.location.href.match('//'+pageCodes[prop].url)) {
thisPage=prop;errorLog("+++");}
}
errorLog("THIS PAGE");
errorLog(thisPage);
try{ document.body.setAttribute("AP_DAJS_pageType",thisPage);
} catch(e) {
errorLog("No body");
}
pageSpecificElements();
}
function initPage(){
errorLog("PAGECODES");
errorLog(JSON.parse(JSON.stringify(pageCodes)));
setupPageType();
errorLog("hey");
errorLog(thisPageOptions());
try{
if(typeof thisPageOptions().customWaitElements != "undefined") {
errorLog("xxx");
errorLog(thisPageOptions().customWaitElements);
errorLog("yyy");
for (const [key, value] of Object.entries(thisPageOptions().customWaitElements)) {
errorLog( `${key}`);
errorLog(value);
waitForKeyElementsWrapper ( `${key}`, value);
}
} } catch (e) {console.log("e is now ",e);}
errorLog("2");
if(thisPage=="pool"){
/************************ pool page functions ************************/
$(document).ready(function(){
$(document.head).append(`
<script id="AP_DAJS_poolScripts">
async function AP_DAJS_getCCPrice(symbol,identifier) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://min-api.cryptocompare.com/data/price?fsym="+symbol+"&tsyms=USD,ETH", true);
xhr.onload = function () {
var ret=JSON.parse(xhr.responseText);
var result=ret.Message?(ret.Message.replace("There is no data for the symbol ","No data on ").replace("There is no data for any of the toSymbols",symbol+" not listed in")):"USD$"+(ret.USD||"unknown")+" ETHΞ"+(ret.ETH||"unknown");document.getElementById("priceSpan"+identifier).innerText=result;
};
xhr.send();
}
</script>
`);
});
/************************ end pool page functions ************************/
}
else
{
/************************ pair page functions ************************/
$(document).ready(function(){
$(document.head).append(
`
<script id="AP_DAJS_pairScripts">
var filterState="";
</script>
`);
});
// waitForKeyElementsWrapper ( "body[ap_dajs_pagetype=pair] h3.page-title>a",hiliteExtraInfo); //nth-child(2) didn't work because 2nd child isn't 'a'!
/************************ end pair page functions ************************/
}
}
/********** end initPage ********/
function hiliteExtraInfo(jNode) { //visually highlight when there's extra contact info for a token
var thisParent=jNode.parent();
if (thisParent.children("a").length>1 && !(jNode.siblings("div#contactInfoFound").length)) {
thisParent.append(" <div id='contactInfoFound' class='badge badge-success'><- <small>has contact info</small><!-- 😊--></div>");
} //let's only post it once.
//jNode.children("a").addClass("badge").addClass("badge-success").html(jNode.children("a").html().append("Contact info found!"));
}
function togglePreview (jNode) {$("#AP_DAJS_preview").toggle();}
function addLogo (jNode)
{jNode.addClass("gearImg").css({"background-repeat":"no-repeat","background-position":"center"})};
function rugPull(jNode) { if (jNode.text()=="-100%") { //var rugHTML='<span class="AP_DAJS_element text-warning badge-danger">RUGPULL</span> ';
jNode.addClass("badge-dark");
jNode.closest("td,datatable-body-cell").prevAll().eq(4).children(":first").children(":first").addClass("badge-dark");
jNode.closest("td,datatable-body-cell").prevAll().eq(4).children(":first").children(":first").text("RUGPULL");
} }
function addLink(jNode) { var creditHTML='<div style="float:right;font-size:1.25em;" class="AP_DAJS_element"><div class="AP_DAJS_element sirImg backImg"></div> <a href="#" class="AP_DAJS_element">DYORassistant Installed</a></div>';
jNode.parent().prepend(creditHTML);
}
function addDisclaimer(jNode) { var creditHTML='<div style="margin:auto 0 auto auto;" class="AP_DAJS_element text-muted bottomdiv">'
+'<a id="creditlink" data-toggle="popover" '
+'data-boundary="body" data-container="body" data-placement="top" type="button" data-html="true" href=""'
+'class="AP_DAJS_element">DYORassistant</a><div class="AP_DAJS_element sirImg backImg easterEgg" '
+'onclick="javascript:this.classList.toggle(\'anim\');"></div> <a id="historylink" '
+'data-toggle="body" data-container="body" data-boundary="body" data-placement="top"'
+'type="button" data-html="true" class="AP_DAJS_element" href="javascript:AP_DAJS_displayHistory()">'
+currentVersion+'</a> installed <span id="newVersion" class="AP_DAJS_element"></span>'
+'</div><!-- div id="creditPopover" class="popover"></div SEEMS LIKE WE DONT NEED THIS -->';
jNode.before(creditHTML);
$("div.navbar-toggler").on('click', 'div.navbar-toggler', function (e) {
});
/******** show credits ******/
var showCreditsFunction=function() { var _this = this;
$("a#creditlink,a#upgradelink,a#historylink").not(this).popover('hide');
$(this).popover("show");//$('#frame'+thisCounter).src='https://apopheniapays.com/cryptosearch/results.html?q=%22'+theContract+'%22+OR+%22'+thePair+'%22';
$(".popover")
.on("mouseleave", function() {
$(_this).popover('hide');
});
}
$("a#creditlink").popover({ trigger: "manual",
html: true,
animation: false,
fallbackPlacement : ['right'],
sanitize:false,
content: function() { return '<span style="font-size:1em">Coded with the white-hot<br>intensity of a thousand<br>suns by <a href="https://twitter.com/ApopheniaPays" target="_blank">@ApopheniaPays</a>.<hr> > <a href="https://github.com/ApopheniaPays/dyorassistant" target="_blank">Github repo</a><hr> > <a href="mailto:DYORfeedback@apopheniapays.com">email</a><hr> > <a href="https://t.me/apopheniaprojects" target="_blank">Telegram Announcements</a></span>';} /* prevent duplicate elements */
})
.on("mouseenter",ShowAssistantOnHover?showCreditsFunction:"" )
.on("click",showCreditsFunction ).on("mouseleave", function() {
var _this = this;
setTimeout(function() { if (!$(".popover:hover").length) { $(_this).popover("hide");
}
}, 150);
});