@midnight-ntwrk/wallet-sdk-address-format 3.0.0-beta.7 → 3.0.0-beta.9

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/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { DustPublicKey, EncryptionSecretKey, UserAddress } from '@midnight-ntwrk/ledger-v6';
2
+ export declare const mainnet: unique symbol;
3
+ export type NetworkId = string | typeof mainnet;
2
4
  export type FormatContext = {
3
- networkId: string | null;
5
+ networkId: NetworkId;
4
6
  };
5
7
  export type Field = {
6
8
  bytes: number;
@@ -11,32 +13,43 @@ export declare const ScaleBigInt: {
11
13
  encode: (data: bigint) => Buffer;
12
14
  decode: (repr: Uint8Array) => bigint;
13
15
  };
16
+ export declare const Bech32mSymbol: unique symbol;
17
+ export type HasCodec<T> = {
18
+ [Bech32mSymbol]: Bech32mCodec<T>;
19
+ };
20
+ export type CodecTarget<T> = T extends HasCodec<infer U> ? U : never;
14
21
  export declare class MidnightBech32m {
15
22
  static readonly prefix = "mn";
23
+ static encode<T extends HasCodec<T>>(networkId: NetworkId, item: T): MidnightBech32m;
16
24
  static validateSegment(segmentName: string, segment: string): void;
17
25
  static parse(bech32string: string): MidnightBech32m;
18
26
  readonly type: string;
19
- readonly network: string | null;
27
+ readonly network: NetworkId;
20
28
  readonly data: Buffer;
21
- constructor(type: string, network: string | null, data: Buffer);
29
+ constructor(type: string, network: NetworkId, data: Buffer);
30
+ decode<TClass extends HasCodec<any>>(tclass: TClass, networkId: NetworkId): CodecTarget<TClass>;
22
31
  asString(): string;
32
+ toString(): string;
23
33
  }
24
34
  export declare class Bech32mCodec<T> {
25
35
  readonly type: string;
26
36
  readonly dataToBytes: (data: T) => Buffer;
27
37
  readonly dataFromBytes: (bytes: Buffer) => T;
28
38
  constructor(type: string, dataToBytes: (data: T) => Buffer, dataFromBytes: (bytes: Buffer) => T);
29
- encode(networkId: string | null, data: T): MidnightBech32m;
30
- decode(networkId: string | null, repr: MidnightBech32m): T;
31
- static createContext(networkId: string | null): FormatContext;
39
+ encode(networkId: NetworkId, data: T): MidnightBech32m;
40
+ decode(networkId: NetworkId, repr: MidnightBech32m): T;
41
+ static createContext(networkId: NetworkId): FormatContext;
32
42
  }
33
43
  export declare class ShieldedAddress {
34
44
  static readonly codec: Bech32mCodec<ShieldedAddress>;
45
+ static readonly [Bech32mSymbol]: Bech32mCodec<ShieldedAddress>;
46
+ readonly [Bech32mSymbol]: Bech32mCodec<ShieldedAddress>;
35
47
  readonly coinPublicKey: ShieldedCoinPublicKey;
36
48
  readonly encryptionPublicKey: ShieldedEncryptionPublicKey;
37
49
  constructor(coinPublicKey: ShieldedCoinPublicKey, encryptionPublicKey: ShieldedEncryptionPublicKey);
38
50
  coinPublicKeyString(): string;
39
51
  encryptionPublicKeyString(): string;
52
+ equals(other: ShieldedAddress): boolean;
40
53
  }
41
54
  export declare class ShieldedEncryptionSecretKey {
42
55
  static readonly codec: Bech32mCodec<ShieldedEncryptionSecretKey>;
@@ -67,13 +80,21 @@ export declare class UnshieldedAddress {
67
80
  readonly data: Buffer;
68
81
  static readonly keyLength = 32;
69
82
  static readonly codec: Bech32mCodec<UnshieldedAddress>;
83
+ static readonly [Bech32mSymbol]: Bech32mCodec<UnshieldedAddress>;
84
+ readonly [Bech32mSymbol]: Bech32mCodec<UnshieldedAddress>;
70
85
  constructor(data: Buffer);
71
86
  get hexString(): UserAddress;
87
+ equals(other: string): boolean;
88
+ equals(other: UnshieldedAddress): boolean;
72
89
  }
73
90
  export declare class DustAddress {
74
91
  readonly data: bigint;
75
92
  static readonly codec: Bech32mCodec<DustAddress>;
93
+ static readonly [Bech32mSymbol]: Bech32mCodec<DustAddress>;
94
+ readonly [Bech32mSymbol]: Bech32mCodec<DustAddress>;
76
95
  static readonly encodePublicKey: (networkId: string, publicKey: DustPublicKey) => string;
77
96
  constructor(data: bigint);
78
97
  serialize(): Buffer;
98
+ equals(other: bigint): boolean;
99
+ equals(other: DustAddress): boolean;
79
100
  }
package/dist/index.js CHANGED
@@ -1,6 +1,24 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 Midnight Foundation
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // You may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
1
13
  import { EncryptionSecretKey } from '@midnight-ntwrk/ledger-v6';
2
14
  import { bech32m } from '@scure/base';
3
15
  import * as subsquidScale from '@subsquid/scale-codec';
16
+ export const mainnet = Symbol('Mainnet');
17
+ const NetworkId = {
18
+ toString: (networkId) => {
19
+ return networkId === mainnet ? 'mainnet' : networkId;
20
+ },
21
+ };
4
22
  export const BLSScalar = {
5
23
  bytes: 32,
6
24
  modulus: BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001'),
@@ -18,8 +36,12 @@ export const ScaleBigInt = {
18
36
  return BigInt(res);
19
37
  },
20
38
  };
39
+ export const Bech32mSymbol = Symbol('MidnightBech32m');
21
40
  export class MidnightBech32m {
22
41
  static prefix = 'mn';
42
+ static encode(networkId, item) {
43
+ return item[Bech32mSymbol].encode(networkId, item);
44
+ }
23
45
  static validateSegment(segmentName, segment) {
24
46
  const result = /^[A-Za-z1-9-]+$/.test(segment);
25
47
  if (!result) {
@@ -28,12 +50,12 @@ export class MidnightBech32m {
28
50
  }
29
51
  static parse(bech32string) {
30
52
  const bech32parsed = bech32m.decodeToBytes(bech32string);
31
- const [prefix, type, network = null] = bech32parsed.prefix.split('_');
53
+ const [prefix, type, network = mainnet] = bech32parsed.prefix.split('_');
32
54
  if (prefix != MidnightBech32m.prefix) {
33
55
  throw new Error(`Expected prefix ${MidnightBech32m.prefix}`);
34
56
  }
35
57
  MidnightBech32m.validateSegment('type', type);
36
- if (network != null) {
58
+ if (network != mainnet) {
37
59
  MidnightBech32m.validateSegment('network', network);
38
60
  }
39
61
  return new MidnightBech32m(type, network, Buffer.from(bech32parsed.bytes));
@@ -46,14 +68,22 @@ export class MidnightBech32m {
46
68
  this.network = network;
47
69
  this.type = type;
48
70
  MidnightBech32m.validateSegment('type', type);
49
- if (network != null) {
71
+ if (network != mainnet) {
50
72
  MidnightBech32m.validateSegment('network', network);
51
73
  }
52
74
  }
75
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
+ decode(tclass, networkId) {
77
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
78
+ return tclass[Bech32mSymbol].decode(networkId, this);
79
+ }
53
80
  asString() {
54
- const networkSegment = this.network == null ? '' : `_${this.network}`;
81
+ const networkSegment = this.network == mainnet ? '' : `_${this.network}`;
55
82
  return bech32m.encode(`${MidnightBech32m.prefix}_${this.type}${networkSegment}`, bech32m.toWords(this.data), false);
56
83
  }
84
+ toString() {
85
+ return this.asString();
86
+ }
57
87
  }
58
88
  export class Bech32mCodec {
59
89
  type;
@@ -74,15 +104,17 @@ export class Bech32mCodec {
74
104
  throw new Error(`Expected type ${this.type}, got ${repr.type}`);
75
105
  }
76
106
  if (context.networkId != repr.network) {
77
- throw new Error(`Expected ${context.networkId ?? 'mainnet'} address, got ${repr.network ?? 'mainnet'} one`);
107
+ throw new Error(`Expected ${NetworkId.toString(context.networkId)} address, got ${NetworkId.toString(repr.network)} one`);
78
108
  }
79
109
  return this.dataFromBytes(repr.data);
80
110
  }
81
111
  static createContext(networkId) {
82
- if (networkId === null) {
83
- return { networkId: null };
112
+ if (networkId === 'mainnet') {
113
+ return { networkId: mainnet };
114
+ }
115
+ else {
116
+ return { networkId };
84
117
  }
85
- return { networkId };
86
118
  }
87
119
  }
88
120
  export class ShieldedAddress {
@@ -91,6 +123,8 @@ export class ShieldedAddress {
91
123
  const encryptionPublicKey = new ShieldedEncryptionPublicKey(bytes.subarray(ShieldedCoinPublicKey.keyLength));
92
124
  return new ShieldedAddress(coinPublicKey, encryptionPublicKey);
93
125
  });
126
+ static [Bech32mSymbol] = ShieldedAddress.codec;
127
+ [Bech32mSymbol] = ShieldedAddress.codec;
94
128
  coinPublicKey;
95
129
  encryptionPublicKey;
96
130
  constructor(coinPublicKey, encryptionPublicKey) {
@@ -103,6 +137,9 @@ export class ShieldedAddress {
103
137
  encryptionPublicKeyString() {
104
138
  return this.encryptionPublicKey.data.toString('hex');
105
139
  }
140
+ equals(other) {
141
+ return this.coinPublicKey.equals(other.coinPublicKey) && this.encryptionPublicKey.equals(other.encryptionPublicKey);
142
+ }
106
143
  }
107
144
  export class ShieldedEncryptionSecretKey {
108
145
  static codec = new Bech32mCodec('shield-esk', (esk) => Buffer.from(esk.zswap.yesIKnowTheSecurityImplicationsOfThis_serialize()), (repr) => new ShieldedEncryptionSecretKey(EncryptionSecretKey.deserialize(repr)));
@@ -156,6 +193,8 @@ export class UnshieldedAddress {
156
193
  data;
157
194
  static keyLength = 32;
158
195
  static codec = new Bech32mCodec('addr', (addr) => addr.data, (repr) => new UnshieldedAddress(repr));
196
+ static [Bech32mSymbol] = UnshieldedAddress.codec;
197
+ [Bech32mSymbol] = UnshieldedAddress.codec;
159
198
  constructor(data) {
160
199
  if (data.length != UnshieldedAddress.keyLength) {
161
200
  throw new Error('Unshielded address needs to be 32 bytes long');
@@ -165,10 +204,16 @@ export class UnshieldedAddress {
165
204
  get hexString() {
166
205
  return this.data.toString('hex');
167
206
  }
207
+ equals(other) {
208
+ const otherAddress = typeof other === 'string' ? new UnshieldedAddress(Buffer.from(other, 'hex')) : other;
209
+ return otherAddress.data.equals(this.data);
210
+ }
168
211
  }
169
212
  export class DustAddress {
170
213
  data;
171
214
  static codec = new Bech32mCodec('dust', (daddr) => daddr.serialize(), (repr) => new DustAddress(ScaleBigInt.decode(repr)));
215
+ static [Bech32mSymbol] = DustAddress.codec;
216
+ [Bech32mSymbol] = DustAddress.codec;
172
217
  static encodePublicKey = (networkId, publicKey) => {
173
218
  return DustAddress.codec.encode(networkId, new DustAddress(publicKey)).asString();
174
219
  };
@@ -181,4 +226,8 @@ export class DustAddress {
181
226
  serialize() {
182
227
  return ScaleBigInt.encode(this.data);
183
228
  }
229
+ equals(other) {
230
+ const otherAddress = typeof other === 'bigint' ? other : other.data;
231
+ return otherAddress === this.data;
232
+ }
184
233
  }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@midnight-ntwrk/wallet-sdk-address-format",
3
- "version": "3.0.0-beta.7",
3
+ "version": "3.0.0-beta.9",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
- "author": "IOHK",
8
+ "author": "Midnight Foundation",
9
9
  "license": "Apache-2.0",
10
10
  "publishConfig": {
11
11
  "registry": "https://npm.pkg.github.com/"
@@ -24,7 +24,7 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
- "@midnight-ntwrk/ledger-v6": "6.1.0-alpha.5",
27
+ "@midnight-ntwrk/ledger-v6": "6.1.0-alpha.6",
28
28
  "@scure/base": "^1.2.6",
29
29
  "@subsquid/scale-codec": "^4.0.1"
30
30
  },
@@ -41,6 +41,7 @@
41
41
  "test": "vitest run",
42
42
  "lint": "eslint --max-warnings 0",
43
43
  "format": "prettier --write \"**/*.{ts,js,json,yaml,yml}\"",
44
+ "format:check": "prettier --check \"**/*.{ts,js,json,yaml,yml}\"",
44
45
  "dist": "tsc -b ./tsconfig.build.json",
45
46
  "dist:publish": "tsc -b ./tsconfig.publish.json",
46
47
  "clean": "rimraf --glob dist 'tsconfig.*.tsbuildinfo' && date +%s > .clean-timestamp",