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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zano_web3",
3
- "version": "9.6.0",
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:web && npm run build:server && npm run build:shared"
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",
@@ -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
  }
@@ -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":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,QAAQ,CAAC;AAWzB,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGnD,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAwBrF,MAAM,YAAY;IACR,SAAS,CAAS;IAClB,SAAS,CAAS;IAClB,eAAe,CAAS;IAEhC,YAAY,MAAyB;QACnC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC;IACtD,CAAC;IAEO,oBAAoB,CAAC,MAAc;QACzC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/D,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC/C,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAEO,cAAc,CAAC,OAAmB,EAAE,SAAiB;QAC3D,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QAC5C,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;aACtD,QAAQ,CAAC,QAAQ,CAAC;aAClB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACrB,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;aACxD,QAAQ,CAAC,QAAQ,CAAC;aAClB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAErB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACtC,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACrC,SAAS,CAAC,MAAM,CAAC,GAAG,aAAa,IAAI,cAAc,EAAE,CAAC,CAAC;QACvD,MAAM,gBAAgB,GAAG,KAAK,CAAC,IAAI;aAChC,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC;aACvC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAErB,OAAO,GAAG,aAAa,IAAI,cAAc,IAAI,gBAAgB,EAAE,CAAC;IAClE,CAAC;IAGO,mBAAmB,CAAC,QAAgB;QAC1C,8CAA8C;QAC9C,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACpC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACpB,MAAM,QAAQ,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;QAErC,kBAAkB;QAClB,MAAM,OAAO,GAAG;YACd,SAAS,EAAE,QAAQ;YACnB,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC;YACnC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,sBAAsB;SAChE,CAAC;QAEF,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;IAC5D,CAAC;IAGD,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,MAAW;QAG3C,MAAM,IAAI,GAAG;YACX,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,CAAC;YACL,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,MAAM;SACf,CAAC;QAEF,MAAM,OAAO,GAAG;YACd,cAAc,EAAE,kBAAkB;YAClC,mBAAmB,EAAE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;SACpE,CAAC;QAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,MAAW;QAE3C,MAAM,IAAI,GAAG;YACX,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,CAAC;YACL,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,MAAM;SACf,CAAC;QAEF,MAAM,OAAO,GAAG;YACd,cAAc,EAAE,kBAAkB;YAClC,mBAAmB,EAAE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;SACnE,CAAC;QAEH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,MAAc;QACrC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,MAAc;QACrC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,KAAK,GAAG,GAAG,CAAC;QAClB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,SAAS,GAAe,EAAE,CAAC;QAC/B,IAAI,YAAY,GAAG,IAAI,CAAC;QAExB,OAAO,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE;oBACzD,KAAK;oBACL,MAAM;iBACP,CAAC,CAAC;gBAEH,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;gBAC3C,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;oBAC1B,YAAY,GAAG,KAAK,CAAC;gBACvB,CAAC;gBACD,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACrC,MAAM,IAAI,KAAK,CAAC;YAClB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,SAAS,CACjB,6BAA6B,EAC7B,oBAAoB,CACrB,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,SAAuB,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,OAAe;QACnC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;QAEzD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,SAAS,CACjB,iBAAiB,OAAO,YAAY,EACpC,iBAAiB,CAClB,CAAC;QACJ,CAAC;QAED,OAAO,KAAiB,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAAe;QAChC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE;gBACxD,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YAEH,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzB,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,SAAS,CACjB,oCAAoC,OAAO,EAAE,EAC7C,kBAAkB,CACnB,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACrB,MAAM,IAAI,SAAS,CACjB,4BAA4B,EAC5B,wBAAwB,CACzB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAAe,EAAE,OAAe,EAAE,MAAc;QACjE,IAAI,YAAoB,CAAC;QACzB,IAAI,SAAkB,CAAC;QAEvB,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;YAC9B,YAAY,GAAG,EAAE,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAClD,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;QACrC,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAC1D,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,SAAS,CAAC,yBAAyB,EAAE,qBAAqB,CAAC,CAAC;QACxE,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;aAC9B,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;aACpC,QAAQ,EAAE,CAAC;QAEd,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE;gBAClD,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;gBACjE,GAAG,EAAE,aAAa;gBAClB,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;aAC1B,CAAC,CAAC;YAEH,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzB,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;YAC9B,CAAC;iBAAM,IACL,QAAQ,CAAC,IAAI,CAAC,KAAK;gBACnB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,KAAK,wCAAwC,EACxE,CAAC;gBACD,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;YAC9D,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,SAAS,CAAC,wBAAwB,EAAE,gBAAgB,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;gBAC/B,MAAM,KAAK,CAAC;YACd,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,SAAS,CAAC,yBAAyB,EAAE,qBAAqB,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,OAAe;QACrC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;YAEzE,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzB,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,SAAS,CACjB,oCAAoC,OAAO,EAAE,EAC7C,mBAAmB,CACpB,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,SAAS,CAAC,uBAAuB,EAAE,mBAAmB,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAC1D,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAwB,CAAC;YAEnE,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAC5C,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,SAAS;gBAChC,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,MAAM;gBAC/B,EAAE,EAAE,KAAK,CAAC,UAAU,CAAC,QAAQ;gBAC7B,MAAM,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;qBAC5B,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;qBACpD,QAAQ,EAAE;gBACb,WAAW,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE;gBAClD,YAAY,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE;gBACpD,KAAK,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE;gBACtC,QAAQ,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE;gBAC5C,UAAU,EAAE,KAAK,CAAC,UAAU;aAC7B,CAAC,CAAC,CAAC;YAEJ,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBAC5B,IAAI,CAAC,CAAC,EAAE,KAAK,aAAa;oBAAE,OAAO,CAAC,CAAC,CAAC;gBACtC,IAAI,CAAC,CAAC,EAAE,KAAK,aAAa;oBAAE,OAAO,CAAC,CAAC;gBACrC,OAAO,CAAC,CAAC;YACX,CAAC,CAAkB,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,SAAS,CAAC,0BAA0B,EAAE,sBAAsB,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,QAAkB;QACrC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;QAEjD,MAAM,KAAK,GAAI,QAAsB,CAAC,KAAK,IAAI,SAAS,CAAC;QACzD,MAAM,IAAI,GAAI,QAAqB,CAAC,IAAI,IAAI,SAAS,CAAC;QAEtD,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAChD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,gBAAgB,GAAqB;YACzC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC7C,GAAG,EAAE,SAAS;SACf,CAAC;QAEF,IAAI,KAAK,EAAE,CAAC;YACV,gBAAgB,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,gBAAgB,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;QAClC,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CACrC,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;QAEF,MAAM,KAAK,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;QAEtD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,oBAAoB,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE;gBACvE,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;YAEH,MAAM,YAAY,GAAG,oBAAoB,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC;YACvE,MAAM,YAAY,GAAG,YAAY,EAAE,OAAO,CAAC;YAE3C,MAAM,YAAY,GAAG,CAAC,CAAC,YAAY,IAAI,YAAY,KAAK,OAAO,CAAC;YAEhE,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,8BAA8B,CAAC,EACnC,eAAe,EACf,aAAa,EACb,SAAS,EACT,OAAO,EACP,iBAAiB,GAOlB;QACC,IAAI,eAAe,KAAK,aAAa,EAAE,CAAC;YACtC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,IAAI,GAAG,kBAAkB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAE7C,MAAM,cAAc,GAAG,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,iBAAiB,CAAC;QAEnE,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC;YACjD,OAAO,EAAE,eAAe;YACxB,SAAS;YACT,OAAO;YACP,IAAI;SACL,CAAC,CAAC;QAEH,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,mBAAmB,GAAG,4BAA4B,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;QACvF,MAAM,WAAW,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;QAE3F,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,OAAO,IAAI,WAAW,KAAK,IAAI,IAAI,WAAW,CAAC,eAAe,IAAI,WAAW,CAAC,oBAAoB,CAAC;QAElJ,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,EAAE,cAAc,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC;QAE9C,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAExD,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAoB;QAC/B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,0BAA0B,EAAE;YAC7D,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,IAAI,KAAK;YACtD,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,IAAI,KAAK;YACxD,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,mBAAmB;YAC1C,qBAAqB,EAAE,MAAM,CAAC,qBAAqB,IAAI,IAAI;SAC5D,CAAC,CAAC;QAEH,OAAO,GAAG,CAAC,IAAI,CAAC,MAAgB,CAAC;IACnC,CAAC;IACD,KAAK,CAAC,eAAe,CAAC,KAAa;QACjC,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE;gBACzD,KAAK;aACR,CAAC,CAAC;YACH,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACvB,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAsB,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACJ,MAAM,IAAI,SAAS,CACf,wBAAwB,KAAK,EAAE,EAC/B,mBAAmB,CACtB,CAAC;YACN,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACL,MAAM,IAAI,SAAS,CAAC,uBAAuB,EAAE,mBAAmB,CAAC,CAAC;QACtE,CAAC;IACL,CAAC;CAEA;AAED,eAAe,YAAY,CAAC"}
@@ -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,
@@ -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;
@@ -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
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
@@ -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
+ }