@mysten/sui 1.17.0 → 1.18.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.
Files changed (97) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/client/types/generated.d.ts +76 -27
  3. package/dist/cjs/client/types/generated.js.map +1 -1
  4. package/dist/cjs/client/types/params.d.ts +5 -1
  5. package/dist/cjs/client/types/params.js.map +1 -1
  6. package/dist/cjs/cryptography/publickey.d.ts +4 -0
  7. package/dist/cjs/cryptography/publickey.js +6 -0
  8. package/dist/cjs/cryptography/publickey.js.map +2 -2
  9. package/dist/cjs/graphql/generated/latest/tada-env.d.js +17 -0
  10. package/dist/cjs/graphql/generated/latest/tada-env.d.js.map +7 -0
  11. package/dist/cjs/graphql/generated/latest/tsconfig.tada.js +12 -0
  12. package/dist/cjs/graphql/generated/latest/tsconfig.tada.js.map +7 -0
  13. package/dist/cjs/graphql/schemas/latest/index.d.ts +9831 -0
  14. package/dist/cjs/graphql/schemas/latest/index.js +31 -0
  15. package/dist/cjs/graphql/schemas/latest/index.js.map +7 -0
  16. package/dist/cjs/keypairs/ed25519/ed25519-hd-key.d.ts +0 -5
  17. package/dist/cjs/keypairs/ed25519/ed25519-hd-key.js +1 -25
  18. package/dist/cjs/keypairs/ed25519/ed25519-hd-key.js.map +3 -3
  19. package/dist/cjs/keypairs/ed25519/keypair.js +22 -18
  20. package/dist/cjs/keypairs/ed25519/keypair.js.map +3 -3
  21. package/dist/cjs/keypairs/ed25519/publickey.js +2 -12
  22. package/dist/cjs/keypairs/ed25519/publickey.js.map +3 -3
  23. package/dist/cjs/transactions/ObjectCache.d.ts +2 -1
  24. package/dist/cjs/transactions/ObjectCache.js +8 -3
  25. package/dist/cjs/transactions/ObjectCache.js.map +2 -2
  26. package/dist/cjs/transactions/Transaction.d.ts +5 -1
  27. package/dist/cjs/transactions/Transaction.js +8 -8
  28. package/dist/cjs/transactions/Transaction.js.map +2 -2
  29. package/dist/cjs/transactions/executor/serial.d.ts +2 -2
  30. package/dist/cjs/transactions/executor/serial.js +3 -5
  31. package/dist/cjs/transactions/executor/serial.js.map +3 -3
  32. package/dist/cjs/verify/verify.d.ts +5 -1
  33. package/dist/cjs/verify/verify.js +10 -1
  34. package/dist/cjs/verify/verify.js.map +2 -2
  35. package/dist/cjs/version.d.ts +1 -1
  36. package/dist/cjs/version.js +1 -1
  37. package/dist/cjs/version.js.map +1 -1
  38. package/dist/cjs/zklogin/publickey.d.ts +4 -0
  39. package/dist/cjs/zklogin/publickey.js +22 -10
  40. package/dist/cjs/zklogin/publickey.js.map +2 -2
  41. package/dist/esm/client/types/generated.d.ts +76 -27
  42. package/dist/esm/client/types/params.d.ts +5 -1
  43. package/dist/esm/cryptography/publickey.d.ts +4 -0
  44. package/dist/esm/cryptography/publickey.js +6 -0
  45. package/dist/esm/cryptography/publickey.js.map +2 -2
  46. package/dist/esm/graphql/generated/latest/tada-env.d.js +1 -0
  47. package/dist/esm/graphql/generated/latest/tada-env.d.js.map +7 -0
  48. package/dist/esm/graphql/generated/latest/tsconfig.tada.js +17 -0
  49. package/dist/esm/graphql/generated/latest/tsconfig.tada.js.map +7 -0
  50. package/dist/esm/graphql/schemas/latest/index.d.ts +9831 -0
  51. package/dist/esm/graphql/schemas/latest/index.js +10 -0
  52. package/dist/esm/graphql/schemas/latest/index.js.map +7 -0
  53. package/dist/esm/keypairs/ed25519/ed25519-hd-key.d.ts +0 -5
  54. package/dist/esm/keypairs/ed25519/ed25519-hd-key.js +1 -15
  55. package/dist/esm/keypairs/ed25519/ed25519-hd-key.js.map +2 -2
  56. package/dist/esm/keypairs/ed25519/keypair.js +22 -8
  57. package/dist/esm/keypairs/ed25519/keypair.js.map +2 -2
  58. package/dist/esm/keypairs/ed25519/publickey.js +2 -2
  59. package/dist/esm/keypairs/ed25519/publickey.js.map +2 -2
  60. package/dist/esm/transactions/ObjectCache.d.ts +2 -1
  61. package/dist/esm/transactions/ObjectCache.js +8 -3
  62. package/dist/esm/transactions/ObjectCache.js.map +2 -2
  63. package/dist/esm/transactions/Transaction.d.ts +5 -1
  64. package/dist/esm/transactions/Transaction.js +8 -8
  65. package/dist/esm/transactions/Transaction.js.map +2 -2
  66. package/dist/esm/transactions/executor/serial.d.ts +2 -2
  67. package/dist/esm/transactions/executor/serial.js +3 -5
  68. package/dist/esm/transactions/executor/serial.js.map +2 -2
  69. package/dist/esm/verify/verify.d.ts +5 -1
  70. package/dist/esm/verify/verify.js +10 -1
  71. package/dist/esm/verify/verify.js.map +2 -2
  72. package/dist/esm/version.d.ts +1 -1
  73. package/dist/esm/version.js +1 -1
  74. package/dist/esm/version.js.map +1 -1
  75. package/dist/esm/zklogin/publickey.d.ts +4 -0
  76. package/dist/esm/zklogin/publickey.js +21 -9
  77. package/dist/esm/zklogin/publickey.js.map +2 -2
  78. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  79. package/dist/tsconfig.tsbuildinfo +1 -1
  80. package/graphql/schemas/latest/package.json +6 -0
  81. package/package.json +5 -2
  82. package/src/client/types/generated.ts +110 -59
  83. package/src/client/types/params.ts +5 -1
  84. package/src/cryptography/publickey.ts +7 -0
  85. package/src/graphql/generated/latest/schema.graphql +4808 -0
  86. package/src/graphql/generated/latest/tada-env.d.ts +220 -0
  87. package/src/graphql/generated/latest/tsconfig.tada.json +11 -0
  88. package/src/graphql/schemas/latest/index.ts +17 -0
  89. package/src/keypairs/ed25519/ed25519-hd-key.ts +4 -14
  90. package/src/keypairs/ed25519/keypair.ts +23 -8
  91. package/src/keypairs/ed25519/publickey.ts +2 -2
  92. package/src/transactions/ObjectCache.ts +5 -1
  93. package/src/transactions/Transaction.ts +18 -14
  94. package/src/transactions/executor/serial.ts +3 -5
  95. package/src/verify/verify.ts +21 -3
  96. package/src/version.ts +1 -1
  97. package/src/zklogin/publickey.ts +19 -8
