mint-day 0.3.3 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/sentry-triage.yml +69 -0
- package/api/classify.ts +2 -0
- package/api/feed.ts +2 -0
- package/api/lib/sentry.ts +28 -0
- package/api/sentry-webhook.ts +91 -0
- package/api/sponsor.ts +2 -0
- package/api/verify.ts +2 -0
- package/dist/index.js +4 -4
- package/dist/services/rare-protocol.d.ts +19 -0
- package/dist/services/rare-protocol.js +77 -0
- package/dist/tools/mint.d.ts +5 -0
- package/dist/tools/mint.js +48 -10
- package/package.json +4 -1
- package/scripts/deploy-rare-collection.mjs +64 -0
- package/site/feed.html +442 -279
- package/site/index.html +40 -7
- package/src/index.ts +4 -4
- package/src/rare-cli.d.ts +37 -0
- package/src/services/rare-protocol.ts +119 -0
- package/src/tools/mint.ts +50 -11
- package/vercel.json +2 -1
package/site/feed.html
CHANGED
|
@@ -4,81 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>mint.day — live feed</title>
|
|
7
|
+
<link rel="stylesheet" href="shared.css">
|
|
7
8
|
<style>
|
|
8
|
-
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&family=IBM+Plex+Sans:wght@400;500;600&display=swap');
|
|
9
|
-
|
|
10
|
-
:root {
|
|
11
|
-
--bg: #0d0a07;
|
|
12
|
-
--surface: #151110;
|
|
13
|
-
--surface-raised: #1c1714;
|
|
14
|
-
--border: #2a2320;
|
|
15
|
-
--border-bright: #352d28;
|
|
16
|
-
--text: #ede8e3;
|
|
17
|
-
--text-secondary: #a39890;
|
|
18
|
-
--text-muted: #6e6259;
|
|
19
|
-
--text-dim: #3d3530;
|
|
20
|
-
--green: #22c55e;
|
|
21
|
-
--blue: #60a5fa;
|
|
22
|
-
--purple: #a78bfa;
|
|
23
|
-
--orange: #fb923c;
|
|
24
|
-
--cyan: #22d3ee;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
28
|
-
|
|
29
|
-
body {
|
|
30
|
-
background: var(--bg);
|
|
31
|
-
color: var(--text);
|
|
32
|
-
font-family: 'IBM Plex Sans', -apple-system, sans-serif;
|
|
33
|
-
-webkit-font-smoothing: antialiased;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.container { max-width: 800px; margin: 0 auto; padding: 0 28px; }
|
|
37
|
-
|
|
38
|
-
nav {
|
|
39
|
-
padding: 28px 0;
|
|
40
|
-
display: flex;
|
|
41
|
-
justify-content: space-between;
|
|
42
|
-
align-items: center;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.logo {
|
|
46
|
-
font-family: 'JetBrains Mono', monospace;
|
|
47
|
-
font-weight: 700;
|
|
48
|
-
font-size: 15px;
|
|
49
|
-
color: var(--text);
|
|
50
|
-
text-decoration: none;
|
|
51
|
-
letter-spacing: -0.03em;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.logo .dot { color: var(--green); }
|
|
55
|
-
|
|
56
|
-
.nav-links {
|
|
57
|
-
display: flex;
|
|
58
|
-
gap: 24px;
|
|
59
|
-
align-items: center;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
.nav-links a {
|
|
63
|
-
font-family: 'JetBrains Mono', monospace;
|
|
64
|
-
font-size: 13px;
|
|
65
|
-
color: var(--text-muted);
|
|
66
|
-
text-decoration: none;
|
|
67
|
-
transition: color 0.2s;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.nav-links a:hover { color: var(--text-secondary); }
|
|
71
|
-
|
|
72
|
-
.badge {
|
|
73
|
-
font-family: 'JetBrains Mono', monospace;
|
|
74
|
-
font-size: 11px;
|
|
75
|
-
padding: 5px 10px;
|
|
76
|
-
border-radius: 4px;
|
|
77
|
-
border: 1px solid var(--border-bright);
|
|
78
|
-
color: var(--text-muted);
|
|
79
|
-
background: var(--surface);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
9
|
.page-header { padding: 48px 0 32px; }
|
|
83
10
|
|
|
84
11
|
.page-header h1 {
|
|
@@ -88,45 +15,27 @@
|
|
|
88
15
|
letter-spacing: -0.03em;
|
|
89
16
|
}
|
|
90
17
|
|
|
91
|
-
.page-header
|
|
18
|
+
.page-header .sub {
|
|
92
19
|
font-family: 'JetBrains Mono', monospace;
|
|
93
20
|
font-size: 12px;
|
|
94
21
|
color: var(--text-dim);
|
|
95
22
|
margin-top: 8px;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
.chain-tabs {
|
|
99
23
|
display: flex;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
background: var(--border);
|
|
103
|
-
border-radius: 8px;
|
|
104
|
-
overflow: hidden;
|
|
24
|
+
align-items: center;
|
|
25
|
+
gap: 8px;
|
|
105
26
|
}
|
|
106
27
|
|
|
107
|
-
.chain-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
background: var(--
|
|
112
|
-
|
|
113
|
-
border: none;
|
|
114
|
-
cursor: pointer;
|
|
115
|
-
flex: 1;
|
|
116
|
-
text-align: center;
|
|
117
|
-
transition: all 0.15s;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
.chain-tab:hover { color: var(--text-secondary); }
|
|
121
|
-
|
|
122
|
-
.chain-tab.active {
|
|
123
|
-
background: var(--surface-raised);
|
|
124
|
-
color: var(--text);
|
|
28
|
+
.chain-dot {
|
|
29
|
+
width: 6px;
|
|
30
|
+
height: 6px;
|
|
31
|
+
border-radius: 50%;
|
|
32
|
+
background: var(--green);
|
|
33
|
+
animation: pulse 2s ease-in-out infinite;
|
|
125
34
|
}
|
|
126
35
|
|
|
127
36
|
.feed-list {
|
|
128
37
|
border: 1px solid var(--border);
|
|
129
|
-
border-radius: 10px;
|
|
38
|
+
border-radius: 0 10px 10px 10px;
|
|
130
39
|
overflow: hidden;
|
|
131
40
|
margin-bottom: 40px;
|
|
132
41
|
}
|
|
@@ -137,13 +46,34 @@
|
|
|
137
46
|
gap: 14px;
|
|
138
47
|
padding: 16px 20px;
|
|
139
48
|
border-bottom: 1px solid var(--border);
|
|
140
|
-
transition: background 0.15s;
|
|
141
|
-
text-decoration: none;
|
|
142
|
-
color: inherit;
|
|
143
49
|
}
|
|
144
50
|
|
|
145
51
|
.feed-item:last-child { border-bottom: none; }
|
|
146
|
-
|
|
52
|
+
|
|
53
|
+
.feed-links {
|
|
54
|
+
display: flex;
|
|
55
|
+
gap: 8px;
|
|
56
|
+
flex-shrink: 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.feed-links a {
|
|
60
|
+
display: flex;
|
|
61
|
+
align-items: center;
|
|
62
|
+
justify-content: center;
|
|
63
|
+
width: 28px;
|
|
64
|
+
height: 28px;
|
|
65
|
+
border-radius: 6px;
|
|
66
|
+
border: 1px solid var(--border);
|
|
67
|
+
color: var(--text-dim);
|
|
68
|
+
text-decoration: none;
|
|
69
|
+
transition: all 0.15s;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.feed-links a:hover {
|
|
73
|
+
border-color: var(--border-bright);
|
|
74
|
+
color: var(--text-muted);
|
|
75
|
+
background: var(--surface-raised);
|
|
76
|
+
}
|
|
147
77
|
|
|
148
78
|
.feed-thumb {
|
|
149
79
|
width: 48px;
|
|
@@ -153,15 +83,25 @@
|
|
|
153
83
|
flex-shrink: 0;
|
|
154
84
|
background: var(--bg);
|
|
155
85
|
border: 1px solid var(--border);
|
|
86
|
+
display: flex;
|
|
87
|
+
align-items: center;
|
|
88
|
+
justify-content: center;
|
|
156
89
|
}
|
|
157
90
|
|
|
158
|
-
.feed-thumb img {
|
|
91
|
+
.feed-thumb img { width: 100%; height: 100%; display: block; object-fit: cover; }
|
|
92
|
+
|
|
93
|
+
.feed-thumb .gen-thumb {
|
|
159
94
|
width: 100%;
|
|
160
95
|
height: 100%;
|
|
161
|
-
display:
|
|
162
|
-
|
|
96
|
+
display: flex;
|
|
97
|
+
flex-direction: column;
|
|
98
|
+
justify-content: flex-end;
|
|
99
|
+
padding: 6px;
|
|
163
100
|
}
|
|
164
101
|
|
|
102
|
+
.feed-thumb .gen-thumb .gt-bar { height: 2px; width: 16px; border-radius: 1px; opacity: 0.6; }
|
|
103
|
+
.feed-thumb .gen-thumb .gt-label { font-family: 'JetBrains Mono', monospace; font-size: 7px; margin-top: 3px; opacity: 0.4; }
|
|
104
|
+
|
|
165
105
|
.feed-info { flex: 1; min-width: 0; }
|
|
166
106
|
|
|
167
107
|
.feed-name {
|
|
@@ -196,18 +136,52 @@
|
|
|
196
136
|
.type-Receipt { color: var(--orange); border: 1px solid rgba(251,146,60,0.2); }
|
|
197
137
|
.type-Pass { color: var(--cyan); border: 1px solid rgba(34,211,238,0.2); }
|
|
198
138
|
|
|
199
|
-
.feed-soulbound {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
139
|
+
.feed-soulbound { font-family: 'JetBrains Mono', monospace; font-size: 9px; color: var(--green); opacity: 0.5; }
|
|
140
|
+
.feed-addr { font-family: 'JetBrains Mono', monospace; font-size: 10px; color: var(--text-dim); }
|
|
141
|
+
.feed-time { font-family: 'JetBrains Mono', monospace; font-size: 10px; color: var(--text-dim); flex-shrink: 0; }
|
|
142
|
+
|
|
143
|
+
.feed-tabs {
|
|
144
|
+
display: flex;
|
|
145
|
+
gap: 0;
|
|
146
|
+
margin-bottom: -1px;
|
|
147
|
+
position: relative;
|
|
148
|
+
z-index: 1;
|
|
204
149
|
}
|
|
205
150
|
|
|
206
|
-
.feed-
|
|
151
|
+
.feed-tab {
|
|
207
152
|
font-family: 'JetBrains Mono', monospace;
|
|
208
|
-
font-size:
|
|
153
|
+
font-size: 12px;
|
|
154
|
+
padding: 10px 20px;
|
|
155
|
+
background: var(--surface-raised);
|
|
156
|
+
border: 1px solid var(--border);
|
|
157
|
+
border-bottom: 1px solid var(--border);
|
|
209
158
|
color: var(--text-dim);
|
|
210
|
-
|
|
159
|
+
cursor: pointer;
|
|
160
|
+
transition: all 0.15s;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.feed-tab:first-child { border-radius: 8px 0 0 0; }
|
|
164
|
+
.feed-tab:last-child { border-radius: 0 8px 0 0; border-left: none; }
|
|
165
|
+
|
|
166
|
+
.feed-tab.active {
|
|
167
|
+
background: var(--surface);
|
|
168
|
+
color: var(--text);
|
|
169
|
+
font-weight: 600;
|
|
170
|
+
border-bottom-color: var(--surface);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.feed-tab:not(.active):hover {
|
|
174
|
+
background: var(--bg);
|
|
175
|
+
color: var(--text-muted);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.feed-tab .tab-dot {
|
|
179
|
+
display: inline-block;
|
|
180
|
+
width: 5px;
|
|
181
|
+
height: 5px;
|
|
182
|
+
border-radius: 50%;
|
|
183
|
+
margin-right: 6px;
|
|
184
|
+
vertical-align: middle;
|
|
211
185
|
}
|
|
212
186
|
|
|
213
187
|
.feed-status {
|
|
@@ -225,8 +199,14 @@
|
|
|
225
199
|
padding: 12px 20px;
|
|
226
200
|
border-bottom: 1px solid var(--border);
|
|
227
201
|
background: var(--surface);
|
|
202
|
+
display: flex;
|
|
203
|
+
justify-content: space-between;
|
|
204
|
+
align-items: center;
|
|
228
205
|
}
|
|
229
206
|
|
|
207
|
+
.feed-count a { color: var(--blue); text-decoration: none; font-size: 10px; }
|
|
208
|
+
.feed-count a:hover { color: var(--text-secondary); }
|
|
209
|
+
|
|
230
210
|
@keyframes fadeIn {
|
|
231
211
|
from { opacity: 0; transform: translateY(4px); }
|
|
232
212
|
to { opacity: 1; transform: translateY(0); }
|
|
@@ -235,204 +215,387 @@
|
|
|
235
215
|
</head>
|
|
236
216
|
<body>
|
|
237
217
|
<div class="container">
|
|
238
|
-
<nav>
|
|
239
|
-
<a href="index.html" class="logo">mint<span class="dot">.</span>day</a>
|
|
240
|
-
<div class="nav-links">
|
|
241
|
-
<a href="feed.html">feed</a>
|
|
242
|
-
<span class="badge" style="font-size:11px;padding:4px 8px;border-color:rgba(96,165,250,0.25);color:#60a5fa;">Base</span>
|
|
243
|
-
<a href="https://github.com/jordanlyall/agent-mint" target="_blank" title="GitHub"><svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg></a>
|
|
244
|
-
<a href="https://x.com/jordanlyall" target="_blank" title="X"><svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg></a>
|
|
245
|
-
</div>
|
|
246
|
-
</nav>
|
|
218
|
+
<div id="site-nav"></div>
|
|
247
219
|
|
|
248
220
|
<div class="page-header">
|
|
249
|
-
<h1>Live
|
|
250
|
-
<
|
|
221
|
+
<h1>Live feed</h1>
|
|
222
|
+
<div class="sub"><span class="chain-dot"></span> Base mainnet</div>
|
|
251
223
|
</div>
|
|
252
224
|
|
|
253
|
-
<div class="
|
|
254
|
-
<button class="
|
|
255
|
-
<button class="
|
|
225
|
+
<div class="feed-tabs">
|
|
226
|
+
<button class="feed-tab active" onclick="switchTab('mintday')"><span class="tab-dot" style="background:var(--green);"></span>mint.day</button>
|
|
227
|
+
<button class="feed-tab" onclick="switchTab('rare')"><span class="tab-dot" style="background:var(--purple);"></span>Rare Protocol</button>
|
|
256
228
|
</div>
|
|
257
|
-
|
|
258
229
|
<div class="feed-list" id="feed-list">
|
|
259
230
|
<div class="feed-status">Loading on-chain data...</div>
|
|
260
231
|
</div>
|
|
232
|
+
|
|
233
|
+
<div id="site-footer"></div>
|
|
261
234
|
</div>
|
|
262
235
|
|
|
236
|
+
<script defer src="/_vercel/insights/script.js"></script>
|
|
237
|
+
<script src="shared.js"></script>
|
|
263
238
|
<script>
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
239
|
+
renderNav("site-nav");
|
|
240
|
+
renderFooter("site-footer");
|
|
241
|
+
|
|
242
|
+
var CACHE_KEY = "mintday_feed";
|
|
243
|
+
var CACHE_KEY_RARE = "rare_feed";
|
|
244
|
+
var RARE_CONTRACT = "0x99Eee317921a9f12176eED25b0aE1D7eb164AE34";
|
|
245
|
+
var RARE_FROM_BLOCK = 43711485;
|
|
246
|
+
var TRANSFER_SIG = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
|
|
247
|
+
var ZERO_ADDR = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
248
|
+
var currentTab = "mintday";
|
|
249
|
+
|
|
250
|
+
function svgEl(tag, attrs) {
|
|
251
|
+
var el = document.createElementNS("http://www.w3.org/2000/svg", tag);
|
|
252
|
+
for (var k in attrs) el.setAttribute(k, attrs[k]);
|
|
253
|
+
return el;
|
|
254
|
+
}
|
|
279
255
|
|
|
280
|
-
|
|
281
|
-
|
|
256
|
+
function makeScanLink(txHash) {
|
|
257
|
+
var a = document.createElement("a");
|
|
258
|
+
a.href = MINTDAY.explorer + "/tx/" + txHash;
|
|
259
|
+
a.target = "_blank";
|
|
260
|
+
a.title = "Basescan";
|
|
261
|
+
var svg = svgEl("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" });
|
|
262
|
+
svg.appendChild(svgEl("path", { d: "M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4" }));
|
|
263
|
+
svg.appendChild(svgEl("path", { d: "M14 4h6v6" }));
|
|
264
|
+
svg.appendChild(svgEl("path", { d: "M14 10L21 3" }));
|
|
265
|
+
a.appendChild(svg);
|
|
266
|
+
return a;
|
|
267
|
+
}
|
|
282
268
|
|
|
283
|
-
function
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
269
|
+
function makeOsLink(tokenId) {
|
|
270
|
+
var a = document.createElement("a");
|
|
271
|
+
a.href = "https://opensea.io/item/base/" + MINTDAY.contract + "/" + tokenId;
|
|
272
|
+
a.target = "_blank";
|
|
273
|
+
a.title = "OpenSea";
|
|
274
|
+
var svg = svgEl("svg", { width: "14", height: "14", viewBox: "0 0 90 90", fill: "currentColor" });
|
|
275
|
+
svg.appendChild(svgEl("path", { d: "M45 0C20.151 0 0 20.151 0 45c0 24.849 20.151 45 45 45 24.849 0 45-20.151 45-45C90 20.151 69.849 0 45 0zM22.203 46.512l.252-.504 12.06-18.858c.18-.27.54-.234.684.054 2.016 4.464 3.762 10.008 2.952 13.464-.342 1.404-1.278 3.312-2.34 5.058-.126.252-.27.486-.414.72-.072.108-.198.162-.324.162H22.563c-.306 0-.486-.342-.36-.612v-.504zm52.38 5.4c0 .198-.126.36-.306.432-1.098.468-4.842 2.196-6.408 4.374-3.978 5.562-7.02 13.518-13.824 13.518H32.49c-10.116 0-18.324-8.226-18.324-18.378v-.324c0-.234.18-.414.414-.414h13.41c.27 0 .468.252.45.522-.09.72.054 1.458.432 2.124.72 1.332 2.07 2.16 3.528 2.16h5.526v-4.266h-5.472c-.306 0-.486-.36-.342-.63.054-.09.108-.18.18-.288.54-.828 1.314-2.142 2.088-3.636.522-.99 1.026-2.034 1.422-3.096.09-.198.162-.396.234-.576.126-.36.252-.702.342-1.044.09-.288.162-.594.234-.882.198-1.008.27-2.07.27-3.168 0-.432-.018-.882-.054-1.314-.018-.486-.072-.972-.144-1.458-.054-.414-.144-.828-.234-1.26-.126-.612-.288-1.224-.486-1.836l-.072-.252c-.144-.468-.27-.918-.432-1.386-1.044-3.042-2.178-5.94-3.276-8.478l-.234-.504c-.072-.162-.144-.306-.216-.45-.198-.414-.414-.81-.63-1.188-.108-.198-.234-.378-.342-.558-.144-.234-.306-.45-.432-.648-.09-.144-.198-.27-.288-.396l-.774-.972c-.09-.108.036-.27.162-.234l4.212 1.116h.018l.558.162.612.18.216.054V17.37c0-1.602 1.278-2.898 2.844-2.898 .792 0 1.494.324 2.016.846.522.522.828 1.242.828 2.052v7.776l.45.126c.036.018.072.036.108.072.126.108.306.27.54.468.18.162.378.36.612.576.468.432 1.026.99 1.602 1.62.162.18.324.36.468.558.612.738 1.296 1.584 1.944 2.52.18.27.36.54.522.828.486.828.918 1.692 1.278 2.574.126.288.234.594.306.882v.036c.108.306.18.63.234.954.162.882.234 1.8.162 2.736-.036.378-.09.738-.162 1.116-.09.378-.18.738-.306 1.116-.252.72-.558 1.422-.918 2.07-.126.234-.27.486-.414.72-.162.234-.306.468-.468.684-.216.306-.45.594-.666.864-.198.252-.414.504-.63.738-.324.378-.648.72-.99 1.044-.198.216-.414.414-.63.594-.216.198-.432.378-.63.54-.324.27-.612.486-.864.666l-.558.396c-.09.072-.216.108-.324.108h-3.366v4.266h4.176c.954 0 1.854-.342 2.574-.954.252-.216 2.736-2.376 5.886-6.462.018-.036.072-.072.126-.09l14.652-4.266c.27-.072.54.126.54.396v.504z" }));
|
|
276
|
+
a.appendChild(svg);
|
|
277
|
+
return a;
|
|
287
278
|
}
|
|
288
279
|
|
|
289
|
-
function
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
280
|
+
function buildThumb(typeName) {
|
|
281
|
+
var colors = MINTDAY.typeColors[typeName] || MINTDAY.typeColors.Attestation;
|
|
282
|
+
var div = document.createElement("div");
|
|
283
|
+
div.className = "gen-thumb";
|
|
284
|
+
div.style.background = colors.bg;
|
|
285
|
+
var bar = document.createElement("div");
|
|
286
|
+
bar.className = "gt-bar";
|
|
287
|
+
bar.style.background = colors.accent;
|
|
288
|
+
div.appendChild(bar);
|
|
289
|
+
var label = document.createElement("div");
|
|
290
|
+
label.className = "gt-label";
|
|
291
|
+
label.style.color = colors.accent;
|
|
292
|
+
label.textContent = typeName.toUpperCase();
|
|
293
|
+
div.appendChild(label);
|
|
294
|
+
return div;
|
|
295
|
+
}
|
|
295
296
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
let tokenURI = "";
|
|
300
|
-
try { tokenURI = new TextDecoder().decode(new Uint8Array(strHex.match(/.{2}/g).map(b => parseInt(b, 16)))); } catch {}
|
|
297
|
+
function renderItems(items, latestBlock) {
|
|
298
|
+
var list = document.getElementById("feed-list");
|
|
299
|
+
list.textContent = "";
|
|
301
300
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
301
|
+
if (items.length === 0) {
|
|
302
|
+
var empty = document.createElement("div");
|
|
303
|
+
empty.className = "feed-status";
|
|
304
|
+
empty.textContent = "No mints yet. Be the first.";
|
|
305
|
+
list.appendChild(empty);
|
|
306
|
+
return;
|
|
305
307
|
}
|
|
306
308
|
|
|
307
|
-
|
|
309
|
+
var count = document.createElement("div");
|
|
310
|
+
count.className = "feed-count";
|
|
311
|
+
var countText = document.createElement("span");
|
|
312
|
+
countText.textContent = items.length + " token" + (items.length !== 1 ? "s" : "") + " minted on Base";
|
|
313
|
+
count.appendChild(countText);
|
|
314
|
+
var contractLink = document.createElement("a");
|
|
315
|
+
contractLink.href = MINTDAY.explorer + "/address/" + MINTDAY.contract;
|
|
316
|
+
contractLink.target = "_blank";
|
|
317
|
+
contractLink.textContent = "view contract";
|
|
318
|
+
count.appendChild(contractLink);
|
|
319
|
+
list.appendChild(count);
|
|
320
|
+
|
|
321
|
+
items.forEach(function(item, i) {
|
|
322
|
+
var typeName = MINTDAY.typeNames[item.tokenType] || "Unknown";
|
|
323
|
+
var name = item.metadata.name || "mint.day #" + item.tokenId;
|
|
324
|
+
var image = item.metadata.image || "";
|
|
325
|
+
var shortAddr = item.to.slice(0, 6) + "..." + item.to.slice(-4);
|
|
326
|
+
|
|
327
|
+
var row = document.createElement("div");
|
|
328
|
+
row.className = "feed-item";
|
|
329
|
+
row.style.animationName = "fadeIn";
|
|
330
|
+
row.style.animationDuration = "0.3s";
|
|
331
|
+
row.style.animationDelay = (i * 0.05) + "s";
|
|
332
|
+
row.style.animationFillMode = "both";
|
|
333
|
+
|
|
334
|
+
var thumb = document.createElement("div");
|
|
335
|
+
thumb.className = "feed-thumb";
|
|
336
|
+
if (image) {
|
|
337
|
+
var img = document.createElement("img");
|
|
338
|
+
img.src = image;
|
|
339
|
+
img.alt = "";
|
|
340
|
+
img.loading = "lazy";
|
|
341
|
+
img.onerror = function() { thumb.textContent = ""; thumb.appendChild(buildThumb(typeName)); };
|
|
342
|
+
thumb.appendChild(img);
|
|
343
|
+
} else {
|
|
344
|
+
thumb.appendChild(buildThumb(typeName));
|
|
345
|
+
}
|
|
346
|
+
row.appendChild(thumb);
|
|
347
|
+
|
|
348
|
+
var info = document.createElement("div");
|
|
349
|
+
info.className = "feed-info";
|
|
350
|
+
var nameEl = document.createElement("div");
|
|
351
|
+
nameEl.className = "feed-name";
|
|
352
|
+
nameEl.textContent = "#" + item.tokenId + " " + name;
|
|
353
|
+
info.appendChild(nameEl);
|
|
354
|
+
|
|
355
|
+
var meta = document.createElement("div");
|
|
356
|
+
meta.className = "feed-meta";
|
|
357
|
+
var typeEl = document.createElement("span");
|
|
358
|
+
typeEl.className = "feed-type type-" + typeName;
|
|
359
|
+
typeEl.textContent = typeName;
|
|
360
|
+
meta.appendChild(typeEl);
|
|
361
|
+
if (item.soulbound) {
|
|
362
|
+
var sb = document.createElement("span");
|
|
363
|
+
sb.className = "feed-soulbound";
|
|
364
|
+
sb.textContent = "soulbound";
|
|
365
|
+
meta.appendChild(sb);
|
|
366
|
+
}
|
|
367
|
+
var addrEl = document.createElement("span");
|
|
368
|
+
addrEl.className = "feed-addr";
|
|
369
|
+
addrEl.textContent = shortAddr;
|
|
370
|
+
meta.appendChild(addrEl);
|
|
371
|
+
info.appendChild(meta);
|
|
372
|
+
row.appendChild(info);
|
|
373
|
+
|
|
374
|
+
var time = document.createElement("div");
|
|
375
|
+
time.className = "feed-time";
|
|
376
|
+
time.textContent = timeAgo(item.blockNumber, latestBlock);
|
|
377
|
+
row.appendChild(time);
|
|
378
|
+
|
|
379
|
+
var links = document.createElement("div");
|
|
380
|
+
links.className = "feed-links";
|
|
381
|
+
links.appendChild(makeScanLink(item.txHash));
|
|
382
|
+
links.appendChild(makeOsLink(item.tokenId));
|
|
383
|
+
row.appendChild(links);
|
|
384
|
+
|
|
385
|
+
list.appendChild(row);
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
async function fetchFeed() {
|
|
390
|
+
var latest = await rpcCall("eth_blockNumber", []);
|
|
391
|
+
var latestBlock = parseInt(latest, 16);
|
|
392
|
+
var allLogs = [];
|
|
393
|
+
var from = MINTDAY.fromBlock;
|
|
394
|
+
while (from <= latestBlock) {
|
|
395
|
+
var to = Math.min(from + 9900, latestBlock);
|
|
396
|
+
var logs = await rpcCall("eth_getLogs", [{
|
|
397
|
+
address: MINTDAY.contract,
|
|
398
|
+
fromBlock: "0x" + from.toString(16),
|
|
399
|
+
toBlock: "0x" + to.toString(16),
|
|
400
|
+
topics: [MINTDAY.mintedSig]
|
|
401
|
+
}]);
|
|
402
|
+
if (logs && logs.length) allLogs = allLogs.concat(logs);
|
|
403
|
+
from = to + 1;
|
|
404
|
+
}
|
|
405
|
+
return { items: allLogs.map(decodeMintedLog).reverse(), latestBlock: latestBlock };
|
|
308
406
|
}
|
|
309
407
|
|
|
310
|
-
function
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
408
|
+
async function fetchRareFeed() {
|
|
409
|
+
var latest = await rpcCall("eth_blockNumber", []);
|
|
410
|
+
var latestBlock = parseInt(latest, 16);
|
|
411
|
+
var allLogs = [];
|
|
412
|
+
var from = RARE_FROM_BLOCK;
|
|
413
|
+
while (from <= latestBlock) {
|
|
414
|
+
var to = Math.min(from + 9900, latestBlock);
|
|
415
|
+
var logs = await rpcCall("eth_getLogs", [{
|
|
416
|
+
address: RARE_CONTRACT,
|
|
417
|
+
fromBlock: "0x" + from.toString(16),
|
|
418
|
+
toBlock: "0x" + to.toString(16),
|
|
419
|
+
topics: [TRANSFER_SIG, ZERO_ADDR]
|
|
420
|
+
}]);
|
|
421
|
+
if (logs && logs.length) allLogs = allLogs.concat(logs);
|
|
422
|
+
from = to + 1;
|
|
423
|
+
}
|
|
424
|
+
return {
|
|
425
|
+
items: allLogs.map(function(log) {
|
|
426
|
+
var tokenId = parseInt(log.topics[3], 16);
|
|
427
|
+
var to = "0x" + log.topics[2].slice(26);
|
|
428
|
+
return {
|
|
429
|
+
tokenId: tokenId,
|
|
430
|
+
to: to,
|
|
431
|
+
txHash: log.transactionHash,
|
|
432
|
+
blockNumber: parseInt(log.blockNumber, 16),
|
|
433
|
+
tokenType: 1,
|
|
434
|
+
soulbound: false,
|
|
435
|
+
metadata: { name: "mint.day #" + tokenId },
|
|
436
|
+
platform: "rare"
|
|
437
|
+
};
|
|
438
|
+
}).reverse(),
|
|
439
|
+
latestBlock: latestBlock
|
|
440
|
+
};
|
|
316
441
|
}
|
|
317
442
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
443
|
+
function renderRareItems(items, latestBlock) {
|
|
444
|
+
var list = document.getElementById("feed-list");
|
|
445
|
+
list.textContent = "";
|
|
446
|
+
|
|
447
|
+
if (items.length === 0) {
|
|
448
|
+
var empty = document.createElement("div");
|
|
449
|
+
empty.className = "feed-status";
|
|
450
|
+
empty.textContent = "No Rare Protocol mints yet.";
|
|
451
|
+
list.appendChild(empty);
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
var count = document.createElement("div");
|
|
456
|
+
count.className = "feed-count";
|
|
457
|
+
var countText = document.createElement("span");
|
|
458
|
+
countText.textContent = items.length + " token" + (items.length !== 1 ? "s" : "") + " minted via Rare Protocol";
|
|
459
|
+
count.appendChild(countText);
|
|
460
|
+
var contractLink = document.createElement("a");
|
|
461
|
+
contractLink.href = MINTDAY.explorer + "/address/" + RARE_CONTRACT;
|
|
462
|
+
contractLink.target = "_blank";
|
|
463
|
+
contractLink.textContent = "view contract";
|
|
464
|
+
count.appendChild(contractLink);
|
|
465
|
+
list.appendChild(count);
|
|
466
|
+
|
|
467
|
+
items.forEach(function(item, i) {
|
|
468
|
+
var shortAddr = item.to.slice(0, 6) + "..." + item.to.slice(-4);
|
|
469
|
+
var row = document.createElement("div");
|
|
470
|
+
row.className = "feed-item";
|
|
471
|
+
row.style.animationName = "fadeIn";
|
|
472
|
+
row.style.animationDuration = "0.3s";
|
|
473
|
+
row.style.animationDelay = (i * 0.05) + "s";
|
|
474
|
+
row.style.animationFillMode = "both";
|
|
475
|
+
|
|
476
|
+
var thumb = document.createElement("div");
|
|
477
|
+
thumb.className = "feed-thumb";
|
|
478
|
+
var gt = document.createElement("div");
|
|
479
|
+
gt.className = "gen-thumb";
|
|
480
|
+
gt.style.background = "#faf5ff";
|
|
481
|
+
var bar = document.createElement("div");
|
|
482
|
+
bar.className = "gt-bar";
|
|
483
|
+
bar.style.background = "#a855f7";
|
|
484
|
+
gt.appendChild(bar);
|
|
485
|
+
var label = document.createElement("div");
|
|
486
|
+
label.className = "gt-label";
|
|
487
|
+
label.style.color = "#a855f7";
|
|
488
|
+
label.textContent = "RARE";
|
|
489
|
+
gt.appendChild(label);
|
|
490
|
+
thumb.appendChild(gt);
|
|
491
|
+
row.appendChild(thumb);
|
|
492
|
+
|
|
493
|
+
var info = document.createElement("div");
|
|
494
|
+
info.className = "feed-info";
|
|
495
|
+
var nameEl = document.createElement("div");
|
|
496
|
+
nameEl.className = "feed-name";
|
|
497
|
+
nameEl.textContent = "#" + item.tokenId + " " + (item.metadata.name || "");
|
|
498
|
+
info.appendChild(nameEl);
|
|
499
|
+
var meta = document.createElement("div");
|
|
500
|
+
meta.className = "feed-meta";
|
|
501
|
+
var typeEl = document.createElement("span");
|
|
502
|
+
typeEl.className = "feed-type";
|
|
503
|
+
typeEl.style.color = "var(--purple)";
|
|
504
|
+
typeEl.style.border = "1px solid rgba(167,139,250,0.2)";
|
|
505
|
+
typeEl.textContent = "Rare Protocol";
|
|
506
|
+
meta.appendChild(typeEl);
|
|
507
|
+
var addrEl = document.createElement("span");
|
|
508
|
+
addrEl.className = "feed-addr";
|
|
509
|
+
addrEl.textContent = shortAddr;
|
|
510
|
+
meta.appendChild(addrEl);
|
|
511
|
+
info.appendChild(meta);
|
|
512
|
+
row.appendChild(info);
|
|
513
|
+
|
|
514
|
+
var time = document.createElement("div");
|
|
515
|
+
time.className = "feed-time";
|
|
516
|
+
time.textContent = timeAgo(item.blockNumber, latestBlock);
|
|
517
|
+
row.appendChild(time);
|
|
518
|
+
|
|
519
|
+
var links = document.createElement("div");
|
|
520
|
+
links.className = "feed-links";
|
|
521
|
+
links.appendChild(makeScanLink(item.txHash));
|
|
522
|
+
row.appendChild(links);
|
|
523
|
+
|
|
524
|
+
list.appendChild(row);
|
|
323
525
|
});
|
|
324
|
-
return (await res.json()).result;
|
|
325
526
|
}
|
|
326
527
|
|
|
327
|
-
|
|
328
|
-
|
|
528
|
+
function switchTab(tab) {
|
|
529
|
+
currentTab = tab;
|
|
530
|
+
var tabs = document.querySelectorAll(".feed-tab");
|
|
531
|
+
tabs.forEach(function(t) { t.classList.remove("active"); });
|
|
532
|
+
if (tab === "mintday") {
|
|
533
|
+
tabs[0].classList.add("active");
|
|
534
|
+
loadMintdayFeed();
|
|
535
|
+
} else {
|
|
536
|
+
tabs[1].classList.add("active");
|
|
537
|
+
loadRareFeed();
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
function showLoading(msg) {
|
|
542
|
+
var list = document.getElementById("feed-list");
|
|
329
543
|
list.textContent = "";
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
list.appendChild(
|
|
544
|
+
var s = document.createElement("div");
|
|
545
|
+
s.className = "feed-status";
|
|
546
|
+
s.textContent = msg;
|
|
547
|
+
list.appendChild(s);
|
|
548
|
+
}
|
|
334
549
|
|
|
550
|
+
async function loadMintdayFeed() {
|
|
551
|
+
showLoading("Loading on-chain data...");
|
|
335
552
|
try {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
const from = "0x" + Math.max(latestBlock - 9900, c.fromBlock).toString(16);
|
|
340
|
-
|
|
341
|
-
const logs = await rpc(c.rpc, "eth_getLogs", [{
|
|
342
|
-
address: c.contract, fromBlock: from, toBlock: "latest", topics: [MINTED_SIG]
|
|
343
|
-
}]) || [];
|
|
344
|
-
|
|
345
|
-
list.textContent = "";
|
|
346
|
-
|
|
347
|
-
if (logs.length === 0) {
|
|
348
|
-
const empty = document.createElement("div");
|
|
349
|
-
empty.className = "feed-status";
|
|
350
|
-
empty.textContent = "No mints yet. Be the first.";
|
|
351
|
-
list.appendChild(empty);
|
|
352
|
-
return;
|
|
553
|
+
var cached = JSON.parse(localStorage.getItem(CACHE_KEY));
|
|
554
|
+
if (cached && cached.items && cached.items.length > 0) {
|
|
555
|
+
renderItems(cached.items, cached.latestBlock);
|
|
353
556
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
count.textContent = items.length + " token" + (items.length !== 1 ? "s" : "") + " minted";
|
|
360
|
-
list.appendChild(count);
|
|
361
|
-
|
|
362
|
-
items.forEach((item, i) => {
|
|
363
|
-
const typeName = TYPE_NAMES[item.tokenType] || "Unknown";
|
|
364
|
-
const name = item.metadata.name || "mint.day token #" + item.tokenId;
|
|
365
|
-
const image = item.metadata.image || "";
|
|
366
|
-
|
|
367
|
-
const a = document.createElement("a");
|
|
368
|
-
a.className = "feed-item";
|
|
369
|
-
a.href = c.explorer + "/tx/" + item.txHash;
|
|
370
|
-
a.target = "_blank";
|
|
371
|
-
a.style.animationName = "fadeIn";
|
|
372
|
-
a.style.animationDuration = "0.3s";
|
|
373
|
-
a.style.animationDelay = (i * 0.05) + "s";
|
|
374
|
-
a.style.animationFillMode = "both";
|
|
375
|
-
|
|
376
|
-
const thumb = document.createElement("div");
|
|
377
|
-
thumb.className = "feed-thumb";
|
|
378
|
-
if (image) {
|
|
379
|
-
const img = document.createElement("img");
|
|
380
|
-
img.src = image;
|
|
381
|
-
img.alt = "";
|
|
382
|
-
img.loading = "lazy";
|
|
383
|
-
thumb.appendChild(img);
|
|
384
|
-
}
|
|
385
|
-
a.appendChild(thumb);
|
|
386
|
-
|
|
387
|
-
const info = document.createElement("div");
|
|
388
|
-
info.className = "feed-info";
|
|
389
|
-
const nameEl = document.createElement("div");
|
|
390
|
-
nameEl.className = "feed-name";
|
|
391
|
-
nameEl.textContent = name;
|
|
392
|
-
info.appendChild(nameEl);
|
|
393
|
-
|
|
394
|
-
const meta = document.createElement("div");
|
|
395
|
-
meta.className = "feed-meta";
|
|
396
|
-
const typeEl = document.createElement("span");
|
|
397
|
-
typeEl.className = "feed-type type-" + typeName;
|
|
398
|
-
typeEl.textContent = typeName;
|
|
399
|
-
meta.appendChild(typeEl);
|
|
400
|
-
if (item.soulbound) {
|
|
401
|
-
const sb = document.createElement("span");
|
|
402
|
-
sb.className = "feed-soulbound";
|
|
403
|
-
sb.textContent = "soulbound";
|
|
404
|
-
meta.appendChild(sb);
|
|
405
|
-
}
|
|
406
|
-
const idEl = document.createElement("span");
|
|
407
|
-
idEl.textContent = "#" + item.tokenId;
|
|
408
|
-
meta.appendChild(idEl);
|
|
409
|
-
info.appendChild(meta);
|
|
410
|
-
a.appendChild(info);
|
|
411
|
-
|
|
412
|
-
const time = document.createElement("div");
|
|
413
|
-
time.className = "feed-time";
|
|
414
|
-
time.textContent = timeAgo(item.blockNumber, latestBlock);
|
|
415
|
-
a.appendChild(time);
|
|
416
|
-
|
|
417
|
-
list.appendChild(a);
|
|
418
|
-
});
|
|
557
|
+
} catch (e) {}
|
|
558
|
+
try {
|
|
559
|
+
var data = await fetchFeed();
|
|
560
|
+
localStorage.setItem(CACHE_KEY, JSON.stringify({ items: data.items, latestBlock: data.latestBlock, ts: Date.now() }));
|
|
561
|
+
renderItems(data.items, data.latestBlock);
|
|
419
562
|
} catch (err) {
|
|
420
|
-
list
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
563
|
+
var list = document.getElementById("feed-list");
|
|
564
|
+
if (!list.querySelector(".feed-item")) {
|
|
565
|
+
list.textContent = "";
|
|
566
|
+
var fail = document.createElement("div");
|
|
567
|
+
fail.className = "feed-status";
|
|
568
|
+
fail.textContent = "Failed to load: " + err.message;
|
|
569
|
+
list.appendChild(fail);
|
|
570
|
+
}
|
|
426
571
|
}
|
|
427
572
|
}
|
|
428
573
|
|
|
429
|
-
function
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
574
|
+
async function loadRareFeed() {
|
|
575
|
+
showLoading("Loading Rare Protocol data...");
|
|
576
|
+
try {
|
|
577
|
+
var cached = JSON.parse(localStorage.getItem(CACHE_KEY_RARE));
|
|
578
|
+
if (cached && cached.items && cached.items.length > 0) {
|
|
579
|
+
renderRareItems(cached.items, cached.latestBlock);
|
|
580
|
+
}
|
|
581
|
+
} catch (e) {}
|
|
582
|
+
try {
|
|
583
|
+
var data = await fetchRareFeed();
|
|
584
|
+
localStorage.setItem(CACHE_KEY_RARE, JSON.stringify({ items: data.items, latestBlock: data.latestBlock, ts: Date.now() }));
|
|
585
|
+
renderRareItems(data.items, data.latestBlock);
|
|
586
|
+
} catch (err) {
|
|
587
|
+
var list = document.getElementById("feed-list");
|
|
588
|
+
if (!list.querySelector(".feed-item")) {
|
|
589
|
+
list.textContent = "";
|
|
590
|
+
var fail = document.createElement("div");
|
|
591
|
+
fail.className = "feed-status";
|
|
592
|
+
fail.textContent = "Failed to load: " + err.message;
|
|
593
|
+
list.appendChild(fail);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
433
596
|
}
|
|
434
597
|
|
|
435
|
-
|
|
598
|
+
loadMintdayFeed();
|
|
436
599
|
</script>
|
|
437
600
|
</body>
|
|
438
601
|
</html>
|