sui.ski 0.1.0
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/AGENTS.md +311 -0
- package/CLAUDE.md +292 -0
- package/CODEBASE_GUIDE.md +217 -0
- package/README.md +77 -0
- package/biome.json +28 -0
- package/package.json +73 -0
- package/scripts/deploy-messaging-mainnet.sh +184 -0
- package/scripts/extract-suins-object.ts +180 -0
- package/scripts/full-deploy.sh +26 -0
- package/scripts/obsidian.ts +243 -0
- package/scripts/set-suins-contenthash.ts +130 -0
- package/scripts/setup-ika-dwallet.ts +338 -0
- package/scripts/transfer-upgrade-cap-from-nft.ts +86 -0
- package/src/durable-objects/wallet-session.ts +333 -0
- package/src/handlers/app.ts +1430 -0
- package/src/handlers/authenticated-events.ts +267 -0
- package/src/handlers/dashboard.ts +1659 -0
- package/src/handlers/landing.ts +6751 -0
- package/src/handlers/mcp.ts +556 -0
- package/src/handlers/messaging-sdk.ts +220 -0
- package/src/handlers/profile.css.ts +9332 -0
- package/src/handlers/profile.ts +12640 -0
- package/src/handlers/register2.ts +2811 -0
- package/src/handlers/ski-sign.ts +1901 -0
- package/src/handlers/ski.ts +314 -0
- package/src/handlers/thunder.ts +940 -0
- package/src/handlers/vault.ts +284 -0
- package/src/handlers/wallet-api.ts +169 -0
- package/src/handlers/x402-register.ts +601 -0
- package/src/index.test.ts +55 -0
- package/src/index.ts +512 -0
- package/src/resolvers/content.ts +231 -0
- package/src/resolvers/rpc.ts +222 -0
- package/src/resolvers/suins.ts +266 -0
- package/src/sdk/messaging.ts +279 -0
- package/src/types.ts +230 -0
- package/src/utils/agent-keypair.ts +40 -0
- package/src/utils/authenticated-events.ts +280 -0
- package/src/utils/cache.ts +82 -0
- package/src/utils/media-pack.ts +27 -0
- package/src/utils/mmr.ts +181 -0
- package/src/utils/ns-price.ts +529 -0
- package/src/utils/og-image.ts +141 -0
- package/src/utils/onchain-activity.ts +211 -0
- package/src/utils/onchain-listing.ts +39 -0
- package/src/utils/premium.ts +29 -0
- package/src/utils/pricing.ts +291 -0
- package/src/utils/pyth-price-info.ts +63 -0
- package/src/utils/response.ts +204 -0
- package/src/utils/rpc.ts +25 -0
- package/src/utils/shared-wallet-js.ts +166 -0
- package/src/utils/social.ts +152 -0
- package/src/utils/status.ts +39 -0
- package/src/utils/subdomain.ts +116 -0
- package/src/utils/surflux-grpc.ts +241 -0
- package/src/utils/swap-transactions.ts +1222 -0
- package/src/utils/thunder-css.ts +1341 -0
- package/src/utils/thunder-js.ts +5046 -0
- package/src/utils/transactions.ts +65 -0
- package/src/utils/vault.ts +18 -0
- package/src/utils/wallet-kit-js.ts +2312 -0
- package/src/utils/wallet-session-js.ts +192 -0
- package/src/utils/wallet-tx-js.ts +2287 -0
- package/src/utils/wallet-ui-js.ts +3057 -0
- package/src/utils/x402-middleware.ts +428 -0
- package/src/utils/x402-sui.ts +171 -0
- package/src/utils/zksend-js.ts +166 -0
- package/tsconfig.json +22 -0
- package/workers/x402-multichain/src/index.ts +237 -0
- package/workers/x402-multichain/src/types.ts +80 -0
- package/workers/x402-multichain/tsconfig.json +20 -0
- package/workers/x402-multichain/wrangler.toml +11 -0
- package/wrangler.toml +84 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import type { Env } from '../types'
|
|
2
|
+
import { generateLogoSvg } from '../utils/og-image'
|
|
3
|
+
import { generateExtensionNoiseFilter, generateWalletKitJs } from '../utils/wallet-kit-js'
|
|
4
|
+
import { generateWalletSessionJs } from '../utils/wallet-session-js'
|
|
5
|
+
import { generateWalletTxJs } from '../utils/wallet-tx-js'
|
|
6
|
+
import { generateWalletUiCss, generateWalletUiJs } from '../utils/wallet-ui-js'
|
|
7
|
+
|
|
8
|
+
interface SkiSession {
|
|
9
|
+
address: string | null
|
|
10
|
+
walletName: string | null
|
|
11
|
+
verified: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function generateSkiPage(env: Env, session?: SkiSession): string {
|
|
15
|
+
const hasVerifiedSession = session?.address && session.verified
|
|
16
|
+
const sessionJson = hasVerifiedSession
|
|
17
|
+
? JSON.stringify({ address: session.address, walletName: session.walletName, verified: true })
|
|
18
|
+
: 'null'
|
|
19
|
+
|
|
20
|
+
return `<!DOCTYPE html>
|
|
21
|
+
<html lang="en"><head>
|
|
22
|
+
${generateExtensionNoiseFilter()}
|
|
23
|
+
<meta charset="utf-8">
|
|
24
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
25
|
+
<title>Sui Key-In</title>
|
|
26
|
+
<style>
|
|
27
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
28
|
+
body{background:#000;color:#e4e4e7;font-family:'Inter',system-ui,sans-serif;min-height:100vh;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:24px;position:relative;overflow:hidden}
|
|
29
|
+
body::before {
|
|
30
|
+
content: '';
|
|
31
|
+
position: absolute;
|
|
32
|
+
top: 50%; left: 50%; transform: translate(-50%, -50%);
|
|
33
|
+
width: 140%; height: 140%;
|
|
34
|
+
background: radial-gradient(circle at center, rgba(34, 197, 94, 0.11) 0%, rgba(16, 185, 129, 0.04) 35%, transparent 62%);
|
|
35
|
+
pointer-events: none; z-index: 0;
|
|
36
|
+
}
|
|
37
|
+
${generateWalletUiCss()}
|
|
38
|
+
.ski-container{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;gap:24px;width:100%;max-width:460px;padding:20px}
|
|
39
|
+
.ski-suins-preview{width:100%;border-radius:20px;border:1px solid rgba(74,222,128,0.25);background:linear-gradient(140deg, rgba(8,20,15,0.96), rgba(10,18,16,0.9));box-shadow:0 18px 42px rgba(16,185,129,0.12), inset 0 0 0 1px rgba(34,197,94,0.08);padding:16px}
|
|
40
|
+
.ski-suins-top{display:flex;gap:14px;align-items:center;margin-bottom:12px}
|
|
41
|
+
.ski-green-orb{width:72px;height:72px;border-radius:999px;background:radial-gradient(circle at 30% 30%, rgba(134,239,172,0.95), rgba(34,197,94,0.55) 44%, rgba(5,46,22,0.6) 78%);box-shadow:0 0 28px rgba(34,197,94,0.25), inset 0 0 0 1px rgba(187,247,208,0.3);display:flex;align-items:center;justify-content:center;color:#f0fdf4}
|
|
42
|
+
.ski-green-orb svg{width:34px;height:34px;filter:drop-shadow(0 0 8px rgba(220,252,231,0.35))}
|
|
43
|
+
.ski-suins-title{display:flex;flex-direction:column;gap:3px;min-width:0}
|
|
44
|
+
.ski-suins-title h2{font-size:1.35rem;font-weight:900;letter-spacing:-0.02em;color:#bbf7d0;line-height:1.05;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:300px}
|
|
45
|
+
.ski-suins-sub{font-size:0.72rem;font-family:'JetBrains Mono',monospace;color:#86efac;letter-spacing:0.04em;text-transform:uppercase}
|
|
46
|
+
.ski-suins-grid{display:grid;grid-template-columns:1fr;gap:8px}
|
|
47
|
+
.ski-meta-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:7px 9px;border-radius:10px;background:rgba(20,36,27,0.55);border:1px solid rgba(34,197,94,0.12);font-size:0.72rem}
|
|
48
|
+
.ski-meta-label{color:#86efac;text-transform:uppercase;letter-spacing:0.05em;font-family:'JetBrains Mono',monospace}
|
|
49
|
+
.ski-meta-value{color:#dcfce7;font-family:'JetBrains Mono',monospace;font-weight:600;text-align:right;word-break:break-all}
|
|
50
|
+
.ski-meta-value.pending{color:#bbf7d0}
|
|
51
|
+
.ski-logo{filter:drop-shadow(0 0 20px rgba(34,197,94,0.35))}
|
|
52
|
+
.ski-header{text-align:center}
|
|
53
|
+
.ski-header h1{font-size:1.5rem;font-weight:800;background:linear-gradient(135deg,#34d399,#22c55e);-webkit-background-clip:text;-webkit-text-fill-color:transparent;margin-bottom:8px;letter-spacing:-0.02em}
|
|
54
|
+
.ski-header p{color:#71717a;font-size:0.85rem;font-family:monospace}
|
|
55
|
+
.ski-status{text-align:center;padding:12px 20px;color:#71717a;font-size:0.85rem;min-height:40px}
|
|
56
|
+
.ski-status.success{color:#34d399}
|
|
57
|
+
.ski-status.error{color:#f87171}
|
|
58
|
+
.ski-locks{display:flex;gap:12px;margin-top:8px}
|
|
59
|
+
.ski-lock{width:32px;height:32px;border-radius:8px;background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.1);display:flex;align-items:center;justify-content:center;color:#52525b;transition:all 0.3s ease}
|
|
60
|
+
.ski-lock.active{color:#22c55e;border-color:rgba(34,197,94,0.36);background:rgba(34,197,94,0.13);box-shadow:0 0 15px rgba(34,197,94,0.24)}
|
|
61
|
+
.ski-login-btn{margin-top:12px;padding:12px 24px;background:linear-gradient(135deg,#22c55e,#10b981);border:none;border-radius:12px;color:white;font-weight:700;font-size:0.95rem;cursor:pointer;transition:all 0.2s ease;box-shadow:0 4px 15px rgba(34,197,94,0.25)}
|
|
62
|
+
.ski-login-btn:hover{transform:translateY(-1px);box-shadow:0 6px 20px rgba(34,197,94,0.35)}
|
|
63
|
+
.ski-login-btn:active{transform:translateY(0)}
|
|
64
|
+
@media (max-width: 560px){
|
|
65
|
+
.ski-container{max-width:100%;padding:14px}
|
|
66
|
+
.ski-suins-title h2{max-width:220px;font-size:1.2rem}
|
|
67
|
+
.ski-green-orb{width:62px;height:62px}
|
|
68
|
+
}
|
|
69
|
+
</style>
|
|
70
|
+
</head><body>
|
|
71
|
+
<div class="ski-container">
|
|
72
|
+
<div class="ski-suins-preview">
|
|
73
|
+
<div class="ski-suins-top">
|
|
74
|
+
<div class="ski-green-orb">${generateLogoSvg(34)}</div>
|
|
75
|
+
<div class="ski-suins-title">
|
|
76
|
+
<h2 id="ski-name-title">pending.sui</h2>
|
|
77
|
+
<div class="ski-suins-sub">SuiNS Pre-Mint Derived Object</div>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
<div class="ski-suins-grid">
|
|
81
|
+
<div class="ski-meta-row">
|
|
82
|
+
<span class="ski-meta-label">Name Key</span>
|
|
83
|
+
<span class="ski-meta-value" id="ski-name-key">pending</span>
|
|
84
|
+
</div>
|
|
85
|
+
<div class="ski-meta-row">
|
|
86
|
+
<span class="ski-meta-label">Derived NFT ID</span>
|
|
87
|
+
<span class="ski-meta-value" id="ski-derived-nft-id">0x--</span>
|
|
88
|
+
</div>
|
|
89
|
+
<div class="ski-meta-row">
|
|
90
|
+
<span class="ski-meta-label">Mint State</span>
|
|
91
|
+
<span class="ski-meta-value pending" id="ski-mint-state">Unminted</span>
|
|
92
|
+
</div>
|
|
93
|
+
<div class="ski-meta-row">
|
|
94
|
+
<span class="ski-meta-label">Owner Key</span>
|
|
95
|
+
<span class="ski-meta-value" id="ski-owner-key">--</span>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
<div class="ski-logo">${generateLogoSvg(64)}</div>
|
|
100
|
+
<div class="ski-header">
|
|
101
|
+
<h1>Sui Key-In</h1>
|
|
102
|
+
<p>ubiquitous authentication</p>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<div id="wk-modal"></div>
|
|
106
|
+
|
|
107
|
+
<div class="ski-locks" id="ski-locks">
|
|
108
|
+
<div class="ski-lock" title="app.sui.ski"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg></div>
|
|
109
|
+
<div class="ski-lock" title="my.sui.ski"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 8v8M8 12h8"/></svg></div>
|
|
110
|
+
<div class="ski-lock" title="rpc.sui.ski"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg></div>
|
|
111
|
+
<div class="ski-lock" title="*.sui.ski"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg></div>
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
<div id="ski-status" class="ski-status">${hasVerifiedSession ? 'Welcome back...' : 'Detecting keys...'}</div>
|
|
115
|
+
|
|
116
|
+
<button id="ski-login-btn" class="ski-login-btn" style="display:none">Sign In with Sui</button>
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
<script>
|
|
120
|
+
var __skiReturnUrl = new URLSearchParams(window.location.search).get('return') || '';
|
|
121
|
+
var __skiServerSession = ${sessionJson};
|
|
122
|
+
|
|
123
|
+
${generateWalletSessionJs()}
|
|
124
|
+
${generateWalletKitJs({ network: env.SUI_NETWORK, autoConnect: true })}
|
|
125
|
+
${generateWalletTxJs()}
|
|
126
|
+
${generateWalletUiJs({ onConnect: '__skiDone' })}
|
|
127
|
+
|
|
128
|
+
function __wkActivateLocks() {
|
|
129
|
+
var locks = document.querySelectorAll('.ski-lock');
|
|
130
|
+
for (var i = 0; i < locks.length; i++) {
|
|
131
|
+
locks[i].classList.add('active');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (__skiServerSession && __skiServerSession.address) {
|
|
136
|
+
initSessionFromServer(__skiServerSession);
|
|
137
|
+
__wkActivateLocks();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
var __skiDoneTriggered = false;
|
|
141
|
+
window.__skiDone = function() {
|
|
142
|
+
if (__skiDoneTriggered) return;
|
|
143
|
+
__skiDoneTriggered = true;
|
|
144
|
+
__wkActivateLocks();
|
|
145
|
+
|
|
146
|
+
var conn = SuiWalletKit.$connection.value;
|
|
147
|
+
var addr = (conn && conn.address) || (__skiServerSession && __skiServerSession.address) || '';
|
|
148
|
+
if (!addr) return;
|
|
149
|
+
var statusEl = document.getElementById('ski-status');
|
|
150
|
+
var loginBtn = document.getElementById('ski-login-btn');
|
|
151
|
+
if (loginBtn) loginBtn.style.display = 'none';
|
|
152
|
+
|
|
153
|
+
var truncAddr = addr.slice(0, 6) + '...' + addr.slice(-4);
|
|
154
|
+
|
|
155
|
+
if (statusEl) {
|
|
156
|
+
statusEl.className = 'ski-status success';
|
|
157
|
+
statusEl.textContent = 'Key verified...';
|
|
158
|
+
}
|
|
159
|
+
__skiUpdatePreviewOwner(addr);
|
|
160
|
+
|
|
161
|
+
var sessionPromise = SuiWalletKit.__sessionReady || Promise.resolve(true);
|
|
162
|
+
var timedOut = false;
|
|
163
|
+
var timer = setTimeout(function() { timedOut = true; }, 15000);
|
|
164
|
+
|
|
165
|
+
sessionPromise.then(function() {
|
|
166
|
+
clearTimeout(timer);
|
|
167
|
+
}).catch(function() {
|
|
168
|
+
clearTimeout(timer);
|
|
169
|
+
}).finally(function() {
|
|
170
|
+
if (statusEl) {
|
|
171
|
+
statusEl.textContent = 'Unlocked as ' + truncAddr;
|
|
172
|
+
}
|
|
173
|
+
if (__skiReturnUrl) {
|
|
174
|
+
if (statusEl) statusEl.textContent += ' — redirecting...';
|
|
175
|
+
setTimeout(function() { window.location.href = __skiReturnUrl; }, 600);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
function __skiNormalizeNameKey(raw) {
|
|
181
|
+
var value = String(raw || '').trim().toLowerCase();
|
|
182
|
+
value = value.replace(/[^a-z0-9.-]/g, '-').replace(/-+/g, '-').replace(/^-+|-+$/g, '');
|
|
183
|
+
if (!value) value = 'pending';
|
|
184
|
+
value = value.replace(/\\.sui$/i, '');
|
|
185
|
+
if (!value) value = 'pending';
|
|
186
|
+
return value;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function __skiExtractNameKeyFromReturn() {
|
|
190
|
+
try {
|
|
191
|
+
var params = new URLSearchParams(window.location.search);
|
|
192
|
+
var explicit = params.get('name');
|
|
193
|
+
if (explicit) return __skiNormalizeNameKey(explicit);
|
|
194
|
+
if (!__skiReturnUrl) return 'pending';
|
|
195
|
+
var parsed = new URL(__skiReturnUrl);
|
|
196
|
+
var host = String(parsed.hostname || '').toLowerCase();
|
|
197
|
+
if (!host.endsWith('.sui.ski')) return 'pending';
|
|
198
|
+
var rawSub = host.slice(0, -('.sui.ski'.length));
|
|
199
|
+
if (!rawSub || rawSub === 'sui' || rawSub === 't' || rawSub === 'd' || rawSub === 'in' || rawSub === 'www') return 'pending';
|
|
200
|
+
return __skiNormalizeNameKey(rawSub);
|
|
201
|
+
} catch (_e) {
|
|
202
|
+
return 'pending';
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function __skiDeriveObjectIdFromNameKey(nameKey) {
|
|
207
|
+
var seed = String(nameKey || 'pending');
|
|
208
|
+
var h1 = 0x811c9dc5;
|
|
209
|
+
var h2 = 0x811c9dc5;
|
|
210
|
+
for (var i = 0; i < seed.length; i++) {
|
|
211
|
+
var c = seed.charCodeAt(i);
|
|
212
|
+
h1 ^= c;
|
|
213
|
+
h2 ^= c + i;
|
|
214
|
+
h1 = Math.imul(h1, 0x01000193);
|
|
215
|
+
h2 = Math.imul(h2, 0x01000197);
|
|
216
|
+
}
|
|
217
|
+
function toChunk(v) {
|
|
218
|
+
var n = (v >>> 0).toString(16);
|
|
219
|
+
return ('00000000' + n).slice(-8);
|
|
220
|
+
}
|
|
221
|
+
var hex = '';
|
|
222
|
+
for (var j = 0; j < 8; j++) {
|
|
223
|
+
h1 = Math.imul(h1 ^ (0x9e3779b9 + j), 0x85ebca6b);
|
|
224
|
+
h2 = Math.imul(h2 ^ (0xc2b2ae35 + j), 0x27d4eb2f);
|
|
225
|
+
hex += toChunk(h1) + toChunk(h2);
|
|
226
|
+
}
|
|
227
|
+
return '0x' + hex.slice(0, 64);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function __skiUpdatePreviewOwner(address) {
|
|
231
|
+
var ownerEl = document.getElementById('ski-owner-key');
|
|
232
|
+
if (!ownerEl) return;
|
|
233
|
+
if (!address) {
|
|
234
|
+
ownerEl.textContent = '--';
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
ownerEl.textContent = address.slice(0, 8) + '...' + address.slice(-6);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function __skiInitDerivedPreview() {
|
|
241
|
+
var nameKey = __skiExtractNameKeyFromReturn();
|
|
242
|
+
var fullName = nameKey + '.sui';
|
|
243
|
+
var nftId = __skiDeriveObjectIdFromNameKey(nameKey);
|
|
244
|
+
var titleEl = document.getElementById('ski-name-title');
|
|
245
|
+
var keyEl = document.getElementById('ski-name-key');
|
|
246
|
+
var nftEl = document.getElementById('ski-derived-nft-id');
|
|
247
|
+
if (titleEl) titleEl.textContent = fullName;
|
|
248
|
+
if (keyEl) keyEl.textContent = nameKey;
|
|
249
|
+
if (nftEl) nftEl.textContent = nftId;
|
|
250
|
+
var conn = SuiWalletKit.$connection.value;
|
|
251
|
+
var session = getWalletSession();
|
|
252
|
+
var owner = (conn && conn.address) || (session && session.address) || (__skiServerSession && __skiServerSession.address) || '';
|
|
253
|
+
__skiUpdatePreviewOwner(owner);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
SuiWalletKit.renderModal('wk-modal');
|
|
257
|
+
__skiInitDerivedPreview();
|
|
258
|
+
|
|
259
|
+
document.getElementById('ski-login-btn').onclick = function() {
|
|
260
|
+
SuiWalletKit.openModal();
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
if (__skiServerSession && __skiServerSession.address && __skiReturnUrl) {
|
|
264
|
+
var statusEl = document.getElementById('ski-status');
|
|
265
|
+
if (statusEl) {
|
|
266
|
+
statusEl.className = 'ski-status success';
|
|
267
|
+
statusEl.textContent = 'Welcome back, ' + __skiServerSession.address.slice(0, 6) + '...' + __skiServerSession.address.slice(-4) + ' — redirecting...';
|
|
268
|
+
}
|
|
269
|
+
setTimeout(function() { window.location.href = __skiReturnUrl; }, 800);
|
|
270
|
+
} else {
|
|
271
|
+
SuiWalletKit.detectWallets().then(function(wallets) {
|
|
272
|
+
var statusEl = document.getElementById('ski-status');
|
|
273
|
+
var loginBtn = document.getElementById('ski-login-btn');
|
|
274
|
+
|
|
275
|
+
var session = getWalletSession();
|
|
276
|
+
if (session && session.address) {
|
|
277
|
+
__wkActivateLocks();
|
|
278
|
+
if (statusEl) {
|
|
279
|
+
statusEl.className = 'ski-status success';
|
|
280
|
+
statusEl.textContent = 'Key detected: ' + session.address.slice(0, 6) + '...' + session.address.slice(-4);
|
|
281
|
+
}
|
|
282
|
+
if (__skiReturnUrl) {
|
|
283
|
+
if (statusEl) statusEl.textContent += ' — redirecting...';
|
|
284
|
+
setTimeout(function() { window.location.href = __skiReturnUrl; }, 1000);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (!wallets || wallets.length === 0) {
|
|
290
|
+
if (statusEl) statusEl.textContent = 'No Sui keys detected. Please install a wallet.';
|
|
291
|
+
if (loginBtn) {
|
|
292
|
+
loginBtn.style.display = 'block';
|
|
293
|
+
loginBtn.textContent = 'Install Sui Wallet';
|
|
294
|
+
loginBtn.onclick = function() { window.open('https://phantom.app/download', '_blank'); };
|
|
295
|
+
}
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (statusEl) statusEl.textContent = 'Ready to unlock';
|
|
300
|
+
if (loginBtn) {
|
|
301
|
+
loginBtn.style.display = 'block';
|
|
302
|
+
loginBtn.textContent = 'Sign In with Sui';
|
|
303
|
+
loginBtn.onclick = function() { SuiWalletKit.openModal(); };
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Auto-open modal if no session
|
|
307
|
+
if (!session || !session.address) {
|
|
308
|
+
setTimeout(function() { SuiWalletKit.openModal(); }, 500);
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
</script>
|
|
313
|
+
</body></html>`
|
|
314
|
+
}
|