├── .github
└── ISSUE_TEMPLATE
│ └── add-my-project.md
├── .gitignore
├── LICENSE.md
├── README.md
├── coming-soon
└── index.html
├── landing
├── backers.js
├── building.html
├── favicon.ico
├── index.html
├── og-preview.jpg
├── projects.js
├── projects
│ ├── aboutlo_ether-swr.png
│ ├── alphawallet_.jpg
│ ├── austintgriffith_scaffold-eth.png
│ ├── bokkypoobah_BestBastardGANPunks.png
│ ├── compound-finance_compound-js.svg
│ ├── ensdomains_ens-app.svg
│ ├── ethereum-optimism_optimism.svg
│ ├── forta-protocol_forta-agent-sdk.jpg
│ ├── holdberg.jpg
│ ├── mdtanrikulu_use-metamask.svg
│ ├── mycryptohq_mycrypto.png
│ ├── nachomazzara_web3playground.jpg
│ ├── nanexcool_daistats.png
│ ├── rkalis_allbastards-com.png
│ ├── rkalis_revoke-cash.png
│ ├── scopelift_umbra-protocol.png
│ ├── statechannels_statechannels.svg
│ ├── tallycash_extension.jpg
│ ├── unknown_whalestats.svg
│ ├── unlock-protocol_unlock.png
│ ├── wallet3_wallet3.png
│ ├── wighawag_mandalas.png
│ └── wmitsuda_otterscan.png
├── sponsoring.html
├── sponsors
│ ├── ankr.png
│ ├── ankr.svg
│ ├── tally-link
│ ├── tally-readme.svg
│ ├── tally.jpg
│ └── test.html
└── static
│ ├── docs.svg
│ ├── icon-discord.svg
│ ├── icon-docs.svg
│ ├── icon-github.svg
│ ├── icon-playground.svg
│ ├── icon-toolbox.svg
│ ├── icon-twitter.svg
│ ├── icon-wallet.svg
│ ├── logo.png
│ ├── script.js
│ ├── st-alchemy.svg
│ ├── st-ankr.png
│ ├── st-ankr.svg
│ ├── st-ethereum.png
│ ├── st-etherscan.svg
│ ├── st-gitcoin.png
│ ├── st-infura.svg
│ ├── st-pokt.svg
│ └── style.css
└── playground
├── app.js
├── docs.js
├── favicon.ico
├── help.js
├── index.html
├── inspect.js
├── og-preview.jpg
├── sandbox.js
├── sources
├── caret.svg
├── checkmark.svg
├── dark-mode-moon.svg
├── dark-mode-stars.svg
├── dark-mode-sun.svg
├── generate.mjs
├── icon-library.svg
├── icon-settings.svg
├── logo.svg
├── options-open.svg
└── style.css
├── style.css
└── v5
├── help.js
├── index.html
├── inspect.js
├── sandbox.js
└── static
├── caret.svg
├── checkmark.svg
├── dark-mode-moon.svg
├── dark-mode-stars.svg
├── dark-mode-sun.svg
├── help.js
├── icon-library.svg
├── icon-settings.svg
├── logo.svg
├── options-open.svg
├── script.js
├── style.css
└── types.js
/.github/ISSUE_TEMPLATE/add-my-project.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Add My Project
3 | about: 'Request to add your project '
4 | title: 'Add my project, please: [PROJECT NAME]'
5 | labels: add-my-project, landing-page
6 | assignees: ''
7 |
8 | ---
9 |
10 | Thanks for using ethers and we look forward to including a link to your project on ethers.
11 |
12 | Please include the following details:
13 |
14 | - Link to GitHub repository (currently only GitHub is supported, and the project must be public)
15 | - A 256x256 px image (JPG or PNG) for a logo to include (attach it to this issue or include a link)
16 | - A public e-mail address or Twitter account with DMs enabled (this is used to resolve dead links or other concerns with the project)
17 |
18 | Notes:
19 | - All projects are previewed and vetted before inclusion, and monitored for changes and regularly reviewed
20 | - Project license should be compatible with Open Source Initiatives
21 | - Images will be hosted by ethers to protect privacy; contact me to update a logo
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | obsolete/
2 | .DS_Store
3 | .tmp/
4 | **/*.swp
5 | *~
6 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Richard Moore
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Ethers Websites
2 | ===============
3 |
4 | - [Landing](https://ethers.org) -- The main landing page for ethers
5 | - [Playground](https://playground.ethers.org/) -- A simple REPL to play around with ethers
6 | - Toolbox (coming soon) -- A simple UI to perform common Ethereum operations
7 | - Wallet (coming soon) -- A simple wallet built on top of ethers
8 |
9 | Other Links
10 | -----------
11 |
12 | - [Documentation](https://docs.ethers.io/)
13 |
14 | License
15 | -------
16 |
17 | MIT License.
18 |
--------------------------------------------------------------------------------
/coming-soon/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Coming soon... :)
4 |
5 |
6 |
--------------------------------------------------------------------------------
/landing/building.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | building - ethers
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
27 |
28 |
29 |
BUILDING PROJECTS
30 |
31 |
32 | Heya! I thought it might be a good idea to keep a collection
33 | of Open Source projects built using ethers and help share
34 | them with the community at large. So, here are a few ground rules. :)
35 |
36 |
37 |
38 |
What do I need to submit?
39 |
40 | A link to your GitHub project (currently, only GitHub projects are supported)
41 | A 256px × 256px logo as a PNG or JPEG
42 | An e-mail address or Twitter account you can be reached at; in case a link becomes dead, to verify updating logos, other concerns, etc.
43 | Please submit a request to add your project
44 |
45 |
46 |
47 |
48 |
NOTES
49 |
50 |
51 |
52 | Scam-like endeavours and criminal activity are not welcome and are deemed at
53 | my discretion.
54 |
55 |
56 | All links are manually verified before inclusion.
57 |
58 |
59 | Links are regularly monitored by to prevent scams.
60 |
61 |
62 | All images are hosted by ethers to protect visitor privacy.
63 | Contact me to update your logo.
64 |
65 |
66 | Forwarding referrer headers are disabled, no cookies are used and
67 | personal data is never stored for any visitor.
68 |
69 |
70 | Inclusion does not represent endorsement.
71 |
72 |
73 | Project licenses should be compatible with Open Source inititives.
74 |
75 |
76 | This is more of an experiment at this time; lets see how it goes.
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/landing/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/favicon.ico
--------------------------------------------------------------------------------
/landing/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | ethers
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
25 |
26 |
27 |
28 | Ethers does NOT have a token. Any token or website claiming
29 | to be affiliated with Ethers is a scam .
30 |
31 |
38 |
43 |
44 |
45 |
DOCS & TOOLS
46 |
66 |
67 |
99 |
107 |
131 |
132 |
133 |
134 |
138 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/landing/og-preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/og-preview.jpg
--------------------------------------------------------------------------------
/landing/projects.js:
--------------------------------------------------------------------------------
1 | const Projects = [{
2 | /* Wait for a GitHub project?
3 | image: "holdberg.jpg",
4 | name: "Holdbeg Financial",
5 | url: "https://github.com/hodlberg",
6 | score: 1
7 | },{
8 | image: "unknown_whalestats.svg",
9 | name: "Whalestats",
10 | url: "",
11 | score: 0
12 | },{
13 | image: "",
14 | name: "",
15 | url: "",
16 | score:
17 | }, {
18 | */
19 | image: "mdtanrikulu_use-metamask.svg",
20 | name: "useMetamask",
21 | url: "https://github.com/mdtanrikulu/use-metamask",
22 | score: 47
23 | },{
24 | image: "rkalis_allbastards-com.png",
25 | name: "AllBastards",
26 | url: "https://github.com/rkalis/allbastards.com",
27 | score: 7
28 | },{
29 | image: "alphawallet_.jpg",
30 | name: "AlphaWallet",
31 | url: "https://github.com/AlphaWallet/",
32 | score: 204
33 | },{
34 | image: "bokkypoobah_BestBastardGANPunks.png",
35 | name: "BestBastardGANPunks",
36 | url: "https://github.com/bokkypoobah/BestBastardGANPunks",
37 | score: 1
38 | },{
39 | image: "compound-finance_compound-js.svg",
40 | name: "Compound.js",
41 | url: "https://github.com/compound-finance/compound-js",
42 | score: 91
43 | },{
44 | image: "ensdomains_ens-app.svg",
45 | name: "ENS App",
46 | url: "https://github.com/ensdomains/ens-app",
47 | score: 79
48 | },{
49 | image: "aboutlo_ether-swr.png",
50 | name: "Ether-SWR",
51 | url: "https://github.com/aboutlo/ether-swr",
52 | score: 84
53 | },{
54 | image: "ethereum-optimism_optimism.svg",
55 | name: "Optimism",
56 | url: "https://github.com/ethereum-optimism/optimism",
57 | score: 507
58 | },{
59 | image: "forta-protocol_forta-agent-sdk.jpg",
60 | name: "Forta",
61 | url: "https://github.com/forta-protocol/forta-agent-sdk",
62 | score: 25
63 | },{
64 | image: "mycryptohq_mycrypto.png",
65 | name: "MyCrypto",
66 | url: "https://github.com/MyCryptoHQ/MyCrypto",
67 | score: 968
68 | },{
69 | image: "nachomazzara_web3playground.jpg",
70 | name: "Web3 Playground",
71 | url: "https://github.com/nachomazzara/web3playground",
72 | score: 20
73 | },{
74 | image: "nanexcool_daistats.png",
75 | name: "Daistats",
76 | url: "https://github.com/nanexcool/daistats",
77 | score: 57
78 | },{
79 | image: "rkalis_revoke-cash.png",
80 | name: "Revoke",
81 | url: "https://github.com/rkalis/revoke.cash",
82 | score: 73
83 | },{
84 | image: "austintgriffith_scaffold-eth.png",
85 | name: "Scaffold-ETH",
86 | url: "https://github.com/austintgriffith/scaffold-eth",
87 | score: 2200
88 | },{
89 | image: "statechannels_statechannels.svg",
90 | name: "State Channels",
91 | url: "https://github.com/statechannels/statechannels",
92 | score: 101
93 | },{
94 | image: "wallet3_wallet3.png",
95 | name: "Wallet3",
96 | url: "https://github.com/Wallet3/Wallet3",
97 | score: 0
98 | },{
99 | image: "scopelift_umbra-protocol.png",
100 | name: "Umbra",
101 | url: "https://github.com/ScopeLift/umbra-protocol",
102 | score: 87
103 | },{
104 | image: "tallycash_extension.jpg",
105 | name: "Tally.cash",
106 | url: "https://github.com/tallycash/extension",
107 | score: 315
108 | },{
109 | image: "unlock-protocol_unlock.png",
110 | name: "Unlock",
111 | url: "https://github.com/unlock-protocol/unlock/",
112 | score: 434
113 | },{
114 | image: "wighawag_mandalas.png",
115 | name: "Mandalas",
116 | url: "https://github.com/wighawag/mandalas",
117 | score: 2
118 | },{
119 | image: "wmitsuda_otterscan.png",
120 | name: "Otterscan",
121 | url: "https://github.com/wmitsuda/otterscan",
122 | score: 118
123 | }].sort((a, b) => (b.score - a.score)).map((p) => {
124 | p.image = "projects/" + p.image;
125 | return p;
126 | });
127 |
--------------------------------------------------------------------------------
/landing/projects/aboutlo_ether-swr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/aboutlo_ether-swr.png
--------------------------------------------------------------------------------
/landing/projects/alphawallet_.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/alphawallet_.jpg
--------------------------------------------------------------------------------
/landing/projects/austintgriffith_scaffold-eth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/austintgriffith_scaffold-eth.png
--------------------------------------------------------------------------------
/landing/projects/bokkypoobah_BestBastardGANPunks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/bokkypoobah_BestBastardGANPunks.png
--------------------------------------------------------------------------------
/landing/projects/compound-finance_compound-js.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
15 |
16 |
--------------------------------------------------------------------------------
/landing/projects/ensdomains_ens-app.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
21 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
32 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/landing/projects/ethereum-optimism_optimism.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
10 |
17 |
23 |
24 |
--------------------------------------------------------------------------------
/landing/projects/forta-protocol_forta-agent-sdk.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/forta-protocol_forta-agent-sdk.jpg
--------------------------------------------------------------------------------
/landing/projects/holdberg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/holdberg.jpg
--------------------------------------------------------------------------------
/landing/projects/mdtanrikulu_use-metamask.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
20 | Created with Sketch.
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
39 |
40 |
41 |
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 |
73 |
75 |
76 |
78 |
79 |
80 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/landing/projects/mycryptohq_mycrypto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/mycryptohq_mycrypto.png
--------------------------------------------------------------------------------
/landing/projects/nachomazzara_web3playground.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/nachomazzara_web3playground.jpg
--------------------------------------------------------------------------------
/landing/projects/nanexcool_daistats.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/nanexcool_daistats.png
--------------------------------------------------------------------------------
/landing/projects/rkalis_allbastards-com.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/rkalis_allbastards-com.png
--------------------------------------------------------------------------------
/landing/projects/rkalis_revoke-cash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/rkalis_revoke-cash.png
--------------------------------------------------------------------------------
/landing/projects/scopelift_umbra-protocol.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/scopelift_umbra-protocol.png
--------------------------------------------------------------------------------
/landing/projects/statechannels_statechannels.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
26 |
27 |
--------------------------------------------------------------------------------
/landing/projects/tallycash_extension.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/tallycash_extension.jpg
--------------------------------------------------------------------------------
/landing/projects/unknown_whalestats.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/landing/projects/unlock-protocol_unlock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/unlock-protocol_unlock.png
--------------------------------------------------------------------------------
/landing/projects/wallet3_wallet3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/wallet3_wallet3.png
--------------------------------------------------------------------------------
/landing/projects/wighawag_mandalas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/wighawag_mandalas.png
--------------------------------------------------------------------------------
/landing/projects/wmitsuda_otterscan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/projects/wmitsuda_otterscan.png
--------------------------------------------------------------------------------
/landing/sponsoring.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | sponsorship - ethers
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
27 |
28 |
29 |
SPONSORSHIP
30 |
31 | Ahoy! I thought I would try something new and test the waters
32 | as to whether there is any interest in sponsors, so here are
33 | some rough ideas I have put together.
34 |
35 |
36 |
37 |
SPONSORSHIP TIERS
38 |
39 |
Backer — anyone who has donated via
GitCoin or
BuyMeACoffee
40 |
41 |
42 | You get your logo+link to your public profile on ethers under the Backers section
43 |
44 |
45 | By default your GitCoin profile avatar is used; contact me to update it
46 |
47 |
48 | All backers are shown probablistically, based on all-time contributions
49 |
50 |
51 |
52 |
53 |
Bronze — $1,000 / month
54 |
55 |
56 | Include logo+link to an approved public website (e.g. GitHub
57 | project, npm package, twitter profile, etc) on ethers
58 | under the Bronze Sponsors section
59 |
60 |
61 |
62 |
63 |
Silver — $5,000 / month
64 |
65 |
66 | Include a logo+link to your project website on ethers
67 | under the Silver Sponsors section
68 |
69 |
70 |
71 |
72 |
Gold — $10,000 / month
73 |
74 |
75 | Include a logo+link to your project website on
76 | ethers under the Gold Sponsors section
77 |
78 |
79 | Also, include a logo+link to your project website in the
80 | README
(and therefore on
81 | NPM )
82 |
83 |
84 |
85 |
86 |
Unobtainium — $25,000 / month
87 |
88 |
89 | Everything from the Gold Tier
90 |
91 |
92 | Also, each month I will purchase a coffee from a local coffee shop
93 | (possibly Starbucks) with your company name on the side and
94 | tweet a photo of me enjoying your wonderful gift.
95 |
96 |
97 |
98 |
99 |
100 |
NOTES
101 |
102 |
103 |
104 | Scam-like endeavours and criminal activity are not welcome and are deemed at
105 | my discretion.
106 |
107 |
108 | All links are manually verified before inclusion, especially on
109 | the README
and NPM page.
110 |
111 |
112 | Links are regularly monitored by scripts to prevent scams.
113 |
114 |
115 | All images are hosted by ethers to protect visitor privacy.
116 | Contact me to update your logo.
117 |
118 |
119 | Forwarding referrer headers are disabled, no cookies are used and
120 | personal data is never stored for any visitor.
121 |
122 |
123 | Sponsorship does not represent endorsement.
124 |
125 |
126 | Sponsorship levels are in USD.
127 |
128 |
129 | This is my first attempt at Sponsorship; tiers may be
130 | adjusted over time.
131 |
132 |
133 | Changes to tier benefits will be conveyed with significant
134 | lead-time, during which grandfathered benefits will apply,
135 | if desired.
136 |
137 |
138 | Logos should be provided in an aspect ratio of as close to 1:1
139 | (e.g. square or circle) as possible for best appearance. SVG,
140 | PNG and JPG supported; if providing a raster format, please make
141 | sure it is at least 256x256 so it looks great on retina displays.
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
--------------------------------------------------------------------------------
/landing/sponsors/ankr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/sponsors/ankr.png
--------------------------------------------------------------------------------
/landing/sponsors/ankr.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
14 |
15 |
--------------------------------------------------------------------------------
/landing/sponsors/tally-link:
--------------------------------------------------------------------------------
1 | https://tally.cash
2 |
--------------------------------------------------------------------------------
/landing/sponsors/tally-readme.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Tally.cash
5 |
6 |
--------------------------------------------------------------------------------
/landing/sponsors/tally.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/sponsors/tally.jpg
--------------------------------------------------------------------------------
/landing/sponsors/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/landing/static/docs.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
12 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/landing/static/icon-discord.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/landing/static/icon-docs.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
12 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/landing/static/icon-github.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
17 |
18 |
--------------------------------------------------------------------------------
/landing/static/icon-playground.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/landing/static/icon-toolbox.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
14 |
20 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/landing/static/icon-twitter.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/landing/static/icon-wallet.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
11 |
13 |
15 |
17 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/landing/static/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/static/logo.png
--------------------------------------------------------------------------------
/landing/static/script.js:
--------------------------------------------------------------------------------
1 |
2 | // Creates a timer that doesn't tick while the screen is not visible.
3 | // If sync, the event synchronizes with the most recent timer with the
4 | // same duration.
5 | const foregroundTimers = { };
6 | function setForegroundTimeout(callback, duration, sync) {
7 | if (duration == null) { duration = 0; }
8 |
9 | // Browser doesn't support visibility API
10 | if (typeof(document.hidden) !== "boolean") {
11 | setTimeout(callback, duration);
12 | return;
13 | }
14 |
15 | // If synchronized, reuse the same callback bucket
16 | let timers = [ callback ];
17 | if (sync) {
18 | if (foregroundTimers[duration] == null) {
19 | foregroundTimers[duration] = timers;
20 | } else {
21 | timers = foregroundTimers[duration];
22 | timers.push(callback);
23 | return;
24 | }
25 | }
26 |
27 | const TICK = 250;
28 |
29 | // Short timeouts can just behave as normal
30 | if (duration < TICK) { return setTimeout(callback, duration); }
31 |
32 | let elapsed = 0;
33 | const timer = setInterval(() => {
34 | // Document is not visible (browser in the background, different tab, etc.)
35 | if (document.hidden) { return; }
36 |
37 | // Move 1 tick forward (break if it's time)
38 | elapsed += TICK;
39 | if (elapsed < duration) { return; }
40 |
41 | // Stop coalescing timers into this bucket
42 | delete foregroundTimers[duration];
43 |
44 | // Done with this timer
45 | clearInterval(timer);
46 |
47 | // Execure each callback (in the next event loop)
48 | timers.forEach((c) => { setTimeout(() => { c(); }, 0); });
49 | }, TICK);
50 |
51 | return; // { _fgTimer: true, timer };
52 | }
53 |
54 |
55 | // Returns an array of random backers, weigted by total donations
56 | const getBackers = (function() {
57 |
58 | // Load backer data
59 | const backers = Backers.split(",").map((backer) => {
60 | const comps = backer.split("=");
61 | return [ comps[0], parseInt(comps[1]) ];
62 | });
63 | const total = backers.reduce((accum, [ name, amount ]) => accum + amount, 0);
64 |
65 | return function (count) {
66 |
67 | // Asking for too many results
68 | if (count >= backers.length) { return backers.map(([ name, amount ]) => name); }
69 |
70 | // The total range to draw from
71 | let remaining = total;
72 |
73 | const result = [ ];
74 | for (let c = 0; c < count; c++) {
75 |
76 | // Random weighted index to pick
77 | let v = parseInt(Math.random() * remaining);
78 |
79 | // Find that backer
80 | for (let i = 0; i < backers.length; i++) {
81 | const [ name, amount ] = backers[i];
82 | if (v < amount) {
83 | result.push(name);
84 | backers.splice(i, 1);
85 | v = amount;
86 | break;
87 | }
88 | v -= amount;
89 | }
90 |
91 | // Adjust the randge to draw from
92 | remaining -= v;
93 | }
94 |
95 | return result;
96 | };
97 | })();
98 |
99 | // container: div.backers
100 | // items: Array<{ name, image, url? }>
101 | const runZipper = function(container, items, count) {
102 | if (count == null) { count = 6; }
103 |
104 | let nextId = 1;
105 |
106 | const template = document.getElementById("template-zipper-item");
107 |
108 | function add(item, animated) {
109 | const bucket = template.cloneNode(true);
110 | bucket.id = `zipper-item-${ nextId++ }`;
111 |
112 | let x = 0;
113 | if (container.children.length) {
114 | //console.log(container.lastChild, container.lastChild.style.transform);
115 | x = parseInt(container.lastChild.getAttribute("data-x")) + 100;
116 | }
117 |
118 | bucket.style.transform = `TranslateX(${ x }%)`;
119 | bucket.setAttribute("data-x", x);
120 |
121 | if (item.url) { bucket.setAttribute("href", item.url); }
122 |
123 | const image = bucket.querySelector(".image");
124 | image.style.background = `url(${ item.image }) center no-repeat`;
125 | image.style.backgroundSize = "contain";
126 |
127 | if (animated) {
128 | bucket.style.opacity = "0";
129 | bucket.style.transition = "opacity 0.2s linear 0.5s, transform 0.2s ease-out 0.5s";
130 | }
131 |
132 | bucket.querySelector(".title").textContent = item.name;
133 |
134 | container.appendChild(bucket);
135 |
136 | if (animated) {
137 | setTimeout(() => {
138 | Array.prototype.forEach.call(container.children, (child, index) => {
139 | const target = (index - 1) * 100;
140 | if (index === 0) {
141 | child.style.transition = "opacity 0.2s linear, transform 0.2s ease-in";
142 | } else if (child === bucket) {
143 | child.style.transition = "opacity 0.2s linear 0.5s, transform 0.2s ease-out 0.5s";
144 | } else {
145 | child.style.transition = "opacity 0.3s linear 0.1s, transform 0.5s linear 0.1s";
146 | }
147 | child.style.opacity = (index === 0) ? "0": "1";
148 | child.style.transform = `TranslateX(${ target }%)`;
149 | child.setAttribute("data-x", target);
150 | });
151 | }, 100);
152 | }
153 |
154 | return bucket;
155 | }
156 |
157 | let nextIndex = 0;
158 | let prefetchImage = null;
159 | function nextItem(prefetch) {
160 | const item = items[nextIndex];
161 |
162 | // Compute the next index
163 | nextIndex = (nextIndex + 1) % items.length;
164 |
165 | // Prefetch the next image
166 | if (prefetch) {
167 | const nextItem = items[nextIndex];
168 | prefetchImage = new Image();
169 | prefetchImage.src = nextItem.image;
170 | prefetchImage.onload = function(e) {
171 | //console.log(`Prefetched: ${ nextItem.name }`);
172 | };
173 | }
174 |
175 | return item;
176 | }
177 |
178 | for (let i = 0; i < count; i++) { add(nextItem(i === (count - 1)), false); }
179 |
180 | function runOnce() {
181 | // Remove the first backer
182 | const bucket = container.firstChild;
183 | setTimeout(() => { bucket.remove(); }, 2000);
184 |
185 | // Add the next backer
186 | const el = add(nextItem(true), true);
187 | setTimeout(() => {
188 | setForegroundTimeout(runOnce, 4000, true);
189 | }, 0);
190 | }
191 | setForegroundTimeout(runOnce, 4000, true);
192 | }
193 |
194 | runZipper(document.getElementById("backers"), getBackers(120).map((name) => ({
195 | name,
196 | image: `https:/\/gitcoin.co/dynamic/avatar/${ name }`,
197 | url: `https://gitcoin.co/${ name }`
198 | })));
199 |
200 | runZipper(document.getElementById("projects"), Projects);
201 |
--------------------------------------------------------------------------------
/landing/static/st-alchemy.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
10 |
11 |
12 |
13 |
14 |
19 |
20 |
21 |
22 |
23 |
27 |
28 |
29 |
30 |
31 |
35 |
36 |
--------------------------------------------------------------------------------
/landing/static/st-ankr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/static/st-ankr.png
--------------------------------------------------------------------------------
/landing/static/st-ankr.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
14 |
15 |
--------------------------------------------------------------------------------
/landing/static/st-ethereum.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/static/st-ethereum.png
--------------------------------------------------------------------------------
/landing/static/st-etherscan.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
10 |
17 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/landing/static/st-gitcoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/landing/static/st-gitcoin.png
--------------------------------------------------------------------------------
/landing/static/st-infura.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/landing/static/st-pokt.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
18 |
19 |
--------------------------------------------------------------------------------
/landing/static/style.css:
--------------------------------------------------------------------------------
1 | html {
2 | color: #1d4c7c;
3 | font-family: sans-serif;
4 | margin: 0;
5 | }
6 | body {
7 | margin: 0;
8 | }
9 | a {
10 | box-sizing: border-box;
11 | }
12 | div {
13 | box-sizing: border-box;
14 | }
15 |
16 | a.link {
17 | color: #3c9cff;
18 | border-bottom: 1px solid #c4e1ff;
19 | text-decoration: none;
20 | }
21 |
22 | a.link:hover {
23 | color: #102b46;
24 | border-bottom: 1px solid #3c9cff;
25 | }
26 |
27 | .social {
28 | display: flex;
29 | flex-flow: row nowrap;
30 | justify-content: space-between;
31 | text-align: right;
32 | top: 20px;
33 | right: 30px;
34 | position: absolute;
35 | width: 170px;
36 | }
37 |
38 | .social a {
39 | display: block;
40 | height: 40px;
41 | opacity: 0.3;
42 | position: relative;
43 | transition: opacity 0.3s linear;
44 | width: 40px;
45 | }
46 |
47 | .social a:hover {
48 | opacity: 1;
49 | transition: opacity 0.1s linear;
50 | }
51 |
52 | .social a .title {
53 | bottom: -20px;
54 | color: #aaa;
55 | font-size: 14px;
56 | font-weight: bold;
57 | left: -30px;
58 | line-height: 30px;
59 | position: absolute;
60 | pointer-events: none;
61 | opacity: 0;
62 | transition: opacity 0.1s linear, transform 0.3s linear;
63 | text-align: center;
64 | width: 100px;
65 | }
66 |
67 | .social a:hover .title {
68 | opacity: 1;
69 | transform: translateY(10px);
70 | }
71 |
72 | .header {
73 | padding: 80px 0 20px;
74 | text-align: center;
75 | }
76 | .header .logo {
77 | background: url(./logo.png) center no-repeat;
78 | background-size: contain;
79 | height: 150px;
80 | text-align: center;
81 | }
82 |
83 | .header .logo a {
84 | line-height: 150px;
85 | display: inline-block;
86 | height: 150px;
87 | text-decoration: none;
88 | width: 250px;
89 | }
90 |
91 | .header .title {
92 | color: #1d4c7c;
93 | font-size: 30px;
94 | }
95 | .header .description {
96 | color: #668;
97 | font-size: 18px;
98 | font-family: sans-serif;
99 | font-style: italic;
100 | letter-spacing: 0.2ex;
101 | padding: 50px 0 10px;
102 | }
103 |
104 | /*.header .description */
105 | .smile {
106 | font-color: #446;
107 | font-family: monospace;
108 | font-weight: bold;
109 | letter-spacing: 0ex;
110 | }
111 |
112 | .content {
113 | padding: 0 100px;
114 | overflow-x: hidden;
115 | }
116 |
117 | .section {
118 | padding: 30px 0 60px;
119 | }
120 |
121 | .section > .title {
122 | border-top: 1px solid #999;
123 | color: #777;
124 | font-size: 17px;
125 | font-weight: bold;
126 | margin: 0 10% 40px;
127 | padding: 40px 0 20px;
128 | text-align: center;
129 | }
130 |
131 | .about {
132 | color: #aaa;
133 | font-style: italic;
134 | font-size: 20px;
135 | text-align: center;
136 | margin-bottom: 30px;
137 | width: 100%;
138 | }
139 |
140 | .blurb {
141 | font-size: 19px;
142 | line-height: 30px;
143 | margin: 0 0 40px 50%;
144 | transform: translateX(-50%);
145 | width: 600px;
146 | }
147 |
148 | .blurb li {
149 | margin: 10px 0;
150 | }
151 |
152 | .separator {
153 | border-bottom: 1px dashed #bbb;
154 | height: 0;
155 | margin-left: 50%;
156 | margin-bottom: 40px;
157 | transform: translateX(-50%);
158 | width: 400px;
159 | }
160 |
161 |
162 | .buckets {
163 | display: flex;
164 | flex-flow: row nowrap;
165 | justify-content: space-between;
166 | margin-left: 50%;
167 | transform: translateX(-50%);
168 | min-width: 850px;
169 | max-width: 1000px;
170 | width: 100%;
171 | }
172 |
173 | .bucket {
174 | border: 6px solid #ddd;
175 | border-radius: 25px;
176 | color: inherit;
177 | display: block;
178 | font-weight: bold;
179 | height: 175px;
180 | padding: 20px;
181 | position: relative;
182 | text-align: center;
183 | text-decoration: none;
184 | transition: box-shadow 0.2s linear;
185 | width: 175px;
186 | overflow: hidden;
187 | }
188 |
189 | .bucket.inactive {
190 | border: 6px solid #eee;
191 | pointer-events: none;
192 | }
193 | .bucket.inactive div.icon {
194 | opacity: 0.7;
195 | }
196 | .bucket.inactive div.title {
197 | opacity: 0.7;
198 | }
199 |
200 | .bucket:hover {
201 | box-shadow: 0px 0px 20px #ddd;
202 | transition: box-shadow 0.05s linear;
203 | }
204 |
205 | .bucket .icon {
206 | height: 100px;
207 | }
208 |
209 | .bucket .banner {
210 | background: #d55;
211 | border: 2px solid #800;
212 | color: #fff;
213 | box-shadow: 0px 0px 5px #800;
214 | font-size: 16px;
215 | font-weight: bold;
216 | right: 0;
217 | top: 0;
218 | padding: 5px 0;
219 | position: absolute;
220 | transform: translate(25%, 50%) rotate(45deg);
221 | width: 200px;
222 | }
223 |
224 | .bucket-icons {
225 | display: flex;
226 | flex-flow: row wrap;
227 | justify-content: space-between;
228 | margin-left: 50%;
229 | padding-bottom: 20px;
230 | transform: translateX(-50%);
231 | min-width: 400px;
232 | max-width: 1200px;
233 | width: 100%;
234 | }
235 |
236 | .bucket-icons a {
237 | display: block;
238 | flex-grow: 1;
239 | height: 70px;
240 | min-width: 10%;
241 | margin: 0 30px 20px;
242 | position: relative;
243 | width: 50px;
244 | }
245 |
246 | .bucket-icons a .title {
247 | color: #555;
248 | font-size: 14px;
249 | font-weight: bold;
250 | line-height: 20px;
251 | position: absolute;
252 | pointer-events: none;
253 | opacity: 0;
254 | text-align: center;
255 | top: 70px;
256 | transform: translateY(-3px);
257 | transition: opacity 0.1s linear, transform 0.3s linear;
258 | width: 100%;
259 | }
260 |
261 | .bucket-icons a:hover .title {
262 | opacity: 1;
263 | transform: translateY(8px);
264 | }
265 |
266 | /* Sponsors */
267 | .tier-container {
268 | dddborder: 10px solid black;
269 | display: flex;
270 | flex-flow: row nowrap;
271 | justify-content: space-between;
272 | margin-bottom: 60px;
273 | margin-left: 50%;
274 | min-width: 300px;
275 | max-width: 1000px;
276 | transform: translateX(-50%);
277 | width: 100%;
278 | }
279 |
280 | .tiers {
281 | border-radius: 25px;
282 | display: flex;
283 | flex-flow: row nowrap;
284 | justify-content: space-between;
285 | margin: 0 30px;
286 | padding-left: 50px;
287 | dddmargin-left: 50%;
288 | dddtransform: translateX(-50%);
289 | dddmargin-top: -20px;
290 | dddmargin-bottom: 40px;
291 | dddmin-width: 850px;
292 | dddmax-width: 1000px;
293 | position: relative;
294 | min-width: 300px;
295 | max-width: 1000px;
296 | width: 50%;
297 | }
298 |
299 | .tiers.gold {
300 | background: #fcfce6;
301 | ddbackground: #fcfcd2;
302 | border: 1px solid #898900;
303 | }
304 |
305 | .tiers.silver {
306 | background: #f1f5f5;
307 | ddborder: 1px solid #a8abab;
308 | border: 1px solid #8f9191;
309 | }
310 |
311 | .tiers .label {
312 | font-weight: bold;
313 | height: 175px;
314 | left: 20px;
315 | position: absolute;
316 | text-align: center;
317 | transform: rotate(-90deg);
318 | width: 175px;
319 | }
320 |
321 | .tiers.gold .label {
322 | color: #898900;
323 | }
324 |
325 | .tiers.silver .label {
326 | color: #8f9191;
327 | }
328 |
329 | .sponsor {
330 | ddd-border: 1px solid #000;
331 | ddd-border-radius: 25px;
332 | color: inherit;
333 | display: block;
334 | font-weight: bold;
335 | height: 175px;
336 | padding: 25px 20px 15px 20px;
337 | position: relative;
338 | text-align: center;
339 | text-decoration: none;
340 | transition: box-shadow 0.2s linear;
341 | width: 175px;
342 | overflow: hidden;
343 | }
344 |
345 | .sponsor .icon {
346 | border: 1px solid #898900;
347 | border-radius: 4px;
348 | height: 100px;
349 | margin-left: calc(87px - 50%);
350 | width: 100px;
351 | }
352 |
353 | .sponsor.no-border .icon {
354 | border: none;
355 | }
356 |
357 | .icon-sponsor-tally {
358 | background: url(/sponsors/tally.jpg) center no-repeat;
359 | background-size: contain;
360 | }
361 | .icon-sponsor-ankr {
362 | background: url(/sponsors/ankr.png) center no-repeat;
363 | background-size: contain;
364 | }
365 |
366 | .sponsor .title {
367 | padding-top: 10px;
368 | }
369 |
370 | .sponsor-about {
371 | font-style: italic;
372 | font-size: 20px;
373 | height: 175px;
374 | line-height: 175px;
375 | text-align: center;
376 | width: 50%;
377 | }
378 |
379 | /* Zipper */
380 |
381 | .zipper {
382 | height: 110px;
383 | margin-left: 50%;
384 | padding-bottom: 20px;
385 | position: relative;
386 | transform: translateX(-50%);
387 | min-width: 600px;
388 | max-width: 1200px;
389 | width: 100%;
390 | }
391 |
392 | .zipper > a {
393 | display: block;
394 | height: 70px;
395 | margin: 0 0px 20px;
396 | position: absolute;
397 | transition: opacity 0.3s linear, transform 0.2s ease-in;
398 | width: 16.6%;
399 | }
400 |
401 | .zipper .image {
402 | box-sizing: border-box;
403 | height: 70px;
404 | margin-left: 50%;
405 | transform: translateX(-50%);
406 | width: 70px;
407 | }
408 |
409 | .zipper .title {
410 | color: #777;
411 | font-size: 14px;
412 | font-weight: bold;
413 | left: 50%;
414 | line-height: 20px;
415 | opacity: 0;
416 | pointer-events: none;
417 | position: absolute;
418 | text-align: center;
419 | transform: translate(-50%, -2px);
420 | transition: opacity 0.1s linear, transform 0.3s linear;
421 | width: 200px;
422 | }
423 |
424 | .zipper a:hover .title {
425 | opacity: 1;
426 | transform: translate(-50%, 8px);
427 | }
428 |
429 |
430 | /* Section-specific Zipper Config */
431 |
432 | #backers .image {
433 | border: 2px solid #555;
434 | border-radius: 35px;
435 | }
436 |
437 | #projects .image {
438 | border-radius: 5px;
439 | }
440 |
441 |
442 | /* Copyright */
443 |
444 | .copyright {
445 | border-top: 1px solid #999;
446 | font-size: 12px;
447 | margin: 0 10% 20px;
448 | padding: 40px 0 30px;
449 | text-align: center;
450 | }
451 |
452 |
453 | /* Icons */
454 |
455 | .icon-discord {
456 | background: url(./icon-discord.svg) center no-repeat;
457 | background-size: contain;
458 | }
459 | .icon-github {
460 | background: url(./icon-github.svg) center no-repeat;
461 | background-size: contain;
462 | }
463 | .icon-twitter {
464 | background: url(./icon-twitter.svg) center no-repeat;
465 | background-size: contain;
466 | }
467 |
468 | .icon-docs {
469 | background: url(./icon-docs.svg) center no-repeat;
470 | background-size: contain;
471 | }
472 | .icon-toolbox {
473 | background: url(./icon-toolbox.svg) center no-repeat;
474 | background-size: contain;
475 | }
476 | .icon-playground {
477 | background: url(./icon-playground.svg) center no-repeat;
478 | background-size: contain;
479 | }
480 | .icon-wallet {
481 | background: url(./icon-wallet.svg) center no-repeat;
482 | background-size: contain;
483 | }
484 |
485 | .icon-st-ethereum {
486 | background: url(./st-ethereum.png) center no-repeat;
487 | background-size: contain;
488 | }
489 | .icon-st-gitcoin {
490 | background: url(./st-gitcoin.png) center no-repeat;
491 | background-size: contain;
492 | }
493 |
494 | .icon-st-etherscan {
495 | background: url(./st-etherscan.svg) center no-repeat;
496 | background-size: contain;
497 | }
498 | .icon-st-infura {
499 | background: url(./st-infura.svg) center no-repeat;
500 | background-size: contain;
501 | }
502 | .icon-st-alchemy {
503 | background: url(./st-alchemy.svg) center no-repeat;
504 | background-size: contain;
505 | }
506 | .icon-st-pokt {
507 | background: url(./st-pokt.svg) center no-repeat;
508 | background-size: contain;
509 | }
510 | .icon-st-ankr {
511 | background: url(./st-ankr.png) center no-repeat;
512 | background-size: contain;
513 | }
514 |
515 |
--------------------------------------------------------------------------------
/playground/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/playground/favicon.ico
--------------------------------------------------------------------------------
/playground/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | ethers playground
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
ethers playground
18 |
19 |
24 |
27 |
28 |
35 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/playground/inspect.js:
--------------------------------------------------------------------------------
1 | const inspect = (function(global) {
2 |
3 | var hasMap = typeof Map === 'function' && Map.prototype;
4 | var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;
5 | var mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;
6 | var mapForEach = hasMap && Map.prototype.forEach;
7 | var hasSet = typeof Set === 'function' && Set.prototype;
8 | var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;
9 | var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;
10 | var setForEach = hasSet && Set.prototype.forEach;
11 | var hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;
12 | var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;
13 | var hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;
14 | var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;
15 | var hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;
16 | var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;
17 | var booleanValueOf = Boolean.prototype.valueOf;
18 | var objectToString = Object.prototype.toString;
19 | var functionToString = Function.prototype.toString;
20 | var match = String.prototype.match;
21 | var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;
22 | var gOPS = Object.getOwnPropertySymbols;
23 | var symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;
24 | var hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';
25 | var isEnumerable = Object.prototype.propertyIsEnumerable;
26 |
27 | var gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (
28 | [].__proto__ === Array.prototype // eslint-disable-line no-proto
29 | ? function (O) {
30 | return O.__proto__; // eslint-disable-line no-proto
31 | }
32 | : null
33 | );
34 |
35 | var inspectCustom = Symbol.for("nodejs.util.inspect.custom"); //require('./util.inspect').custom;
36 | var inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;
37 | var toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null;
38 |
39 | global.exports = function inspect_(obj, options, depth, seen) {
40 | var opts = options || {};
41 |
42 | if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {
43 | throw new TypeError('option "quoteStyle" must be "single" or "double"');
44 | }
45 | if (
46 | has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'
47 | ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity
48 | : opts.maxStringLength !== null
49 | )
50 | ) {
51 | throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');
52 | }
53 | var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;
54 | if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {
55 | throw new TypeError('option "customInspect", if provided, must be `true`, `false`, or `\'symbol\'`');
56 | }
57 |
58 | if (
59 | has(opts, 'indent')
60 | && opts.indent !== null
61 | && opts.indent !== '\t'
62 | && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)
63 | ) {
64 | throw new TypeError('options "indent" must be "\\t", an integer > 0, or `null`');
65 | }
66 |
67 | if (typeof obj === 'undefined') {
68 | return 'undefined';
69 | }
70 | if (obj === null) {
71 | return 'null';
72 | }
73 | if (typeof obj === 'boolean') {
74 | return obj ? 'true' : 'false';
75 | }
76 |
77 | if (typeof obj === 'string') {
78 | return inspectString(obj, opts);
79 | }
80 | if (typeof obj === 'number') {
81 | if (obj === 0) {
82 | return Infinity / obj > 0 ? '0' : '-0';
83 | }
84 | return String(obj);
85 | }
86 | if (typeof obj === 'bigint') {
87 | return String(obj) + 'n';
88 | }
89 |
90 | var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;
91 | if (typeof depth === 'undefined') { depth = 0; }
92 | if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {
93 | return isArray(obj) ? '[Array]' : '[Object]';
94 | }
95 |
96 | var indent = getIndent(opts, depth);
97 |
98 | if (typeof seen === 'undefined') {
99 | seen = [];
100 | } else if (indexOf(seen, obj) >= 0) {
101 | return '[Circular]';
102 | }
103 |
104 | function inspect(value, from, noIndent) {
105 | if (from) {
106 | seen = seen.slice();
107 | seen.push(from);
108 | }
109 | if (noIndent) {
110 | var newOpts = {
111 | depth: opts.depth
112 | };
113 | if (has(opts, 'quoteStyle')) {
114 | newOpts.quoteStyle = opts.quoteStyle;
115 | }
116 | return inspect_(value, newOpts, depth + 1, seen);
117 | }
118 | return inspect_(value, opts, depth + 1, seen);
119 | }
120 |
121 | if (typeof obj === 'function') {
122 | var name = nameOf(obj);
123 | var keys = arrObjKeys(obj, inspect);
124 | return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : '');
125 | }
126 | if (isSymbol(obj)) {
127 | var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\(.*\))_[^)]*$/, '$1') : symToString.call(obj);
128 | return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;
129 | }
130 | if (isElement(obj)) {
131 | var s = '<' + String(obj.nodeName).toLowerCase();
132 | var attrs = obj.attributes || [];
133 | for (var i = 0; i < attrs.length; i++) {
134 | s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);
135 | }
136 | s += '>';
137 | if (obj.childNodes && obj.childNodes.length) { s += '...'; }
138 | s += '' + String(obj.nodeName).toLowerCase() + '>';
139 | return s;
140 | }
141 | if (isArray(obj)) {
142 | if (obj.length === 0) { return '[]'; }
143 | var xs = arrObjKeys(obj, inspect);
144 | if (indent && !singleLineValues(xs)) {
145 | return '[' + indentedJoin(xs, indent) + ']';
146 | }
147 | return '[ ' + xs.join(', ') + ' ]';
148 | }
149 | if (isError(obj)) {
150 | var parts = arrObjKeys(obj, inspect);
151 | if (parts.length === 0) { return '[' + String(obj) + ']'; }
152 | return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }';
153 | }
154 | if (typeof obj === 'object' && customInspect) {
155 | if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {
156 | var result = obj[inspectSymbol]();
157 | if (result && typeof(result) === "object" && result.name && result.values) {
158 | var ys = arrObjKeys(result.values, inspect);
159 | if (ys.length === 0) { return result.name + ' {}'; }
160 | if (indent) {
161 | return result.name + ' {' + indentedJoin(ys, indent) + '}';
162 | }
163 | return result.name + ' { ' + ys.join(', ') + ' }';
164 | }
165 | return result;
166 | } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {
167 | return obj.inspect();
168 | }
169 | }
170 | if (isMap(obj)) {
171 | var mapParts = [];
172 | mapForEach.call(obj, function (value, key) {
173 | mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));
174 | });
175 | return collectionOf('Map', mapSize.call(obj), mapParts, indent);
176 | }
177 | if (isSet(obj)) {
178 | var setParts = [];
179 | setForEach.call(obj, function (value) {
180 | setParts.push(inspect(value, obj));
181 | });
182 | return collectionOf('Set', setSize.call(obj), setParts, indent);
183 | }
184 | if (isWeakMap(obj)) {
185 | return weakCollectionOf('WeakMap');
186 | }
187 | if (isWeakSet(obj)) {
188 | return weakCollectionOf('WeakSet');
189 | }
190 | if (isWeakRef(obj)) {
191 | return weakCollectionOf('WeakRef');
192 | }
193 | if (isNumber(obj)) {
194 | return markBoxed(inspect(Number(obj)));
195 | }
196 | if (isBigInt(obj)) {
197 | return markBoxed(inspect(bigIntValueOf.call(obj)));
198 | }
199 | if (isBoolean(obj)) {
200 | return markBoxed(booleanValueOf.call(obj));
201 | }
202 | if (isString(obj)) {
203 | return markBoxed(inspect(String(obj)));
204 | }
205 | if (!isDate(obj) && !isRegExp(obj)) {
206 | var ys = arrObjKeys(obj, inspect);
207 | var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
208 | var protoTag = obj instanceof Object ? '' : 'null prototype';
209 | var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : '';
210 | var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';
211 | var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : '');
212 | if (ys.length === 0) { return tag + '{}'; }
213 | if (indent) {
214 | return tag + '{' + indentedJoin(ys, indent) + '}';
215 | }
216 | return tag + '{ ' + ys.join(', ') + ' }';
217 | }
218 | return String(obj);
219 | };
220 |
221 | function wrapQuotes(s, defaultStyle, opts) {
222 | var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '"' : "'";
223 | return quoteChar + s + quoteChar;
224 | }
225 |
226 | function quote(s) {
227 | return String(s).replace(/"/g, '"');
228 | }
229 |
230 | function isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
231 | function isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
232 | function isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
233 | function isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
234 | function isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
235 | function isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
236 | function isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
237 |
238 | // Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives
239 | function isSymbol(obj) {
240 | if (hasShammedSymbols) {
241 | return obj && typeof obj === 'object' && obj instanceof Symbol;
242 | }
243 | if (typeof obj === 'symbol') {
244 | return true;
245 | }
246 | if (!obj || typeof obj !== 'object' || !symToString) {
247 | return false;
248 | }
249 | try {
250 | symToString.call(obj);
251 | return true;
252 | } catch (e) {}
253 | return false;
254 | }
255 |
256 | function isBigInt(obj) {
257 | if (!obj || typeof obj !== 'object' || !bigIntValueOf) {
258 | return false;
259 | }
260 | try {
261 | bigIntValueOf.call(obj);
262 | return true;
263 | } catch (e) {}
264 | return false;
265 | }
266 |
267 | var hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };
268 | function has(obj, key) {
269 | return hasOwn.call(obj, key);
270 | }
271 |
272 | function toStr(obj) {
273 | return objectToString.call(obj);
274 | }
275 |
276 | function nameOf(f) {
277 | if (f.name) { return f.name; }
278 | var m = match.call(functionToString.call(f), /^function\s*([\w$]+)/);
279 | if (m) { return m[1]; }
280 | return null;
281 | }
282 |
283 | function indexOf(xs, x) {
284 | if (xs.indexOf) { return xs.indexOf(x); }
285 | for (var i = 0, l = xs.length; i < l; i++) {
286 | if (xs[i] === x) { return i; }
287 | }
288 | return -1;
289 | }
290 |
291 | function isMap(x) {
292 | if (!mapSize || !x || typeof x !== 'object') {
293 | return false;
294 | }
295 | try {
296 | mapSize.call(x);
297 | try {
298 | setSize.call(x);
299 | } catch (s) {
300 | return true;
301 | }
302 | return x instanceof Map; // core-js workaround, pre-v2.5.0
303 | } catch (e) {}
304 | return false;
305 | }
306 |
307 | function isWeakMap(x) {
308 | if (!weakMapHas || !x || typeof x !== 'object') {
309 | return false;
310 | }
311 | try {
312 | weakMapHas.call(x, weakMapHas);
313 | try {
314 | weakSetHas.call(x, weakSetHas);
315 | } catch (s) {
316 | return true;
317 | }
318 | return x instanceof WeakMap; // core-js workaround, pre-v2.5.0
319 | } catch (e) {}
320 | return false;
321 | }
322 |
323 | function isWeakRef(x) {
324 | if (!weakRefDeref || !x || typeof x !== 'object') {
325 | return false;
326 | }
327 | try {
328 | weakRefDeref.call(x);
329 | return true;
330 | } catch (e) {}
331 | return false;
332 | }
333 |
334 | function isSet(x) {
335 | if (!setSize || !x || typeof x !== 'object') {
336 | return false;
337 | }
338 | try {
339 | setSize.call(x);
340 | try {
341 | mapSize.call(x);
342 | } catch (m) {
343 | return true;
344 | }
345 | return x instanceof Set; // core-js workaround, pre-v2.5.0
346 | } catch (e) {}
347 | return false;
348 | }
349 |
350 | function isWeakSet(x) {
351 | if (!weakSetHas || !x || typeof x !== 'object') {
352 | return false;
353 | }
354 | try {
355 | weakSetHas.call(x, weakSetHas);
356 | try {
357 | weakMapHas.call(x, weakMapHas);
358 | } catch (s) {
359 | return true;
360 | }
361 | return x instanceof WeakSet; // core-js workaround, pre-v2.5.0
362 | } catch (e) {}
363 | return false;
364 | }
365 |
366 | function isElement(x) {
367 | if (!x || typeof x !== 'object') { return false; }
368 | if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {
369 | return true;
370 | }
371 | return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';
372 | }
373 |
374 | function inspectString(str, opts) {
375 | if (str.length > opts.maxStringLength) {
376 | var remaining = str.length - opts.maxStringLength;
377 | var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');
378 | return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer;
379 | }
380 | // eslint-disable-next-line no-control-regex
381 | var s = str.replace(/(['\\])/g, '\\$1').replace(/[\x00-\x1f]/g, lowbyte);
382 | return wrapQuotes(s, 'single', opts);
383 | }
384 |
385 | function lowbyte(c) {
386 | var n = c.charCodeAt(0);
387 | var x = {
388 | 8: 'b',
389 | 9: 't',
390 | 10: 'n',
391 | 12: 'f',
392 | 13: 'r'
393 | }[n];
394 | if (x) { return '\\' + x; }
395 | return '\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase();
396 | }
397 |
398 | function markBoxed(str) {
399 | return 'Object(' + str + ')';
400 | }
401 |
402 | function weakCollectionOf(type) {
403 | return type + ' { ? }';
404 | }
405 |
406 | function collectionOf(type, size, entries, indent) {
407 | var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', ');
408 | return type + ' (' + size + ') {' + joinedEntries + '}';
409 | }
410 |
411 | function singleLineValues(xs) {
412 | for (var i = 0; i < xs.length; i++) {
413 | if (indexOf(xs[i], '\n') >= 0) {
414 | return false;
415 | }
416 | }
417 | return true;
418 | }
419 |
420 | function getIndent(opts, depth) {
421 | var baseIndent;
422 | if (opts.indent === '\t') {
423 | baseIndent = '\t';
424 | } else if (typeof opts.indent === 'number' && opts.indent > 0) {
425 | baseIndent = Array(opts.indent + 1).join(' ');
426 | } else {
427 | return null;
428 | }
429 | return {
430 | base: baseIndent,
431 | prev: Array(depth + 1).join(baseIndent)
432 | };
433 | }
434 |
435 | function indentedJoin(xs, indent) {
436 | if (xs.length === 0) { return ''; }
437 | var lineJoiner = '\n' + indent.prev + indent.base;
438 | return lineJoiner + xs.join(',' + lineJoiner) + '\n' + indent.prev;
439 | }
440 |
441 | function arrObjKeys(obj, inspect) {
442 | var isArr = isArray(obj);
443 | var xs = [];
444 | if (isArr) {
445 | xs.length = obj.length;
446 | for (var i = 0; i < obj.length; i++) {
447 | xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';
448 | }
449 | }
450 | var syms = typeof gOPS === 'function' ? gOPS(obj) : [];
451 | var symMap;
452 | if (hasShammedSymbols) {
453 | symMap = {};
454 | for (var k = 0; k < syms.length; k++) {
455 | symMap['$' + syms[k]] = syms[k];
456 | }
457 | }
458 |
459 | for (var key in obj) { // eslint-disable-line no-restricted-syntax
460 | if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
461 | if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
462 | if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {
463 | // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section
464 | continue; // eslint-disable-line no-restricted-syntax, no-continue
465 | } else if ((/[^\w$]/).test(key)) {
466 | xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));
467 | } else {
468 | xs.push(key + ': ' + inspect(obj[key], obj));
469 | }
470 | }
471 | if (typeof gOPS === 'function') {
472 | for (var j = 0; j < syms.length; j++) {
473 | if (isEnumerable.call(obj, syms[j])) {
474 | xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));
475 | }
476 | }
477 | }
478 | return xs;
479 | }
480 |
481 | function NamedObject(name, values) {
482 | this.name = name;
483 | this.values = values;
484 | }
485 |
486 | const sandboxInspect = function(obj) {
487 | return exports(obj, {
488 | quoteStyle: "double",
489 | indent: 2
490 | });
491 | };
492 |
493 | Object.defineProperty(sandboxInspect, "custom", {
494 | configurable: false,
495 | enumerable: true,
496 | writable: false,
497 | value: inspectCustom
498 | });
499 |
500 | Object.defineProperty(sandboxInspect, "NamedObject", {
501 | configurable: false,
502 | enumerable: true,
503 | writable: false,
504 | value: NamedObject
505 | });
506 |
507 | return sandboxInspect;
508 |
509 | })(self);
510 |
--------------------------------------------------------------------------------
/playground/og-preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethers-io/website/c3e460cbb2e79be7369201ed47d2bc097a7dc3bd/playground/og-preview.jpg
--------------------------------------------------------------------------------
/playground/sandbox.js:
--------------------------------------------------------------------------------
1 | importScripts("https:\/\/cdnjs.cloudflare.com/ajax/libs/ethers/6.13.2/ethers.umd.min.js");
2 | importScripts("./inspect.js");
3 | importScripts("./help.js");
4 |
5 | /**
6 | * Communication Packets for two-way communication
7 | *
8 | * Action; sends a request which expects a Response
9 | * - { action: string, id: number, params: object }
10 | * Notce; sends a one-way notification
11 | * - { notice: string, params: object }
12 | * Response; the response to an earlier Action
13 | * - { id: number, result: any }
14 | */
15 |
16 | let _ = undefined;
17 | let _p = undefined;
18 |
19 | // Debug
20 | //self.w = ethers.Wallet.createRandom();
21 |
22 | const { _onMessage, ethereum } = (function({ Basic, Globals, Help, Returns }, evalFunc) {
23 |
24 | class Eip1193PassThrough {
25 | constructor() { }
26 |
27 | async request(params) {
28 | const resp = await send("provider", params);
29 | if (resp.error) {
30 | throw new Error(resp.error);
31 | }
32 | return resp.result;
33 | }
34 |
35 | on() {
36 | throw new Error("not implemented yet; coming soon");
37 | }
38 | }
39 |
40 | const lookupClass = new Map();
41 | Help.forEach((info) => {
42 | if (info.cls) { lookupClass.set(info.cls, info); }
43 | if (info.func) { lookupClass.set(info.func, info); }
44 | });
45 |
46 | class Follower {
47 |
48 | // descr:
49 | // - name
50 | // - returns: Returns; used to determine follow
51 | // - display?
52 | // - params?: Array
53 |
54 | constructor(descr) {
55 | if (typeof(descr) === "string") {
56 | descr = { name };
57 | } else {
58 | descr = Object.assign({ }, descr);
59 | }
60 |
61 | descr.display = descr.insert = descr.name;
62 |
63 | // It's a function, dress it up
64 | if (descr.params) {
65 | descr.display += "()";
66 | descr.insert = descr.name + "(" + descr.params.reduce((accum, p) => {
67 | if (p[0] !== "%") {
68 | accum.push(`%${ p }`);
69 | } else if (p.indexOf("=") >= 0) {
70 | accum.push(p.substring(p.indexOf("=") + 1).trim());
71 | }
72 | return accum;
73 | }, [ ]).join(", ") + ")";
74 | }
75 |
76 | // Unknown return type
77 | if (!descr.returns) { descr.returns = new Returns("_"); }
78 |
79 | this._descr = descr;
80 | }
81 |
82 | descr(options) { return this._descr; }
83 |
84 | keys() { return [ ]; }
85 |
86 | follow() { return null; }
87 |
88 | toString() {
89 | return `<${ this.constructor.name } descr="${ JSON.stringify(this.descr) }" keys=(${ this.keys().join(", ") })>`;
90 | }
91 |
92 | // This will always returns a DotFollower or CallFollower?
93 | static from(name, value) {
94 |
95 | if (value == null) { return null; }
96 |
97 | if (value.returns && value.returns instanceof Returns) {
98 | //if (value.returns.type === "class") {
99 | // return new ClassFollower();
100 | //}
101 | let follower = new PropsFollower(Object.assign({ name }, value), value.returns.props());
102 | if (value.params) {
103 | return new CallFollower(follower);
104 | }
105 | return new DotFollower(follower);
106 | }
107 |
108 | let match = lookupClass.get(value);
109 | if (match) {
110 | // In case they use hexx = hexlify, allow the new thing to know
111 | const renamed = Object.assign({ }, match, { name });
112 |
113 | // A class we provide
114 | if (match.cls) { return new ClassFollower(renamed); }
115 |
116 | // A function we provide
117 | if (match.func) { return Follower.from(name, renamed); }
118 |
119 | throw new Error("hmm...");
120 | }
121 |
122 | // An instance of a class we provide
123 | match = lookupClass.get(value.constructor);
124 | if (match && match.cls) {
125 | const properties = Object.assign({ }, match.properties);
126 | for (const key in value) {
127 | if (!(key in properties)) {
128 | properties[key] = { returns: Returns.from("_") };
129 | }
130 | }
131 | return new DotFollower(new PropsFollower({
132 | name: name,
133 | returns: Returns.from(match.name)
134 | }, properties));
135 | }
136 |
137 | // Something basic
138 | const returns = Returns.fromBasic(value);
139 | if (returns) {
140 | return new DotFollower(new PropsFollower({
141 | name, returns
142 | }, returns.props()));
143 | }
144 |
145 | // Something else
146 | return new DotFollower(new ObjectFollower(name, value));
147 | }
148 | }
149 |
150 | class StateFollower extends Follower {
151 | constructor(descr, followers) {
152 | super(descr);
153 | this.followers = followers;
154 | }
155 |
156 | follow(key) {
157 | return this.followers[key] || null;
158 | }
159 |
160 | toString() {
161 | const followers = Object.keys(this.followers).map((key) => {
162 | return `${ JSON.stringify(key) }=${ this.followers[key].toString() }`;
163 | });
164 | return `<${ this.constructor.name } ${ followers.join("\n ") })>`;
165 | }
166 | }
167 |
168 | class DotFollower extends StateFollower {
169 | constructor(follower) { super(follower.descr(), { ".": follower }); }
170 | }
171 |
172 | class CallFollower extends StateFollower {
173 | constructor(follower) {
174 | super(follower.descr(), { "()": new DotFollower(follower) });
175 | }
176 | }
177 |
178 | class ClassFollower extends StateFollower {
179 | constructor(help) {
180 | const name = help.name;
181 |
182 | const dotFollower = new PropsFollower({
183 | name, returns: Returns.from(help.cls)
184 | }, help.staticProperties);
185 |
186 | const callFollower = new DotFollower(new PropsFollower({
187 | name, params: help.params, returns: Returns.from(help.name)
188 | }, help.properties));
189 |
190 | super(dotFollower.descr(), {
191 | ".": dotFollower,
192 | "()": callFollower
193 | });
194 |
195 | this.help = help;
196 | }
197 |
198 | descr(options) {
199 | if (options && options.newing) {
200 | return this.follow("()").descr();
201 | }
202 | return super.descr(options);
203 | }
204 | }
205 |
206 | /*
207 | class ContractFollower extends Follower {
208 | constructor(contract) {
209 | super({ returns: Returns.from("Contract") });
210 | }
211 |
212 | keys() {
213 | const keys = [ "address" ];
214 | // populateTransaction, staticCall, estimateGas
215 | }
216 |
217 | follow(key) {
218 | }
219 | }
220 | */
221 |
222 | class PropsFollower extends Follower {
223 | constructor(descr, props) {
224 | super(descr);
225 | this._props = props;
226 | }
227 |
228 | keys() { return Object.keys(this._props); }
229 |
230 | follow(key) {
231 | return Follower.from(key, Object.assign({ name: key }, this._props[key]));
232 | }
233 | }
234 |
235 | class ObjectFollower extends Follower {
236 | constructor(name, object) {
237 | super({ name, returns: Returns.from("_") });
238 | this.object = Object.assign({ }, object);
239 | }
240 |
241 | add(object) {
242 | Object.keys(object).forEach((key) => {
243 | this.object[key] = object[key];
244 | });
245 | }
246 |
247 | keys() { return Object.keys(this.object); }
248 |
249 | follow(key) {
250 | if (!(key in this.object)) { return null; }
251 | return Follower.from(key, this.object[key]);
252 | }
253 | }
254 |
255 | function findMatches(tokens) {
256 | //console.log("FIND"); /// DEBUG
257 |
258 | let follower = new Follower();
259 | let allowed = [ "ROOT" ];
260 |
261 | let descrOptions = { };
262 |
263 | while(follower && tokens.length) {
264 | const token = tokens.pop();
265 | //console.log("TOKEN", token.token, token.text, follower.toString()); ///DEBUG
266 |
267 | if (token.token === "CURSOR") {
268 | //console.internal(token);
269 | const prefix = token.text;
270 |
271 | const matches = follower.keys().reduce((accum, key) => {
272 | if (key.substring(0, prefix.length) === prefix) {
273 | const next = follower.follow(key);
274 | if (next) { accum.push(next.descr(descrOptions)); }
275 | }
276 | return accum;
277 | }, [ ]);
278 |
279 | return { offset: token.offset, width: (token.width + token.precog.length), precog: token.precog, matches};
280 | }
281 |
282 | if (allowed.indexOf(token.token) === -1) {
283 | //console.internal("Expected:", allowed, "Got:", token);
284 | follower = null;
285 | break;
286 | }
287 |
288 | switch (token.token) {
289 | case "ROOT":
290 | allowed = [ "IDENTIFIER", "NEW", "AWAIT" ];
291 | follower = new ObjectFollower("self", self);
292 | follower.add(Globals);
293 | break;
294 |
295 | case "DOT":
296 | follower = follower.follow(".");
297 | allowed = [ "IDENTIFIER" ];
298 | break;
299 |
300 | case "NEW":
301 | allowed = [ "IDENTIFIER" ];
302 | descrOptions.newing = true
303 | break;
304 |
305 | case "AWAIT":
306 | allowed = [ "IDENTIFIER" ];
307 | descrOptions.awaiting = true
308 | break;
309 |
310 | case "IDENTIFIER":
311 | allowed = [ "DOT", "PAREN", "BRACKET" ];
312 | follower = follower.follow(token.text);
313 | break;
314 |
315 | case "PAREN":
316 | allowed = [ "DOT" ];
317 | follower = follower.follow("()");
318 | descrOptions.newing = false;
319 | descrOptions.awaiting = false;
320 | break;
321 |
322 | case "BRACKET":
323 | allowed = [ "DOT" ];
324 | break;
325 | }
326 | }
327 |
328 | return null;
329 | }
330 |
331 | /*
332 | function getInspect(value) {
333 | if (value == null) { return null };
334 |
335 | for (const name in ethers.providers) {
336 | const klass = ethers.providers[name];
337 | if (klass === value) {
338 | return { type: "Class", name };
339 | }
340 | }
341 |
342 | for (const name in ethers.providers) {
343 | const klass = ethers.providers[name];
344 | if (klass && klass === value.constructor) { return { type: name }; }
345 | }
346 |
347 | if (ethers.BigNumber.isBigNumber(value)) {
348 | return { type: "BigNumber" };
349 | }
350 |
351 | if (Array.isArray(value)) {
352 | return { type: "array", length: value.length };
353 | }
354 |
355 | if (typeof(value) === "object") {
356 | return { type: "object", keys: Object.keys(value) };
357 | }
358 |
359 | return typeof(value);
360 | }
361 | */
362 |
363 | function _getSigners() {
364 | return [ ];
365 | }
366 |
367 | function S(v) { return JSON.stringify(v); }
368 | function post(v) { postMessage(S(v)); }
369 |
370 | let nextId = 1;
371 | const resolveMap = { };
372 | function send(action, params) {
373 | const id = nextId++;
374 | post({ action, id, params });
375 | return new Promise((resolve) => {
376 | resolveMap[String(id)] = resolve;
377 | });
378 | }
379 |
380 | async function handleAction(action, params) {
381 |
382 | if (action === "eval") {
383 |
384 | let result = null;
385 | try {
386 | result = evalFunc(params.code);
387 | } catch (error) {
388 | if (error instanceof SyntaxError && params.asyncExpr) {
389 | return { sync: "sync", type: "error", value: JSON.stringify(error.message), note: "NB: only expressions are allowed if using `await` (no statements)", error: inspect(error) };
390 | }
391 | return { sync: "sync", type: "error", value: JSON.stringify(error.message), error: inspect(error) };
392 | }
393 |
394 | _ = result;
395 | _p = undefined;
396 |
397 | if (result instanceof Promise) {
398 | post({ notice: "async-running", id: id });
399 | return await result.then((result) => {
400 | if (params.asyncExpr) { _ = result; }
401 | _p = result;
402 | return { sync: "async", type: "result", value: inspect(result) };
403 | }, (error) => {
404 | _p = error;
405 | return { sync: "async", type: "error", value: JSON.stringify(error.message), error: inspect(error) };
406 | });
407 |
408 | } else {
409 | return { sync: "sync", type: "result", value: inspect(result) };
410 | }
411 |
412 | } else if (action === "inspect") {
413 | return findMatches(params.tokens);
414 | }
415 | }
416 |
417 | function handleNotice(notice, params) {
418 | }
419 |
420 | function _onMessage(e) {
421 | const data = JSON.parse(e.data);
422 | const id = data.id;
423 |
424 | if (data.result) {
425 | const resolve = resolveMap[String(id)];
426 |
427 | if (resolve) {
428 | delete resolveMap[String(id)];
429 | resolve(data.result);
430 | } else {
431 | console.log(`result for ${ id } with no resolver`);
432 | }
433 |
434 | } else if (data.notice) {
435 | handleNotice(data.notice, data.params || { });
436 |
437 | } else if (data.action) {
438 | handleAction(data.action, data.params || { }).then((result) => {;
439 | post({ id, result });
440 | }, (error) => {
441 | console.internal(error);
442 | console.internal(error.stack);
443 | });
444 | }
445 | }
446 |
447 | const ethereum = new Eip1193PassThrough();
448 |
449 | // Set up the console
450 | ["log", "warn", "error"].forEach((logger) => {
451 | const log = console[logger].bind(console);
452 | console[logger] = function(...args) {
453 | log(...args);
454 | post({ notice: "log", params: { logger, args: args.map(inspect) } });
455 | };
456 | });
457 |
458 | Object.defineProperty(console, "internal", {
459 | configurable: false,
460 | enumerable: true,
461 | value: (function (...args) {
462 | post({ notice: "internal", params: { args: args.map(inspect) }});
463 | })
464 | });
465 |
466 | // Expose all Ethers function, classes and constants
467 | for (const key in ethers) {
468 | self[key] = ethers[key];
469 | }
470 |
471 | // Some convenient things to expose
472 | abiCoder = ethers.AbiCoder.defaultAbiCoder();
473 | provider = ethers.getDefaultProvider();
474 |
475 |
476 | // Pretty Format some common ethers classes
477 |
478 | Help.forEach((help) => {
479 | if (!help.cls || !help.inspect) { return; }
480 | help.cls.prototype[inspect.custom] = function() {
481 | return inspect(help.inspect.call(this));
482 | }
483 | });
484 |
485 | Uint8Array.prototype[inspect.custom] = function() {
486 | return `Uint8Array { ${ Array.prototype.map.call(this, (i) => String(i)).join(", ") } }`;
487 | };
488 |
489 | /*
490 | ethers.providers.AlchemyProvider.prototype[inspect.custom] = function() {
491 | return new inspect.NamedObject(this.constructor.name, {
492 | network: this._network.name,
493 | url: this.connection.url,
494 | apiKey: (this.isCommunityResource() ? "default": this.apiKey)
495 | });
496 | };
497 |
498 | ethers.providers.CloudflareProvider.prototype[inspect.custom] = function() {
499 | return new inspect.NamedObject(this.constructor.name, {
500 | network: this._network.name,
501 | url: this.connection.url
502 | });
503 | };
504 |
505 | ethers.providers.EtherscanProvider.prototype[inspect.custom] = function() {
506 | return new inspect.NamedObject(this.constructor.name, {
507 | network: this._network.name,
508 | baseUrl: this.baseUrl,
509 | apiKey: this.isCommunityResource() ? "default": this.apiKey
510 | });
511 | };
512 |
513 | ethers.providers.FallbackProvider.prototype[inspect.custom] = function() {
514 | return new inspect.NamedObject(this.constructor.name, {
515 | network: this._network.name,
516 | anyNetwork: this.anyNetwork,
517 | providerConfigs: this.providerConfigs,
518 | quorum: this.quorum
519 | });
520 | };
521 |
522 | ethers.providers.InfuraProvider.prototype[inspect.custom] = function() {
523 | return new inspect.NamedObject(this.constructor.name, {
524 | network: this._network.name,
525 | url: this.connection.url,
526 | projectId: (this.isCommunityResource() ? "default": this.projectId),
527 | projectSecret: this.projectSecret
528 | });
529 | };
530 |
531 | ethers.providers.PocketProvider.prototype[inspect.custom] = function() {
532 | return new inspect.NamedObject(this.constructor.name, {
533 | network: this._network.name,
534 | url: this.connection.url,
535 | applicationId: (this.isCommunityResource() ? "default": this.projectId),
536 | applicationSecretKey: this.applicationSecretKey,
537 | loadBalancer: this.loadBalancer
538 | });
539 | };
540 | */
541 |
542 | // Set up an alias to self as window
543 | Object.defineProperty(self, "signers", {
544 | configurable: false,
545 | enumerable: true,
546 | get: _getSigners
547 | });
548 |
549 | return {
550 | _onMessage, ethereum
551 | };
552 |
553 |
554 | })(Help(ethers), (_code) => eval(_code));
555 | delete Help;
556 | // The above helps us isolate a few extra variables from the
557 | // eval; only the _code should be visible, all other variables
558 | // are hidden
559 |
560 | // Set the message handler (read-only)
561 | onmessage = _onMessage
562 | Object.defineProperty(self, "onmessage", {
563 | configurable: false,
564 | enumerable: true,
565 | writable: false,
566 | value: _onMessage
567 | });
568 |
569 | // Set up an alias to self as window (read-only)
570 | Object.defineProperty(self, "window", {
571 | configurable: false,
572 | enumerable: true,
573 | writable: false,
574 | value: self
575 | });
576 |
577 | // Set up an alias to self as window
578 | Object.defineProperty(self, "self", {
579 | configurable: false,
580 | enumerable: true,
581 | writable: false,
582 | value: self
583 | });
584 |
585 | // Set up self.ethereum (also window.ethereum; read-only)
586 | Object.defineProperty(self, "ethereum", {
587 | configurable: false,
588 | enumerable: true,
589 | writable: false,
590 | value: ethereum
591 | });
592 |
593 | // Notify our container we are ready to party on!
594 | postMessage(JSON.stringify("ready"));
595 |
--------------------------------------------------------------------------------
/playground/sources/caret.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/playground/sources/checkmark.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/playground/sources/dark-mode-moon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
10 |
11 |
--------------------------------------------------------------------------------
/playground/sources/dark-mode-stars.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
10 |
12 |
14 |
15 |
--------------------------------------------------------------------------------
/playground/sources/dark-mode-sun.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/playground/sources/generate.mjs:
--------------------------------------------------------------------------------
1 | import { readFileSync } from "fs";
2 |
3 | const css = readFileSync("./style.css").toString();
4 |
5 | const output = css.replace(/url\((.*)\)/g, (all, url) => {
6 | const base64 = readFileSync(url).toString("base64");
7 | return `url(data:image/svg+xml;base64,${ base64 })`;
8 | });
9 |
10 | console.log(output);
11 |
--------------------------------------------------------------------------------
/playground/sources/icon-library.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
12 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/playground/sources/icon-settings.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
24 |
38 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/playground/sources/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
12 |
13 |
--------------------------------------------------------------------------------
/playground/sources/options-open.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
12 |
14 |
18 |
20 |
24 |
26 |
27 |
--------------------------------------------------------------------------------
/playground/sources/style.css:
--------------------------------------------------------------------------------
1 | html {
2 | margin: 0;
3 | }
4 |
5 | body {
6 | margin: 0;
7 | transition: background-color 0.2s linear;
8 | }
9 | body.darkMode {
10 | background: #111;
11 | color: #fff;
12 | }
13 |
14 | /* We initialize all animations off until JavaScript
15 | has had a chance to set thigns up */
16 |
17 | body.disableAnimations { transition: none !important; }
18 | body.disableAnimations * { transition: none !important; }
19 |
20 | div { box-sizing: border-box; }
21 |
22 | /* Animated classes for showing the sidebar */
23 |
24 | .left {
25 | transition: width 0.3s ease-out;
26 | width: 100%;
27 | }
28 |
29 | .right {
30 | bottom: 0;
31 | position: fixed;
32 | right: -400px;
33 | top: 0;
34 | transition: transform 0.3s ease-out;
35 | width: 400px;
36 | }
37 |
38 | body.showSidebar .left {
39 | width: calc(100% - 400px);
40 | }
41 |
42 | body.showSidebar .right {
43 | transform: TranslateX(-400px);
44 | }
45 |
46 | #banner-background {
47 | background-color: #2535a0;
48 | border-bottom: 2px solid #121a4d;
49 | height: 70px;
50 | left: 0;
51 | position: fixed;
52 | right: 0;
53 | top: 0;
54 | }
55 |
56 | body.darkMode #banner-background {
57 | background-color: #182268;
58 | border-bottom: 1px solid #2c40c0;
59 | }
60 |
61 | #banner {
62 | color: #fff;
63 | height: 70px;
64 | overflow: hidden;
65 | position: fixed;
66 | transition: background-color 0.2s linear, color 0.2s linear, width 0.3s ease-out;
67 | left: 0;
68 | top: 0;
69 | }
70 |
71 | body.darkMode #banner {
72 | ddd-color: #3b54ff;
73 | }
74 |
75 | #banner .logo {
76 | background: url(./logo.svg) no-repeat center;
77 | display: block;
78 | height: 70px;
79 | left: 20px;
80 | opacity: 0.7;
81 | position: absolute;
82 | top: 0px;
83 | width: 70px;
84 | }
85 | #banner .title {
86 | font-family: monospace;
87 | font-size: 30px;
88 | line-height: 70px;
89 | opacity: 0.7;
90 | padding: 0 100px;
91 | text-align: center;
92 | }
93 |
94 | #button-sidebar {
95 | cursor: pointer;
96 | height: 30px;
97 | right: 30px;
98 | opacity: 0.7;
99 | position: absolute;
100 | top: 20px;
101 | width: 30px;
102 | }
103 |
104 | #button-sidebar .open {
105 | background: url(./options-open.svg) no-repeat center;
106 | background-size: contain;
107 | height: 100%;
108 | width: 100%;
109 | }
110 |
111 | #banner #button-darkmode {
112 | cursor: pointer;
113 | opacity: 0.7;
114 | position: absolute;
115 | right: 90px;
116 | top: 20px;
117 | width: 30px;
118 | height: 30px;
119 | }
120 |
121 | #banner #button-darkmode .stars {
122 | background: url(./dark-mode-stars.svg);
123 | background-size: contain;
124 | height: 100%;
125 | position: absolute;
126 | width: 100%;
127 |
128 | opacity: 0;
129 | transition: opacity 0.1s linear 0.15s;
130 | }
131 |
132 | #banner #button-darkmode .light {
133 | background: url(./dark-mode-sun.svg);
134 | background-size: contain;
135 | height: 100%;
136 | position: absolute;
137 | width: 100%;
138 |
139 | transform: translateY(0);
140 | transition: transform 0.3s ease-out 0.3s;
141 | }
142 |
143 | #banner #button-darkmode .dark {
144 | background: url(./dark-mode-moon.svg);
145 | background-size: contain;
146 | height: 100%;
147 | position: absolute;
148 | width: 100%;
149 |
150 | transform: translateY(70px);
151 | transition: transform 0.3s ease-in;
152 | }
153 |
154 | body.darkMode #banner #button-darkmode .stars {
155 | opacity: 1;
156 | transition: opacity 0.3s linear 0.5s;
157 | }
158 |
159 | body.darkMode #banner #button-darkmode .light {
160 | transform: translateY(70px);
161 | transition: transform 0.3s ease-in;
162 | }
163 |
164 | body.darkMode #banner #button-darkmode .dark {
165 | transform: translateY(0);
166 | transition: transform 0.3s ease-out 0.3s;
167 | }
168 |
169 | #output {
170 | margin: 0;
171 | padding: 90px 30px 0 0;
172 | min-height: 100%;
173 | overflow: auto;
174 | }
175 | #output div.output {
176 | font-size: 24px;
177 | font-family: monospace;
178 | padding: 4px 30px 4px;
179 | white-space: pre;
180 | width: 100%;
181 | }
182 | #output div.output.log-warn {
183 | color: #880;
184 | }
185 | body.darMode #output div.output.log-warn {
186 | color: #aa6;
187 | }
188 | #output div.output.log-error {
189 | color: 800;
190 | }
191 | body.darkMode #output div.output.log-error {
192 | color: a66;
193 | }
194 | #output div.output.log-log {
195 | color: #008;
196 | }
197 | body.darkMode #output div.output.log-log {
198 | color: #66a;
199 | }
200 | #output div.output.log-note {
201 | color: #880;
202 | font-size: 16px;
203 | font-style: italic;
204 | }
205 | body.darkMode #output div.output.log-note {
206 | color: #aa5;
207 | }
208 | #output div.output.log-provider {
209 | color: #880;
210 | font-size: 16px;
211 | }
212 | body.darkMode #output div.output.log-provider {
213 | color: #aa5;
214 | }
215 | #output div.output.entry {
216 | background: url(./caret.svg) no-repeat 8px 12px;
217 | background-size: 17px 17px;
218 | color: #888;
219 | }
220 | body.darkMode #output div.output.entry {
221 | color: #aaa;
222 | }
223 | #output div.output.result {
224 | color: #00f;
225 | }
226 | #output div.output.result-bold {
227 | color: #00f;
228 | font-weight: bold;
229 | }
230 | body.darkMode #output div.output.result {
231 | color: #88f;
232 | }
233 | body.darkMode #output div.output.result-bold {
234 | color: #88f;
235 | font-weight: bold;
236 | }
237 | #output div.output.pending {
238 | color: #aaa;
239 | font-style: italic;
240 | }
241 | #output div.output.error {
242 | color: #f00;
243 | }
244 | body.darkMode #output div.output.error {
245 | color: #f88;
246 | }
247 |
248 | #input-box {
249 | position: relative;
250 | }
251 |
252 | textarea {
253 | background: url(./caret.svg) no-repeat 8px 12px;
254 | background-size: 17px 17px;
255 | outline: none;
256 | resize: none;
257 | }
258 |
259 | #sizer-container {
260 | border: 1px solid green;
261 | opacity: 0;
262 | position: absolute;
263 | pointer-events: none;
264 | top: -20px;
265 | white-space: pre-wrap;
266 | }
267 |
268 | .input-style {
269 | border: none;
270 | font-size: 24px;
271 | font-family: monospace;
272 | overflow: hidden;
273 | padding: 4px 30px 4px;
274 | width: 100%;
275 | }
276 |
277 | /* off-screen box to approximate width of monospace font used in the textarea */
278 | #sizer {
279 | position: absolute;
280 | font-size: 24px;
281 | font-family: monospace;
282 | left: 0;
283 | transform: translateX(-200%);
284 | }
285 |
286 |
287 | body.darkMode textarea {
288 | color: #eee;
289 | }
290 |
291 | #suggestions {
292 | background: #fff;
293 | border: 1px solid #66f;
294 | box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);
295 | color: #008;
296 | font-family: monospace;
297 | font-size: 20px;
298 | opacity: 0.9;
299 | position: absolute;
300 | top: 0px;
301 | transform: translateY(-100%);
302 | ddd-transition: opacity 0.3s linear;
303 | width: 270px;
304 | }
305 |
306 | body.darkMode #suggestions {
307 | background: #222;
308 | border: 1px solid #888;
309 | box-shadow: 0 0 15px #000;
310 | color: #888;
311 | }
312 |
313 | body.hideSuggestions #suggestions {
314 | opacity: 0;
315 | pointer-events: none;
316 | }
317 |
318 | #suggestions > div {
319 | border-bottom: 1px solid #66f;
320 | padding: 4px 10px;
321 | }
322 |
323 | body.darkMode #suggestions > div {
324 | border-bottom: 1px solid #888;
325 | }
326 |
327 | #suggestions > div.selected {
328 | background: #66f;
329 | color: #fff;
330 | }
331 |
332 | body.darkMode #suggestions > div.selected {
333 | background: #555;
334 | color: #fff;
335 | }
336 |
337 | #suggestions > div:last-child {
338 | border-bottom: none;
339 | }
340 |
341 | #sidebar {
342 | background: #333;
343 | color: #fff;
344 | font-family: monospace;
345 | font-size: 18px;
346 | }
347 |
348 | #sidebar .shadow-clip {
349 | top: 0px;
350 | left: 0;
351 | height: 100%; /*calc(100% - 70px); */
352 | overflow: hidden;
353 | position: absolute;
354 | width: 50px;
355 | }
356 |
357 | #sidebar .shadow {
358 | box-shadow: -10px 0px 18px 18px #000;
359 | position: absolute;
360 | height: 100%;
361 | width: 0;
362 | }
363 | #sidebar .header {
364 | background: #111;
365 | display: flex;
366 | flex-flow: row nowrap;
367 | height: 70px;
368 | line-height: 70px;
369 | }
370 |
371 | #sidebar .header .tab {
372 | flex-grow: 1;
373 | text-align: center;
374 | }
375 |
376 | #sidebar .header .tab.selected {
377 | background: #333;
378 | }
379 |
380 | #sidebar .header .icon {
381 | display: inline-block;
382 | height: 70px;
383 | opacity: 0.3;
384 | cursor: pointer;
385 | transform: scale(0.7);
386 | transition: opacity 0.3s linear, transform 0.3s ease;
387 | width: 50px;
388 | }
389 |
390 | #sidebar .header .tab.selected .icon {
391 | opacity: 0.7;
392 | transform: scale(1);
393 | }
394 |
395 | .icon-library {
396 | background: url(./icon-library.svg) no-repeat center;
397 | }
398 |
399 | .icon-settings {
400 | background: url(./icon-settings.svg) no-repeat center;
401 | }
402 |
403 | #sidebar .header .tab .icon:hover {
404 | opacity: 0.5;
405 | }
406 |
407 | #sidebar .panel {
408 | display: none;
409 | }
410 |
411 | #sidebar .panel.selected {
412 | display: block;
413 | }
414 |
415 | #sidebar .banner {
416 | color: #aaa;
417 | line-height: 30px;
418 | padding: 15px 0 0px;
419 | text-align: center;
420 | }
421 |
422 | #sidebar .search {
423 | border-bottom: 1px solid #222;
424 | padding: 15px 20px 30px;
425 | position: relative;
426 | }
427 | #sidebar .search input {
428 | border-radius: 10px;
429 | font-size: 20px;
430 | height: 30px;
431 | outline: none;
432 | line-height: 30px;
433 | text-align: center;
434 | width: 100%;
435 | }
436 | #sidebar-items {
437 | height: calc(100% - 190px);
438 | overflow: auto;
439 | padding: 0px 0 30px;
440 | position: relative;
441 | }
442 | #sidebar-items > div {
443 | padding: 4px 20px;
444 | transition: background-color 0.3s linear, opacity 0.3s linear;
445 | }
446 |
447 | #sidebar-items > div .group {
448 | color: #888;
449 | font-size: 14px;
450 | white-space: nowrap;
451 | padding: 10px 0px 0px 12px;
452 | }
453 |
454 | /* Highlight only the selected options item; if any */
455 | /*
456 | #sidebar-items.selected > div .title {
457 | opacity: 0.5;
458 | }
459 | #sidebar-items.selected > div.selected .title {
460 | opacity: 1;
461 | }
462 | */
463 | #sidebar-items > div.selected {
464 | background: rgba(0, 0, 0, 0.8);
465 | }
466 |
467 | /* Add expanded arrows to the options items */
468 | #sidebar-items div .title:before {
469 | content: "\00a0\00a0\25b6\00a0";
470 | }
471 | #sidebar-items > div.selected .title:before {
472 | content: "\00a0\00a0\25bc\00a0";
473 | }
474 |
475 | /* Options item title */
476 | #sidebar-items div .title {
477 | color: #ddd;
478 | cursor: pointer;
479 | white-space: nowrap;
480 | }
481 | #sidebar-items div .title .prefix {
482 | color: #888;
483 | cursor: pointer;
484 | font-size: 14px;
485 | white-space: nowrap;
486 | }
487 | #sidebar-items div.selected .title {
488 | font-weight: bold;
489 | }
490 | #sidebar-items div .item {
491 | position: relative;
492 | }
493 | #sidebar-items div .item.experimental {
494 | pointer-events: none;
495 | opacity: 0.2;
496 | }
497 | #sidebar-items div .item .use {
498 | color: #88f;
499 | font-size: 16px;
500 | position: absolute;
501 | cursor: pointer;
502 | right: 0px;
503 | }
504 | #sidebar-items div .item .use:hover {
505 | color: #8f8;
506 | }
507 |
508 | /* Info Blob */
509 | #sidebar-items div .info .usage {
510 | display: none; /* Maybe don't need this?? */
511 | }
512 | #sidebar-items div .info {
513 | color: #ddd;
514 | overflow: auto;
515 | padding-left: 23px;
516 | max-height: 0;
517 | transition: max-height 0.3s ease-out;
518 | }
519 | #sidebar-items div.selected .info {
520 | color: #ddd;
521 | padding-right: 7px;
522 | }
523 | /*
524 | #sidebar-items div .info .usage {
525 | margin-bottom: 5px;
526 | white-space: nowrap;
527 | }
528 | */
529 | #sidebar-items div .info > .description {
530 | color: #aaa;
531 | font-size: 16px;
532 | padding-top: 4px;
533 | }
534 | #sidebar-items div .info .no-params {
535 | margin-bottom: 5px;
536 | line-height: 20px;
537 | font-style: italic;
538 | color: #aaa;
539 | font-family: sans-serif;
540 | font-size: 16px;
541 | padding: 15px 30px 15px 0;
542 | text-align: center;
543 | }
544 | #sidebar-items div .info > .returns:before {
545 | content: "\21aa\00a0";
546 | }
547 | #sidebar-items div .info > .returns {
548 | color: #4a4;
549 | font-size: 16px;
550 | padding-top: 4px;
551 | }
552 | #sidebar-items div .info .param {
553 | margin: 5px 0;
554 | }
555 | #sidebar-items div .info .param .name {
556 | font-weight: bold;
557 | }
558 | #sidebar-items div .info .param .name i {
559 | color: #aaa;
560 | font-size: 12px;
561 | font-weight: normal;
562 | position: relative;
563 | top: -4px;
564 | }
565 | #sidebar-items div .info .param .description {
566 | color: #aaa;
567 | font-family: sans-serif;
568 | font-size: 16px;
569 | padding-left: 20px;
570 | }
571 |
572 | #sidebar-items div.item .option {
573 | padding-left: 23px;
574 | }
575 |
576 | #sidebar-items div.item .option .checkbox {
577 | border: 2px solid #ddd;
578 | border-radius: 4px;
579 | display: inline-block;
580 | height: 17px;
581 | position: absolute;
582 | cursor: pointer;
583 | right: 0px;
584 | width: 17px;
585 | }
586 |
587 | #sidebar-items div.item .option .checkbox .checkmark {
588 | background: url(./checkmark.svg) no-repeat center;
589 | height: 23px;
590 | left: 1px;
591 | opacity: 0;
592 | position: absolute;
593 | transform: translate(-7px, 3px) scale(0.3);
594 | transition: opacity 0.2s linear, transform 0.2s ease-out;
595 | top: -5px;
596 | width: 23px;
597 | }
598 |
599 | #sidebar-items div.item .option .checkbox.selected .checkmark {
600 | opacity: 1;
601 | transform: translate(0, 0) scale(1.0);
602 | transition: opacity 0.2s linear, transform 0.2s cubic-bezier(0.2, 0.4, 0.6, 1.8);
603 | }
604 |
605 | #sidebar-items .option-info {
606 | color: #aaa;
607 | font-size: 16px;
608 | font-style: italic;
609 | padding: 4px 13px 5px 23px;
610 | }
611 |
612 | #sidebar-items .option-info code {
613 | color: #666;
614 | font-style: normal;
615 | }
616 |
617 | #sidebar-items .button {
618 | border: 1px solid #ddd;
619 | color: #ddd;
620 | cursor: pointer;
621 | font-size: 16px;
622 | font-weight: bold;
623 | line-height: 35px;
624 | margin: 5px 23px;
625 | text-align: center;
626 | transition: background-color 0.1s linear, color 0.1s linear;
627 | }
628 |
629 | #sidebar-items .button:hover {
630 | background: #ddd;
631 | border: 1px solid #111;
632 | color: #111;
633 | transition: background-color 0.2s linear, color 0.2s linear;
634 | }
635 |
--------------------------------------------------------------------------------
/playground/v5/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | ethers playground
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
ethers playground
18 |
19 |
24 |
27 |
28 |
35 |
80 |
81 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/playground/v5/static/caret.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/playground/v5/static/checkmark.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/playground/v5/static/dark-mode-moon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
10 |
11 |
--------------------------------------------------------------------------------
/playground/v5/static/dark-mode-stars.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
10 |
12 |
14 |
15 |
--------------------------------------------------------------------------------
/playground/v5/static/dark-mode-sun.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/playground/v5/static/icon-library.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
12 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/playground/v5/static/icon-settings.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
24 |
38 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/playground/v5/static/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
12 |
13 |
--------------------------------------------------------------------------------
/playground/v5/static/options-open.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
12 |
14 |
18 |
20 |
24 |
26 |
27 |
--------------------------------------------------------------------------------
/playground/v5/static/style.css:
--------------------------------------------------------------------------------
1 | html {
2 | margin: 0;
3 | }
4 |
5 | body {
6 | margin: 0;
7 | transition: background-color 0.2s linear;
8 | }
9 | body.darkMode {
10 | background: #111;
11 | color: #fff;
12 | }
13 |
14 | /* We initialize all animations off until JavaScript
15 | has had a chance to set thigns up */
16 |
17 | body.disableAnimations { transition: none !important; }
18 | body.disableAnimations * { transition: none !important; }
19 |
20 | div { box-sizing: border-box; }
21 |
22 | /* Animated classes for showing the sidebar */
23 |
24 | .left {
25 | transition: width 0.3s ease-out;
26 | width: 100%;
27 | }
28 |
29 | .right {
30 | bottom: 0;
31 | position: fixed;
32 | right: -400px;
33 | top: 0;
34 | transition: transform 0.3s ease-out;
35 | width: 400px;
36 | }
37 |
38 | body.showSidebar .left {
39 | width: calc(100% - 400px);
40 | }
41 |
42 | body.showSidebar .right {
43 | transform: TranslateX(-400px);
44 | }
45 |
46 | #banner-background {
47 | background-color: #2535a0;
48 | border-bottom: 2px solid #121a4d;
49 | height: 70px;
50 | left: 0;
51 | position: fixed;
52 | right: 0;
53 | top: 0;
54 | }
55 |
56 | body.darkMode #banner-background {
57 | background-color: #182268;
58 | border-bottom: 1px solid #2c40c0;
59 | }
60 |
61 | #banner {
62 | color: #fff;
63 | height: 70px;
64 | overflow: hidden;
65 | position: fixed;
66 | transition: background-color 0.2s linear, color 0.2s linear, width 0.3s ease-out;
67 | left: 0;
68 | top: 0;
69 | }
70 |
71 | body.darkMode #banner {
72 | ddd-color: #3b54ff;
73 | }
74 |
75 | #banner .logo {
76 | background: url(./logo.svg) no-repeat center;
77 | display: block;
78 | height: 70px;
79 | left: 20px;
80 | opacity: 0.7;
81 | position: absolute;
82 | top: 0px;
83 | width: 70px;
84 | }
85 | #banner .title {
86 | font-family: monospace;
87 | font-size: 30px;
88 | line-height: 70px;
89 | opacity: 0.7;
90 | padding: 0 100px;
91 | text-align: center;
92 | }
93 | /*
94 | #banner #button-sidebar {
95 | background: url(./logo.svg) no-repeat center;
96 | height: 70px;
97 | margin-right: 30px;
98 | opacity: 0.7;
99 | position: absolute;
100 | right: 0px;
101 | top: 0;
102 | width: 70px;
103 | }
104 | */
105 |
106 | #button-sidebar {
107 | height: 30px;
108 | right: 30px;
109 | opacity: 0.7;
110 | position: absolute;
111 | top: 20px;
112 | width: 30px;
113 | }
114 |
115 | #button-sidebar .open {
116 | background: url(./options-open.svg) no-repeat center;
117 | background-size: contain;
118 | height: 100%;
119 | width: 100%;
120 | }
121 |
122 | #banner #button-darkmode {
123 | opacity: 0.7;
124 | position: absolute;
125 | right: 90px;
126 | top: 20px;
127 | width: 30px;
128 | height: 30px;
129 | }
130 |
131 | #banner #button-darkmode .stars {
132 | background: url(./dark-mode-stars.svg);
133 | background-size: contain;
134 | height: 100%;
135 | position: absolute;
136 | width: 100%;
137 |
138 | opacity: 0;
139 | transition: opacity 0.1s linear 0.15s;
140 | }
141 |
142 | #banner #button-darkmode .light {
143 | background: url(./dark-mode-sun.svg);
144 | background-size: contain;
145 | height: 100%;
146 | position: absolute;
147 | width: 100%;
148 |
149 | transform: translateY(0);
150 | transition: transform 0.3s ease-out 0.3s;
151 | }
152 |
153 | #banner #button-darkmode .dark {
154 | background: url(./dark-mode-moon.svg);
155 | background-size: contain;
156 | height: 100%;
157 | position: absolute;
158 | width: 100%;
159 |
160 | transform: translateY(70px);
161 | transition: transform 0.3s ease-in;
162 | }
163 |
164 | body.darkMode #banner #button-darkmode .stars {
165 | opacity: 1;
166 | transition: opacity 0.3s linear 0.5s;
167 | }
168 |
169 | body.darkMode #banner #button-darkmode .light {
170 | transform: translateY(70px);
171 | transition: transform 0.3s ease-in;
172 | }
173 |
174 | body.darkMode #banner #button-darkmode .dark {
175 | transform: translateY(0);
176 | transition: transform 0.3s ease-out 0.3s;
177 | }
178 |
179 | #output {
180 | margin: 0;
181 | padding: 90px 30px 0 0;
182 | min-height: 100%;
183 | overflow: auto;
184 | }
185 | #output div.output {
186 | font-size: 24px;
187 | font-family: monospace;
188 | padding: 4px 30px 4px;
189 | white-space: pre;
190 | width: 100%;
191 | }
192 | #output div.output.log-warn {
193 | color: #880;
194 | }
195 | body.darMode #output div.output.log-warn {
196 | color: #aa6;
197 | }
198 | #output div.output.log-error {
199 | color: 800;
200 | }
201 | body.darkMode #output div.output.log-error {
202 | color: a66;
203 | }
204 | #output div.output.log-log {
205 | color: #008;
206 | }
207 | body.darkMode #output div.output.log-log {
208 | color: #66a;
209 | }
210 | #output div.output.log-note {
211 | color: #880;
212 | font-size: 16px;
213 | font-style: italic;
214 | }
215 | body.darkMode #output div.output.log-note {
216 | color: #aa5;
217 | }
218 | #output div.output.log-provider {
219 | color: #880;
220 | font-size: 16px;
221 | }
222 | body.darkMode #output div.output.log-provider {
223 | color: #aa5;
224 | }
225 | #output div.output.entry {
226 | background: url(./caret.svg) no-repeat 8px 12px;
227 | background-size: 17px 17px;
228 | color: #888;
229 | }
230 | body.darkMode #output div.output.entry {
231 | color: #aaa;
232 | }
233 | #output div.output.result {
234 | color: #00f;
235 | }
236 | #output div.output.result-bold {
237 | color: #00f;
238 | font-weight: bold;
239 | }
240 | body.darkMode #output div.output.result {
241 | color: #88f;
242 | }
243 | body.darkMode #output div.output.result-bold {
244 | color: #88f;
245 | font-weight: bold;
246 | }
247 | #output div.output.pending {
248 | color: #aaa;
249 | font-style: italic;
250 | }
251 | #output div.output.error {
252 | color: #f00;
253 | }
254 | body.darkMode #output div.output.error {
255 | color: #f88;
256 | }
257 |
258 | #input-box {
259 | position: relative;
260 | }
261 |
262 | textarea {
263 | background: url(./caret.svg) no-repeat 8px 12px;
264 | background-size: 17px 17px;
265 | outline: none;
266 | resize: none;
267 | }
268 |
269 | #sizer-container {
270 | border: 1px solid green;
271 | opacity: 0;
272 | position: absolute;
273 | pointer-events: none;
274 | top: -20px;
275 | white-space: pre-wrap;
276 | }
277 |
278 | .input-style {
279 | border: none;
280 | font-size: 24px;
281 | font-family: monospace;
282 | overflow: hidden;
283 | padding: 4px 30px 4px;
284 | width: 100%;
285 | }
286 |
287 | /* off-screen box to approximate width of monospace font used in the textarea */
288 | #sizer {
289 | position: absolute;
290 | font-size: 24px;
291 | font-family: monospace;
292 | left: 0;
293 | transform: translateX(-200%);
294 | }
295 |
296 |
297 | body.darkMode textarea {
298 | color: #eee;
299 | }
300 |
301 | #suggestions {
302 | background: #fff;
303 | border: 1px solid #66f;
304 | box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);
305 | color: #008;
306 | font-family: monospace;
307 | font-size: 20px;
308 | opacity: 0.9;
309 | position: absolute;
310 | top: 0px;
311 | transform: translateY(-100%);
312 | ddd-transition: opacity 0.3s linear;
313 | width: 270px;
314 | }
315 |
316 | body.darkMode #suggestions {
317 | background: #222;
318 | border: 1px solid #888;
319 | box-shadow: 0 0 15px #000;
320 | color: #888;
321 | }
322 |
323 | body.hideSuggestions #suggestions {
324 | opacity: 0;
325 | pointer-events: none;
326 | }
327 |
328 | #suggestions > div {
329 | border-bottom: 1px solid #66f;
330 | padding: 4px 10px;
331 | }
332 |
333 | body.darkMode #suggestions > div {
334 | border-bottom: 1px solid #888;
335 | }
336 |
337 | #suggestions > div.selected {
338 | background: #66f;
339 | color: #fff;
340 | }
341 |
342 | body.darkMode #suggestions > div.selected {
343 | background: #555;
344 | color: #fff;
345 | }
346 |
347 | #suggestions > div:last-child {
348 | border-bottom: none;
349 | }
350 |
351 | #sidebar {
352 | background: #333;
353 | color: #fff;
354 | font-family: monospace;
355 | font-size: 18px;
356 | }
357 |
358 | #sidebar .shadow-clip {
359 | top: 0px;
360 | left: 0;
361 | height: 100%; /*calc(100% - 70px); */
362 | overflow: hidden;
363 | position: absolute;
364 | width: 50px;
365 | }
366 |
367 | #sidebar .shadow {
368 | box-shadow: -10px 0px 18px 18px #000;
369 | position: absolute;
370 | height: 100%;
371 | width: 0;
372 | }
373 | #sidebar .header {
374 | background: #111;
375 | display: flex;
376 | flex-flow: row nowrap;
377 | height: 70px;
378 | line-height: 70px;
379 | }
380 |
381 | #sidebar .header .tab {
382 | flex-grow: 1;
383 | text-align: center;
384 | }
385 |
386 | #sidebar .header .tab.selected {
387 | background: #333;
388 | }
389 |
390 | #sidebar .header .icon {
391 | display: inline-block;
392 | height: 70px;
393 | opacity: 0.3;
394 | cursor: pointer;
395 | transform: scale(0.7);
396 | transition: opacity 0.3s linear, transform 0.3s ease;
397 | width: 50px;
398 | }
399 |
400 | #sidebar .header .tab.selected .icon {
401 | opacity: 0.7;
402 | transform: scale(1);
403 | }
404 |
405 | .icon-library {
406 | background: url(./icon-library.svg) no-repeat center;
407 | }
408 |
409 | .icon-settings {
410 | background: url(./icon-settings.svg) no-repeat center;
411 | }
412 |
413 | #sidebar .header .tab .icon:hover {
414 | opacity: 0.5;
415 | }
416 |
417 | #sidebar .panel {
418 | display: none;
419 | }
420 |
421 | #sidebar .panel.selected {
422 | display: block;
423 | }
424 |
425 | #sidebar .banner {
426 | color: #aaa;
427 | line-height: 30px;
428 | padding: 15px 0 0px;
429 | text-align: center;
430 | }
431 |
432 | #sidebar .search {
433 | border-bottom: 1px solid #222;
434 | padding: 15px 20px 30px;
435 | position: relative;
436 | }
437 | #sidebar .search input {
438 | border-radius: 10px;
439 | font-size: 20px;
440 | height: 30px;
441 | outline: none;
442 | line-height: 30px;
443 | text-align: center;
444 | width: 100%;
445 | }
446 | #sidebar-items {
447 | height: calc(100% - 190px);
448 | overflow: auto;
449 | padding: 0px 0 30px;
450 | position: relative;
451 | }
452 | #sidebar-items > div {
453 | padding: 4px 20px;
454 | transition: background-color 0.3s linear, opacity 0.3s linear;
455 | }
456 |
457 | #sidebar-items > div .group {
458 | color: #888;
459 | font-size: 14px;
460 | white-space: nowrap;
461 | padding: 10px 0px 0px 12px;
462 | }
463 |
464 | /* Highlight only the selected options item; if any */
465 | /*
466 | #sidebar-items.selected > div .title {
467 | opacity: 0.5;
468 | }
469 | #sidebar-items.selected > div.selected .title {
470 | opacity: 1;
471 | }
472 | */
473 | #sidebar-items > div.selected {
474 | background: rgba(0, 0, 0, 0.8);
475 | }
476 |
477 | /* Add expanded arrows to the options items */
478 | #sidebar-items div .title:before {
479 | content: "\00a0\00a0\25b6\00a0";
480 | }
481 | #sidebar-items > div.selected .title:before {
482 | content: "\00a0\00a0\25bc\00a0";
483 | }
484 |
485 | /* Options item title */
486 | #sidebar-items div .title {
487 | color: #ddd;
488 | cursor: pointer;
489 | white-space: nowrap;
490 | }
491 | #sidebar-items div .title .prefix {
492 | color: #888;
493 | cursor: pointer;
494 | font-size: 14px;
495 | white-space: nowrap;
496 | }
497 | #sidebar-items div.selected .title {
498 | font-weight: bold;
499 | }
500 | #sidebar-items div .item {
501 | position: relative;
502 | }
503 | #sidebar-items div .item.experimental {
504 | pointer-events: none;
505 | opacity: 0.2;
506 | }
507 | #sidebar-items div .item .use {
508 | color: #88f;
509 | font-size: 16px;
510 | position: absolute;
511 | cursor: pointer;
512 | right: 0px;
513 | }
514 | #sidebar-items div .item .use:hover {
515 | color: #8f8;
516 | }
517 |
518 | /* Info Blob */
519 | #sidebar-items div .info .usage {
520 | display: none; /* Maybe don't need this?? */
521 | }
522 | #sidebar-items div .info {
523 | color: #ddd;
524 | overflow: auto;
525 | padding-left: 23px;
526 | max-height: 0;
527 | transition: max-height 0.3s ease-out;
528 | }
529 | #sidebar-items div.selected .info {
530 | color: #ddd;
531 | padding-right: 7px;
532 | }
533 | /*
534 | #sidebar-items div .info .usage {
535 | margin-bottom: 5px;
536 | white-space: nowrap;
537 | }
538 | */
539 | #sidebar-items div .info > .description {
540 | color: #aaa;
541 | font-size: 16px;
542 | padding-top: 4px;
543 | }
544 | #sidebar-items div .info .no-params {
545 | margin-bottom: 5px;
546 | line-height: 20px;
547 | font-style: italic;
548 | color: #aaa;
549 | font-family: sans-serif;
550 | font-size: 16px;
551 | padding: 15px 30px 15px 0;
552 | text-align: center;
553 | }
554 | #sidebar-items div .info > .returns:before {
555 | content: "\21aa\00a0";
556 | }
557 | #sidebar-items div .info > .returns {
558 | color: #4a4;
559 | font-size: 16px;
560 | padding-top: 4px;
561 | }
562 | #sidebar-items div .info .param {
563 | margin: 5px 0;
564 | }
565 | #sidebar-items div .info .param .name {
566 | font-weight: bold;
567 | }
568 | #sidebar-items div .info .param .name i {
569 | color: #aaa;
570 | font-size: 12px;
571 | font-weight: normal;
572 | position: relative;
573 | top: -4px;
574 | }
575 | #sidebar-items div .info .param .description {
576 | color: #aaa;
577 | font-family: sans-serif;
578 | font-size: 16px;
579 | padding-left: 20px;
580 | }
581 |
582 | #sidebar-items div.item .option {
583 | padding-left: 23px;
584 | }
585 |
586 | #sidebar-items div.item .option .checkbox {
587 | border: 2px solid #ddd;
588 | border-radius: 4px;
589 | display: inline-block;
590 | height: 17px;
591 | position: absolute;
592 | cursor: pointer;
593 | right: 0px;
594 | width: 17px;
595 | }
596 |
597 | #sidebar-items div.item .option .checkbox .checkmark {
598 | background: url(./checkmark.svg) no-repeat center;
599 | height: 23px;
600 | left: 1px;
601 | opacity: 0;
602 | position: absolute;
603 | transform: translate(-7px, 3px) scale(0.3);
604 | transition: opacity 0.2s linear, transform 0.2s ease-out;
605 | top: -5px;
606 | width: 23px;
607 | }
608 |
609 | #sidebar-items div.item .option .checkbox.selected .checkmark {
610 | opacity: 1;
611 | transform: translate(0, 0) scale(1.0);
612 | transition: opacity 0.2s linear, transform 0.2s cubic-bezier(0.2, 0.4, 0.6, 1.8);
613 | }
614 |
615 | #sidebar-items .option-info {
616 | color: #aaa;
617 | font-size: 16px;
618 | font-style: italic;
619 | padding: 4px 13px 5px 23px;
620 | }
621 |
622 | #sidebar-items .option-info code {
623 | color: #666;
624 | font-style: normal;
625 | }
626 |
627 | #sidebar-items .button {
628 | border: 1px solid #ddd;
629 | color: #ddd;
630 | cursor: pointer;
631 | font-size: 16px;
632 | font-weight: bold;
633 | line-height: 35px;
634 | margin: 5px 23px;
635 | text-align: center;
636 | transition: background-color 0.1s linear, color 0.1s linear;
637 | }
638 |
639 | #sidebar-items .button:hover {
640 | background: #ddd;
641 | border: 1px solid #111;
642 | color: #111;
643 | transition: background-color 0.2s linear, color 0.2s linear;
644 | }
645 |
--------------------------------------------------------------------------------
/playground/v5/static/types.js:
--------------------------------------------------------------------------------
1 | const Types = {
2 | ethers: {
3 | type: "object",
4 | values: {
5 | constants: ethers.constants,
6 | getDefaultProvider: find("getDefaultProvider"),
7 | providers: {
8 | AlchemyProvider: find("AlchemyProvider", [
9 |
10 | ]);
11 | }
12 | }
13 | }
14 | };
15 |
--------------------------------------------------------------------------------