@qntx/siwx 0.0.0-stage → 0.7.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/LICENSE-APACHE +201 -0
- package/LICENSE-MIT +21 -0
- package/README.md +38 -2
- package/dist/eip4361-XA-TUOKF.mjs +125 -0
- package/dist/evm.d.mts +41 -0
- package/dist/evm.mjs +289 -0
- package/dist/index.d.mts +113 -0
- package/dist/index.mjs +32 -0
- package/dist/message-ZewmOzps.mjs +510 -0
- package/dist/namespace-Cl7PJYC-.mjs +68 -0
- package/dist/namespace-DlgXqLsI.d.mts +105 -0
- package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/dist/svm.d.mts +42 -0
- package/dist/svm.mjs +329 -0
- package/package.json +84 -4
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { __exportAll as t };
|
package/dist/svm.d.mts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { n as Namespace, o as Message } from "./namespace-DlgXqLsI.mjs";
|
|
2
|
+
//#region src/svm/address.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Validate that `address` is a canonical, non-identity, prime-order-subgroup Ed25519 verifying key
|
|
5
|
+
* in base58 form.
|
|
6
|
+
*
|
|
7
|
+
* @throws {SiwxError} `InvalidField` `address`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateAddress(address: string): void;
|
|
10
|
+
declare namespace siws_d_exports {
|
|
11
|
+
export { format, parse, parseBytes };
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Format `message` as a SIWS signing text.
|
|
15
|
+
*
|
|
16
|
+
* @throws {SiwxError} `InvalidField` `scheme` (SIWS has none) or `statement` (empty).
|
|
17
|
+
*/
|
|
18
|
+
declare function format(message: Message): string;
|
|
19
|
+
/**
|
|
20
|
+
* Parse `text` into a validated message; the preamble label must be exactly `"Solana"`.
|
|
21
|
+
*
|
|
22
|
+
* @throws {SiwxError} `Syntax`, `Mismatch` `label`, or `InvalidField`.
|
|
23
|
+
*/
|
|
24
|
+
declare function parse(text: string): Message;
|
|
25
|
+
/**
|
|
26
|
+
* {@link parse} over raw bytes: size check, strict UTF-8 (`InvalidUtf8`), then parse.
|
|
27
|
+
*
|
|
28
|
+
* @throws {SiwxError}
|
|
29
|
+
*/
|
|
30
|
+
declare function parseBytes(bytes: Uint8Array): Message;
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/svm/index.d.ts
|
|
33
|
+
/**
|
|
34
|
+
* Wrap `text` in the off-chain message v1 envelope for `signer` (validated as an SIWS address).
|
|
35
|
+
*
|
|
36
|
+
* @throws {SiwxError} `InvalidField` `address`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function offchainMessage(text: string, signer: string): Uint8Array;
|
|
39
|
+
/** Create the Solana namespace profile. */
|
|
40
|
+
export declare function svm(): Namespace;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { siws_d_exports as siws };
|
package/dist/svm.mjs
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
+
import { g as createAccountId, h as optionalTags, i as utf8Encode, m as SUFFIX, n as utf8ByteLength, p as MID, r as utf8Decode, s as MAX_MESSAGE_BYTES, t as createMessage, v as SiwxError, x as syntaxError, y as fieldError } from "./message-ZewmOzps.mjs";
|
|
3
|
+
import { n as settle } from "./namespace-Cl7PJYC-.mjs";
|
|
4
|
+
import { bytesToNumberLE, equalBytes } from "@noble/curves/utils.js";
|
|
5
|
+
import { ed25519 } from "@noble/curves/ed25519.js";
|
|
6
|
+
import { base58 } from "@scure/base";
|
|
7
|
+
//#region src/svm/address.ts
|
|
8
|
+
/** Solana address rules: canonical on-curve Ed25519 key in base58. */
|
|
9
|
+
/**
|
|
10
|
+
* Decode `address` as a base58 (Bitcoin alphabet) string of 32–44 chars that decodes to exactly 32
|
|
11
|
+
* bytes.
|
|
12
|
+
*
|
|
13
|
+
* @throws {SiwxError} `InvalidField` `address`.
|
|
14
|
+
*/
|
|
15
|
+
function addressBytes(address) {
|
|
16
|
+
if (address.length < 32 || address.length > 44) throw fieldError("address", "expected 32–44 base58 chars");
|
|
17
|
+
let bytes;
|
|
18
|
+
try {
|
|
19
|
+
bytes = base58.decode(address);
|
|
20
|
+
} catch {
|
|
21
|
+
throw fieldError("address", "invalid base58");
|
|
22
|
+
}
|
|
23
|
+
if (bytes.length !== 32) throw fieldError("address", "expected 32 bytes");
|
|
24
|
+
return bytes;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The canonical, non-identity, prime-order-subgroup Ed25519 point for `bytes` (decompress →
|
|
28
|
+
* recompress byte equality proves canonicity).
|
|
29
|
+
*
|
|
30
|
+
* @throws {SiwxError} `InvalidField` `address`.
|
|
31
|
+
*/
|
|
32
|
+
function canonicalPoint(bytes) {
|
|
33
|
+
let point;
|
|
34
|
+
try {
|
|
35
|
+
point = ed25519.Point.fromBytes(bytes);
|
|
36
|
+
} catch {
|
|
37
|
+
throw fieldError("address", "invalid Ed25519 pubkey");
|
|
38
|
+
}
|
|
39
|
+
if (point.equals(ed25519.Point.ZERO)) throw fieldError("address", "identity pubkey");
|
|
40
|
+
if (!point.isTorsionFree()) throw fieldError("address", "not in the prime-order subgroup");
|
|
41
|
+
if (!equalBytes(point.toBytes(), bytes)) throw fieldError("address", "non-canonical pubkey");
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Validate that `address` is a canonical, non-identity, prime-order-subgroup Ed25519 verifying key
|
|
45
|
+
* in base58 form.
|
|
46
|
+
*
|
|
47
|
+
* @throws {SiwxError} `InvalidField` `address`.
|
|
48
|
+
*/
|
|
49
|
+
function validateAddress(address) {
|
|
50
|
+
canonicalPoint(addressBytes(address));
|
|
51
|
+
}
|
|
52
|
+
/** Base58-encode `bytes` (error messages). */
|
|
53
|
+
function b58(bytes) {
|
|
54
|
+
return base58.encode(bytes);
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/svm/ed25519.ts
|
|
58
|
+
/** Ed25519 signature verification for Solana (internal). */
|
|
59
|
+
const L = ed25519.Point.CURVE().n;
|
|
60
|
+
const P = ed25519.Point;
|
|
61
|
+
/**
|
|
62
|
+
* RFC 8032 verification over the exact `signed` bytes.
|
|
63
|
+
*
|
|
64
|
+
* `A` (the address key) and `R` must be canonical encodings of prime-order-subgroup points
|
|
65
|
+
* (torsion-free — excluding identity, small-order and mixed points) and `S < L`; for torsion-free
|
|
66
|
+
* `A`/`R` the cofactored and cofactorless equations coincide, so library verifiers agree.
|
|
67
|
+
*
|
|
68
|
+
* @throws {SiwxError} `InvalidSignature` (wrong length or `S >= L`) or `VerificationFailed` (bad
|
|
69
|
+
* `R`, or the equation fails).
|
|
70
|
+
*/
|
|
71
|
+
function verifyEddsa(message, signed, signature) {
|
|
72
|
+
if (signature.length !== 64) throw new SiwxError({
|
|
73
|
+
code: "InvalidSignature",
|
|
74
|
+
reason: "Ed25519 signature must be 64 bytes"
|
|
75
|
+
});
|
|
76
|
+
if (bytesToNumberLE(signature.subarray(32, 64)) >= L) throw new SiwxError({
|
|
77
|
+
code: "InvalidSignature",
|
|
78
|
+
reason: "S must be a canonical scalar (S < L)"
|
|
79
|
+
});
|
|
80
|
+
const key = addressBytes(message.address);
|
|
81
|
+
canonicalPoint(key);
|
|
82
|
+
const rBytes = signature.subarray(0, 32);
|
|
83
|
+
let r;
|
|
84
|
+
try {
|
|
85
|
+
r = P.fromBytes(rBytes);
|
|
86
|
+
} catch {
|
|
87
|
+
throw new SiwxError({ code: "VerificationFailed" });
|
|
88
|
+
}
|
|
89
|
+
if (!equalBytes(r.toBytes(), rBytes) || !r.isTorsionFree() || r.equals(P.ZERO)) throw new SiwxError({ code: "VerificationFailed" });
|
|
90
|
+
let ok;
|
|
91
|
+
try {
|
|
92
|
+
ok = ed25519.verify(signature, signed, key, { zip215: false });
|
|
93
|
+
} catch {
|
|
94
|
+
throw new SiwxError({ code: "VerificationFailed" });
|
|
95
|
+
}
|
|
96
|
+
if (!ok) throw new SiwxError({ code: "VerificationFailed" });
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
//#region src/svm/siws.ts
|
|
100
|
+
/** SIWS (Sign-In-With-Solana) text layout — Phantom ABNF, LF only. */
|
|
101
|
+
var siws_exports = /* @__PURE__ */ __exportAll({
|
|
102
|
+
format: () => format,
|
|
103
|
+
parse: () => parse,
|
|
104
|
+
parseBytes: () => parseBytes
|
|
105
|
+
});
|
|
106
|
+
const LABEL = "Solana";
|
|
107
|
+
/**
|
|
108
|
+
* Format `message` as a SIWS signing text.
|
|
109
|
+
*
|
|
110
|
+
* @throws {SiwxError} `InvalidField` `scheme` (SIWS has none) or `statement` (empty).
|
|
111
|
+
*/
|
|
112
|
+
function format(message) {
|
|
113
|
+
if (message.scheme !== void 0) throw new SiwxError({
|
|
114
|
+
code: "InvalidField",
|
|
115
|
+
field: "scheme",
|
|
116
|
+
reason: "not supported by SIWS"
|
|
117
|
+
});
|
|
118
|
+
if (message.statement !== void 0) {
|
|
119
|
+
if (message.statement === "") throw new SiwxError({
|
|
120
|
+
code: "InvalidField",
|
|
121
|
+
field: "statement",
|
|
122
|
+
reason: "empty"
|
|
123
|
+
});
|
|
124
|
+
if (message.statement.startsWith("URI: ")) throw new SiwxError({
|
|
125
|
+
code: "InvalidField",
|
|
126
|
+
field: "statement",
|
|
127
|
+
reason: "ambiguous with the URI: tag"
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
let out = `${message.domain}${MID}${LABEL}${SUFFIX}\n${message.address}`;
|
|
131
|
+
if (message.statement !== void 0) out += `\n\n${message.statement}`;
|
|
132
|
+
out += `\n\nURI: ${message.uri}`;
|
|
133
|
+
out += `\nVersion: ${message.version}`;
|
|
134
|
+
out += `\nChain ID: ${message.chainId}`;
|
|
135
|
+
out += `\nNonce: ${message.nonce}`;
|
|
136
|
+
out += `\nIssued At: ${message.issuedAt}`;
|
|
137
|
+
if (message.expirationTime !== void 0) out += `\nExpiration Time: ${message.expirationTime}`;
|
|
138
|
+
if (message.notBefore !== void 0) out += `\nNot Before: ${message.notBefore}`;
|
|
139
|
+
if (message.requestId !== void 0) out += `\nRequest ID: ${message.requestId}`;
|
|
140
|
+
if (message.resources !== void 0) {
|
|
141
|
+
out += "\nResources:";
|
|
142
|
+
for (const r of message.resources) out += `\n- ${r}`;
|
|
143
|
+
}
|
|
144
|
+
return out;
|
|
145
|
+
}
|
|
146
|
+
const missingUri = () => syntaxError("MissingField", "uri");
|
|
147
|
+
/** The optional statement and the gap up to the required `URI: ` line. */
|
|
148
|
+
function statementThenFields(lines, i) {
|
|
149
|
+
if (i.v >= lines.length) throw missingUri();
|
|
150
|
+
if (lines[i.v] !== "") throw syntaxError("ExpectedBlankLine");
|
|
151
|
+
i.v++;
|
|
152
|
+
const l = lines[i.v];
|
|
153
|
+
if (l === void 0) throw missingUri();
|
|
154
|
+
if (l === "") throw syntaxError("ExpectedBlankLine");
|
|
155
|
+
if (l.startsWith("URI: ")) return;
|
|
156
|
+
i.v++;
|
|
157
|
+
const after = lines[i.v];
|
|
158
|
+
if (after === void 0) throw missingUri();
|
|
159
|
+
if (after !== "") throw syntaxError("ExpectedBlankLine");
|
|
160
|
+
i.v++;
|
|
161
|
+
return l;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Parse `text` into a validated message; the preamble label must be exactly `"Solana"`.
|
|
165
|
+
*
|
|
166
|
+
* @throws {SiwxError} `Syntax`, `Mismatch` `label`, or `InvalidField`.
|
|
167
|
+
*/
|
|
168
|
+
function parse(text) {
|
|
169
|
+
const byteLength = utf8ByteLength(text);
|
|
170
|
+
if (byteLength > 16384) throw new SiwxError({
|
|
171
|
+
code: "MessageTooLarge",
|
|
172
|
+
length: byteLength,
|
|
173
|
+
max: MAX_MESSAGE_BYTES
|
|
174
|
+
});
|
|
175
|
+
if (text.includes("\r")) throw syntaxError("CarriageReturn");
|
|
176
|
+
if (text.endsWith("\n")) throw syntaxError("UnexpectedTrailing");
|
|
177
|
+
const lines = text.split("\n");
|
|
178
|
+
const idx = { v: 0 };
|
|
179
|
+
const preamble = lines[idx.v++];
|
|
180
|
+
if (preamble === void 0) throw syntaxError("UnexpectedEof");
|
|
181
|
+
const mid = preamble.indexOf(MID);
|
|
182
|
+
if (mid === -1) throw syntaxError("MissingPreamble");
|
|
183
|
+
const domain = preamble.slice(0, mid);
|
|
184
|
+
const tail = preamble.slice(mid + MID.length);
|
|
185
|
+
if (!tail.endsWith(" account:")) throw syntaxError("MissingAccountSuffix");
|
|
186
|
+
const label = tail.slice(0, tail.length - SUFFIX.length);
|
|
187
|
+
if (label !== LABEL) throw new SiwxError({
|
|
188
|
+
code: "Mismatch",
|
|
189
|
+
field: "label",
|
|
190
|
+
expected: LABEL,
|
|
191
|
+
actual: label
|
|
192
|
+
});
|
|
193
|
+
const address = lines[idx.v++];
|
|
194
|
+
if (address === void 0) throw syntaxError("UnexpectedEof");
|
|
195
|
+
const statement = statementThenFields(lines, idx);
|
|
196
|
+
const take = (tag, field) => {
|
|
197
|
+
const line = lines[idx.v];
|
|
198
|
+
if (line === void 0 || !line.startsWith(tag)) throw syntaxError("MissingField", field);
|
|
199
|
+
idx.v++;
|
|
200
|
+
return line.slice(tag.length);
|
|
201
|
+
};
|
|
202
|
+
const uri = take("URI: ", "uri");
|
|
203
|
+
const version = take("Version: ", "version");
|
|
204
|
+
const chainId = take("Chain ID: ", "chainId");
|
|
205
|
+
const nonce = take("Nonce: ", "nonce");
|
|
206
|
+
const issuedAt = take("Issued At: ", "issuedAt");
|
|
207
|
+
const tail4 = optionalTags(lines, idx.v);
|
|
208
|
+
return createMessage({
|
|
209
|
+
domain,
|
|
210
|
+
address,
|
|
211
|
+
...statement === void 0 ? {} : { statement },
|
|
212
|
+
uri,
|
|
213
|
+
version,
|
|
214
|
+
chainId,
|
|
215
|
+
nonce,
|
|
216
|
+
issuedAt,
|
|
217
|
+
...tail4
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* {@link parse} over raw bytes: size check, strict UTF-8 (`InvalidUtf8`), then parse.
|
|
222
|
+
*
|
|
223
|
+
* @throws {SiwxError}
|
|
224
|
+
*/
|
|
225
|
+
function parseBytes(bytes) {
|
|
226
|
+
if (bytes.length > 16384) throw new SiwxError({
|
|
227
|
+
code: "MessageTooLarge",
|
|
228
|
+
length: bytes.length,
|
|
229
|
+
max: MAX_MESSAGE_BYTES
|
|
230
|
+
});
|
|
231
|
+
const text = utf8Decode(bytes);
|
|
232
|
+
if (text === void 0) throw syntaxError("InvalidUtf8");
|
|
233
|
+
return parse(text);
|
|
234
|
+
}
|
|
235
|
+
//#endregion
|
|
236
|
+
//#region src/svm/index.ts
|
|
237
|
+
/**
|
|
238
|
+
* `siwx` Solana (`solana`) namespace profile — SIWS layout plus the off-chain message v1 envelope
|
|
239
|
+
* (sRFC 38).
|
|
240
|
+
*/
|
|
241
|
+
const NAMESPACE = "solana";
|
|
242
|
+
const CHAIN_NAME = "Solana";
|
|
243
|
+
const OFFCHAIN_DOMAIN = new Uint8Array([255, ...utf8Encode("solana offchain")]);
|
|
244
|
+
/** CAIP-2 reference for a Solana `chainId` alias. */
|
|
245
|
+
function chainReference(chainId) {
|
|
246
|
+
switch (chainId.startsWith("solana:") ? chainId.slice(7) : chainId) {
|
|
247
|
+
case "mainnet": return "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
|
|
248
|
+
case "testnet": return "4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";
|
|
249
|
+
case "devnet": return "EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
|
|
250
|
+
case "localnet": return "localnet";
|
|
251
|
+
default: throw fieldError("chainId", "unknown Solana cluster");
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function invalidEnvelope() {
|
|
255
|
+
return syntaxError("InvalidEnvelope");
|
|
256
|
+
}
|
|
257
|
+
/** Decode the v1 envelope at the start of `signed`. */
|
|
258
|
+
function decodeEnvelope(signed) {
|
|
259
|
+
if (signed.length < 18) throw invalidEnvelope();
|
|
260
|
+
if ((signed[16] ?? 0) !== 1) throw new SiwxError({
|
|
261
|
+
code: "Unsupported",
|
|
262
|
+
reason: "off-chain message version"
|
|
263
|
+
});
|
|
264
|
+
if ((signed[17] ?? 0) !== 1) throw invalidEnvelope();
|
|
265
|
+
const signers = signed.subarray(18, 50);
|
|
266
|
+
if (signers.length !== 32) throw invalidEnvelope();
|
|
267
|
+
const content = signed.subarray(50);
|
|
268
|
+
if (content.length === 0) throw invalidEnvelope();
|
|
269
|
+
return {
|
|
270
|
+
signer: signers.subarray(0, 32),
|
|
271
|
+
content
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Wrap `text` in the off-chain message v1 envelope for `signer` (validated as an SIWS address).
|
|
276
|
+
*
|
|
277
|
+
* @throws {SiwxError} `InvalidField` `address`.
|
|
278
|
+
*/
|
|
279
|
+
function offchainMessage(text, signer) {
|
|
280
|
+
const signerBytes = addressBytes(signer);
|
|
281
|
+
canonicalPoint(signerBytes);
|
|
282
|
+
const textBytes = utf8Encode(text);
|
|
283
|
+
const out = new Uint8Array(50 + textBytes.length);
|
|
284
|
+
out.set(OFFCHAIN_DOMAIN, 0);
|
|
285
|
+
out[16] = 1;
|
|
286
|
+
out[17] = 1;
|
|
287
|
+
out.set(signerBytes, 18);
|
|
288
|
+
out.set(textBytes, 50);
|
|
289
|
+
return out;
|
|
290
|
+
}
|
|
291
|
+
function svmAccount(message) {
|
|
292
|
+
validateAddress(message.address);
|
|
293
|
+
return createAccountId(NAMESPACE, chainReference(message.chainId), message.address);
|
|
294
|
+
}
|
|
295
|
+
/** Create the Solana namespace profile. */
|
|
296
|
+
function svm() {
|
|
297
|
+
return {
|
|
298
|
+
namespace: NAMESPACE,
|
|
299
|
+
label: CHAIN_NAME,
|
|
300
|
+
account: svmAccount,
|
|
301
|
+
format(message) {
|
|
302
|
+
svmAccount(message);
|
|
303
|
+
return format(message);
|
|
304
|
+
},
|
|
305
|
+
parse(signed) {
|
|
306
|
+
if (signed.length > 16384) throw new SiwxError({
|
|
307
|
+
code: "MessageTooLarge",
|
|
308
|
+
length: signed.length,
|
|
309
|
+
max: MAX_MESSAGE_BYTES
|
|
310
|
+
});
|
|
311
|
+
if (signed.length >= OFFCHAIN_DOMAIN.length && equalBytes(signed.subarray(0, OFFCHAIN_DOMAIN.length), OFFCHAIN_DOMAIN)) {
|
|
312
|
+
const env = decodeEnvelope(signed);
|
|
313
|
+
const message = parseBytes(env.content);
|
|
314
|
+
const expected = addressBytes(message.address);
|
|
315
|
+
if (!equalBytes(env.signer, expected)) throw new SiwxError({
|
|
316
|
+
code: "Mismatch",
|
|
317
|
+
field: "address",
|
|
318
|
+
expected: message.address,
|
|
319
|
+
actual: b58(env.signer)
|
|
320
|
+
});
|
|
321
|
+
return message;
|
|
322
|
+
}
|
|
323
|
+
return parseBytes(signed);
|
|
324
|
+
},
|
|
325
|
+
verify: async (message, signed, signature) => settle(() => verifyEddsa(message, signed, signature))
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
//#endregion
|
|
329
|
+
export { offchainMessage, siws_exports as siws, svm, validateAddress };
|
package/package.json
CHANGED
|
@@ -1,6 +1,86 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qntx/siwx",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.7.0",
|
|
4
|
+
"description": "Sign-In with X (CAIP-122) for TypeScript: SIWE, SIWS, message parsing, validation, and signature verification.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"authentication",
|
|
7
|
+
"caip-122",
|
|
8
|
+
"ethereum",
|
|
9
|
+
"sign-in",
|
|
10
|
+
"siwe",
|
|
11
|
+
"siws",
|
|
12
|
+
"siwx",
|
|
13
|
+
"solana"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/qntx/siwx#readme",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/qntx/siwx/issues"
|
|
18
|
+
},
|
|
19
|
+
"license": "MIT OR Apache-2.0",
|
|
20
|
+
"author": "QuantX <x@qntx.org>",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/qntx/siwx.git",
|
|
24
|
+
"directory": "packages/siwx"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"LICENSE-MIT",
|
|
29
|
+
"LICENSE-APACHE"
|
|
30
|
+
],
|
|
31
|
+
"type": "module",
|
|
32
|
+
"sideEffects": false,
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/index.d.mts",
|
|
36
|
+
"import": "./dist/index.mjs",
|
|
37
|
+
"default": "./dist/index.mjs"
|
|
38
|
+
},
|
|
39
|
+
"./evm": {
|
|
40
|
+
"types": "./dist/evm.d.mts",
|
|
41
|
+
"import": "./dist/evm.mjs",
|
|
42
|
+
"default": "./dist/evm.mjs"
|
|
43
|
+
},
|
|
44
|
+
"./svm": {
|
|
45
|
+
"types": "./dist/svm.d.mts",
|
|
46
|
+
"import": "./dist/svm.mjs",
|
|
47
|
+
"default": "./dist/svm.mjs"
|
|
48
|
+
},
|
|
49
|
+
"./package.json": "./package.json"
|
|
50
|
+
},
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "vp pack",
|
|
56
|
+
"dev": "vp pack --watch",
|
|
57
|
+
"test": "vp test",
|
|
58
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.src.json",
|
|
59
|
+
"check:pkg": "vp pack && publint && attw --pack . --profile esm-only",
|
|
60
|
+
"prepublishOnly": "vp run build",
|
|
61
|
+
"smoke:hermes": "bun scripts/hermes-smoke.ts"
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"@noble/curves": "^2.4.0",
|
|
65
|
+
"@noble/hashes": "^2.4.0",
|
|
66
|
+
"@scure/base": "^2.4.0"
|
|
67
|
+
},
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"@arethetypeswrong/cli": "0.18.5",
|
|
70
|
+
"@qntx/tsconfig": "1.0.1",
|
|
71
|
+
"@types/node": "26.6.5",
|
|
72
|
+
"publint": "0.3.25",
|
|
73
|
+
"typescript": "7.0.2",
|
|
74
|
+
"vite-plus": "1.3.0"
|
|
75
|
+
},
|
|
76
|
+
"devEngines": {
|
|
77
|
+
"packageManager": {
|
|
78
|
+
"name": "bun",
|
|
79
|
+
"version": "1.4.0",
|
|
80
|
+
"onFail": "ignore"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"engines": {
|
|
84
|
+
"node": ">=20.19.0"
|
|
85
|
+
}
|
|
86
|
+
}
|