@@ -7,7 +7,6 @@
7
7
  import { fromHex } from '@mysten/bcs';
8
8
  import { hmac } from '@noble/hashes/hmac';
9
9
  import { sha512 } from '@noble/hashes/sha512';
10
- import nacl from 'tweetnacl';
11
10
 
12
11
  type Hex = string;
13
12
  type Path = string;
@@ -20,11 +19,11 @@ type Keys = {
20
19
  const ED25519_CURVE = 'ed25519 seed';
21
20
  const HARDENED_OFFSET = 0x80000000;
22
21
 
23
- export const pathRegex = new RegExp("^m(\\/[0-9]+')+$");
22
+ const pathRegex = new RegExp("^m(\\/[0-9]+')+$");
24
23
 
25
- export const replaceDerive = (val: string): string => val.replace("'", '');
24
+ const replaceDerive = (val: string): string => val.replace("'", '');
26
25
 
27
- export const getMasterKeyFromSeed = (seed: Hex): Keys => {
26
+ const getMasterKeyFromSeed = (seed: Hex): Keys => {
28
27
  const h = hmac.create(sha512, ED25519_CURVE);
29
28
  const I = h.update(fromHex(seed)).digest();
30
29
  const IL = I.slice(0, 32);
@@ -54,16 +53,7 @@ const CKDPriv = ({ key, chainCode }: Keys, index: number): Keys => {
54
53
  };
55
54
  };
56
55
 
57
- export const getPublicKey = (privateKey: Uint8Array, withZeroByte = true): Uint8Array => {
58
- const keyPair = nacl.sign.keyPair.fromSeed(privateKey);
59
- const signPk = keyPair.secretKey.subarray(32);
60
- const newArr = new Uint8Array(signPk.length + 1);
61
- newArr.set([0]);
62
- newArr.set(signPk, 1);
63
- return withZeroByte ? newArr : signPk;
64
- };
65
-
66
- export const isValidPath = (path: string): boolean => {
56
+ const isValidPath = (path: string): boolean => {
67
57
  if (!pathRegex.test(path)) {
68
58
  return false;
69
59
  }
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Mysten Labs, Inc.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import nacl from 'tweetnacl';
4
+ import { ed25519 } from '@noble/curves/ed25519';
5
5
 
6
6
  import {
7
7
  decodeSuiPrivateKey,
@@ -41,9 +41,16 @@ export class Ed25519Keypair extends Keypair {
41
41
  constructor(keypair?: Ed25519KeypairData) {
42
42
  super();
43
43
  if (keypair) {
44
- this.keypair = keypair;
44
+ this.keypair = {
45
+ publicKey: keypair.publicKey,
46
+ secretKey: keypair.secretKey.slice(0, 32),
47
+ };
45
48
  } else {
46
- this.keypair = nacl.sign.keyPair();
49
+ const privateKey = ed25519.utils.randomPrivateKey();
50
+ this.keypair = {
51
+ publicKey: ed25519.getPublicKey(privateKey),
52
+ secretKey: privateKey,
53
+ };
47
54
  }
48
55
  }
49
56
 
@@ -58,7 +65,11 @@ export class Ed25519Keypair extends Keypair {
58
65
  * Generate a new random Ed25519 keypair
59
66
  */
60
67
  static generate(): Ed25519Keypair {
61
- return new Ed25519Keypair(nacl.sign.keyPair());
68
+ const secretKey = ed25519.utils.randomPrivateKey();
69
+ return new Ed25519Keypair({
70
+ publicKey: ed25519.getPublicKey(secretKey),
71
+ secretKey,
72
+ });
62
73
  }
63
74
 
64
75
  /**
@@ -91,12 +102,16 @@ export class Ed25519Keypair extends Keypair {
91
102
  `Wrong secretKey size. Expected ${PRIVATE_KEY_SIZE} bytes, got ${secretKeyLength}.`,
92
103
  );
93
104
  }
94
- const keypair = nacl.sign.keyPair.fromSeed(secretKey);
105
+ const keypair = {
106
+ publicKey: ed25519.getPublicKey(secretKey),
107
+ secretKey,
108
+ };
109
+
95
110
  if (!options || !options.skipValidation) {
96
111
  const encoder = new TextEncoder();
97
112
  const signData = encoder.encode('sui validation');
98
- const signature = nacl.sign.detached(signData, keypair.secretKey);
99
- if (!nacl.sign.detached.verify(signData, signature, keypair.publicKey)) {
113
+ const signature = ed25519.sign(signData, secretKey);
114
+ if (!ed25519.verify(signature, signData, keypair.publicKey)) {
100
115
  throw new Error('provided secretKey is invalid');
101
116
  }
102
117
  }
@@ -124,7 +139,7 @@ export class Ed25519Keypair extends Keypair {
124
139
  * Return the signature for the provided data using Ed25519.
125
140
  */
126
141
  async sign(data: Uint8Array) {
127
- return nacl.sign.detached(data, this.keypair.secretKey);
142
+ return ed25519.sign(data, this.keypair.secretKey);
128
143
  }
129
144
 
130
145
  /**
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { fromBase64 } from '@mysten/bcs';
5
- import nacl from 'tweetnacl';
5
+ import { ed25519 } from '@noble/curves/ed25519';
6
6
 
7
7
  import type { PublicKeyInitData } from '../../cryptography/publickey.js';
8
8
  import { bytesEqual, PublicKey } from '../../cryptography/publickey.js';
@@ -81,6 +81,6 @@ export class Ed25519PublicKey extends PublicKey {
81
81
  bytes = signature;
82
82
  }
83
83
 
84
- return nacl.sign.detached.verify(message, bytes, this.toRawBytes());
84
+ return ed25519.verify(bytes, message, this.toRawBytes());
85
85
  }
86
86
  }
@@ -148,13 +148,16 @@ export class InMemoryCache extends AsyncCache {
148
148
 
149
149
  export interface ObjectCacheOptions {
150
150
  cache?: AsyncCache;
151
+ onEffects?: (effects: typeof bcs.TransactionEffects.$inferType) => Promise<void>;
151
152
  }
152
153
 
153
154
  export class ObjectCache {
154
155
  #cache: AsyncCache;
156
+ #onEffects?: (effects: typeof bcs.TransactionEffects.$inferType) => Promise<void>;
155
157
 
156
- constructor({ cache = new InMemoryCache() }: ObjectCacheOptions) {
158
+ constructor({ cache = new InMemoryCache(), onEffects }: ObjectCacheOptions) {
157
159
  this.#cache = cache;
160
+ this.#onEffects = onEffects;
158
161
  }
159
162
 
160
163
  asPlugin(): TransactionPlugin {
@@ -291,6 +294,7 @@ export class ObjectCache {
291
294
  await Promise.all([
292
295
  this.#cache.addObjects(addedObjects),
293
296
  this.#cache.deleteObjects(deletedIds),
297
+ this.#onEffects?.(effects),
294
298
  ]);
295
299
  }
296
300
  }
@@ -34,7 +34,7 @@ export type TransactionObjectArgument =
34
34
  export type TransactionResult = Extract<Argument, { Result: unknown }> &
35
35
  Extract<Argument, { NestedResult: unknown }>[];
36
36
 
37
- function createTransactionResult(index: number) {
37
+ function createTransactionResult(index: number, length = Infinity): TransactionResult {
38
38
  const baseResult = { $kind: 'Result' as const, Result: index };
39
39
 
40
40
  const nestedResults: {
@@ -71,7 +71,7 @@ function createTransactionResult(index: number) {
71
71
  if (property === Symbol.iterator) {
72
72
  return function* () {
73
73
  let i = 0;
74
- while (true) {
74
+ while (i < length) {
75
75
  yield nestedResultFor(i);
76
76
  i++;
77
77
  }
@@ -410,20 +410,24 @@ export class Transaction {
410
410
 
411
411
  // Method shorthands:
412
412
 
413
- splitCoins(
414
- coin: TransactionObjectArgument | string,
415
- amounts: (TransactionArgument | SerializedBcs<any> | number | string | bigint)[],
416
- ) {
417
- return this.add(
418
- Commands.SplitCoins(
419
- typeof coin === 'string' ? this.object(coin) : this.#resolveArgument(coin),
420
- amounts.map((amount) =>
421
- typeof amount === 'number' || typeof amount === 'bigint' || typeof amount === 'string'
422
- ? this.pure.u64(amount)
423
- : this.#normalizeTransactionArgument(amount),
424
- ),
413
+ splitCoins<
414
+ const Amounts extends (TransactionArgument | SerializedBcs<any> | number | string | bigint)[],
415
+ >(coin: TransactionObjectArgument | string, amounts: Amounts) {
416
+ const command = Commands.SplitCoins(
417
+ typeof coin === 'string' ? this.object(coin) : this.#resolveArgument(coin),
418
+ amounts.map((amount) =>
419
+ typeof amount === 'number' || typeof amount === 'bigint' || typeof amount === 'string'
420
+ ? this.pure.u64(amount)
421
+ : this.#normalizeTransactionArgument(amount),
425
422
  ),
426
423
  );
424
+ const index = this.#data.commands.push(command);
425
+ return createTransactionResult(index - 1, amounts.length) as Extract<
426
+ Argument,
427
+ { Result: unknown }
428
+ > & {
429
+ [K in keyof Amounts]: Extract<Argument, { NestedResult: unknown }>;
430
+ };
427
431
  }
428
432
  mergeCoins(
429
433
  destination: TransactionObjectArgument | string,
@@ -3,7 +3,7 @@
3
3
 
4
4
  import { toBase64 } from '@mysten/bcs';
5
5
 
6
- import { bcs } from '../../bcs/index.js';
6
+ import type { bcs } from '../../bcs/index.js';
7
7
  import type { SuiClient, SuiTransactionBlockResponseOptions } from '../../client/index.js';
8
8
  import type { Signer } from '../../cryptography/keypair.js';
9
9
  import type { ObjectCacheOptions } from '../ObjectCache.js';
@@ -32,11 +32,12 @@ export class SerialTransactionExecutor {
32
32
  this.#cache = new CachingTransactionExecutor({
33
33
  client: options.client,
34
34
  cache: options.cache,
35
+ onEffects: (effects) => this.#cacheGasCoin(effects),
35
36
  });
36
37
  }
37
38
 
38
39
  async applyEffects(effects: typeof bcs.TransactionEffects.$inferType) {
39
- return Promise.all([this.#cacheGasCoin(effects), this.#cache.cache.applyEffects(effects)]);
40
+ return this.#cache.applyEffects(effects);
40
41
  }
41
42
 
42
43
  #cacheGasCoin = async (effects: typeof bcs.TransactionEffects.$inferType) => {
@@ -104,9 +105,6 @@ export class SerialTransactionExecutor {
104
105
  });
105
106
 
106
107
  const effectsBytes = Uint8Array.from(results.rawEffects!);
107
- const effects = bcs.TransactionEffects.parse(effectsBytes);
108
- await this.applyEffects(effects);
109
-
110
108
  return {
111
109
  digest: results.digest,
112
110
  effects: toBase64(effectsBytes),
@@ -14,20 +14,30 @@ import { Secp256r1PublicKey } from '../keypairs/secp256r1/publickey.js';
14
14
  import { MultiSigPublicKey } from '../multisig/publickey.js';
15
15
  import { ZkLoginPublicIdentifier } from '../zklogin/publickey.js';
16
16
 
17
- export async function verifySignature(bytes: Uint8Array, signature: string): Promise<PublicKey> {
17
+ export async function verifySignature(
18
+ bytes: Uint8Array,
19
+ signature: string,
20
+ options?: {
21
+ address?: string;
22
+ },
23
+ ): Promise<PublicKey> {
18
24
  const parsedSignature = parseSignature(signature);
19
25
 
20
26
  if (!(await parsedSignature.publicKey.verify(bytes, parsedSignature.serializedSignature))) {
21
27
  throw new Error(`Signature is not valid for the provided data`);
22
28
  }
23
29
 
30
+ if (options?.address && !parsedSignature.publicKey.verifyAddress(options.address)) {
31
+ throw new Error(`Signature is not valid for the provided address`);
32
+ }
33
+
24
34
  return parsedSignature.publicKey;
25
35
  }
26
36
 
27
37
  export async function verifyPersonalMessageSignature(
28
38
  message: Uint8Array,
29
39
  signature: string,
30
- options: { client?: SuiGraphQLClient } = {},
40
+ options: { client?: SuiGraphQLClient; address?: string } = {},
31
41
  ): Promise<PublicKey> {
32
42
  const parsedSignature = parseSignature(signature, options);
33
43
 
@@ -40,13 +50,17 @@ export async function verifyPersonalMessageSignature(
40
50
  throw new Error(`Signature is not valid for the provided message`);
41
51
  }
42
52
 
53
+ if (options?.address && !parsedSignature.publicKey.verifyAddress(options.address)) {
54
+ throw new Error(`Signature is not valid for the provided address`);
55
+ }
56
+
43
57
  return parsedSignature.publicKey;
44
58
  }
45
59
 
46
60
  export async function verifyTransactionSignature(
47
61
  transaction: Uint8Array,
48
62
  signature: string,
49
- options: { client?: SuiGraphQLClient } = {},
63
+ options: { client?: SuiGraphQLClient; address?: string } = {},
50
64
  ): Promise<PublicKey> {
51
65
  const parsedSignature = parseSignature(signature, options);
52
66
 
@@ -59,6 +73,10 @@ export async function verifyTransactionSignature(
59
73
  throw new Error(`Signature is not valid for the provided Transaction`);
60
74
  }
61
75
 
76
+ if (options?.address && !parsedSignature.publicKey.verifyAddress(options.address)) {
77
+ throw new Error(`Signature is not valid for the provided address`);
78
+ }
79
+
62
80
  return parsedSignature.publicKey;
63
81
  }
64
82
 
package/src/version.ts CHANGED
@@ -3,5 +3,5 @@
3
3
 
4
4
  // This file is generated by genversion.mjs. Do not edit it directly.
5
5
 
6
- export const PACKAGE_VERSION = '1.17.0';
6
+ export const PACKAGE_VERSION = '1.18.0';
7
7
  export const TARGETED_RPC_VERSION = '1.40.0';
@@ -9,7 +9,7 @@ import { PublicKey } from '../cryptography/publickey.js';
9
9
  import type { PublicKeyInitData } from '../cryptography/publickey.js';
10
10
  import { SIGNATURE_SCHEME_TO_FLAG } from '../cryptography/signature-scheme.js';
11
11
  import { SuiGraphQLClient } from '../graphql/client.js';
12
- import { graphql } from '../graphql/schemas/2024.4/index.js';
12
+ import { graphql } from '../graphql/schemas/latest/index.js';
13
13
  import { normalizeSuiAddress, SUI_ADDRESS_LENGTH } from '../utils/sui-types.js';
14
14
  import { extractClaimValue } from './jwt-utils.js';
15
15
  import { parseZkLoginSignature } from './signature.js';
@@ -55,18 +55,22 @@ export class ZkLoginPublicIdentifier extends PublicKey {
55
55
 
56
56
  override toSuiAddress(): string {
57
57
  if (this.#legacyAddress) {
58
- const legacyBytes = normalizeZkLoginPublicKeyBytes(this.#data, true);
59
- const addressBytes = new Uint8Array(legacyBytes.length + 1);
60
- addressBytes[0] = this.flag();
61
- addressBytes.set(legacyBytes, 1);
62
- return normalizeSuiAddress(
63
- bytesToHex(blake2b(addressBytes, { dkLen: 32 })).slice(0, SUI_ADDRESS_LENGTH * 2),
64
- );
58
+ return this.#toLegacyAddress();
65
59
  }
66
60
 
67
61
  return super.toSuiAddress();
68
62
  }
69
63
 
64
+ #toLegacyAddress() {
65
+ const legacyBytes = normalizeZkLoginPublicKeyBytes(this.#data, true);
66
+ const addressBytes = new Uint8Array(legacyBytes.length + 1);
67
+ addressBytes[0] = this.flag();
68
+ addressBytes.set(legacyBytes, 1);
69
+ return normalizeSuiAddress(
70
+ bytesToHex(blake2b(addressBytes, { dkLen: 32 })).slice(0, SUI_ADDRESS_LENGTH * 2),
71
+ );
72
+ }
73
+
70
74
  /**
71
75
  * Return the byte array representation of the zkLogin public identifier
72
76
  */
@@ -118,6 +122,13 @@ export class ZkLoginPublicIdentifier extends PublicKey {
118
122
  client: this.#client,
119
123
  });
120
124
  }
125
+
126
+ /**
127
+ * Verifies that the public key is associated with the provided address
128
+ */
129
+ override verifyAddress(address: string): boolean {
130
+ return address === super.toSuiAddress() || address === this.#toLegacyAddress();
131
+ }
121
132
  }
122
133
 
123
134
  // Derive the public identifier for zklogin based on address seed and iss.