@notabene/verify-proof 1.9.0 → 1.11.1-next.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.
Files changed (78) hide show
  1. package/README.md +21 -15
  2. package/dist/bitcoin-3CW4MNAW.cjs +314 -0
  3. package/dist/bitcoin-3CW4MNAW.cjs.map +1 -0
  4. package/dist/bitcoin-QK53ILBF.js +312 -0
  5. package/dist/bitcoin-QK53ILBF.js.map +1 -0
  6. package/dist/cardano-DYBYEAAF.cjs +53 -0
  7. package/dist/cardano-DYBYEAAF.cjs.map +1 -0
  8. package/dist/cardano-WE6YXYLW.js +31 -0
  9. package/dist/cardano-WE6YXYLW.js.map +1 -0
  10. package/dist/chunk-E3V5ATTC.js +38 -0
  11. package/dist/chunk-E3V5ATTC.js.map +1 -0
  12. package/dist/chunk-OAXNH5XR.cjs +42 -0
  13. package/dist/chunk-OAXNH5XR.cjs.map +1 -0
  14. package/dist/concordium-HQC37GCK.cjs +188 -0
  15. package/dist/concordium-HQC37GCK.cjs.map +1 -0
  16. package/dist/concordium-XX4XYLLU.js +186 -0
  17. package/dist/concordium-XX4XYLLU.js.map +1 -0
  18. package/dist/cosmos-64MKE5FJ.cjs +683 -0
  19. package/dist/cosmos-64MKE5FJ.cjs.map +1 -0
  20. package/dist/cosmos-QMH7BK7S.js +681 -0
  21. package/dist/cosmos-QMH7BK7S.js.map +1 -0
  22. package/dist/eth-3DX3PXDU.cjs +37 -0
  23. package/dist/eth-3DX3PXDU.cjs.map +1 -0
  24. package/dist/eth-ICLGRJE5.js +34 -0
  25. package/dist/eth-ICLGRJE5.js.map +1 -0
  26. package/dist/index.cjs +69 -1
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +5 -0
  29. package/dist/index.d.ts +5 -2
  30. package/dist/index.js +67 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/solana-4KQFLZUC.js +342 -0
  33. package/dist/solana-4KQFLZUC.js.map +1 -0
  34. package/dist/solana-PQ5K4NGO.cjs +365 -0
  35. package/dist/solana-PQ5K4NGO.cjs.map +1 -0
  36. package/dist/tron-F5AARBY4.cjs +58 -0
  37. package/dist/tron-F5AARBY4.cjs.map +1 -0
  38. package/dist/tron-OBLPB2LN.js +53 -0
  39. package/dist/tron-OBLPB2LN.js.map +1 -0
  40. package/dist/xlm-5GODWWL2.cjs +28 -0
  41. package/dist/xlm-5GODWWL2.cjs.map +1 -0
  42. package/dist/xlm-GX2QGFLI.js +26 -0
  43. package/dist/xlm-GX2QGFLI.js.map +1 -0
  44. package/dist/xrpl-7HQLIDAK.cjs +1174 -0
  45. package/dist/xrpl-7HQLIDAK.cjs.map +1 -0
  46. package/dist/xrpl-YCDFXBGQ.js +1169 -0
  47. package/dist/xrpl-YCDFXBGQ.js.map +1 -0
  48. package/package.json +11 -2
  49. package/src/bitcoin.ts +98 -37
  50. package/src/cardano.ts +2 -2
  51. package/src/index.ts +31 -19
  52. package/src/solana.ts +1 -1
  53. package/src/tests/bitcoin.test.ts +105 -16
  54. package/src/tests/solana.test.ts +1 -1
  55. package/src/xlm.ts +1 -2
  56. package/dist/bitcoin.d.ts +0 -2
  57. package/dist/cardano.d.ts +0 -2
  58. package/dist/concordium.d.ts +0 -15
  59. package/dist/cosmos.d.ts +0 -2
  60. package/dist/eth.d.ts +0 -4
  61. package/dist/index.modern.js +0 -2
  62. package/dist/index.modern.js.map +0 -1
  63. package/dist/index.umd.js +0 -2
  64. package/dist/index.umd.js.map +0 -1
  65. package/dist/solana.d.ts +0 -17
  66. package/dist/tests/bitcoin.test.d.ts +0 -1
  67. package/dist/tests/cardano.test.d.ts +0 -1
  68. package/dist/tests/concordium.test.d.ts +0 -1
  69. package/dist/tests/cosmos.test.d.ts +0 -1
  70. package/dist/tests/eth.test.d.ts +0 -1
  71. package/dist/tests/index.test.d.ts +0 -1
  72. package/dist/tests/solana.test.d.ts +0 -1
  73. package/dist/tests/tron.test.d.ts +0 -1
  74. package/dist/tests/xlm.test.d.ts +0 -1
  75. package/dist/tests/xrpl.test.d.ts +0 -1
  76. package/dist/tron.d.ts +0 -6
  77. package/dist/xlm.d.ts +0 -2
  78. package/dist/xrpl.d.ts +0 -5
