zano_web3 9.6.0 → 9.8.0-canary.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/package.json +4 -2
- package/server/dist/server.d.ts +7 -0
- package/server/dist/server.js +32 -0
- package/server/dist/server.js.map +1 -1
- package/server/src/server.ts +58 -0
- package/shared/dist/utils.d.ts +63 -0
- package/shared/dist/utils.js +174 -0
- package/shared/dist/utils.js.map +1 -1
- package/shared/src/utils.ts +260 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zano_web3",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.8.0-canary.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./web/dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"build:web": "tsc --project tsconfig.web.json",
|
|
21
21
|
"build:server": "tsc --project tsconfig.server.json",
|
|
22
22
|
"build:shared": "tsc --project tsconfig.shared.json",
|
|
23
|
-
"build": "npm run build:
|
|
23
|
+
"build": "npm run build:shared && npm run build:web && npm run build:server"
|
|
24
24
|
},
|
|
25
25
|
"repository": {
|
|
26
26
|
"type": "git",
|
|
@@ -36,6 +36,8 @@
|
|
|
36
36
|
"author": "",
|
|
37
37
|
"license": "ISC",
|
|
38
38
|
"dependencies": {
|
|
39
|
+
"@noble/hashes": "^2.2.0",
|
|
40
|
+
"@scure/base": "^2.2.0",
|
|
39
41
|
"@types/big.js": "^6.2.2",
|
|
40
42
|
"@types/node": "^20.14.12",
|
|
41
43
|
"@types/node-forge": "^1.3.11",
|
package/server/dist/server.d.ts
CHANGED
|
@@ -32,6 +32,13 @@ declare class ServerWallet {
|
|
|
32
32
|
getAliasByAddress(address: string): Promise<any>;
|
|
33
33
|
getBalances(): Promise<BalanceInfo[]>;
|
|
34
34
|
validateWallet(authData: AuthData): Promise<boolean>;
|
|
35
|
+
validateSecureMessageSignature({ originalMessage, signedMessage, signature, address, pkeyFromSignature, }: {
|
|
36
|
+
originalMessage: string;
|
|
37
|
+
signedMessage: string;
|
|
38
|
+
signature: string;
|
|
39
|
+
address: string;
|
|
40
|
+
pkeyFromSignature: string;
|
|
41
|
+
}): Promise<boolean>;
|
|
35
42
|
getTxs(params: GetTxsParams): Promise<TxInfo>;
|
|
36
43
|
getAliasDetails(alias: string): Promise<AliasDetails>;
|
|
37
44
|
}
|
package/server/dist/server.js
CHANGED
|
@@ -2,6 +2,7 @@ import axios from "axios";
|
|
|
2
2
|
import Big from "big.js";
|
|
3
3
|
import { ZANO_ASSET_ID, ZanoError } from "./utils";
|
|
4
4
|
import forge from "node-forge";
|
|
5
|
+
import { getPkeyFromAddress, parseSecureMessageForSigning } from "../../shared/dist";
|
|
5
6
|
class ServerWallet {
|
|
6
7
|
walletUrl;
|
|
7
8
|
daemonUrl;
|
|
@@ -251,6 +252,37 @@ class ServerWallet {
|
|
|
251
252
|
}
|
|
252
253
|
return valid;
|
|
253
254
|
}
|
|
255
|
+
async validateSecureMessageSignature({ originalMessage, signedMessage, signature, address, pkeyFromSignature, }) {
|
|
256
|
+
if (originalMessage !== signedMessage) {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
const pkey = getPkeyFromAddress({ address });
|
|
260
|
+
const isPkeyMatching = pkey !== null && pkey === pkeyFromSignature;
|
|
261
|
+
if (!isPkeyMatching) {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
const isSignatureValid = await this.validateWallet({
|
|
265
|
+
message: originalMessage,
|
|
266
|
+
signature,
|
|
267
|
+
address,
|
|
268
|
+
pkey,
|
|
269
|
+
});
|
|
270
|
+
if (!isSignatureValid) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
const parsedMessageResult = parseSecureMessageForSigning({ message: originalMessage });
|
|
274
|
+
const parsingData = parsedMessageResult.success ? parsedMessageResult.parsingResult : null;
|
|
275
|
+
const parsedSuccessfully = parsedMessageResult.success && parsingData !== null && parsingData.isSecureMessage && parsingData.isValidSecureMessage;
|
|
276
|
+
if (!parsedSuccessfully) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
const { expirationTime } = parsingData.values;
|
|
280
|
+
const isExpired = expirationTime.getTime() < Date.now();
|
|
281
|
+
if (isExpired) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
254
286
|
async getTxs(params) {
|
|
255
287
|
const txs = await this.fetchWallet("get_recent_txs_and_info2", {
|
|
256
288
|
count: params.count,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/server/src/server.ts
CHANGED
|
@@ -12,7 +12,9 @@ import {
|
|
|
12
12
|
|
|
13
13
|
import { ZANO_ASSET_ID, ZanoError } from "./utils";
|
|
14
14
|
import { APIAsset, APIBalance } from "./types";
|
|
15
|
+
|
|
15
16
|
import forge from "node-forge";
|
|
17
|
+
import { getPkeyFromAddress, parseSecureMessageForSigning } from "../../shared/dist";
|
|
16
18
|
|
|
17
19
|
interface ConstructorParams {
|
|
18
20
|
walletUrl: string;
|
|
@@ -345,6 +347,62 @@ class ServerWallet {
|
|
|
345
347
|
return valid;
|
|
346
348
|
}
|
|
347
349
|
|
|
350
|
+
async validateSecureMessageSignature({
|
|
351
|
+
originalMessage,
|
|
352
|
+
signedMessage,
|
|
353
|
+
signature,
|
|
354
|
+
address,
|
|
355
|
+
pkeyFromSignature,
|
|
356
|
+
}: {
|
|
357
|
+
originalMessage: string;
|
|
358
|
+
signedMessage: string;
|
|
359
|
+
signature: string;
|
|
360
|
+
address: string;
|
|
361
|
+
pkeyFromSignature: string;
|
|
362
|
+
}): Promise<boolean> {
|
|
363
|
+
if (originalMessage !== signedMessage) {
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const pkey = getPkeyFromAddress({ address });
|
|
368
|
+
|
|
369
|
+
const isPkeyMatching = pkey !== null && pkey === pkeyFromSignature;
|
|
370
|
+
|
|
371
|
+
if (!isPkeyMatching) {
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const isSignatureValid = await this.validateWallet({
|
|
376
|
+
message: originalMessage,
|
|
377
|
+
signature,
|
|
378
|
+
address,
|
|
379
|
+
pkey,
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
if (!isSignatureValid) {
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const parsedMessageResult = parseSecureMessageForSigning({ message: originalMessage });
|
|
387
|
+
const parsingData = parsedMessageResult.success ? parsedMessageResult.parsingResult : null;
|
|
388
|
+
|
|
389
|
+
const parsedSuccessfully = parsedMessageResult.success && parsingData !== null && parsingData.isSecureMessage && parsingData.isValidSecureMessage;
|
|
390
|
+
|
|
391
|
+
if (!parsedSuccessfully) {
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
const { expirationTime } = parsingData.values;
|
|
396
|
+
|
|
397
|
+
const isExpired = expirationTime.getTime() < Date.now();
|
|
398
|
+
|
|
399
|
+
if (isExpired) {
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
return true;
|
|
404
|
+
}
|
|
405
|
+
|
|
348
406
|
async getTxs(params: GetTxsParams) {
|
|
349
407
|
const txs = await this.fetchWallet("get_recent_txs_and_info2", {
|
|
350
408
|
count: params.count,
|
package/shared/dist/utils.d.ts
CHANGED
|
@@ -5,3 +5,66 @@ export declare function validateTokensInput(input: string | number, decimal_poin
|
|
|
5
5
|
valid: boolean;
|
|
6
6
|
error?: undefined;
|
|
7
7
|
};
|
|
8
|
+
export type GenerateSecureMessageForSigningResult = {
|
|
9
|
+
success: true;
|
|
10
|
+
message: string;
|
|
11
|
+
} | {
|
|
12
|
+
success: false;
|
|
13
|
+
error: 'NONCE_TOO_SHORT';
|
|
14
|
+
};
|
|
15
|
+
export declare function generateSecureMessageForSigning({ domain, address, statement, uri, nonce, expirationTime, isTestnet }: {
|
|
16
|
+
domain: string;
|
|
17
|
+
address: string;
|
|
18
|
+
statement: string;
|
|
19
|
+
uri: string;
|
|
20
|
+
nonce: string;
|
|
21
|
+
expirationTime: Date;
|
|
22
|
+
isTestnet?: boolean;
|
|
23
|
+
}): GenerateSecureMessageForSigningResult;
|
|
24
|
+
export type ParseSecureMessageForSigningResult = {
|
|
25
|
+
success: true;
|
|
26
|
+
parsingResult: {
|
|
27
|
+
isSecureMessage: true;
|
|
28
|
+
isValidSecureMessage: true;
|
|
29
|
+
values: {
|
|
30
|
+
domain: string;
|
|
31
|
+
address: string;
|
|
32
|
+
statement: string;
|
|
33
|
+
uri: string;
|
|
34
|
+
nonce: string;
|
|
35
|
+
expirationTime: Date;
|
|
36
|
+
chainId: string;
|
|
37
|
+
version: string;
|
|
38
|
+
};
|
|
39
|
+
} | {
|
|
40
|
+
isSecureMessage: boolean;
|
|
41
|
+
isValidSecureMessage: false;
|
|
42
|
+
};
|
|
43
|
+
} | {
|
|
44
|
+
success: false;
|
|
45
|
+
error: never;
|
|
46
|
+
};
|
|
47
|
+
export declare function parseSecureMessageForSigning({ message, }: {
|
|
48
|
+
message: string;
|
|
49
|
+
}): ParseSecureMessageForSigningResult;
|
|
50
|
+
/**
|
|
51
|
+
* Extracts the public spend key (`pkey`) from a Zano address.
|
|
52
|
+
*
|
|
53
|
+
* This is a pure-TS port of the decode path used by the native
|
|
54
|
+
* `zano-node-util` addon (`base58::decode_addr` -> parse `account_public_address`):
|
|
55
|
+
* 1. CryptoNote block-based base58 decode of the address.
|
|
56
|
+
* 2. Split the blob into `varint(prefix) | data | checksum(4)`.
|
|
57
|
+
* 3. Verify the checksum (first 4 bytes of keccak-256 over `prefix | data`).
|
|
58
|
+
* 4. Read the `spend_public_key` (first 32 bytes of `data`) as the pkey.
|
|
59
|
+
*
|
|
60
|
+
* The `pkey` accepted by the `validate_signature` daemon RPC is exactly this
|
|
61
|
+
* spend public key, so this can be used to bind a claimed address to a pkey.
|
|
62
|
+
*
|
|
63
|
+
* @returns The spend public key as a lowercase hex string, or `null` if the
|
|
64
|
+
* address is malformed (too short, checksum mismatch, or missing key).
|
|
65
|
+
* Unexpected errors (e.g. invalid base58) are not swallowed and
|
|
66
|
+
* propagate to the caller.
|
|
67
|
+
*/
|
|
68
|
+
export declare function getPkeyFromAddress({ address }: {
|
|
69
|
+
address: string;
|
|
70
|
+
}): string | null;
|
package/shared/dist/utils.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import Decimal from "decimal.js";
|
|
2
|
+
import { keccak_256 } from "@noble/hashes/sha3.js";
|
|
3
|
+
import { bytesToHex } from "@noble/hashes/utils.js";
|
|
4
|
+
import { base58xmr } from "@scure/base";
|
|
2
5
|
export function validateTokensInput(input, decimal_point = 12) {
|
|
3
6
|
if (typeof input === 'number') {
|
|
4
7
|
input = input.toString();
|
|
@@ -67,4 +70,175 @@ export function validateTokensInput(input, decimal_point = 12) {
|
|
|
67
70
|
valid: true
|
|
68
71
|
};
|
|
69
72
|
}
|
|
73
|
+
export function generateSecureMessageForSigning({ domain, address, statement, uri, nonce, expirationTime, isTestnet }) {
|
|
74
|
+
if (nonce.length < 8) {
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
error: 'NONCE_TOO_SHORT'
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
let result = '';
|
|
81
|
+
result += `${domain} wants you to sign in with your Zano account:\n`;
|
|
82
|
+
result += `${address}\n`;
|
|
83
|
+
result += `\n`;
|
|
84
|
+
result += `${statement}\n`;
|
|
85
|
+
result += `\n`;
|
|
86
|
+
result += `URI: ${uri}\n`;
|
|
87
|
+
result += `Version: 1\n`;
|
|
88
|
+
result += `Chain ID: ${isTestnet ? 'zano:testnet' : 'zano:mainnet'}\n`;
|
|
89
|
+
result += `Nonce: ${nonce}\n`;
|
|
90
|
+
result += `Expiration Time: ${expirationTime.toISOString()}`;
|
|
91
|
+
return {
|
|
92
|
+
success: true,
|
|
93
|
+
message: result
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export function parseSecureMessageForSigning({ message, }) {
|
|
97
|
+
// The message layout is fixed and positional (see
|
|
98
|
+
// generateSecureMessageForSigning):
|
|
99
|
+
//
|
|
100
|
+
// 0: "{domain} wants you to sign in with your Zano account:"
|
|
101
|
+
// 1: {address}
|
|
102
|
+
// 2: ""
|
|
103
|
+
// 3: {statement}
|
|
104
|
+
// 4: ""
|
|
105
|
+
// 5+: "Key: value" fields (URI, Version, Chain ID, Nonce, Expiration Time)
|
|
106
|
+
const HEADER_SUFFIX = ' wants you to sign in with your Zano account:';
|
|
107
|
+
const HEADER_LINE_COUNT = 5;
|
|
108
|
+
// A "Version: ..." line is the cheap signal that this is a secure message at
|
|
109
|
+
// all, independent of whether it fully parses.
|
|
110
|
+
const isSecureMessage = /(\r|\n)Version:.*/g.test(message);
|
|
111
|
+
const lines = message.split('\n');
|
|
112
|
+
if (lines.length < HEADER_LINE_COUNT ||
|
|
113
|
+
!lines[0].endsWith(HEADER_SUFFIX) ||
|
|
114
|
+
lines[2] !== '' ||
|
|
115
|
+
lines[4] !== '') {
|
|
116
|
+
return {
|
|
117
|
+
success: true,
|
|
118
|
+
parsingResult: { isSecureMessage, isValidSecureMessage: false }
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const domain = lines[0].slice(0, -HEADER_SUFFIX.length);
|
|
122
|
+
const address = lines[1];
|
|
123
|
+
const statement = lines[3];
|
|
124
|
+
// The remaining lines are "Key: value" fields and may appear in any order.
|
|
125
|
+
const fields = new Map();
|
|
126
|
+
for (const line of lines.slice(HEADER_LINE_COUNT)) {
|
|
127
|
+
const separatorIndex = line.indexOf(': ');
|
|
128
|
+
if (separatorIndex === -1) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
fields.set(line.slice(0, separatorIndex), line.slice(separatorIndex + 2));
|
|
132
|
+
}
|
|
133
|
+
const uri = fields.get('URI');
|
|
134
|
+
const version = fields.get('Version');
|
|
135
|
+
const chainId = fields.get('Chain ID');
|
|
136
|
+
const nonce = fields.get('Nonce');
|
|
137
|
+
const expirationTimeRaw = fields.get('Expiration Time');
|
|
138
|
+
// Every field that carries a value we expose must be present.
|
|
139
|
+
if (domain.length === 0 ||
|
|
140
|
+
uri === undefined ||
|
|
141
|
+
version === undefined ||
|
|
142
|
+
chainId === undefined ||
|
|
143
|
+
nonce === undefined ||
|
|
144
|
+
expirationTimeRaw === undefined) {
|
|
145
|
+
return {
|
|
146
|
+
success: true,
|
|
147
|
+
parsingResult: { isSecureMessage, isValidSecureMessage: false }
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// Fixed-value fields must match what generateSecureMessageForSigning emits,
|
|
151
|
+
// and the nonce carries the same minimum length it enforces.
|
|
152
|
+
if (nonce.length < 8 ||
|
|
153
|
+
version !== '1' ||
|
|
154
|
+
(chainId !== 'zano:mainnet' && chainId !== 'zano:testnet')) {
|
|
155
|
+
return {
|
|
156
|
+
success: true,
|
|
157
|
+
parsingResult: { isSecureMessage, isValidSecureMessage: false }
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
// Expiration Time must be a valid timestamp that has not already passed.
|
|
161
|
+
const expirationTime = new Date(expirationTimeRaw);
|
|
162
|
+
if (Number.isNaN(expirationTime.getTime()) ||
|
|
163
|
+
expirationTime.getTime() <= Date.now()) {
|
|
164
|
+
return {
|
|
165
|
+
success: true,
|
|
166
|
+
parsingResult: { isSecureMessage, isValidSecureMessage: false }
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
success: true,
|
|
171
|
+
parsingResult: {
|
|
172
|
+
isSecureMessage: true,
|
|
173
|
+
isValidSecureMessage: true,
|
|
174
|
+
values: {
|
|
175
|
+
domain,
|
|
176
|
+
address,
|
|
177
|
+
statement,
|
|
178
|
+
uri,
|
|
179
|
+
nonce,
|
|
180
|
+
expirationTime,
|
|
181
|
+
chainId,
|
|
182
|
+
version
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function readVarint(buf, start) {
|
|
188
|
+
let result = 0n;
|
|
189
|
+
let shift = 0n;
|
|
190
|
+
let i = start;
|
|
191
|
+
while (true) {
|
|
192
|
+
const byte = buf[i++];
|
|
193
|
+
result |= BigInt(byte & 0x7f) << shift;
|
|
194
|
+
if ((byte & 0x80) === 0) {
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
shift += 7n;
|
|
198
|
+
}
|
|
199
|
+
return [result, i];
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Extracts the public spend key (`pkey`) from a Zano address.
|
|
203
|
+
*
|
|
204
|
+
* This is a pure-TS port of the decode path used by the native
|
|
205
|
+
* `zano-node-util` addon (`base58::decode_addr` -> parse `account_public_address`):
|
|
206
|
+
* 1. CryptoNote block-based base58 decode of the address.
|
|
207
|
+
* 2. Split the blob into `varint(prefix) | data | checksum(4)`.
|
|
208
|
+
* 3. Verify the checksum (first 4 bytes of keccak-256 over `prefix | data`).
|
|
209
|
+
* 4. Read the `spend_public_key` (first 32 bytes of `data`) as the pkey.
|
|
210
|
+
*
|
|
211
|
+
* The `pkey` accepted by the `validate_signature` daemon RPC is exactly this
|
|
212
|
+
* spend public key, so this can be used to bind a claimed address to a pkey.
|
|
213
|
+
*
|
|
214
|
+
* @returns The spend public key as a lowercase hex string, or `null` if the
|
|
215
|
+
* address is malformed (too short, checksum mismatch, or missing key).
|
|
216
|
+
* Unexpected errors (e.g. invalid base58) are not swallowed and
|
|
217
|
+
* propagate to the caller.
|
|
218
|
+
*/
|
|
219
|
+
export function getPkeyFromAddress({ address }) {
|
|
220
|
+
const blob = base58xmr.decode(address);
|
|
221
|
+
// Layout: varint(prefix) | data | checksum(4)
|
|
222
|
+
const ADDRESS_CHECKSUM_SIZE = 4;
|
|
223
|
+
if (blob.length < ADDRESS_CHECKSUM_SIZE) {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
const body = blob.subarray(0, blob.length - ADDRESS_CHECKSUM_SIZE);
|
|
227
|
+
const checksum = blob.subarray(blob.length - ADDRESS_CHECKSUM_SIZE);
|
|
228
|
+
const expectedChecksum = keccak_256(body).subarray(0, ADDRESS_CHECKSUM_SIZE);
|
|
229
|
+
for (let i = 0; i < ADDRESS_CHECKSUM_SIZE; i++) {
|
|
230
|
+
if (checksum[i] !== expectedChecksum[i]) {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Skip the prefix varint; `account_public_address` begins with the
|
|
235
|
+
// 32-byte spend_public_key, followed by the 32-byte view_public_key.
|
|
236
|
+
const [, dataStart] = readVarint(body, 0);
|
|
237
|
+
const data = body.subarray(dataStart);
|
|
238
|
+
const PUBLIC_KEY_SIZE = 32;
|
|
239
|
+
if (data.length < PUBLIC_KEY_SIZE * 2) {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
return bytesToHex(data.subarray(0, PUBLIC_KEY_SIZE));
|
|
243
|
+
}
|
|
70
244
|
//# sourceMappingURL=utils.js.map
|
package/shared/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,YAAY,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,UAAU,mBAAmB,CAAC,KAAsB,EAAE,gBAAwB,EAAE;IAElF,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACf,OAAO;YACH,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,eAAe;SACzB,CAAC;IACN,CAAC;IAED,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAEvC,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnD,IAAI,aAAa,GAAG,CAAC,IAAI,aAAa,GAAG,EAAE,EAAE,CAAC;QAC1C,OAAO;YACH,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,uBAAuB;SACjC,CAAC;IACN,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAE1C,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAE1D,MAAM,gBAAgB,GAAG,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAExD,MAAM,gBAAgB,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAE5D,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE;QAClB,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAEzC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1D,MAAM,eAAe,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;gBAC/C,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC;gBAEtF,IAAI,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;oBAC9C,OAAO,YAAY,CAAC;gBACxB,CAAC;YACL,CAAC;YAED,OAAO,KAAK,CAAC;QACjB,CAAC;aAAM,CAAC;YACJ,OAAO,QAAQ,CAAC;QACpB,CAAC;IACL,CAAC,CAAC,EAAE,CAAC;IAEL,MAAM,cAAc,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC;IAE3D,IAAI,cAAc,GAAG,aAAa,EAAE,CAAC;QACjC,OAAO;YACH,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,0CAA0C;SACpD,CAAC;IACN,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;QACpB,OAAO;YACH,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,mEAAmE;SAC7E,CAAC;IACN,CAAC;IAED,MAAM,eAAe,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAE7C,IAAI,eAAe,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACvC,OAAO;YACH,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,oCAAoC;SAC9C,CAAC;IACN,CAAC;IAED,IAAI,eAAe,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACvC,OAAO;YACH,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,sCAAsC;SAChD,CAAC;IACN,CAAC;IAED,OAAO;QACH,KAAK,EAAE,IAAI;KACd,CAAC;AACN,CAAC;AASD,MAAM,UAAU,+BAA+B,CAAC,EAC5C,MAAM,EACN,OAAO,EACP,SAAS,EACT,GAAG,EACH,KAAK,EACL,cAAc,EACd,SAAS,EASZ;IACG,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnB,OAAO;YACH,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,iBAAiB;SAC3B,CAAC;IACN,CAAC;IAED,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,MAAM,IAAI,GAAG,MAAM,iDAAiD,CAAC;IACrE,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC;IACzB,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,IAAI,GAAG,SAAS,IAAI,CAAC;IAC3B,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,IAAI,QAAQ,GAAG,IAAI,CAAC;IAC1B,MAAM,IAAI,cAAc,CAAC;IACzB,MAAM,IAAI,aAAa,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC;IACvE,MAAM,IAAI,UAAU,KAAK,IAAI,CAAC;IAC9B,MAAM,IAAI,oBAAoB,cAAc,CAAC,WAAW,EAAE,EAAE,CAAC;IAE7D,OAAO;QACH,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,MAAM;KAClB,CAAC;AACN,CAAC;AAyBD,MAAM,UAAU,4BAA4B,CAAC,EACzC,OAAO,GAGV;IACG,kDAAkD;IAClD,oCAAoC;IACpC,EAAE;IACF,+DAA+D;IAC/D,iBAAiB;IACjB,UAAU;IACV,mBAAmB;IACnB,UAAU;IACV,6EAA6E;IAC7E,MAAM,aAAa,GAAG,+CAA+C,CAAC;IACtE,MAAM,iBAAiB,GAAG,CAAC,CAAC;IAE5B,6EAA6E;IAC7E,+CAA+C;IAC/C,MAAM,eAAe,GAAG,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAE3D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,IACI,KAAK,CAAC,MAAM,GAAG,iBAAiB;QAChC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;QACjC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE;QACf,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,EACjB,CAAC;QACC,OAAO;YACH,OAAO,EAAE,IAAI;YACb,aAAa,EAAE,EAAE,eAAe,EAAE,oBAAoB,EAAE,KAAK,EAAE;SAClE,CAAC;IACN,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAE3B,2EAA2E;IAC3E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAChD,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,cAAc,KAAK,CAAC,CAAC,EAAE,CAAC;YACxB,SAAS;QACb,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,iBAAiB,GAAG,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAExD,8DAA8D;IAC9D,IACI,MAAM,CAAC,MAAM,KAAK,CAAC;QACnB,GAAG,KAAK,SAAS;QACjB,OAAO,KAAK,SAAS;QACrB,OAAO,KAAK,SAAS;QACrB,KAAK,KAAK,SAAS;QACnB,iBAAiB,KAAK,SAAS,EACjC,CAAC;QACC,OAAO;YACH,OAAO,EAAE,IAAI;YACb,aAAa,EAAE,EAAE,eAAe,EAAE,oBAAoB,EAAE,KAAK,EAAE;SAClE,CAAC;IACN,CAAC;IAED,4EAA4E;IAC5E,6DAA6D;IAC7D,IACI,KAAK,CAAC,MAAM,GAAG,CAAC;QAChB,OAAO,KAAK,GAAG;QACf,CAAC,OAAO,KAAK,cAAc,IAAI,OAAO,KAAK,cAAc,CAAC,EAC5D,CAAC;QACC,OAAO;YACH,OAAO,EAAE,IAAI;YACb,aAAa,EAAE,EAAE,eAAe,EAAE,oBAAoB,EAAE,KAAK,EAAE;SAClE,CAAC;IACN,CAAC;IAED,yEAAyE;IACzE,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACnD,IACI,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;QACtC,cAAc,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,EACxC,CAAC;QACC,OAAO;YACH,OAAO,EAAE,IAAI;YACb,aAAa,EAAE,EAAE,eAAe,EAAE,oBAAoB,EAAE,KAAK,EAAE;SAClE,CAAC;IACN,CAAC;IAED,OAAO;QACH,OAAO,EAAE,IAAI;QACb,aAAa,EAAE;YACX,eAAe,EAAE,IAAI;YACrB,oBAAoB,EAAE,IAAI;YAC1B,MAAM,EAAE;gBACJ,MAAM;gBACN,OAAO;gBACP,SAAS;gBACT,GAAG;gBACH,KAAK;gBACL,cAAc;gBACd,OAAO;gBACP,OAAO;aACV;SACJ;KACJ,CAAC;AACN,CAAC;AAED,SAAS,UAAU,CAAC,GAAe,EAAE,KAAa;IAC9C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,CAAC,GAAG,KAAK,CAAC;IACd,OAAO,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;QACtB,MAAM,IAAI,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM;QACV,CAAC;QACD,KAAK,IAAI,EAAE,CAAC;IAChB,CAAC;IACD,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAC/B,OAAO,EAGV;IACG,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEvC,8CAA8C;IAC9C,MAAM,qBAAqB,GAAG,CAAC,CAAC;IAChC,IAAI,IAAI,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,qBAAqB,CAAC,CAAC;IACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,GAAG,qBAAqB,CAAC,CAAC;IACpE,MAAM,gBAAgB,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;IAE7E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,qBAAqB,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED,mEAAmE;IACnE,qEAAqE;IACrE,MAAM,CAAC,EAAE,SAAS,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAEtC,MAAM,eAAe,GAAG,EAAE,CAAC;IAC3B,IAAI,IAAI,CAAC,MAAM,GAAG,eAAe,GAAG,CAAC,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;AACzD,CAAC"}
|
package/shared/src/utils.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import Decimal from "decimal.js";
|
|
2
|
+
import { keccak_256 } from "@noble/hashes/sha3.js";
|
|
3
|
+
import { bytesToHex } from "@noble/hashes/utils.js";
|
|
4
|
+
import { base58xmr } from "@scure/base";
|
|
2
5
|
|
|
3
6
|
export function validateTokensInput(input: string | number, decimal_point: number = 12) {
|
|
4
7
|
|
|
@@ -86,4 +89,260 @@ export function validateTokensInput(input: string | number, decimal_point: numbe
|
|
|
86
89
|
return {
|
|
87
90
|
valid: true
|
|
88
91
|
};
|
|
89
|
-
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export type GenerateSecureMessageForSigningResult = {
|
|
95
|
+
success: true;
|
|
96
|
+
message: string;
|
|
97
|
+
} | {
|
|
98
|
+
success: false;
|
|
99
|
+
error: 'NONCE_TOO_SHORT';
|
|
100
|
+
}
|
|
101
|
+
export function generateSecureMessageForSigning({
|
|
102
|
+
domain,
|
|
103
|
+
address,
|
|
104
|
+
statement,
|
|
105
|
+
uri,
|
|
106
|
+
nonce,
|
|
107
|
+
expirationTime,
|
|
108
|
+
isTestnet
|
|
109
|
+
}: {
|
|
110
|
+
domain: string;
|
|
111
|
+
address: string;
|
|
112
|
+
statement: string;
|
|
113
|
+
uri: string;
|
|
114
|
+
nonce: string;
|
|
115
|
+
expirationTime: Date;
|
|
116
|
+
isTestnet?: boolean;
|
|
117
|
+
}): GenerateSecureMessageForSigningResult {
|
|
118
|
+
if (nonce.length < 8) {
|
|
119
|
+
return {
|
|
120
|
+
success: false,
|
|
121
|
+
error: 'NONCE_TOO_SHORT'
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let result = '';
|
|
126
|
+
|
|
127
|
+
result += `${domain} wants you to sign in with your Zano account:\n`;
|
|
128
|
+
result += `${address}\n`;
|
|
129
|
+
result += `\n`;
|
|
130
|
+
result += `${statement}\n`;
|
|
131
|
+
result += `\n`;
|
|
132
|
+
result += `URI: ${uri}\n`;
|
|
133
|
+
result += `Version: 1\n`;
|
|
134
|
+
result += `Chain ID: ${isTestnet ? 'zano:testnet' : 'zano:mainnet'}\n`;
|
|
135
|
+
result += `Nonce: ${nonce}\n`;
|
|
136
|
+
result += `Expiration Time: ${expirationTime.toISOString()}`;
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
success: true,
|
|
140
|
+
message: result
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export type ParseSecureMessageForSigningResult = {
|
|
145
|
+
success: true;
|
|
146
|
+
parsingResult: {
|
|
147
|
+
isSecureMessage: true;
|
|
148
|
+
isValidSecureMessage: true;
|
|
149
|
+
values: {
|
|
150
|
+
domain: string;
|
|
151
|
+
address: string;
|
|
152
|
+
statement: string;
|
|
153
|
+
uri: string;
|
|
154
|
+
nonce: string;
|
|
155
|
+
expirationTime: Date;
|
|
156
|
+
chainId: string;
|
|
157
|
+
version: string;
|
|
158
|
+
}
|
|
159
|
+
} | {
|
|
160
|
+
isSecureMessage: boolean;
|
|
161
|
+
isValidSecureMessage: false;
|
|
162
|
+
}
|
|
163
|
+
} | {
|
|
164
|
+
success: false;
|
|
165
|
+
error: never;
|
|
166
|
+
}
|
|
167
|
+
export function parseSecureMessageForSigning({
|
|
168
|
+
message,
|
|
169
|
+
}: {
|
|
170
|
+
message: string;
|
|
171
|
+
}): ParseSecureMessageForSigningResult {
|
|
172
|
+
// The message layout is fixed and positional (see
|
|
173
|
+
// generateSecureMessageForSigning):
|
|
174
|
+
//
|
|
175
|
+
// 0: "{domain} wants you to sign in with your Zano account:"
|
|
176
|
+
// 1: {address}
|
|
177
|
+
// 2: ""
|
|
178
|
+
// 3: {statement}
|
|
179
|
+
// 4: ""
|
|
180
|
+
// 5+: "Key: value" fields (URI, Version, Chain ID, Nonce, Expiration Time)
|
|
181
|
+
const HEADER_SUFFIX = ' wants you to sign in with your Zano account:';
|
|
182
|
+
const HEADER_LINE_COUNT = 5;
|
|
183
|
+
|
|
184
|
+
// A "Version: ..." line is the cheap signal that this is a secure message at
|
|
185
|
+
// all, independent of whether it fully parses.
|
|
186
|
+
const isSecureMessage = /(\r|\n)Version:.*/g.test(message);
|
|
187
|
+
|
|
188
|
+
const lines = message.split('\n');
|
|
189
|
+
|
|
190
|
+
if (
|
|
191
|
+
lines.length < HEADER_LINE_COUNT ||
|
|
192
|
+
!lines[0].endsWith(HEADER_SUFFIX) ||
|
|
193
|
+
lines[2] !== '' ||
|
|
194
|
+
lines[4] !== ''
|
|
195
|
+
) {
|
|
196
|
+
return {
|
|
197
|
+
success: true,
|
|
198
|
+
parsingResult: { isSecureMessage, isValidSecureMessage: false }
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const domain = lines[0].slice(0, -HEADER_SUFFIX.length);
|
|
203
|
+
const address = lines[1];
|
|
204
|
+
const statement = lines[3];
|
|
205
|
+
|
|
206
|
+
// The remaining lines are "Key: value" fields and may appear in any order.
|
|
207
|
+
const fields = new Map<string, string>();
|
|
208
|
+
for (const line of lines.slice(HEADER_LINE_COUNT)) {
|
|
209
|
+
const separatorIndex = line.indexOf(': ');
|
|
210
|
+
if (separatorIndex === -1) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
fields.set(line.slice(0, separatorIndex), line.slice(separatorIndex + 2));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const uri = fields.get('URI');
|
|
217
|
+
const version = fields.get('Version');
|
|
218
|
+
const chainId = fields.get('Chain ID');
|
|
219
|
+
const nonce = fields.get('Nonce');
|
|
220
|
+
const expirationTimeRaw = fields.get('Expiration Time');
|
|
221
|
+
|
|
222
|
+
// Every field that carries a value we expose must be present.
|
|
223
|
+
if (
|
|
224
|
+
domain.length === 0 ||
|
|
225
|
+
uri === undefined ||
|
|
226
|
+
version === undefined ||
|
|
227
|
+
chainId === undefined ||
|
|
228
|
+
nonce === undefined ||
|
|
229
|
+
expirationTimeRaw === undefined
|
|
230
|
+
) {
|
|
231
|
+
return {
|
|
232
|
+
success: true,
|
|
233
|
+
parsingResult: { isSecureMessage, isValidSecureMessage: false }
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Fixed-value fields must match what generateSecureMessageForSigning emits,
|
|
238
|
+
// and the nonce carries the same minimum length it enforces.
|
|
239
|
+
if (
|
|
240
|
+
nonce.length < 8 ||
|
|
241
|
+
version !== '1' ||
|
|
242
|
+
(chainId !== 'zano:mainnet' && chainId !== 'zano:testnet')
|
|
243
|
+
) {
|
|
244
|
+
return {
|
|
245
|
+
success: true,
|
|
246
|
+
parsingResult: { isSecureMessage, isValidSecureMessage: false }
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Expiration Time must be a valid timestamp that has not already passed.
|
|
251
|
+
const expirationTime = new Date(expirationTimeRaw);
|
|
252
|
+
if (
|
|
253
|
+
Number.isNaN(expirationTime.getTime()) ||
|
|
254
|
+
expirationTime.getTime() <= Date.now()
|
|
255
|
+
) {
|
|
256
|
+
return {
|
|
257
|
+
success: true,
|
|
258
|
+
parsingResult: { isSecureMessage, isValidSecureMessage: false }
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return {
|
|
263
|
+
success: true,
|
|
264
|
+
parsingResult: {
|
|
265
|
+
isSecureMessage: true,
|
|
266
|
+
isValidSecureMessage: true,
|
|
267
|
+
values: {
|
|
268
|
+
domain,
|
|
269
|
+
address,
|
|
270
|
+
statement,
|
|
271
|
+
uri,
|
|
272
|
+
nonce,
|
|
273
|
+
expirationTime,
|
|
274
|
+
chainId,
|
|
275
|
+
version
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function readVarint(buf: Uint8Array, start: number): [bigint, number] {
|
|
282
|
+
let result = 0n;
|
|
283
|
+
let shift = 0n;
|
|
284
|
+
let i = start;
|
|
285
|
+
while (true) {
|
|
286
|
+
const byte = buf[i++];
|
|
287
|
+
result |= BigInt(byte & 0x7f) << shift;
|
|
288
|
+
if ((byte & 0x80) === 0) {
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
shift += 7n;
|
|
292
|
+
}
|
|
293
|
+
return [result, i];
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Extracts the public spend key (`pkey`) from a Zano address.
|
|
298
|
+
*
|
|
299
|
+
* This is a pure-TS port of the decode path used by the native
|
|
300
|
+
* `zano-node-util` addon (`base58::decode_addr` -> parse `account_public_address`):
|
|
301
|
+
* 1. CryptoNote block-based base58 decode of the address.
|
|
302
|
+
* 2. Split the blob into `varint(prefix) | data | checksum(4)`.
|
|
303
|
+
* 3. Verify the checksum (first 4 bytes of keccak-256 over `prefix | data`).
|
|
304
|
+
* 4. Read the `spend_public_key` (first 32 bytes of `data`) as the pkey.
|
|
305
|
+
*
|
|
306
|
+
* The `pkey` accepted by the `validate_signature` daemon RPC is exactly this
|
|
307
|
+
* spend public key, so this can be used to bind a claimed address to a pkey.
|
|
308
|
+
*
|
|
309
|
+
* @returns The spend public key as a lowercase hex string, or `null` if the
|
|
310
|
+
* address is malformed (too short, checksum mismatch, or missing key).
|
|
311
|
+
* Unexpected errors (e.g. invalid base58) are not swallowed and
|
|
312
|
+
* propagate to the caller.
|
|
313
|
+
*/
|
|
314
|
+
export function getPkeyFromAddress({
|
|
315
|
+
address
|
|
316
|
+
}: {
|
|
317
|
+
address: string
|
|
318
|
+
}): string | null {
|
|
319
|
+
const blob = base58xmr.decode(address);
|
|
320
|
+
|
|
321
|
+
// Layout: varint(prefix) | data | checksum(4)
|
|
322
|
+
const ADDRESS_CHECKSUM_SIZE = 4;
|
|
323
|
+
if (blob.length < ADDRESS_CHECKSUM_SIZE) {
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const body = blob.subarray(0, blob.length - ADDRESS_CHECKSUM_SIZE);
|
|
328
|
+
const checksum = blob.subarray(blob.length - ADDRESS_CHECKSUM_SIZE);
|
|
329
|
+
const expectedChecksum = keccak_256(body).subarray(0, ADDRESS_CHECKSUM_SIZE);
|
|
330
|
+
|
|
331
|
+
for (let i = 0; i < ADDRESS_CHECKSUM_SIZE; i++) {
|
|
332
|
+
if (checksum[i] !== expectedChecksum[i]) {
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Skip the prefix varint; `account_public_address` begins with the
|
|
338
|
+
// 32-byte spend_public_key, followed by the 32-byte view_public_key.
|
|
339
|
+
const [, dataStart] = readVarint(body, 0);
|
|
340
|
+
const data = body.subarray(dataStart);
|
|
341
|
+
|
|
342
|
+
const PUBLIC_KEY_SIZE = 32;
|
|
343
|
+
if (data.length < PUBLIC_KEY_SIZE * 2) {
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return bytesToHex(data.subarray(0, PUBLIC_KEY_SIZE));
|
|
348
|
+
}
|