@@ -0,0 +1,365 @@
1
+ 'use strict';
2
+
3
+ var buffer = require('buffer');
4
+ require('./chunk-OAXNH5XR.cjs');
5
+ var nacl = require('tweetnacl');
6
+ var javascriptSdk = require('@notabene/javascript-sdk');
7
+ var base = require('@scure/base');
8
+
9
+ function _interopNamespace(e) {
10
+ if (e && e.__esModule) return e;
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ var nacl__namespace = /*#__PURE__*/_interopNamespace(nacl);
28
+
29
+ if (typeof globalThis !== 'undefined' && !globalThis.Buffer) { globalThis.Buffer = buffer.Buffer; }
30
+ async function verifySolanaSignature(proof) {
31
+ const [ns, , address] = proof.address.split(/:/);
32
+ if (ns !== "solana") return { ...proof, status: javascriptSdk.ProofStatus.FAILED };
33
+ try {
34
+ const publicKey = base.base58.decode(address);
35
+ const messageBytes = new TextEncoder().encode(proof.attestation);
36
+ const signatureBytes = base.base64.decode(proof.proof);
37
+ const verified = nacl__namespace.sign.detached.verify(
38
+ messageBytes,
39
+ signatureBytes,
40
+ publicKey
41
+ );
42
+ return {
43
+ ...proof,
44
+ status: verified ? javascriptSdk.ProofStatus.VERIFIED : javascriptSdk.ProofStatus.FAILED
45
+ };
46
+ } catch {
47
+ return { ...proof, status: javascriptSdk.ProofStatus.FAILED };
48
+ }
49
+ }
50
+ function isSolanaSignInInput(obj) {
51
+ if (!obj || typeof obj !== "object") return false;
52
+ const input = obj;
53
+ return typeof input.domain === "string" && typeof input.address === "string" && (input.statement === void 0 || typeof input.statement === "string") && (input.uri === void 0 || typeof input.uri === "string") && (input.version === void 0 || typeof input.version === "string") && (input.chainId === void 0 || typeof input.chainId === "string") && (input.nonce === void 0 || typeof input.nonce === "string") && (input.issuedAt === void 0 || typeof input.issuedAt === "string") && (input.expirationTime === void 0 || typeof input.expirationTime === "string") && (input.notBefore === void 0 || typeof input.notBefore === "string") && (input.requestId === void 0 || typeof input.requestId === "string") && (input.resources === void 0 || Array.isArray(input.resources));
54
+ }
55
+ function isSolanaSignInMetadata(obj) {
56
+ if (!obj || typeof obj !== "object") return false;
57
+ const metadata = obj;
58
+ if (!metadata.account || typeof metadata.account !== "object") return false;
59
+ const account = metadata.account;
60
+ if (typeof account.address !== "string") return false;
61
+ if (!account.publicKey) return false;
62
+ if (!(account.publicKey instanceof Uint8Array)) {
63
+ const pkObj = account.publicKey;
64
+ if (typeof pkObj === "object") {
65
+ const keys = Object.keys(pkObj).filter((key) => !isNaN(Number(key))).sort((a, b) => Number(a) - Number(b));
66
+ if (keys.length === 32) {
67
+ const bytes = keys.map((key) => Number(pkObj[key]));
68
+ if (bytes.every((b) => typeof b === "number" && b >= 0 && b <= 255)) {
69
+ account.publicKey = new Uint8Array(bytes);
70
+ } else {
71
+ return false;
72
+ }
73
+ } else {
74
+ return false;
75
+ }
76
+ } else {
77
+ return false;
78
+ }
79
+ }
80
+ if (!metadata.signedMessage) return false;
81
+ if (!(metadata.signedMessage instanceof Uint8Array)) {
82
+ const smObj = metadata.signedMessage;
83
+ if (smObj.type === "Buffer" && Array.isArray(smObj.data)) {
84
+ metadata.signedMessage = new Uint8Array(smObj.data);
85
+ } else {
86
+ return false;
87
+ }
88
+ }
89
+ if (!metadata.signature) return false;
90
+ if (!(metadata.signature instanceof Uint8Array)) {
91
+ const sigObj = metadata.signature;
92
+ if (sigObj.type === "Buffer" && Array.isArray(sigObj.data)) {
93
+ metadata.signature = new Uint8Array(sigObj.data);
94
+ } else {
95
+ return false;
96
+ }
97
+ }
98
+ if (!metadata.message || typeof metadata.message !== "object") {
99
+ return false;
100
+ }
101
+ const message = metadata.message;
102
+ if (typeof message === "object" && message !== null) {
103
+ const messageObj = message;
104
+ if (!messageObj.address && metadata.signedMessage instanceof Uint8Array) {
105
+ try {
106
+ const signedMessageText = new TextDecoder().decode(metadata.signedMessage);
107
+ const lines = signedMessageText.split("\n");
108
+ if (lines.length >= 2) {
109
+ const address = lines[1].trim();
110
+ if (address && /^[a-zA-Z0-9]{32,44}$/.test(address)) {
111
+ messageObj.address = address;
112
+ }
113
+ }
114
+ } catch {
115
+ }
116
+ }
117
+ }
118
+ if (!isSolanaSignInInput(metadata.message)) {
119
+ return false;
120
+ }
121
+ return true;
122
+ }
123
+ async function verifySolanaSIWS(proof) {
124
+ const [ns] = proof.address.split(/:/);
125
+ if (ns !== "solana") {
126
+ return { ...proof, status: javascriptSdk.ProofStatus.FAILED };
127
+ }
128
+ if (!proof.chainSpecificData || !isSolanaSignInMetadata(proof.chainSpecificData)) {
129
+ return { ...proof, status: javascriptSdk.ProofStatus.FAILED };
130
+ }
131
+ try {
132
+ const metadata = proof.chainSpecificData;
133
+ const signedMessageText = new TextDecoder().decode(metadata.signedMessage);
134
+ const parsedMessage = parseSIWSMessage(signedMessageText);
135
+ if (!parsedMessage) {
136
+ return { ...proof, status: javascriptSdk.ProofStatus.FAILED };
137
+ }
138
+ if (!validateSIWSMessage(parsedMessage, metadata.message)) {
139
+ return { ...proof, status: javascriptSdk.ProofStatus.FAILED };
140
+ }
141
+ const reconstructedMessage = createSIWSMessage(parsedMessage);
142
+ if (reconstructedMessage !== signedMessageText) {
143
+ return { ...proof, status: javascriptSdk.ProofStatus.FAILED };
144
+ }
145
+ const verified = nacl__namespace.sign.detached.verify(
146
+ metadata.signedMessage,
147
+ metadata.signature,
148
+ metadata.account.publicKey
149
+ );
150
+ return {
151
+ ...proof,
152
+ status: verified ? javascriptSdk.ProofStatus.VERIFIED : javascriptSdk.ProofStatus.FAILED
153
+ };
154
+ } catch {
155
+ return { ...proof, status: javascriptSdk.ProofStatus.FAILED };
156
+ }
157
+ }
158
+ function parseSIWSMessage(message) {
159
+ try {
160
+ const lines = message.split("\n");
161
+ const header = parseHeader(lines);
162
+ if (!header) return null;
163
+ const result = { ...header };
164
+ let lineIndex = 2;
165
+ const statementResult = parseStatement(lines, lineIndex);
166
+ if (statementResult.statement !== void 0) {
167
+ result.statement = statementResult.statement;
168
+ lineIndex = statementResult.nextIndex;
169
+ }
170
+ const advancedFields = parseAdvancedFields(lines, lineIndex);
171
+ Object.assign(result, advancedFields);
172
+ return result;
173
+ } catch {
174
+ return null;
175
+ }
176
+ }
177
+ function parseHeader(lines) {
178
+ const domainMatch = lines[0]?.match(/^(.+) wants you to sign in with your Solana account:$/);
179
+ if (!domainMatch) return null;
180
+ const domain = domainMatch[1];
181
+ const address = lines[1];
182
+ if (!address || !/^[a-zA-Z0-9]{32,44}$/.test(address)) return null;
183
+ return { domain, address };
184
+ }
185
+ function parseStatement(lines, startIndex) {
186
+ let lineIndex = startIndex;
187
+ if (lines[lineIndex] === "" && lines[lineIndex + 1] && !lines[lineIndex + 1].includes(":")) {
188
+ lineIndex++;
189
+ const statement = lines[lineIndex];
190
+ lineIndex++;
191
+ if (lines[lineIndex] === "") {
192
+ lineIndex++;
193
+ }
194
+ return { statement, nextIndex: lineIndex };
195
+ }
196
+ return { nextIndex: lineIndex };
197
+ }
198
+ function parseAdvancedFields(lines, startIndex) {
199
+ const result = {};
200
+ const fieldParsers = [
201
+ { prefix: "URI: ", key: "uri" },
202
+ { prefix: "Version: ", key: "version" },
203
+ { prefix: "Chain ID: ", key: "chainId" },
204
+ { prefix: "Nonce: ", key: "nonce" },
205
+ { prefix: "Issued At: ", key: "issuedAt" },
206
+ { prefix: "Expiration Time: ", key: "expirationTime" },
207
+ { prefix: "Not Before: ", key: "notBefore" },
208
+ { prefix: "Request ID: ", key: "requestId" }
209
+ ];
210
+ let lineIndex = startIndex;
211
+ while (lineIndex < lines.length) {
212
+ const line = lines[lineIndex];
213
+ if (!line) {
214
+ lineIndex++;
215
+ continue;
216
+ }
217
+ if (line.startsWith("Resources:")) {
218
+ const resources = parseResources(lines, lineIndex + 1);
219
+ if (resources.length > 0) {
220
+ result.resources = resources;
221
+ lineIndex += resources.length + 1;
222
+ continue;
223
+ }
224
+ }
225
+ for (const { prefix, key } of fieldParsers) {
226
+ if (line.startsWith(prefix)) {
227
+ const value = line.substring(prefix.length);
228
+ result[key] = value;
229
+ break;
230
+ }
231
+ }
232
+ lineIndex++;
233
+ }
234
+ return result;
235
+ }
236
+ function parseResources(lines, startIndex) {
237
+ const resources = [];
238
+ let lineIndex = startIndex;
239
+ while (lineIndex < lines.length && lines[lineIndex]?.startsWith("- ")) {
240
+ resources.push(lines[lineIndex].substring(2));
241
+ lineIndex++;
242
+ }
243
+ return resources;
244
+ }
245
+ function validateSIWSMessage(parsed, input) {
246
+ if (parsed.domain !== input.domain || parsed.address !== input.address) {
247
+ return false;
248
+ }
249
+ const fieldValidations = [
250
+ { inputKey: "statement", parsedKey: "statement" },
251
+ { inputKey: "uri", parsedKey: "uri" },
252
+ { inputKey: "version", parsedKey: "version" },
253
+ { inputKey: "chainId", parsedKey: "chainId" },
254
+ { inputKey: "nonce", parsedKey: "nonce" },
255
+ { inputKey: "issuedAt", parsedKey: "issuedAt" },
256
+ { inputKey: "expirationTime", parsedKey: "expirationTime" },
257
+ { inputKey: "notBefore", parsedKey: "notBefore" },
258
+ { inputKey: "requestId", parsedKey: "requestId" },
259
+ {
260
+ inputKey: "resources",
261
+ parsedKey: "resources",
262
+ validator: (inputValue, parsedValue) => {
263
+ if (!Array.isArray(inputValue) || !Array.isArray(parsedValue)) {
264
+ return false;
265
+ }
266
+ return inputValue.length === parsedValue.length && inputValue.every((item, index) => item === parsedValue[index]);
267
+ }
268
+ }
269
+ ];
270
+ for (const { inputKey, parsedKey, validator } of fieldValidations) {
271
+ const inputValue = input[inputKey];
272
+ const parsedValue = parsed[parsedKey];
273
+ if (inputValue !== void 0) {
274
+ if (validator) {
275
+ if (!validator(inputValue, parsedValue)) {
276
+ return false;
277
+ }
278
+ } else if (inputValue !== parsedValue) {
279
+ return false;
280
+ }
281
+ }
282
+ }
283
+ return validateTimestamps(parsed);
284
+ }
285
+ function validateTimestamps(parsed) {
286
+ const now = Date.now();
287
+ if (parsed.issuedAt) {
288
+ const issuedAt = new Date(parsed.issuedAt);
289
+ const threshold = 24 * 60 * 60 * 1e3;
290
+ const timeDiff = Math.abs(issuedAt.getTime() - now);
291
+ if (timeDiff > threshold) {
292
+ return false;
293
+ }
294
+ }
295
+ if (parsed.expirationTime) {
296
+ const expirationTime = new Date(parsed.expirationTime);
297
+ if (expirationTime.getTime() <= now) {
298
+ return false;
299
+ }
300
+ }
301
+ if (parsed.notBefore) {
302
+ const notBefore = new Date(parsed.notBefore);
303
+ if (notBefore.getTime() > now) {
304
+ return false;
305
+ }
306
+ }
307
+ return true;
308
+ }
309
+ function createSIWSMessage(input) {
310
+ let message = `${input.domain} wants you to sign in with your Solana account:
311
+ `;
312
+ message += `${input.address}`;
313
+ if (input.statement) {
314
+ message += `
315
+
316
+ ${input.statement}`;
317
+ }
318
+ const fields = buildFieldLines(input);
319
+ if (fields.length) {
320
+ message += `
321
+
322
+ ${fields.join("\n")}`;
323
+ }
324
+ return message;
325
+ }
326
+ function buildFieldLines(input) {
327
+ const fields = [];
328
+ const fieldMappings = [
329
+ { key: "uri", prefix: "URI: " },
330
+ { key: "version", prefix: "Version: " },
331
+ { key: "chainId", prefix: "Chain ID: " },
332
+ { key: "nonce", prefix: "Nonce: " },
333
+ { key: "issuedAt", prefix: "Issued At: " },
334
+ { key: "expirationTime", prefix: "Expiration Time: " },
335
+ { key: "notBefore", prefix: "Not Before: " },
336
+ { key: "requestId", prefix: "Request ID: " },
337
+ {
338
+ key: "resources",
339
+ prefix: "Resources:",
340
+ formatter: (value) => {
341
+ if (Array.isArray(value) && value.length > 0) {
342
+ return ["Resources:", ...value.map((resource) => `- ${resource}`)];
343
+ }
344
+ return [];
345
+ }
346
+ }
347
+ ];
348
+ for (const { key, prefix, formatter } of fieldMappings) {
349
+ const value = input[key];
350
+ if (value !== void 0) {
351
+ if (formatter) {
352
+ const formatted = formatter(value);
353
+ fields.push(...formatted);
354
+ } else if (typeof value === "string") {
355
+ fields.push(`${prefix}${value}`);
356
+ }
357
+ }
358
+ }
359
+ return fields;
360
+ }
361
+
362
+ exports.verifySolanaSIWS = verifySolanaSIWS;
363
+ exports.verifySolanaSignature = verifySolanaSignature;
364
+ //# sourceMappingURL=solana-PQ5K4NGO.cjs.map
365
+ //# sourceMappingURL=solana-PQ5K4NGO.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/solana.ts"],"names":["ProofStatus","base58","base64","nacl"],"mappings":"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","file":"solana-PQ5K4NGO.cjs","sourcesContent":["import * as nacl from \"tweetnacl\";\nimport { ProofStatus, SignatureProof, type SIWXInput, type SolanaMetadata } from \"@notabene/javascript-sdk\";\nimport { base64, base58 } from \"@scure/base\";\n\ninterface ParsedSIWSMessage {\n domain: string;\n address: string;\n statement?: string;\n uri?: string;\n version?: string;\n chainId?: string;\n nonce?: string;\n issuedAt?: string;\n expirationTime?: string;\n notBefore?: string;\n requestId?: string;\n resources?: string[];\n}\n\n\n\n/**\n * Verifies a Solana signature proof.\n * \n * This function can verify two types of Solana signatures:\n * 1. Standard Solana signatures\n * \n * @param proof - The signature proof containing the address, attestation, and signature\n * @returns Promise that resolves to a SignatureProof with updated status (VERIFIED or FAILED)\n * \n * @example\n * // Standard Solana signature verification\n * const result = await verifySolanaSignature(proof);\n * \n */\nexport async function verifySolanaSignature(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"solana\") return { ...proof, status: ProofStatus.FAILED };\n\n try {\n const publicKey = base58.decode(address);\n const messageBytes = new TextEncoder().encode(proof.attestation);\n const signatureBytes = base64.decode(proof.proof);\n const verified = nacl.sign.detached.verify(\n messageBytes,\n signatureBytes,\n publicKey,\n );\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n } catch {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n\nfunction isSolanaSignInInput(obj: unknown): obj is SIWXInput {\n if (!obj || typeof obj !== 'object') return false;\n \n const input = obj as Record<string, unknown>;\n \n // Check for required properties\n return (\n typeof input.domain === 'string' &&\n typeof input.address === 'string' &&\n (input.statement === undefined || typeof input.statement === 'string') &&\n (input.uri === undefined || typeof input.uri === 'string') &&\n (input.version === undefined || typeof input.version === 'string') &&\n (input.chainId === undefined || typeof input.chainId === 'string') &&\n (input.nonce === undefined || typeof input.nonce === 'string') &&\n (input.issuedAt === undefined || typeof input.issuedAt === 'string') &&\n (input.expirationTime === undefined || typeof input.expirationTime === 'string') &&\n (input.notBefore === undefined || typeof input.notBefore === 'string') &&\n (input.requestId === undefined || typeof input.requestId === 'string') &&\n (input.resources === undefined || Array.isArray(input.resources))\n );\n}\n\nfunction isSolanaSignInMetadata(obj: unknown): obj is SolanaMetadata {\n if (!obj || typeof obj !== 'object') return false;\n \n const metadata = obj as Record<string, unknown>;\n \n // Check account object\n if (!metadata.account || typeof metadata.account !== 'object') return false;\n const account = metadata.account as Record<string, unknown>;\n if (typeof account.address !== 'string') return false;\n \n // Handle publicKey - could be Uint8Array or serialized object with numeric keys\n if (!account.publicKey) return false;\n if (!(account.publicKey instanceof Uint8Array)) {\n // Try to convert from serialized format\n const pkObj = account.publicKey as Record<string, unknown>;\n if (typeof pkObj === 'object') {\n // Convert object with numeric keys to Uint8Array\n const keys = Object.keys(pkObj).filter(key => !isNaN(Number(key))).sort((a, b) => Number(a) - Number(b));\n if (keys.length === 32) { // Solana public keys are 32 bytes\n const bytes = keys.map(key => Number(pkObj[key]));\n if (bytes.every(b => typeof b === 'number' && b >= 0 && b <= 255)) {\n account.publicKey = new Uint8Array(bytes);\n } else {\n return false;\n }\n } else {\n return false;\n }\n } else {\n return false;\n }\n }\n \n // Handle signedMessage - could be Uint8Array or Buffer-like object\n if (!metadata.signedMessage) return false;\n if (!(metadata.signedMessage instanceof Uint8Array)) {\n const smObj = metadata.signedMessage as Record<string, unknown>;\n if (smObj.type === 'Buffer' && Array.isArray(smObj.data)) {\n metadata.signedMessage = new Uint8Array(smObj.data as number[]);\n } else {\n return false;\n }\n }\n \n // Handle signature - could be Uint8Array or Buffer-like object\n if (!metadata.signature) return false;\n if (!(metadata.signature instanceof Uint8Array)) {\n const sigObj = metadata.signature as Record<string, unknown>;\n if (sigObj.type === 'Buffer' && Array.isArray(sigObj.data)) {\n metadata.signature = new Uint8Array(sigObj.data as number[]);\n } else {\n return false;\n }\n }\n \n // Check message field contains valid SolanaSignInInput\n if (!metadata.message || typeof metadata.message !== 'object') {\n return false;\n }\n \n const message = metadata.message as unknown;\n \n // If address is missing from message, try to extract it from signedMessage\n if (typeof message === 'object' && message !== null) {\n const messageObj = message as Record<string, unknown>;\n if (!messageObj.address && metadata.signedMessage instanceof Uint8Array) {\n try {\n const signedMessageText = new TextDecoder().decode(metadata.signedMessage);\n const lines = signedMessageText.split('\\n');\n if (lines.length >= 2) {\n const address = lines[1].trim();\n if (address && /^[a-zA-Z0-9]{32,44}$/.test(address)) {\n messageObj.address = address;\n }\n }\n } catch {\n // Ignore errors in address extraction\n }\n }\n }\n \n if (!isSolanaSignInInput(metadata.message)) {\n return false;\n }\n \n return true;\n}\n\nexport async function verifySolanaSIWS(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns] = proof.address.split(/:/);\n if (ns !== \"solana\") {\n return { ...proof, status: ProofStatus.FAILED };\n }\n \n // Validate that metadata conforms to SolanaSignInMetadata\n if (!proof.chainSpecificData || !isSolanaSignInMetadata(proof.chainSpecificData)) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n\n try {\n // Now we can safely cast to SolanaMetadata since we validated it\n const metadata = proof.chainSpecificData as SolanaMetadata;\n \n const signedMessageText = new TextDecoder().decode(metadata.signedMessage);\n const parsedMessage = parseSIWSMessage(signedMessageText);\n \n if (!parsedMessage) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n\n // Validate the parsed message against the input\n if (!validateSIWSMessage(parsedMessage, metadata.message as SIWXInput)) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n\n // Reconstruct the message to ensure it matches the signed message\n const reconstructedMessage = createSIWSMessage(parsedMessage);\n if (reconstructedMessage !== signedMessageText) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n\n // Verify the signature against the message\n const verified = nacl.sign.detached.verify(\n metadata.signedMessage,\n metadata.signature,\n metadata.account.publicKey as Uint8Array\n );\n \n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n } catch {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n\n// Parse SIWS message according to ABNF format\n// https://github.com/phantom/sign-in-with-solana/blob/e4060d2916469116d5080a712feaf81ea1db4f65/README.md#message-construction\nfunction parseSIWSMessage(message: string): ParsedSIWSMessage | null {\n try {\n const lines = message.split('\\n');\n \n // Parse header (domain and address)\n const header = parseHeader(lines);\n if (!header) return null;\n \n const result: ParsedSIWSMessage = { ...header };\n \n let lineIndex = 2;\n \n // Parse statement if present\n const statementResult = parseStatement(lines, lineIndex);\n if (statementResult.statement !== undefined) {\n result.statement = statementResult.statement;\n lineIndex = statementResult.nextIndex;\n }\n \n // Parse advanced fields\n const advancedFields = parseAdvancedFields(lines, lineIndex);\n Object.assign(result, advancedFields);\n \n return result;\n } catch {\n return null;\n }\n}\n\nfunction parseHeader(lines: string[]): { domain: string; address: string } | null {\n // First line: domain + \" wants you to sign in with your Solana account:\"\n const domainMatch = lines[0]?.match(/^(.+) wants you to sign in with your Solana account:$/);\n if (!domainMatch) return null;\n \n const domain = domainMatch[1];\n \n // Second line: address\n const address = lines[1];\n if (!address || !/^[a-zA-Z0-9]{32,44}$/.test(address)) return null;\n \n return { domain, address };\n}\n\nfunction parseStatement(lines: string[], startIndex: number): { statement?: string; nextIndex: number } {\n let lineIndex = startIndex;\n \n // Check for statement (after empty line)\n if (lines[lineIndex] === '' && lines[lineIndex + 1] && !lines[lineIndex + 1].includes(':')) {\n lineIndex++; // Skip empty line\n const statement = lines[lineIndex];\n lineIndex++;\n \n // Skip another empty line after statement\n if (lines[lineIndex] === '') {\n lineIndex++;\n }\n \n return { statement, nextIndex: lineIndex };\n }\n \n return { nextIndex: lineIndex };\n}\n\nfunction parseAdvancedFields(lines: string[], startIndex: number): Partial<ParsedSIWSMessage> {\n const result: Partial<ParsedSIWSMessage> = {};\n \n // Define field parsers for string fields only\n const fieldParsers: Array<{\n prefix: string;\n key: keyof Omit<ParsedSIWSMessage, 'resources'>;\n }> = [\n { prefix: 'URI: ', key: 'uri' },\n { prefix: 'Version: ', key: 'version' },\n { prefix: 'Chain ID: ', key: 'chainId' },\n { prefix: 'Nonce: ', key: 'nonce' },\n { prefix: 'Issued At: ', key: 'issuedAt' },\n { prefix: 'Expiration Time: ', key: 'expirationTime' },\n { prefix: 'Not Before: ', key: 'notBefore' },\n { prefix: 'Request ID: ', key: 'requestId' }\n ];\n \n let lineIndex = startIndex;\n \n while (lineIndex < lines.length) {\n const line = lines[lineIndex];\n if (!line) {\n lineIndex++;\n continue;\n }\n \n // Check for resources (special case)\n if (line.startsWith('Resources:')) {\n const resources = parseResources(lines, lineIndex + 1);\n if (resources.length > 0) {\n result.resources = resources;\n lineIndex += resources.length + 1; // +1 for the \"Resources:\" line\n continue;\n }\n }\n \n // Check for other fields\n let fieldFound = false;\n for (const { prefix, key } of fieldParsers) {\n if (line.startsWith(prefix)) {\n const value = line.substring(prefix.length);\n result[key] = value;\n fieldFound = true;\n break;\n }\n }\n \n if (!fieldFound) {\n // Unknown field, skip it\n }\n \n lineIndex++;\n }\n \n return result;\n}\n\nfunction parseResources(lines: string[], startIndex: number): string[] {\n const resources: string[] = [];\n let lineIndex = startIndex;\n \n while (lineIndex < lines.length && lines[lineIndex]?.startsWith('- ')) {\n resources.push(lines[lineIndex].substring(2));\n lineIndex++;\n }\n \n return resources;\n}\n\n// Validate parsed SIWS message against input\nfunction validateSIWSMessage(parsed: ParsedSIWSMessage, input: SIWXInput): boolean {\n // Required fields validation\n if (parsed.domain !== input.domain || parsed.address !== input.address) {\n return false;\n }\n \n // Define validation rules for optional fields\n const fieldValidations: Array<{\n inputKey: keyof SIWXInput;\n parsedKey: keyof ParsedSIWSMessage;\n validator?: (inputValue: unknown, parsedValue: unknown) => boolean;\n }> = [\n { inputKey: 'statement', parsedKey: 'statement' },\n { inputKey: 'uri', parsedKey: 'uri' },\n { inputKey: 'version', parsedKey: 'version' },\n { inputKey: 'chainId', parsedKey: 'chainId' },\n { inputKey: 'nonce', parsedKey: 'nonce' },\n { inputKey: 'issuedAt', parsedKey: 'issuedAt' },\n { inputKey: 'expirationTime', parsedKey: 'expirationTime' },\n { inputKey: 'notBefore', parsedKey: 'notBefore' },\n { inputKey: 'requestId', parsedKey: 'requestId' },\n {\n inputKey: 'resources',\n parsedKey: 'resources',\n validator: (inputValue, parsedValue) => {\n if (!Array.isArray(inputValue) || !Array.isArray(parsedValue)) {\n return false;\n }\n return inputValue.length === parsedValue.length && \n inputValue.every((item, index) => item === parsedValue[index]);\n }\n }\n ];\n \n // Validate optional fields\n for (const { inputKey, parsedKey, validator } of fieldValidations) {\n const inputValue = input[inputKey];\n const parsedValue = parsed[parsedKey];\n \n if (inputValue !== undefined) {\n if (validator) {\n if (!validator(inputValue, parsedValue)) {\n return false;\n }\n } else if (inputValue !== parsedValue) {\n return false;\n }\n }\n }\n \n // Validate timestamps\n return validateTimestamps(parsed);\n}\n\n// Separate timestamp validation for better testability and clarity\nfunction validateTimestamps(parsed: ParsedSIWSMessage): boolean {\n const now = Date.now();\n \n // Validate issuedAt (allow 24 hour threshold for testing)\n if (parsed.issuedAt) {\n const issuedAt = new Date(parsed.issuedAt);\n const threshold = 24 * 60 * 60 * 1000; // 24 hours in milliseconds\n const timeDiff = Math.abs(issuedAt.getTime() - now);\n if (timeDiff > threshold) {\n return false;\n }\n }\n \n // Validate expirationTime\n if (parsed.expirationTime) {\n const expirationTime = new Date(parsed.expirationTime);\n if (expirationTime.getTime() <= now) {\n return false; // Message has expired\n }\n }\n \n // Validate notBefore\n if (parsed.notBefore) {\n const notBefore = new Date(parsed.notBefore);\n if (notBefore.getTime() > now) {\n return false; // Message not yet valid\n }\n }\n \n return true;\n}\n\n// Create SIWS message string according to ABNF format\n// https://github.com/phantom/sign-in-with-solana/blob/e4060d2916469116d5080a712feaf81ea1db4f65/README.md#abnf-message-format\nfunction createSIWSMessage(input: ParsedSIWSMessage): string {\n let message = `${input.domain} wants you to sign in with your Solana account:\\n`;\n message += `${input.address}`;\n\n if (input.statement) {\n message += `\\n\\n${input.statement}`;\n }\n\n const fields = buildFieldLines(input);\n \n if (fields.length) {\n message += `\\n\\n${fields.join('\\n')}`;\n }\n\n return message;\n}\n\nfunction buildFieldLines(input: ParsedSIWSMessage): string[] {\n const fields: string[] = [];\n \n // Define field mappings\n const fieldMappings: Array<{\n key: keyof ParsedSIWSMessage;\n prefix: string;\n formatter?: (value: unknown) => string[];\n }> = [\n { key: 'uri', prefix: 'URI: ' },\n { key: 'version', prefix: 'Version: ' },\n { key: 'chainId', prefix: 'Chain ID: ' },\n { key: 'nonce', prefix: 'Nonce: ' },\n { key: 'issuedAt', prefix: 'Issued At: ' },\n { key: 'expirationTime', prefix: 'Expiration Time: ' },\n { key: 'notBefore', prefix: 'Not Before: ' },\n { key: 'requestId', prefix: 'Request ID: ' },\n {\n key: 'resources',\n prefix: 'Resources:',\n formatter: (value) => {\n if (Array.isArray(value) && value.length > 0) {\n return ['Resources:', ...value.map(resource => `- ${resource}`)];\n }\n return [];\n }\n }\n ];\n \n for (const { key, prefix, formatter } of fieldMappings) {\n const value = input[key];\n if (value !== undefined) {\n if (formatter) {\n const formatted = formatter(value);\n fields.push(...formatted);\n } else if (typeof value === 'string') {\n fields.push(`${prefix}${value}`);\n }\n }\n }\n \n return fields;\n}\n"]}
@@ -0,0 +1,58 @@
1
+ 'use strict';
2
+
3
+ var buffer = require('buffer');
4
+ require('./chunk-OAXNH5XR.cjs');
5
+ var javascriptSdk = require('@notabene/javascript-sdk');
6
+ var ox = require('ox');
7
+ var base = require('@scure/base');
8
+
9
+ if (typeof globalThis !== 'undefined' && !globalThis.Buffer) { globalThis.Buffer = buffer.Buffer; }
10
+ function verifyTIP191(address, message, proof) {
11
+ try {
12
+ const payload = getSignPayload(ox.Hex.fromString(message));
13
+ const signature = ox.Signature.fromHex(proof);
14
+ const publicKey = ox.Secp256k1.recoverPublicKey({ payload, signature });
15
+ const hex = `0x41${ox.Hash.keccak256(
16
+ `0x${ox.PublicKey.toHex(publicKey).slice(4)}`
17
+ ).substring(26)}`;
18
+ const bytes = ox.Bytes.from(hex);
19
+ const checksum = ox.Bytes.from(ox.Hash.sha256(ox.Hash.sha256(hex))).slice(0, 4);
20
+ const checked = ox.Bytes.concat(bytes, checksum);
21
+ const b58 = base.base58.encode(checked);
22
+ return b58 === address;
23
+ } catch (error) {
24
+ return false;
25
+ }
26
+ }
27
+ async function verifyPersonalSignTIP191(proof) {
28
+ const [ns, , address] = proof.address.split(/:/);
29
+ if (ns !== "tron") return { ...proof, status: javascriptSdk.ProofStatus.FAILED };
30
+ const verified = verifyTIP191(
31
+ address,
32
+ proof.attestation,
33
+ proof.proof
34
+ );
35
+ return {
36
+ ...proof,
37
+ status: verified ? javascriptSdk.ProofStatus.VERIFIED : javascriptSdk.ProofStatus.FAILED
38
+ };
39
+ }
40
+ function encode(data) {
41
+ const message = ox.Hex.from(data);
42
+ return ox.Hex.concat(
43
+ // Personal Sign Format: `0x19 ‖ "Ethereum Signed Message:\n" ‖ message.length ‖ message`
44
+ "0x19",
45
+ ox.Hex.fromString("TRON Signed Message:\n" + ox.Hex.size(message)),
46
+ message
47
+ );
48
+ }
49
+ function getSignPayload(data) {
50
+ return ox.Hash.keccak256(encode(data));
51
+ }
52
+
53
+ exports.encode = encode;
54
+ exports.getSignPayload = getSignPayload;
55
+ exports.verifyPersonalSignTIP191 = verifyPersonalSignTIP191;
56
+ exports.verifyTIP191 = verifyTIP191;
57
+ //# sourceMappingURL=tron-F5AARBY4.cjs.map
58
+ //# sourceMappingURL=tron-F5AARBY4.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tron.ts"],"names":["Hex","Signature","Secp256k1","Hash","PublicKey","Bytes","base58","ProofStatus"],"mappings":";;;;;;;;;AAIO,SAAS,YAAA,CACd,OAAA,EACA,OAAA,EACA,KAAA,EACS;AACT,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAU,cAAA,CAAeA,MAAA,CAAI,UAAA,CAAW,OAAO,CAAC,CAAA;AACtD,IAAA,MAAM,SAAA,GAAYC,YAAA,CAAU,OAAA,CAAQ,KAAK,CAAA;AACzC,IAAA,MAAM,YAAYC,YAAA,CAAU,gBAAA,CAAiB,EAAE,OAAA,EAAS,WAAW,CAAA;AACnE,IAAA,MAAM,GAAA,GAAe,OAAOC,OAAA,CAAK,SAAA;AAAA,MAC/B,KAAKC,YAAA,CAAU,KAAA,CAAM,SAAS,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,KAC1C,CAAE,SAAA,CAAU,EAAE,CAAC,CAAA,CAAA;AACf,IAAA,MAAM,KAAA,GAAQC,QAAA,CAAM,IAAA,CAAK,GAAG,CAAA;AAC5B,IAAA,MAAM,QAAA,GAAWA,QAAA,CAAM,IAAA,CAAKF,OAAA,CAAK,MAAA,CAAOA,OAAA,CAAK,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA,CAAE,KAAA,CAAM,GAAG,CAAC,CAAA;AACrE,IAAA,MAAM,OAAA,GAAUE,QAAA,CAAM,MAAA,CAAO,KAAA,EAAO,QAAQ,CAAA;AAC5C,IAAA,MAAM,GAAA,GAAMC,WAAA,CAAO,MAAA,CAAO,OAAO,CAAA;AACjC,IAAA,OAAO,GAAA,KAAQ,OAAA;AAAA,EAEjB,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,eAAsB,yBACpB,KAAA,EACyB;AACzB,EAAA,MAAM,CAAC,MAAM,OAAO,IAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,GAAG,CAAA;AAC/C,EAAA,IAAI,EAAA,KAAO,QAAQ,OAAO,EAAE,GAAG,KAAA,EAAO,MAAA,EAAQC,0BAAY,MAAA,EAAO;AAEjE,EAAA,MAAM,QAAA,GAAW,YAAA;AAAA,IACf,OAAA;AAAA,IACA,KAAA,CAAM,WAAA;AAAA,IACN,KAAA,CAAM;AAAA,GACR;AACA,EAAA,OAAO;AAAA,IACL,GAAG,KAAA;AAAA,IACH,MAAA,EAAQ,QAAA,GAAWA,yBAAA,CAAY,QAAA,GAAWA,yBAAA,CAAY;AAAA,GACxD;AACF;AAEO,SAAS,OAAO,IAAA,EAAsC;AAC3D,EAAA,MAAM,OAAA,GAAUP,MAAA,CAAI,IAAA,CAAK,IAAI,CAAA;AAC7B,EAAA,OAAOA,MAAA,CAAI,MAAA;AAAA;AAAA,IAET,MAAA;AAAA,IACAA,OAAI,UAAA,CAAW,wBAAA,GAA2BA,MAAA,CAAI,IAAA,CAAK,OAAO,CAAC,CAAA;AAAA,IAC3D;AAAA,GACF;AACF;AACO,SAAS,eAAe,IAAA,EAAsC;AACnE,EAAA,OAAOG,OAAA,CAAK,SAAA,CAAU,MAAA,CAAO,IAAI,CAAC,CAAA;AACpC","file":"tron-F5AARBY4.cjs","sourcesContent":["import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, Signature, Hash, Bytes, PublicKey } from \"ox\";\nimport { base58 } from \"@scure/base\";\n\nexport function verifyTIP191(\n address: string,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const hex: Hex.Hex = `0x41${Hash.keccak256(\n `0x${PublicKey.toHex(publicKey).slice(4)}`,\n ).substring(26)}`;\n const bytes = Bytes.from(hex);\n const checksum = Bytes.from(Hash.sha256(Hash.sha256(hex))).slice(0, 4);\n const checked = Bytes.concat(bytes, checksum);\n const b58 = base58.encode(checked);\n return b58 === address;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignTIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"tron\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyTIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nexport function encode(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n const message = Hex.from(data);\n return Hex.concat(\n // Personal Sign Format: `0x19 ‖ \"Ethereum Signed Message:\\n\" ‖ message.length ‖ message`\n \"0x19\",\n Hex.fromString(\"TRON Signed Message:\\n\" + Hex.size(message)),\n message,\n );\n}\nexport function getSignPayload(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n return Hash.keccak256(encode(data));\n}\n"]}
@@ -0,0 +1,53 @@
1
+ import { Buffer } from 'buffer';
2
+ import './chunk-E3V5ATTC.js';
3
+ import { ProofStatus } from '@notabene/javascript-sdk';
4
+ import { Hex, Signature, Secp256k1, Hash, PublicKey, Bytes } from 'ox';
5
+ import { base58 } from '@scure/base';
6
+
7
+ if (typeof globalThis !== 'undefined' && !globalThis.Buffer) { globalThis.Buffer = Buffer; }
8
+ function verifyTIP191(address, message, proof) {
9
+ try {
10
+ const payload = getSignPayload(Hex.fromString(message));
11
+ const signature = Signature.fromHex(proof);
12
+ const publicKey = Secp256k1.recoverPublicKey({ payload, signature });
13
+ const hex = `0x41${Hash.keccak256(
14
+ `0x${PublicKey.toHex(publicKey).slice(4)}`
15
+ ).substring(26)}`;
16
+ const bytes = Bytes.from(hex);
17
+ const checksum = Bytes.from(Hash.sha256(Hash.sha256(hex))).slice(0, 4);
18
+ const checked = Bytes.concat(bytes, checksum);
19
+ const b58 = base58.encode(checked);
20
+ return b58 === address;
21
+ } catch (error) {
22
+ return false;
23
+ }
24
+ }
25
+ async function verifyPersonalSignTIP191(proof) {
26
+ const [ns, , address] = proof.address.split(/:/);
27
+ if (ns !== "tron") return { ...proof, status: ProofStatus.FAILED };
28
+ const verified = verifyTIP191(
29
+ address,
30
+ proof.attestation,
31
+ proof.proof
32
+ );
33
+ return {
34
+ ...proof,
35
+ status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED
36
+ };
37
+ }
38
+ function encode(data) {
39
+ const message = Hex.from(data);
40
+ return Hex.concat(
41
+ // Personal Sign Format: `0x19 ‖ "Ethereum Signed Message:\n" ‖ message.length ‖ message`
42
+ "0x19",
43
+ Hex.fromString("TRON Signed Message:\n" + Hex.size(message)),
44
+ message
45
+ );
46
+ }
47
+ function getSignPayload(data) {
48
+ return Hash.keccak256(encode(data));
49
+ }
50
+
51
+ export { encode, getSignPayload, verifyPersonalSignTIP191, verifyTIP191 };
52
+ //# sourceMappingURL=tron-OBLPB2LN.js.map
53
+ //# sourceMappingURL=tron-OBLPB2LN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tron.ts"],"names":[],"mappings":";;;;;;;AAIO,SAAS,YAAA,CACd,OAAA,EACA,OAAA,EACA,KAAA,EACS;AACT,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAU,cAAA,CAAe,GAAA,CAAI,UAAA,CAAW,OAAO,CAAC,CAAA;AACtD,IAAA,MAAM,SAAA,GAAY,SAAA,CAAU,OAAA,CAAQ,KAAK,CAAA;AACzC,IAAA,MAAM,YAAY,SAAA,CAAU,gBAAA,CAAiB,EAAE,OAAA,EAAS,WAAW,CAAA;AACnE,IAAA,MAAM,GAAA,GAAe,OAAO,IAAA,CAAK,SAAA;AAAA,MAC/B,KAAK,SAAA,CAAU,KAAA,CAAM,SAAS,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,KAC1C,CAAE,SAAA,CAAU,EAAE,CAAC,CAAA,CAAA;AACf,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,CAAK,GAAG,CAAA;AAC5B,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA,CAAE,KAAA,CAAM,GAAG,CAAC,CAAA;AACrE,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,MAAA,CAAO,KAAA,EAAO,QAAQ,CAAA;AAC5C,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,MAAA,CAAO,OAAO,CAAA;AACjC,IAAA,OAAO,GAAA,KAAQ,OAAA;AAAA,EAEjB,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,eAAsB,yBACpB,KAAA,EACyB;AACzB,EAAA,MAAM,CAAC,MAAM,OAAO,IAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,GAAG,CAAA;AAC/C,EAAA,IAAI,EAAA,KAAO,QAAQ,OAAO,EAAE,GAAG,KAAA,EAAO,MAAA,EAAQ,YAAY,MAAA,EAAO;AAEjE,EAAA,MAAM,QAAA,GAAW,YAAA;AAAA,IACf,OAAA;AAAA,IACA,KAAA,CAAM,WAAA;AAAA,IACN,KAAA,CAAM;AAAA,GACR;AACA,EAAA,OAAO;AAAA,IACL,GAAG,KAAA;AAAA,IACH,MAAA,EAAQ,QAAA,GAAW,WAAA,CAAY,QAAA,GAAW,WAAA,CAAY;AAAA,GACxD;AACF;AAEO,SAAS,OAAO,IAAA,EAAsC;AAC3D,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA;AAC7B,EAAA,OAAO,GAAA,CAAI,MAAA;AAAA;AAAA,IAET,MAAA;AAAA,IACA,IAAI,UAAA,CAAW,wBAAA,GAA2B,GAAA,CAAI,IAAA,CAAK,OAAO,CAAC,CAAA;AAAA,IAC3D;AAAA,GACF;AACF;AACO,SAAS,eAAe,IAAA,EAAsC;AACnE,EAAA,OAAO,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,IAAI,CAAC,CAAA;AACpC","file":"tron-OBLPB2LN.js","sourcesContent":["import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, Signature, Hash, Bytes, PublicKey } from \"ox\";\nimport { base58 } from \"@scure/base\";\n\nexport function verifyTIP191(\n address: string,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const hex: Hex.Hex = `0x41${Hash.keccak256(\n `0x${PublicKey.toHex(publicKey).slice(4)}`,\n ).substring(26)}`;\n const bytes = Bytes.from(hex);\n const checksum = Bytes.from(Hash.sha256(Hash.sha256(hex))).slice(0, 4);\n const checked = Bytes.concat(bytes, checksum);\n const b58 = base58.encode(checked);\n return b58 === address;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignTIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"tron\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyTIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nexport function encode(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n const message = Hex.from(data);\n return Hex.concat(\n // Personal Sign Format: `0x19 ‖ \"Ethereum Signed Message:\\n\" ‖ message.length ‖ message`\n \"0x19\",\n Hex.fromString(\"TRON Signed Message:\\n\" + Hex.size(message)),\n message,\n );\n}\nexport function getSignPayload(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n return Hash.keccak256(encode(data));\n}\n"]}
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ var buffer = require('buffer');
4
+ require('./chunk-OAXNH5XR.cjs');
5
+ var javascriptSdk = require('@notabene/javascript-sdk');
6
+ var stellarSdk = require('@stellar/stellar-sdk');
7
+
8
+ if (typeof globalThis !== 'undefined' && !globalThis.Buffer) { globalThis.Buffer = buffer.Buffer; }
9
+ function verifyStellarSignature(proof) {
10
+ const [ns, , address] = proof.address.split(/:/);
11
+ if (ns !== "stellar") return { ...proof, status: javascriptSdk.ProofStatus.FAILED };
12
+ try {
13
+ const keypair = stellarSdk.Keypair.fromPublicKey(address);
14
+ const messageBuffer = buffer.Buffer.from(proof.attestation, "utf-8");
15
+ const signatureBuffer = buffer.Buffer.from(proof.proof, "base64");
16
+ const verified = keypair.verify(messageBuffer, signatureBuffer);
17
+ return {
18
+ ...proof,
19
+ status: verified ? javascriptSdk.ProofStatus.VERIFIED : javascriptSdk.ProofStatus.FAILED
20
+ };
21
+ } catch {
22
+ return { ...proof, status: javascriptSdk.ProofStatus.FAILED };
23
+ }
24
+ }
25
+
26
+ exports.verifyStellarSignature = verifyStellarSignature;
27
+ //# sourceMappingURL=xlm-5GODWWL2.cjs.map
28
+ //# sourceMappingURL=xlm-5GODWWL2.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/xlm.ts"],"names":["ProofStatus","Keypair","Buffer"],"mappings":";;;;;;;;AAGO,SAAS,uBACd,KAAA,EACgB;AAChB,EAAA,MAAM,CAAC,MAAM,OAAO,IAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,GAAG,CAAA;AAC/C,EAAA,IAAI,EAAA,KAAO,WAAW,OAAO,EAAE,GAAG,KAAA,EAAO,MAAA,EAAQA,0BAAY,MAAA,EAAO;AAEpE,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAUC,kBAAA,CAAQ,aAAA,CAAc,OAAO,CAAA;AAC7C,IAAA,MAAM,aAAA,GAAgBC,aAAA,CAAO,IAAA,CAAK,KAAA,CAAM,aAAa,OAAO,CAAA;AAC5D,IAAA,MAAM,eAAA,GAAkBA,aAAA,CAAO,IAAA,CAAK,KAAA,CAAM,OAAO,QAAQ,CAAA;AAEzD,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,MAAA,CAAO,aAAA,EAAe,eAAe,CAAA;AAE9D,IAAA,OAAO;AAAA,MACL,GAAG,KAAA;AAAA,MACH,MAAA,EAAQ,QAAA,GAAWF,yBAAA,CAAY,QAAA,GAAWA,yBAAA,CAAY;AAAA,KACxD;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,GAAG,KAAA,EAAO,MAAA,EAAQA,0BAAY,MAAA,EAAO;AAAA,EAChD;AACF","file":"xlm-5GODWWL2.cjs","sourcesContent":["import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Keypair } from \"@stellar/stellar-sdk\";\n\nexport function verifyStellarSignature(\n proof: SignatureProof,\n): SignatureProof {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"stellar\") return { ...proof, status: ProofStatus.FAILED };\n\n try {\n const keypair = Keypair.fromPublicKey(address);\n const messageBuffer = Buffer.from(proof.attestation, \"utf-8\");\n const signatureBuffer = Buffer.from(proof.proof, \"base64\");\n\n const verified = keypair.verify(messageBuffer, signatureBuffer);\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n } catch {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n"]}
@@ -0,0 +1,26 @@
1
+ import { Buffer } from 'buffer';
2
+ import './chunk-E3V5ATTC.js';
3
+ import { ProofStatus } from '@notabene/javascript-sdk';
4
+ import { Keypair } from '@stellar/stellar-sdk';
5
+
6
+ if (typeof globalThis !== 'undefined' && !globalThis.Buffer) { globalThis.Buffer = Buffer; }
7
+ function verifyStellarSignature(proof) {
8
+ const [ns, , address] = proof.address.split(/:/);
9
+ if (ns !== "stellar") return { ...proof, status: ProofStatus.FAILED };
10
+ try {
11
+ const keypair = Keypair.fromPublicKey(address);
12
+ const messageBuffer = Buffer.from(proof.attestation, "utf-8");
13
+ const signatureBuffer = Buffer.from(proof.proof, "base64");
14
+ const verified = keypair.verify(messageBuffer, signatureBuffer);
15
+ return {
16
+ ...proof,
17
+ status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED
18
+ };
19
+ } catch {
20
+ return { ...proof, status: ProofStatus.FAILED };
21
+ }
22
+ }
23
+
24
+ export { verifyStellarSignature };
25
+ //# sourceMappingURL=xlm-GX2QGFLI.js.map
26
+ //# sourceMappingURL=xlm-GX2QGFLI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/xlm.ts"],"names":[],"mappings":";;;;;;AAGO,SAAS,uBACd,KAAA,EACgB;AAChB,EAAA,MAAM,CAAC,MAAM,OAAO,IAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,GAAG,CAAA;AAC/C,EAAA,IAAI,EAAA,KAAO,WAAW,OAAO,EAAE,GAAG,KAAA,EAAO,MAAA,EAAQ,YAAY,MAAA,EAAO;AAEpE,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,aAAA,CAAc,OAAO,CAAA;AAC7C,IAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,aAAa,OAAO,CAAA;AAC5D,IAAA,MAAM,eAAA,GAAkB,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,OAAO,QAAQ,CAAA;AAEzD,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,MAAA,CAAO,aAAA,EAAe,eAAe,CAAA;AAE9D,IAAA,OAAO;AAAA,MACL,GAAG,KAAA;AAAA,MACH,MAAA,EAAQ,QAAA,GAAW,WAAA,CAAY,QAAA,GAAW,WAAA,CAAY;AAAA,KACxD;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,GAAG,KAAA,EAAO,MAAA,EAAQ,YAAY,MAAA,EAAO;AAAA,EAChD;AACF","file":"xlm-GX2QGFLI.js","sourcesContent":["import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Keypair } from \"@stellar/stellar-sdk\";\n\nexport function verifyStellarSignature(\n proof: SignatureProof,\n): SignatureProof {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"stellar\") return { ...proof, status: ProofStatus.FAILED };\n\n try {\n const keypair = Keypair.fromPublicKey(address);\n const messageBuffer = Buffer.from(proof.attestation, \"utf-8\");\n const signatureBuffer = Buffer.from(proof.proof, \"base64\");\n\n const verified = keypair.verify(messageBuffer, signatureBuffer);\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n } catch {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n"]}