@mysten/sui 2.18.0 → 2.20.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 (40) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/bcs/bcs.d.mts +6 -6
  3. package/dist/cryptography/signature.d.mts +6 -6
  4. package/dist/grpc/proto/sui/rpc/v2/ledger_service.client.d.mts +4 -4
  5. package/dist/grpc/proto/sui/rpc/v2/move_package_service.client.d.mts +4 -4
  6. package/dist/grpc/proto/sui/rpc/v2/name_service.client.d.mts +4 -4
  7. package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.client.d.mts +4 -4
  8. package/dist/grpc/proto/sui/rpc/v2/state_service.client.d.mts +4 -4
  9. package/dist/grpc/proto/sui/rpc/v2/subscription_service.client.d.mts +4 -4
  10. package/dist/grpc/proto/sui/rpc/v2/transaction_execution_service.client.d.mts +4 -4
  11. package/dist/transactions/Transaction.d.mts +6 -6
  12. package/dist/transactions/Transaction.d.mts.map +1 -1
  13. package/dist/verify/index.d.mts +2 -2
  14. package/dist/verify/index.mjs +2 -2
  15. package/dist/verify/verify.d.mts +21 -1
  16. package/dist/verify/verify.d.mts.map +1 -1
  17. package/dist/verify/verify.mjs +49 -14
  18. package/dist/verify/verify.mjs.map +1 -1
  19. package/dist/version.mjs +1 -1
  20. package/dist/version.mjs.map +1 -1
  21. package/dist/zklogin/bcs.d.mts +14 -14
  22. package/dist/zklogin/bcs.d.mts.map +1 -1
  23. package/dist/zklogin/index.d.mts +2 -1
  24. package/dist/zklogin/index.mjs +2 -1
  25. package/dist/zklogin/publickey.d.mts +4 -0
  26. package/dist/zklogin/publickey.d.mts.map +1 -1
  27. package/dist/zklogin/publickey.mjs +6 -0
  28. package/dist/zklogin/publickey.mjs.map +1 -1
  29. package/dist/zklogin/signer.d.mts +55 -0
  30. package/dist/zklogin/signer.d.mts.map +1 -0
  31. package/dist/zklogin/signer.mjs +68 -0
  32. package/dist/zklogin/signer.mjs.map +1 -0
  33. package/docs/migrations/sui-2.0/dapp-kit.md +5 -1
  34. package/package.json +3 -3
  35. package/src/verify/index.ts +3 -0
  36. package/src/verify/verify.ts +68 -34
  37. package/src/version.ts +1 -1
  38. package/src/zklogin/index.ts +2 -0
  39. package/src/zklogin/publickey.ts +7 -0
  40. package/src/zklogin/signer.ts +121 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @mysten/sui.js
2
2
 
3
+ ## 2.20.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 7452835: Add `ZkLoginSigner`, a transport- and provider-agnostic zkLogin signer. It wraps any
8
+ ephemeral `Signer` and transforms its signatures into zkLogin signatures using the supplied proof
9
+ `inputs` and `maxEpoch`:
10
+ `new ZkLoginSigner({ ephemeralSigner, maxEpoch, inputs, legacyAddress })`. The address is derived
11
+ from the proof; `legacyAddress` is a required boolean (consistent with `jwtToAddress`,
12
+ `toZkLoginPublicIdentifier`, and the other zkLogin address APIs). Optionally pass `address` to
13
+ validate the derived address (throws on mismatch) and `client` to make the derived public key able
14
+ to verify signatures. Like other composite signers (e.g. `MultiSigSigner`), calling `sign()`
15
+ directly throws — use `signTransaction` / `signPersonalMessage`.
16
+
17
+ Also adds a read-only `legacyAddress` getter to `ZkLoginPublicIdentifier`.
18
+
19
+ ## 2.19.0
20
+
21
+ ### Minor Changes
22
+
23
+ - 2be98ce: Add `isValidSignature`, `isValidPersonalMessageSignature`, and
24
+ `isValidTransactionSignature` to `@mysten/sui/verify` — boolean-returning siblings of the existing
25
+ `verify*` functions, taking the same arguments. They return `false` for a malformed or invalid
26
+ signature (or one that doesn't match a supplied `address`) instead of throwing, while still
27
+ letting a genuine environmental failure during verification (e.g. a zkLogin JWK/epoch lookup)
28
+ propagate. The `verify*` functions now delegate to these.
29
+
3
30
  ## 2.18.0
4
31
 
5
32
  ### Minor Changes
@@ -1,21 +1,21 @@
1
1
  import { TypeTag as TypeTag$1 } from "./types.mjs";
2
- import * as _mysten_bcs830 from "@mysten/bcs";
2
+ import * as _mysten_bcs810 from "@mysten/bcs";
3
3
  import { BcsType } from "@mysten/bcs";
4
4
 
5
5
  //#region src/bcs/bcs.d.ts
6
6
  declare const TypeTag: BcsType<string, string | TypeTag$1, string>;
7
- declare function IntentMessage<T extends BcsType<any>>(T: T): _mysten_bcs830.BcsStruct<{
8
- intent: _mysten_bcs830.BcsStruct<{
9
- scope: _mysten_bcs830.BcsEnum<{
7
+ declare function IntentMessage<T extends BcsType<any>>(T: T): _mysten_bcs810.BcsStruct<{
8
+ intent: _mysten_bcs810.BcsStruct<{
9
+ scope: _mysten_bcs810.BcsEnum<{
10
10
  TransactionData: null;
11
11
  TransactionEffects: null;
12
12
  CheckpointSummary: null;
13
13
  PersonalMessage: null;
14
14
  }, "IntentScope">;
15
- version: _mysten_bcs830.BcsEnum<{
15
+ version: _mysten_bcs810.BcsEnum<{
16
16
  V0: null;
17
17
  }, "IntentVersion">;
18
- appId: _mysten_bcs830.BcsEnum<{
18
+ appId: _mysten_bcs810.BcsEnum<{
19
19
  Sui: null;
20
20
  }, "AppId">;
21
21
  }, string>;
@@ -23,12 +23,6 @@ declare function toSerializedSignature({
23
23
  * Decodes a serialized signature into its constituent components: the signature scheme, the actual signature, and the public key
24
24
  */
25
25
  declare function parseSerializedSignature(serializedSignature: string): {
26
- serializedSignature: string;
27
- signatureScheme: "ED25519" | "Secp256k1" | "Secp256r1";
28
- signature: Uint8Array<ArrayBuffer>;
29
- publicKey: Uint8Array<ArrayBuffer>;
30
- bytes: Uint8Array<ArrayBuffer>;
31
- } | {
32
26
  signatureScheme: "Passkey";
33
27
  serializedSignature: string;
34
28
  signature: Uint8Array<ArrayBufferLike>;
@@ -60,6 +54,12 @@ declare function parseSerializedSignature(serializedSignature: string): {
60
54
  };
61
55
  signature: Uint8Array<ArrayBufferLike>;
62
56
  publicKey: Uint8Array<ArrayBuffer>;
57
+ } | {
58
+ serializedSignature: string;
59
+ signatureScheme: "ED25519" | "Secp256k1" | "Secp256r1";
60
+ signature: Uint8Array<ArrayBuffer>;
61
+ publicKey: Uint8Array<ArrayBuffer>;
62
+ bytes: Uint8Array<ArrayBuffer>;
63
63
  } | {
64
64
  serializedSignature: string;
65
65
  signatureScheme: "MultiSig";
@@ -1,6 +1,6 @@
1
1
  import { BatchGetObjectsRequest, BatchGetObjectsResponse, BatchGetTransactionsRequest, BatchGetTransactionsResponse, GetCheckpointRequest, GetCheckpointResponse, GetEpochRequest, GetEpochResponse, GetObjectRequest, GetObjectResponse, GetServiceInfoRequest, GetServiceInfoResponse, GetTransactionRequest, GetTransactionResponse } from "./ledger_service.mjs";
2
- import * as _protobuf_ts_runtime5 from "@protobuf-ts/runtime";
3
- import * as _protobuf_ts_runtime_rpc5 from "@protobuf-ts/runtime-rpc";
2
+ import * as _protobuf_ts_runtime3 from "@protobuf-ts/runtime";
3
+ import * as _protobuf_ts_runtime_rpc3 from "@protobuf-ts/runtime-rpc";
4
4
  import { RpcOptions, RpcTransport, ServiceInfo, UnaryCall } from "@protobuf-ts/runtime-rpc";
5
5
 
6
6
  //#region src/grpc/proto/sui/rpc/v2/ledger_service.client.d.ts
@@ -45,9 +45,9 @@ interface ILedgerServiceClient {
45
45
  declare class LedgerServiceClient implements ILedgerServiceClient, ServiceInfo {
46
46
  private readonly _transport;
47
47
  typeName: string;
48
- methods: _protobuf_ts_runtime_rpc5.MethodInfo<any, any>[];
48
+ methods: _protobuf_ts_runtime_rpc3.MethodInfo<any, any>[];
49
49
  options: {
50
- [extensionName: string]: _protobuf_ts_runtime5.JsonValue;
50
+ [extensionName: string]: _protobuf_ts_runtime3.JsonValue;
51
51
  };
52
52
  constructor(_transport: RpcTransport);
53
53
  /**
@@ -1,6 +1,6 @@
1
1
  import { GetDatatypeRequest, GetDatatypeResponse, GetFunctionRequest, GetFunctionResponse, GetPackageRequest, GetPackageResponse, ListPackageVersionsRequest, ListPackageVersionsResponse } from "./move_package_service.mjs";
2
- import * as _protobuf_ts_runtime6 from "@protobuf-ts/runtime";
3
- import * as _protobuf_ts_runtime_rpc6 from "@protobuf-ts/runtime-rpc";
2
+ import * as _protobuf_ts_runtime0 from "@protobuf-ts/runtime";
3
+ import * as _protobuf_ts_runtime_rpc0 from "@protobuf-ts/runtime-rpc";
4
4
  import { RpcOptions, RpcTransport, ServiceInfo, UnaryCall } from "@protobuf-ts/runtime-rpc";
5
5
 
6
6
  //#region src/grpc/proto/sui/rpc/v2/move_package_service.client.d.ts
@@ -31,9 +31,9 @@ interface IMovePackageServiceClient {
31
31
  declare class MovePackageServiceClient implements IMovePackageServiceClient, ServiceInfo {
32
32
  private readonly _transport;
33
33
  typeName: string;
34
- methods: _protobuf_ts_runtime_rpc6.MethodInfo<any, any>[];
34
+ methods: _protobuf_ts_runtime_rpc0.MethodInfo<any, any>[];
35
35
  options: {
36
- [extensionName: string]: _protobuf_ts_runtime6.JsonValue;
36
+ [extensionName: string]: _protobuf_ts_runtime0.JsonValue;
37
37
  };
38
38
  constructor(_transport: RpcTransport);
39
39
  /**
@@ -1,6 +1,6 @@
1
1
  import { LookupNameRequest, LookupNameResponse, ReverseLookupNameRequest, ReverseLookupNameResponse } from "./name_service.mjs";
2
- import * as _protobuf_ts_runtime4 from "@protobuf-ts/runtime";
3
- import * as _protobuf_ts_runtime_rpc4 from "@protobuf-ts/runtime-rpc";
2
+ import * as _protobuf_ts_runtime5 from "@protobuf-ts/runtime";
3
+ import * as _protobuf_ts_runtime_rpc5 from "@protobuf-ts/runtime-rpc";
4
4
  import { RpcOptions, RpcTransport, ServiceInfo, UnaryCall } from "@protobuf-ts/runtime-rpc";
5
5
 
6
6
  //#region src/grpc/proto/sui/rpc/v2/name_service.client.d.ts
@@ -23,9 +23,9 @@ interface INameServiceClient {
23
23
  declare class NameServiceClient implements INameServiceClient, ServiceInfo {
24
24
  private readonly _transport;
25
25
  typeName: string;
26
- methods: _protobuf_ts_runtime_rpc4.MethodInfo<any, any>[];
26
+ methods: _protobuf_ts_runtime_rpc5.MethodInfo<any, any>[];
27
27
  options: {
28
- [extensionName: string]: _protobuf_ts_runtime4.JsonValue;
28
+ [extensionName: string]: _protobuf_ts_runtime5.JsonValue;
29
29
  };
30
30
  constructor(_transport: RpcTransport);
31
31
  /**
@@ -1,6 +1,6 @@
1
1
  import { VerifySignatureRequest, VerifySignatureResponse } from "./signature_verification_service.mjs";
2
- import * as _protobuf_ts_runtime3 from "@protobuf-ts/runtime";
3
- import * as _protobuf_ts_runtime_rpc3 from "@protobuf-ts/runtime-rpc";
2
+ import * as _protobuf_ts_runtime2 from "@protobuf-ts/runtime";
3
+ import * as _protobuf_ts_runtime_rpc2 from "@protobuf-ts/runtime-rpc";
4
4
  import { RpcOptions, RpcTransport, ServiceInfo, UnaryCall } from "@protobuf-ts/runtime-rpc";
5
5
 
6
6
  //#region src/grpc/proto/sui/rpc/v2/signature_verification_service.client.d.ts
@@ -21,9 +21,9 @@ interface ISignatureVerificationServiceClient {
21
21
  declare class SignatureVerificationServiceClient implements ISignatureVerificationServiceClient, ServiceInfo {
22
22
  private readonly _transport;
23
23
  typeName: string;
24
- methods: _protobuf_ts_runtime_rpc3.MethodInfo<any, any>[];
24
+ methods: _protobuf_ts_runtime_rpc2.MethodInfo<any, any>[];
25
25
  options: {
26
- [extensionName: string]: _protobuf_ts_runtime3.JsonValue;
26
+ [extensionName: string]: _protobuf_ts_runtime2.JsonValue;
27
27
  };
28
28
  constructor(_transport: RpcTransport);
29
29
  /**
@@ -1,6 +1,6 @@
1
1
  import { GetBalanceRequest, GetBalanceResponse, GetCoinInfoRequest, GetCoinInfoResponse, ListBalancesRequest, ListBalancesResponse, ListDynamicFieldsRequest, ListDynamicFieldsResponse, ListOwnedObjectsRequest, ListOwnedObjectsResponse } from "./state_service.mjs";
2
- import * as _protobuf_ts_runtime1 from "@protobuf-ts/runtime";
3
- import * as _protobuf_ts_runtime_rpc1 from "@protobuf-ts/runtime-rpc";
2
+ import * as _protobuf_ts_runtime4 from "@protobuf-ts/runtime";
3
+ import * as _protobuf_ts_runtime_rpc4 from "@protobuf-ts/runtime-rpc";
4
4
  import { RpcOptions, RpcTransport, ServiceInfo, UnaryCall } from "@protobuf-ts/runtime-rpc";
5
5
 
6
6
  //#region src/grpc/proto/sui/rpc/v2/state_service.client.d.ts
@@ -35,9 +35,9 @@ interface IStateServiceClient {
35
35
  declare class StateServiceClient implements IStateServiceClient, ServiceInfo {
36
36
  private readonly _transport;
37
37
  typeName: string;
38
- methods: _protobuf_ts_runtime_rpc1.MethodInfo<any, any>[];
38
+ methods: _protobuf_ts_runtime_rpc4.MethodInfo<any, any>[];
39
39
  options: {
40
- [extensionName: string]: _protobuf_ts_runtime1.JsonValue;
40
+ [extensionName: string]: _protobuf_ts_runtime4.JsonValue;
41
41
  };
42
42
  constructor(_transport: RpcTransport);
43
43
  /**
@@ -1,6 +1,6 @@
1
1
  import { SubscribeCheckpointsRequest, SubscribeCheckpointsResponse } from "./subscription_service.mjs";
2
- import * as _protobuf_ts_runtime2 from "@protobuf-ts/runtime";
3
- import * as _protobuf_ts_runtime_rpc2 from "@protobuf-ts/runtime-rpc";
2
+ import * as _protobuf_ts_runtime6 from "@protobuf-ts/runtime";
3
+ import * as _protobuf_ts_runtime_rpc6 from "@protobuf-ts/runtime-rpc";
4
4
  import { RpcOptions, RpcTransport, ServerStreamingCall, ServiceInfo } from "@protobuf-ts/runtime-rpc";
5
5
 
6
6
  //#region src/grpc/proto/sui/rpc/v2/subscription_service.client.d.ts
@@ -31,9 +31,9 @@ interface ISubscriptionServiceClient {
31
31
  declare class SubscriptionServiceClient implements ISubscriptionServiceClient, ServiceInfo {
32
32
  private readonly _transport;
33
33
  typeName: string;
34
- methods: _protobuf_ts_runtime_rpc2.MethodInfo<any, any>[];
34
+ methods: _protobuf_ts_runtime_rpc6.MethodInfo<any, any>[];
35
35
  options: {
36
- [extensionName: string]: _protobuf_ts_runtime2.JsonValue;
36
+ [extensionName: string]: _protobuf_ts_runtime6.JsonValue;
37
37
  };
38
38
  constructor(_transport: RpcTransport);
39
39
  /**
@@ -1,6 +1,6 @@
1
1
  import { ExecuteTransactionRequest, ExecuteTransactionResponse, SimulateTransactionRequest, SimulateTransactionResponse } from "./transaction_execution_service.mjs";
2
- import * as _protobuf_ts_runtime0 from "@protobuf-ts/runtime";
3
- import * as _protobuf_ts_runtime_rpc0 from "@protobuf-ts/runtime-rpc";
2
+ import * as _protobuf_ts_runtime1 from "@protobuf-ts/runtime";
3
+ import * as _protobuf_ts_runtime_rpc1 from "@protobuf-ts/runtime-rpc";
4
4
  import { RpcOptions, RpcTransport, ServiceInfo, UnaryCall } from "@protobuf-ts/runtime-rpc";
5
5
 
6
6
  //#region src/grpc/proto/sui/rpc/v2/transaction_execution_service.client.d.ts
@@ -23,9 +23,9 @@ interface ITransactionExecutionServiceClient {
23
23
  declare class TransactionExecutionServiceClient implements ITransactionExecutionServiceClient, ServiceInfo {
24
24
  private readonly _transport;
25
25
  typeName: string;
26
- methods: _protobuf_ts_runtime_rpc0.MethodInfo<any, any>[];
26
+ methods: _protobuf_ts_runtime_rpc1.MethodInfo<any, any>[];
27
27
  options: {
28
- [extensionName: string]: _protobuf_ts_runtime0.JsonValue;
28
+ [extensionName: string]: _protobuf_ts_runtime1.JsonValue;
29
29
  };
30
30
  constructor(_transport: RpcTransport);
31
31
  /**
@@ -8,7 +8,7 @@ import { createPure } from "./pure.mjs";
8
8
  import { SignatureWithBytes, Signer } from "../cryptography/keypair.mjs";
9
9
  import "../cryptography/index.mjs";
10
10
  import { ClientWithCoreApi } from "../client/core.mjs";
11
- import * as _mysten_bcs823 from "@mysten/bcs";
11
+ import * as _mysten_bcs1124 from "@mysten/bcs";
12
12
  import { SerializedBcs } from "@mysten/bcs";
13
13
  import { InferInput } from "valibot";
14
14
 
@@ -91,7 +91,7 @@ declare class Transaction {
91
91
  getData(): {
92
92
  version: 2;
93
93
  sender?: string | null | undefined;
94
- expiration?: _mysten_bcs823.EnumOutputShapeWithKeys<{
94
+ expiration?: _mysten_bcs1124.EnumOutputShapeWithKeys<{
95
95
  None: true;
96
96
  Epoch: string | number;
97
97
  ValidDuring: {
@@ -113,8 +113,8 @@ declare class Transaction {
113
113
  digest: string;
114
114
  }[] | null;
115
115
  };
116
- inputs: _mysten_bcs823.EnumOutputShapeWithKeys<{
117
- Object: _mysten_bcs823.EnumOutputShapeWithKeys<{
116
+ inputs: _mysten_bcs1124.EnumOutputShapeWithKeys<{
117
+ Object: _mysten_bcs1124.EnumOutputShapeWithKeys<{
118
118
  ImmOrOwnedObject: {
119
119
  objectId: string;
120
120
  version: string | number;
@@ -153,13 +153,13 @@ declare class Transaction {
153
153
  Balance: string;
154
154
  $kind: "Balance";
155
155
  };
156
- withdrawFrom: _mysten_bcs823.EnumOutputShapeWithKeys<{
156
+ withdrawFrom: _mysten_bcs1124.EnumOutputShapeWithKeys<{
157
157
  Sender: true;
158
158
  Sponsor: true;
159
159
  }, "Sender" | "Sponsor">;
160
160
  };
161
161
  }, "Object" | "Pure" | "FundsWithdrawal" | "UnresolvedPure" | "UnresolvedObject">[];
162
- commands: _mysten_bcs823.EnumOutputShapeWithKeys<{
162
+ commands: _mysten_bcs1124.EnumOutputShapeWithKeys<{
163
163
  MoveCall: {
164
164
  package: string;
165
165
  module: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Transaction.d.mts","names":[],"sources":["../../src/transactions/Transaction.ts"],"mappings":"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"}
1
+ {"version":3,"file":"Transaction.d.mts","names":[],"sources":["../../src/transactions/Transaction.ts"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { publicKeyFromRawBytes, publicKeyFromSuiBytes, verifyPersonalMessageSignature, verifySignature, verifyTransactionSignature } from "./verify.mjs";
2
- export { publicKeyFromRawBytes, publicKeyFromSuiBytes, verifyPersonalMessageSignature, verifySignature, verifyTransactionSignature };
1
+ import { isValidPersonalMessageSignature, isValidSignature, isValidTransactionSignature, publicKeyFromRawBytes, publicKeyFromSuiBytes, verifyPersonalMessageSignature, verifySignature, verifyTransactionSignature } from "./verify.mjs";
2
+ export { isValidPersonalMessageSignature, isValidSignature, isValidTransactionSignature, publicKeyFromRawBytes, publicKeyFromSuiBytes, verifyPersonalMessageSignature, verifySignature, verifyTransactionSignature };
@@ -1,3 +1,3 @@
1
- import { publicKeyFromRawBytes, publicKeyFromSuiBytes, verifyPersonalMessageSignature, verifySignature, verifyTransactionSignature } from "./verify.mjs";
1
+ import { isValidPersonalMessageSignature, isValidSignature, isValidTransactionSignature, publicKeyFromRawBytes, publicKeyFromSuiBytes, verifyPersonalMessageSignature, verifySignature, verifyTransactionSignature } from "./verify.mjs";
2
2
 
3
- export { publicKeyFromRawBytes, publicKeyFromSuiBytes, verifyPersonalMessageSignature, verifySignature, verifyTransactionSignature };
3
+ export { isValidPersonalMessageSignature, isValidSignature, isValidTransactionSignature, publicKeyFromRawBytes, publicKeyFromSuiBytes, verifyPersonalMessageSignature, verifySignature, verifyTransactionSignature };
@@ -4,6 +4,26 @@ import "../cryptography/index.mjs";
4
4
  import { ClientWithCoreApi } from "../client/core.mjs";
5
5
 
6
6
  //#region src/verify/verify.d.ts
7
+ /**
8
+ * Whether `signature` is a valid signature over `bytes` (and, if `options.address`
9
+ * is given, was produced by that address). Returns `false` for a malformed or
10
+ * cryptographically invalid signature, or one that doesn't match the address;
11
+ * only an *environmental* failure (e.g. a zkLogin JWK/epoch lookup) throws, so a
12
+ * network blip is never reported as an invalid signature.
13
+ */
14
+ declare function isValidSignature(bytes: Uint8Array, signature: string, options?: {
15
+ address?: string;
16
+ }): Promise<boolean>;
17
+ /** Like {@link isValidSignature}, for a personal message. */
18
+ declare function isValidPersonalMessageSignature(message: Uint8Array, signature: string, options?: {
19
+ client?: ClientWithCoreApi;
20
+ address?: string;
21
+ }): Promise<boolean>;
22
+ /** Like {@link isValidSignature}, for transaction bytes. */
23
+ declare function isValidTransactionSignature(transaction: Uint8Array, signature: string, options?: {
24
+ client?: ClientWithCoreApi;
25
+ address?: string;
26
+ }): Promise<boolean>;
7
27
  declare function verifySignature(bytes: Uint8Array, signature: string, options?: {
8
28
  address?: string;
9
29
  }): Promise<PublicKey>;
@@ -24,5 +44,5 @@ declare function publicKeyFromSuiBytes(publicKey: string | Uint8Array, options?:
24
44
  address?: string;
25
45
  }): PublicKey;
26
46
  //#endregion
27
- export { publicKeyFromRawBytes, publicKeyFromSuiBytes, verifyPersonalMessageSignature, verifySignature, verifyTransactionSignature };
47
+ export { isValidPersonalMessageSignature, isValidSignature, isValidTransactionSignature, publicKeyFromRawBytes, publicKeyFromSuiBytes, verifyPersonalMessageSignature, verifySignature, verifyTransactionSignature };
28
48
  //# sourceMappingURL=verify.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify.d.mts","names":[],"sources":["../../src/verify/verify.ts"],"mappings":";;;;;;iBAesB,eAAA,CACrB,KAAA,EAAO,UAAA,EACP,SAAA,UACA,OAAA;EACC,OAAA;AAAA,IAEC,OAAA,CAAQ,SAAA;AAAA,iBAcW,8BAAA,CACrB,OAAA,EAAS,UAAA,EACT,SAAA,UACA,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IACrC,OAAA,CAAQ,SAAA;AAAA,iBAmBW,0BAAA,CACrB,WAAA,EAAa,UAAA,EACb,SAAA,UACA,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IACrC,OAAA,CAAQ,SAAA;AAAA,iBAwCK,qBAAA,CACf,eAAA,EAAiB,eAAA,EACjB,KAAA,EAAO,UAAA,EACP,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IACrC,SAAA;AAAA,iBAgCa,qBAAA,CACf,SAAA,WAAoB,UAAA,EACpB,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IAAuB,SAAA"}
1
+ {"version":3,"file":"verify.d.mts","names":[],"sources":["../../src/verify/verify.ts"],"mappings":";;;;;;;;;;AAsBA;;;iBAAsB,gBAAA,CACrB,KAAA,EAAO,UAAA,EACP,SAAA,UACA,OAAA;EAAW,OAAA;AAAA,IACT,OAAA;;iBAQmB,+BAAA,CACrB,OAAA,EAAS,UAAA,EACT,SAAA,UACA,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IACrC,OAAA;;iBAUmB,2BAAA,CACrB,WAAA,EAAa,UAAA,EACb,SAAA,UACA,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IACrC,OAAA;AAAA,iBASmB,eAAA,CACrB,KAAA,EAAO,UAAA,EACP,SAAA,UACA,OAAA;EAAW,OAAA;AAAA,IACT,OAAA,CAAQ,SAAA;AAAA,iBAWW,8BAAA,CACrB,OAAA,EAAS,UAAA,EACT,SAAA,UACA,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IACrC,OAAA,CAAQ,SAAA;AAAA,iBAWW,0BAAA,CACrB,WAAA,EAAa,UAAA,EACb,SAAA,UACA,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IACrC,OAAA,CAAQ,SAAA;AAAA,iBAyCK,qBAAA,CACf,eAAA,EAAiB,eAAA,EACjB,KAAA,EAAO,UAAA,EACP,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IACrC,SAAA;AAAA,iBAgCa,qBAAA,CACf,SAAA,WAAoB,UAAA,EACpB,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IAAuB,SAAA"}
@@ -9,23 +9,50 @@ import { MultiSigPublicKey } from "../multisig/publickey.mjs";
9
9
  import { fromBase64 } from "@mysten/bcs";
10
10
 
11
11
  //#region src/verify/verify.ts
12
- async function verifySignature(bytes, signature, options) {
13
- const parsedSignature = parseSignature(signature);
14
- if (!await parsedSignature.publicKey.verify(bytes, parsedSignature.serializedSignature)) throw new Error(`Signature is not valid for the provided data`);
15
- if (options?.address && !parsedSignature.publicKey.verifyAddress(options.address)) throw new Error(`Signature is not valid for the provided address`);
16
- return parsedSignature.publicKey;
12
+ /**
13
+ * Whether `signature` is a valid signature over `bytes` (and, if `options.address`
14
+ * is given, was produced by that address). Returns `false` for a malformed or
15
+ * cryptographically invalid signature, or one that doesn't match the address;
16
+ * only an *environmental* failure (e.g. a zkLogin JWK/epoch lookup) throws, so a
17
+ * network blip is never reported as an invalid signature.
18
+ */
19
+ async function isValidSignature(bytes, signature, options = {}) {
20
+ const parsed = tryParseSignature(signature);
21
+ if (!parsed) return false;
22
+ if (!await parsed.publicKey.verify(bytes, parsed.serializedSignature)) return false;
23
+ return options.address ? parsed.publicKey.verifyAddress(options.address) : true;
24
+ }
25
+ /** Like {@link isValidSignature}, for a personal message. */
26
+ async function isValidPersonalMessageSignature(message, signature, options = {}) {
27
+ const parsed = tryParseSignature(signature, { client: options.client });
28
+ if (!parsed) return false;
29
+ if (!await parsed.publicKey.verifyPersonalMessage(message, parsed.serializedSignature)) return false;
30
+ return options.address ? parsed.publicKey.verifyAddress(options.address) : true;
31
+ }
32
+ /** Like {@link isValidSignature}, for transaction bytes. */
33
+ async function isValidTransactionSignature(transaction, signature, options = {}) {
34
+ const parsed = tryParseSignature(signature, { client: options.client });
35
+ if (!parsed) return false;
36
+ if (!await parsed.publicKey.verifyTransaction(transaction, parsed.serializedSignature)) return false;
37
+ return options.address ? parsed.publicKey.verifyAddress(options.address) : true;
38
+ }
39
+ async function verifySignature(bytes, signature, options = {}) {
40
+ const { publicKey } = parseSignature(signature);
41
+ if (!await isValidSignature(bytes, signature)) throw new Error(`Signature is not valid for the provided data`);
42
+ if (options.address && !publicKey.verifyAddress(options.address)) throw new Error(`Signature is not valid for the provided address`);
43
+ return publicKey;
17
44
  }
18
45
  async function verifyPersonalMessageSignature(message, signature, options = {}) {
19
- const parsedSignature = parseSignature(signature, options);
20
- if (!await parsedSignature.publicKey.verifyPersonalMessage(message, parsedSignature.serializedSignature)) throw new Error(`Signature is not valid for the provided message`);
21
- if (options?.address && !parsedSignature.publicKey.verifyAddress(options.address)) throw new Error(`Signature is not valid for the provided address`);
22
- return parsedSignature.publicKey;
46
+ const { publicKey } = parseSignature(signature, options);
47
+ if (!await isValidPersonalMessageSignature(message, signature, { client: options.client })) throw new Error(`Signature is not valid for the provided message`);
48
+ if (options.address && !publicKey.verifyAddress(options.address)) throw new Error(`Signature is not valid for the provided address`);
49
+ return publicKey;
23
50
  }
24
51
  async function verifyTransactionSignature(transaction, signature, options = {}) {
25
- const parsedSignature = parseSignature(signature, options);
26
- if (!await parsedSignature.publicKey.verifyTransaction(transaction, parsedSignature.serializedSignature)) throw new Error(`Signature is not valid for the provided Transaction`);
27
- if (options?.address && !parsedSignature.publicKey.verifyAddress(options.address)) throw new Error(`Signature is not valid for the provided address`);
28
- return parsedSignature.publicKey;
52
+ const { publicKey } = parseSignature(signature, options);
53
+ if (!await isValidTransactionSignature(transaction, signature, { client: options.client })) throw new Error(`Signature is not valid for the provided Transaction`);
54
+ if (options.address && !publicKey.verifyAddress(options.address)) throw new Error(`Signature is not valid for the provided address`);
55
+ return publicKey;
29
56
  }
30
57
  function parseSignature(signature, options = {}) {
31
58
  const parsedSignature = parseSerializedSignature(signature);
@@ -39,6 +66,14 @@ function parseSignature(signature, options = {}) {
39
66
  publicKey
40
67
  };
41
68
  }
69
+ /** {@link parseSignature}, returning `null` instead of throwing on a malformed signature. */
70
+ function tryParseSignature(signature, options = {}) {
71
+ try {
72
+ return parseSignature(signature, options);
73
+ } catch {
74
+ return null;
75
+ }
76
+ }
42
77
  function publicKeyFromRawBytes(signatureScheme, bytes, options = {}) {
43
78
  let publicKey;
44
79
  switch (signatureScheme) {
@@ -72,5 +107,5 @@ function publicKeyFromSuiBytes(publicKey, options = {}) {
72
107
  }
73
108
 
74
109
  //#endregion
75
- export { publicKeyFromRawBytes, publicKeyFromSuiBytes, verifyPersonalMessageSignature, verifySignature, verifyTransactionSignature };
110
+ export { isValidPersonalMessageSignature, isValidSignature, isValidTransactionSignature, publicKeyFromRawBytes, publicKeyFromSuiBytes, verifyPersonalMessageSignature, verifySignature, verifyTransactionSignature };
76
111
  //# sourceMappingURL=verify.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify.mjs","names":[],"sources":["../../src/verify/verify.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromBase64 } from '@mysten/bcs';\n\nimport type { PublicKey, SignatureFlag, SignatureScheme } from '../cryptography/index.js';\nimport { parseSerializedSignature, SIGNATURE_FLAG_TO_SCHEME } from '../cryptography/index.js';\nimport { Ed25519PublicKey } from '../keypairs/ed25519/publickey.js';\nimport { PasskeyPublicKey } from '../keypairs/passkey/publickey.js';\nimport { Secp256k1PublicKey } from '../keypairs/secp256k1/publickey.js';\nimport { Secp256r1PublicKey } from '../keypairs/secp256r1/publickey.js';\nimport { MultiSigPublicKey } from '../multisig/publickey.js';\nimport { ZkLoginPublicIdentifier } from '../zklogin/publickey.js';\nimport type { ClientWithCoreApi } from '../client/core.js';\n\nexport async function verifySignature(\n\tbytes: Uint8Array,\n\tsignature: string,\n\toptions?: {\n\t\taddress?: string;\n\t},\n): Promise<PublicKey> {\n\tconst parsedSignature = parseSignature(signature);\n\n\tif (!(await parsedSignature.publicKey.verify(bytes, parsedSignature.serializedSignature))) {\n\t\tthrow new Error(`Signature is not valid for the provided data`);\n\t}\n\n\tif (options?.address && !parsedSignature.publicKey.verifyAddress(options.address)) {\n\t\tthrow new Error(`Signature is not valid for the provided address`);\n\t}\n\n\treturn parsedSignature.publicKey;\n}\n\nexport async function verifyPersonalMessageSignature(\n\tmessage: Uint8Array,\n\tsignature: string,\n\toptions: { client?: ClientWithCoreApi; address?: string } = {},\n): Promise<PublicKey> {\n\tconst parsedSignature = parseSignature(signature, options);\n\n\tif (\n\t\t!(await parsedSignature.publicKey.verifyPersonalMessage(\n\t\t\tmessage,\n\t\t\tparsedSignature.serializedSignature,\n\t\t))\n\t) {\n\t\tthrow new Error(`Signature is not valid for the provided message`);\n\t}\n\n\tif (options?.address && !parsedSignature.publicKey.verifyAddress(options.address)) {\n\t\tthrow new Error(`Signature is not valid for the provided address`);\n\t}\n\n\treturn parsedSignature.publicKey;\n}\n\nexport async function verifyTransactionSignature(\n\ttransaction: Uint8Array,\n\tsignature: string,\n\toptions: { client?: ClientWithCoreApi; address?: string } = {},\n): Promise<PublicKey> {\n\tconst parsedSignature = parseSignature(signature, options);\n\n\tif (\n\t\t!(await parsedSignature.publicKey.verifyTransaction(\n\t\t\ttransaction,\n\t\t\tparsedSignature.serializedSignature,\n\t\t))\n\t) {\n\t\tthrow new Error(`Signature is not valid for the provided Transaction`);\n\t}\n\n\tif (options?.address && !parsedSignature.publicKey.verifyAddress(options.address)) {\n\t\tthrow new Error(`Signature is not valid for the provided address`);\n\t}\n\n\treturn parsedSignature.publicKey;\n}\n\nfunction parseSignature(signature: string, options: { client?: ClientWithCoreApi } = {}) {\n\tconst parsedSignature = parseSerializedSignature(signature);\n\n\tif (parsedSignature.signatureScheme === 'MultiSig') {\n\t\treturn {\n\t\t\t...parsedSignature,\n\t\t\tpublicKey: new MultiSigPublicKey(parsedSignature.multisig.multisig_pk),\n\t\t};\n\t}\n\n\tconst publicKey = publicKeyFromRawBytes(\n\t\tparsedSignature.signatureScheme,\n\t\tparsedSignature.publicKey,\n\t\toptions,\n\t);\n\treturn {\n\t\t...parsedSignature,\n\t\tpublicKey,\n\t};\n}\n\nexport function publicKeyFromRawBytes(\n\tsignatureScheme: SignatureScheme,\n\tbytes: Uint8Array,\n\toptions: { client?: ClientWithCoreApi; address?: string } = {},\n): PublicKey {\n\tlet publicKey: PublicKey;\n\tswitch (signatureScheme) {\n\t\tcase 'ED25519':\n\t\t\tpublicKey = new Ed25519PublicKey(bytes);\n\t\t\tbreak;\n\t\tcase 'Secp256k1':\n\t\t\tpublicKey = new Secp256k1PublicKey(bytes);\n\t\t\tbreak;\n\t\tcase 'Secp256r1':\n\t\t\tpublicKey = new Secp256r1PublicKey(bytes);\n\t\t\tbreak;\n\t\tcase 'MultiSig':\n\t\t\tpublicKey = new MultiSigPublicKey(bytes);\n\t\t\tbreak;\n\t\tcase 'ZkLogin':\n\t\t\tpublicKey = ZkLoginPublicIdentifier.fromBytes(bytes, options);\n\t\t\tbreak;\n\t\tcase 'Passkey':\n\t\t\tpublicKey = new PasskeyPublicKey(bytes);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported signature scheme ${signatureScheme}`);\n\t}\n\n\tif (options.address && publicKey.toSuiAddress() !== options.address) {\n\t\tthrow new Error(`Public key bytes do not match the provided address`);\n\t}\n\n\treturn publicKey;\n}\n\nexport function publicKeyFromSuiBytes(\n\tpublicKey: string | Uint8Array,\n\toptions: { client?: ClientWithCoreApi; address?: string } = {},\n) {\n\tconst bytes = typeof publicKey === 'string' ? fromBase64(publicKey) : publicKey;\n\n\tconst signatureScheme = SIGNATURE_FLAG_TO_SCHEME[bytes[0] as SignatureFlag];\n\n\treturn publicKeyFromRawBytes(signatureScheme, bytes.slice(1), options);\n}\n"],"mappings":";;;;;;;;;;;AAeA,eAAsB,gBACrB,OACA,WACA,SAGqB;CACrB,MAAM,kBAAkB,eAAe,UAAU;AAEjD,KAAI,CAAE,MAAM,gBAAgB,UAAU,OAAO,OAAO,gBAAgB,oBAAoB,CACvF,OAAM,IAAI,MAAM,+CAA+C;AAGhE,KAAI,SAAS,WAAW,CAAC,gBAAgB,UAAU,cAAc,QAAQ,QAAQ,CAChF,OAAM,IAAI,MAAM,kDAAkD;AAGnE,QAAO,gBAAgB;;AAGxB,eAAsB,+BACrB,SACA,WACA,UAA4D,EAAE,EACzC;CACrB,MAAM,kBAAkB,eAAe,WAAW,QAAQ;AAE1D,KACC,CAAE,MAAM,gBAAgB,UAAU,sBACjC,SACA,gBAAgB,oBAChB,CAED,OAAM,IAAI,MAAM,kDAAkD;AAGnE,KAAI,SAAS,WAAW,CAAC,gBAAgB,UAAU,cAAc,QAAQ,QAAQ,CAChF,OAAM,IAAI,MAAM,kDAAkD;AAGnE,QAAO,gBAAgB;;AAGxB,eAAsB,2BACrB,aACA,WACA,UAA4D,EAAE,EACzC;CACrB,MAAM,kBAAkB,eAAe,WAAW,QAAQ;AAE1D,KACC,CAAE,MAAM,gBAAgB,UAAU,kBACjC,aACA,gBAAgB,oBAChB,CAED,OAAM,IAAI,MAAM,sDAAsD;AAGvE,KAAI,SAAS,WAAW,CAAC,gBAAgB,UAAU,cAAc,QAAQ,QAAQ,CAChF,OAAM,IAAI,MAAM,kDAAkD;AAGnE,QAAO,gBAAgB;;AAGxB,SAAS,eAAe,WAAmB,UAA0C,EAAE,EAAE;CACxF,MAAM,kBAAkB,yBAAyB,UAAU;AAE3D,KAAI,gBAAgB,oBAAoB,WACvC,QAAO;EACN,GAAG;EACH,WAAW,IAAI,kBAAkB,gBAAgB,SAAS,YAAY;EACtE;CAGF,MAAM,YAAY,sBACjB,gBAAgB,iBAChB,gBAAgB,WAChB,QACA;AACD,QAAO;EACN,GAAG;EACH;EACA;;AAGF,SAAgB,sBACf,iBACA,OACA,UAA4D,EAAE,EAClD;CACZ,IAAI;AACJ,SAAQ,iBAAR;EACC,KAAK;AACJ,eAAY,IAAI,iBAAiB,MAAM;AACvC;EACD,KAAK;AACJ,eAAY,IAAI,mBAAmB,MAAM;AACzC;EACD,KAAK;AACJ,eAAY,IAAI,mBAAmB,MAAM;AACzC;EACD,KAAK;AACJ,eAAY,IAAI,kBAAkB,MAAM;AACxC;EACD,KAAK;AACJ,eAAY,wBAAwB,UAAU,OAAO,QAAQ;AAC7D;EACD,KAAK;AACJ,eAAY,IAAI,iBAAiB,MAAM;AACvC;EACD,QACC,OAAM,IAAI,MAAM,gCAAgC,kBAAkB;;AAGpE,KAAI,QAAQ,WAAW,UAAU,cAAc,KAAK,QAAQ,QAC3D,OAAM,IAAI,MAAM,qDAAqD;AAGtE,QAAO;;AAGR,SAAgB,sBACf,WACA,UAA4D,EAAE,EAC7D;CACD,MAAM,QAAQ,OAAO,cAAc,WAAW,WAAW,UAAU,GAAG;CAEtE,MAAM,kBAAkB,yBAAyB,MAAM;AAEvD,QAAO,sBAAsB,iBAAiB,MAAM,MAAM,EAAE,EAAE,QAAQ"}
1
+ {"version":3,"file":"verify.mjs","names":[],"sources":["../../src/verify/verify.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromBase64 } from '@mysten/bcs';\n\nimport type { PublicKey, SignatureFlag, SignatureScheme } from '../cryptography/index.js';\nimport { parseSerializedSignature, SIGNATURE_FLAG_TO_SCHEME } from '../cryptography/index.js';\nimport { Ed25519PublicKey } from '../keypairs/ed25519/publickey.js';\nimport { PasskeyPublicKey } from '../keypairs/passkey/publickey.js';\nimport { Secp256k1PublicKey } from '../keypairs/secp256k1/publickey.js';\nimport { Secp256r1PublicKey } from '../keypairs/secp256r1/publickey.js';\nimport { MultiSigPublicKey } from '../multisig/publickey.js';\nimport { ZkLoginPublicIdentifier } from '../zklogin/publickey.js';\nimport type { ClientWithCoreApi } from '../client/core.js';\n\n/**\n * Whether `signature` is a valid signature over `bytes` (and, if `options.address`\n * is given, was produced by that address). Returns `false` for a malformed or\n * cryptographically invalid signature, or one that doesn't match the address;\n * only an *environmental* failure (e.g. a zkLogin JWK/epoch lookup) throws, so a\n * network blip is never reported as an invalid signature.\n */\nexport async function isValidSignature(\n\tbytes: Uint8Array,\n\tsignature: string,\n\toptions: { address?: string } = {},\n): Promise<boolean> {\n\tconst parsed = tryParseSignature(signature);\n\tif (!parsed) return false;\n\tif (!(await parsed.publicKey.verify(bytes, parsed.serializedSignature))) return false;\n\treturn options.address ? parsed.publicKey.verifyAddress(options.address) : true;\n}\n\n/** Like {@link isValidSignature}, for a personal message. */\nexport async function isValidPersonalMessageSignature(\n\tmessage: Uint8Array,\n\tsignature: string,\n\toptions: { client?: ClientWithCoreApi; address?: string } = {},\n): Promise<boolean> {\n\tconst parsed = tryParseSignature(signature, { client: options.client });\n\tif (!parsed) return false;\n\tif (!(await parsed.publicKey.verifyPersonalMessage(message, parsed.serializedSignature))) {\n\t\treturn false;\n\t}\n\treturn options.address ? parsed.publicKey.verifyAddress(options.address) : true;\n}\n\n/** Like {@link isValidSignature}, for transaction bytes. */\nexport async function isValidTransactionSignature(\n\ttransaction: Uint8Array,\n\tsignature: string,\n\toptions: { client?: ClientWithCoreApi; address?: string } = {},\n): Promise<boolean> {\n\tconst parsed = tryParseSignature(signature, { client: options.client });\n\tif (!parsed) return false;\n\tif (!(await parsed.publicKey.verifyTransaction(transaction, parsed.serializedSignature))) {\n\t\treturn false;\n\t}\n\treturn options.address ? parsed.publicKey.verifyAddress(options.address) : true;\n}\n\nexport async function verifySignature(\n\tbytes: Uint8Array,\n\tsignature: string,\n\toptions: { address?: string } = {},\n): Promise<PublicKey> {\n\tconst { publicKey } = parseSignature(signature);\n\tif (!(await isValidSignature(bytes, signature))) {\n\t\tthrow new Error(`Signature is not valid for the provided data`);\n\t}\n\tif (options.address && !publicKey.verifyAddress(options.address)) {\n\t\tthrow new Error(`Signature is not valid for the provided address`);\n\t}\n\treturn publicKey;\n}\n\nexport async function verifyPersonalMessageSignature(\n\tmessage: Uint8Array,\n\tsignature: string,\n\toptions: { client?: ClientWithCoreApi; address?: string } = {},\n): Promise<PublicKey> {\n\tconst { publicKey } = parseSignature(signature, options);\n\tif (!(await isValidPersonalMessageSignature(message, signature, { client: options.client }))) {\n\t\tthrow new Error(`Signature is not valid for the provided message`);\n\t}\n\tif (options.address && !publicKey.verifyAddress(options.address)) {\n\t\tthrow new Error(`Signature is not valid for the provided address`);\n\t}\n\treturn publicKey;\n}\n\nexport async function verifyTransactionSignature(\n\ttransaction: Uint8Array,\n\tsignature: string,\n\toptions: { client?: ClientWithCoreApi; address?: string } = {},\n): Promise<PublicKey> {\n\tconst { publicKey } = parseSignature(signature, options);\n\tif (!(await isValidTransactionSignature(transaction, signature, { client: options.client }))) {\n\t\tthrow new Error(`Signature is not valid for the provided Transaction`);\n\t}\n\tif (options.address && !publicKey.verifyAddress(options.address)) {\n\t\tthrow new Error(`Signature is not valid for the provided address`);\n\t}\n\treturn publicKey;\n}\n\nfunction parseSignature(signature: string, options: { client?: ClientWithCoreApi } = {}) {\n\tconst parsedSignature = parseSerializedSignature(signature);\n\n\tif (parsedSignature.signatureScheme === 'MultiSig') {\n\t\treturn {\n\t\t\t...parsedSignature,\n\t\t\tpublicKey: new MultiSigPublicKey(parsedSignature.multisig.multisig_pk),\n\t\t};\n\t}\n\n\tconst publicKey = publicKeyFromRawBytes(\n\t\tparsedSignature.signatureScheme,\n\t\tparsedSignature.publicKey,\n\t\toptions,\n\t);\n\treturn {\n\t\t...parsedSignature,\n\t\tpublicKey,\n\t};\n}\n\n/** {@link parseSignature}, returning `null` instead of throwing on a malformed signature. */\nfunction tryParseSignature(signature: string, options: { client?: ClientWithCoreApi } = {}) {\n\ttry {\n\t\treturn parseSignature(signature, options);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport function publicKeyFromRawBytes(\n\tsignatureScheme: SignatureScheme,\n\tbytes: Uint8Array,\n\toptions: { client?: ClientWithCoreApi; address?: string } = {},\n): PublicKey {\n\tlet publicKey: PublicKey;\n\tswitch (signatureScheme) {\n\t\tcase 'ED25519':\n\t\t\tpublicKey = new Ed25519PublicKey(bytes);\n\t\t\tbreak;\n\t\tcase 'Secp256k1':\n\t\t\tpublicKey = new Secp256k1PublicKey(bytes);\n\t\t\tbreak;\n\t\tcase 'Secp256r1':\n\t\t\tpublicKey = new Secp256r1PublicKey(bytes);\n\t\t\tbreak;\n\t\tcase 'MultiSig':\n\t\t\tpublicKey = new MultiSigPublicKey(bytes);\n\t\t\tbreak;\n\t\tcase 'ZkLogin':\n\t\t\tpublicKey = ZkLoginPublicIdentifier.fromBytes(bytes, options);\n\t\t\tbreak;\n\t\tcase 'Passkey':\n\t\t\tpublicKey = new PasskeyPublicKey(bytes);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported signature scheme ${signatureScheme}`);\n\t}\n\n\tif (options.address && publicKey.toSuiAddress() !== options.address) {\n\t\tthrow new Error(`Public key bytes do not match the provided address`);\n\t}\n\n\treturn publicKey;\n}\n\nexport function publicKeyFromSuiBytes(\n\tpublicKey: string | Uint8Array,\n\toptions: { client?: ClientWithCoreApi; address?: string } = {},\n) {\n\tconst bytes = typeof publicKey === 'string' ? fromBase64(publicKey) : publicKey;\n\n\tconst signatureScheme = SIGNATURE_FLAG_TO_SCHEME[bytes[0] as SignatureFlag];\n\n\treturn publicKeyFromRawBytes(signatureScheme, bytes.slice(1), options);\n}\n"],"mappings":"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"}
package/dist/version.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/version.ts
2
- const PACKAGE_VERSION = "2.18.0";
2
+ const PACKAGE_VERSION = "2.20.0";
3
3
 
4
4
  //#endregion
5
5
  export { PACKAGE_VERSION };
@@ -1 +1 @@
1
- {"version":3,"file":"version.mjs","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n// This file is generated by genversion.mjs. Do not edit it directly.\n\nexport const PACKAGE_VERSION = '2.18.0';\n"],"mappings":";AAKA,MAAa,kBAAkB"}
1
+ {"version":3,"file":"version.mjs","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n// This file is generated by genversion.mjs. Do not edit it directly.\n\nexport const PACKAGE_VERSION = '2.20.0';\n"],"mappings":";AAKA,MAAa,kBAAkB"}
@@ -1,31 +1,31 @@
1
- import * as _mysten_bcs810 from "@mysten/bcs";
1
+ import * as _mysten_bcs1111 from "@mysten/bcs";
2
2
  import { InferBcsInput } from "@mysten/bcs";
3
3
 
4
4
  //#region src/zklogin/bcs.d.ts
5
- declare const zkLoginSignature: _mysten_bcs810.BcsStruct<{
6
- inputs: _mysten_bcs810.BcsStruct<{
7
- proofPoints: _mysten_bcs810.BcsStruct<{
8
- a: _mysten_bcs810.BcsType<string[], Iterable<string> & {
5
+ declare const zkLoginSignature: _mysten_bcs1111.BcsStruct<{
6
+ inputs: _mysten_bcs1111.BcsStruct<{
7
+ proofPoints: _mysten_bcs1111.BcsStruct<{
8
+ a: _mysten_bcs1111.BcsType<string[], Iterable<string> & {
9
9
  length: number;
10
10
  }, string>;
11
- b: _mysten_bcs810.BcsType<string[][], Iterable<Iterable<string> & {
11
+ b: _mysten_bcs1111.BcsType<string[][], Iterable<Iterable<string> & {
12
12
  length: number;
13
13
  }> & {
14
14
  length: number;
15
15
  }, string>;
16
- c: _mysten_bcs810.BcsType<string[], Iterable<string> & {
16
+ c: _mysten_bcs1111.BcsType<string[], Iterable<string> & {
17
17
  length: number;
18
18
  }, string>;
19
19
  }, string>;
20
- issBase64Details: _mysten_bcs810.BcsStruct<{
21
- value: _mysten_bcs810.BcsType<string, string, "string">;
22
- indexMod4: _mysten_bcs810.BcsType<number, number, "u8">;
20
+ issBase64Details: _mysten_bcs1111.BcsStruct<{
21
+ value: _mysten_bcs1111.BcsType<string, string, "string">;
22
+ indexMod4: _mysten_bcs1111.BcsType<number, number, "u8">;
23
23
  }, string>;
24
- headerBase64: _mysten_bcs810.BcsType<string, string, "string">;
25
- addressSeed: _mysten_bcs810.BcsType<string, string, "string">;
24
+ headerBase64: _mysten_bcs1111.BcsType<string, string, "string">;
25
+ addressSeed: _mysten_bcs1111.BcsType<string, string, "string">;
26
26
  }, string>;
27
- maxEpoch: _mysten_bcs810.BcsType<string, string | number | bigint, "u64">;
28
- userSignature: _mysten_bcs810.BcsType<Uint8Array<ArrayBufferLike>, Iterable<number>, "vector<u8>">;
27
+ maxEpoch: _mysten_bcs1111.BcsType<string, string | number | bigint, "u64">;
28
+ userSignature: _mysten_bcs1111.BcsType<Uint8Array<ArrayBufferLike>, Iterable<number>, "vector<u8>">;
29
29
  }, string>;
30
30
  type ZkLoginSignature = InferBcsInput<typeof zkLoginSignature>;
31
31
  type ZkLoginSignatureInputs = ZkLoginSignature['inputs'];
@@ -1 +1 @@
1
- {"version":3,"file":"bcs.d.mts","names":[],"sources":["../../src/zklogin/bcs.ts"],"mappings":";;;;cAMa,gBAAA,iBAAgB,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;KAkBjB,gBAAA,GAAmB,aAAA,QAAqB,gBAAA;AAAA,KACxC,sBAAA,GAAyB,gBAAA"}
1
+ {"version":3,"file":"bcs.d.mts","names":[],"sources":["../../src/zklogin/bcs.ts"],"mappings":";;;;cAMa,gBAAA,kBAAgB,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;KAkBjB,gBAAA,GAAmB,aAAA,QAAqB,gBAAA;AAAA,KACxC,sBAAA,GAAyB,gBAAA"}
@@ -3,7 +3,8 @@ import { getZkLoginSignature, parseZkLoginSignature } from "./signature.mjs";
3
3
  import { genAddressSeed, getExtendedEphemeralPublicKey, hashASCIIStrToField, toBigEndianBytes, toPaddedBigEndianBytes } from "./utils.mjs";
4
4
  import { ComputeZkLoginAddressOptions, computeZkLoginAddress, computeZkLoginAddressFromSeed, jwtToAddress } from "./address.mjs";
5
5
  import { ZkLoginPublicIdentifier, toZkLoginPublicIdentifier } from "./publickey.mjs";
6
+ import { ZkLoginSigner, ZkLoginSignerOptions } from "./signer.mjs";
6
7
  import { poseidonHash } from "./poseidon.mjs";
7
8
  import { generateNonce, generateRandomness } from "./nonce.mjs";
8
9
  import { decodeJwt } from "./jwt-utils.mjs";
9
- export { type ComputeZkLoginAddressOptions, ZkLoginPublicIdentifier, type ZkLoginSignatureInputs, computeZkLoginAddress, computeZkLoginAddressFromSeed, decodeJwt, genAddressSeed, generateNonce, generateRandomness, getExtendedEphemeralPublicKey, getZkLoginSignature, hashASCIIStrToField, jwtToAddress, parseZkLoginSignature, poseidonHash, toBigEndianBytes, toPaddedBigEndianBytes, toZkLoginPublicIdentifier };
10
+ export { type ComputeZkLoginAddressOptions, ZkLoginPublicIdentifier, type ZkLoginSignatureInputs, ZkLoginSigner, type ZkLoginSignerOptions, computeZkLoginAddress, computeZkLoginAddressFromSeed, decodeJwt, genAddressSeed, generateNonce, generateRandomness, getExtendedEphemeralPublicKey, getZkLoginSignature, hashASCIIStrToField, jwtToAddress, parseZkLoginSignature, poseidonHash, toBigEndianBytes, toPaddedBigEndianBytes, toZkLoginPublicIdentifier };
@@ -4,6 +4,7 @@ import { decodeJwt } from "./jwt-utils.mjs";
4
4
  import { getZkLoginSignature, parseZkLoginSignature } from "./signature.mjs";
5
5
  import { ZkLoginPublicIdentifier, toZkLoginPublicIdentifier } from "./publickey.mjs";
6
6
  import { computeZkLoginAddress, computeZkLoginAddressFromSeed, jwtToAddress } from "./address.mjs";
7
+ import { ZkLoginSigner } from "./signer.mjs";
7
8
  import { generateNonce, generateRandomness } from "./nonce.mjs";
8
9
 
9
- export { ZkLoginPublicIdentifier, computeZkLoginAddress, computeZkLoginAddressFromSeed, decodeJwt, genAddressSeed, generateNonce, generateRandomness, getExtendedEphemeralPublicKey, getZkLoginSignature, hashASCIIStrToField, jwtToAddress, parseZkLoginSignature, poseidonHash, toBigEndianBytes, toPaddedBigEndianBytes, toZkLoginPublicIdentifier };
10
+ export { ZkLoginPublicIdentifier, ZkLoginSigner, computeZkLoginAddress, computeZkLoginAddressFromSeed, decodeJwt, genAddressSeed, generateNonce, generateRandomness, getExtendedEphemeralPublicKey, getZkLoginSignature, hashASCIIStrToField, jwtToAddress, parseZkLoginSignature, poseidonHash, toBigEndianBytes, toPaddedBigEndianBytes, toZkLoginPublicIdentifier };
@@ -17,6 +17,10 @@ declare class ZkLoginPublicIdentifier extends PublicKey {
17
17
  }?: {
18
18
  client?: ClientWithCoreApi;
19
19
  });
20
+ /**
21
+ * Whether this identifier resolves to the deprecated legacy address derivation.
22
+ */
23
+ get legacyAddress(): boolean;
20
24
  static fromBytes(bytes: Uint8Array, {
21
25
  client,
22
26
  address,
@@ -1 +1 @@
1
- {"version":3,"file":"publickey.d.mts","names":[],"sources":["../../src/zklogin/publickey.ts"],"mappings":";;;;;;AAoBA;;cAAa,uBAAA,SAAgC,SAAA;EAAA;EASJ;;;;cAA5B,KAAA,EAAO,iBAAA;IAAqB;EAAA;IAAY,MAAA,GAAS,iBAAA;EAAA;EAAA,OAmBtD,SAAA,CACN,KAAA,EAAO,UAAA;IAEN,MAAA;IACA,OAAA;IACA;EAAA;IACI,MAAA,GAAS,iBAAA;IAAmB,OAAA;IAAkB,aAAA;EAAA,IAA8B,uBAAA;EAAA,OAmC3E,SAAA,CAAU,OAAA,UAAiB,KAAA,EAAO,sBAAA,GAAsB,uBAAA;EAiExC;;;EAvCd,MAAA,CAAO,SAAA,EAAW,uBAAA;EAIlB,YAAA,CAAA;EA0CmE;;;EArB5E,UAAA,CAAA,GAAc,UAAA,CAAW,WAAA;EAxHmB;;;EA+H5C,IAAA,CAAA;;;;EAOM,MAAA,CAAO,QAAA,EAAU,UAAA,EAAY,UAAA,EAAY,UAAA,YAAsB,OAAA;EA7H7B;;;EAoIxC,qBAAA,CAAsB,OAAA,EAAS,UAAA,EAAY,SAAA,EAAW,UAAA,YAAsB,OAAA;EAjHrE;;;EAiIP,iBAAA,CAAkB,WAAA,EAAa,UAAA,EAAY,SAAA,EAAW,UAAA,YAAsB,OAAA;EA9H1E;;;EA6IO,aAAA,CAAc,OAAA;AAAA;AAAA,iBAMR,yBAAA,CACf,WAAA,UACA,GAAA,UACA,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,aAAA;AAAA,IACrC,uBAAA"}
1
+ {"version":3,"file":"publickey.d.mts","names":[],"sources":["../../src/zklogin/publickey.ts"],"mappings":";;;;;;AAoBA;;cAAa,uBAAA,SAAgC,SAAA;EAAA;EASJ;;;;cAA5B,KAAA,EAAO,iBAAA;IAAqB;EAAA;IAAY,MAAA,GAAS,iBAAA;EAAA;EAgCqB;;;EAAA,IAV9E,aAAA,CAAA;EAAA,OAIG,SAAA,CACN,KAAA,EAAO,UAAA;IAEN,MAAA;IACA,OAAA;IACA;EAAA;IACI,MAAA,GAAS,iBAAA;IAAmB,OAAA;IAAkB,aAAA;EAAA,IAA8B,uBAAA;EAAA,OAmC3E,SAAA,CAAU,OAAA,UAAiB,KAAA,EAAO,sBAAA,GAAsB,uBAAA;EAwET;;;EA9C7C,MAAA,CAAO,SAAA,EAAW,uBAAA;EAIlB,YAAA,CAAA;EA1GmC;;;EA+H5C,UAAA,CAAA,GAAc,UAAA,CAAW,WAAA;;;;EAOzB,IAAA,CAAA;EA7HwC;;;EAoIlC,MAAA,CAAO,QAAA,EAAU,UAAA,EAAY,UAAA,EAAY,UAAA,YAAsB,OAAA;EA9GjE;;;EAqHJ,qBAAA,CAAsB,OAAA,EAAS,UAAA,EAAY,SAAA,EAAW,UAAA,YAAsB,OAAA;EA9G1E;;;EA8HF,iBAAA,CAAkB,WAAA,EAAa,UAAA,EAAY,SAAA,EAAW,UAAA,YAAsB,OAAA;EA5H1E;;;EA2IO,aAAA,CAAc,OAAA;AAAA;AAAA,iBAMR,yBAAA,CACf,WAAA,UACA,GAAA,UACA,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,aAAA;AAAA,IACrC,uBAAA"}
@@ -29,6 +29,12 @@ var ZkLoginPublicIdentifier = class ZkLoginPublicIdentifier extends PublicKey {
29
29
  this.#legacyAddress = this.#data.length !== this.#data[0] + 1 + 32;
30
30
  if (this.#legacyAddress) this.#data = normalizeZkLoginPublicKeyBytes(this.#data, false);
31
31
  }
32
+ /**
33
+ * Whether this identifier resolves to the deprecated legacy address derivation.
34
+ */
35
+ get legacyAddress() {
36
+ return this.#legacyAddress;
37
+ }
32
38
  static fromBytes(bytes, { client, address, legacyAddress } = {}) {
33
39
  let publicKey;
34
40
  if (legacyAddress === true) publicKey = new ZkLoginPublicIdentifier(normalizeZkLoginPublicKeyBytes(bytes, true), { client });
@@ -1 +1 @@
1
- {"version":3,"file":"publickey.mjs","names":["#client","#data","#legacyAddress","#toLegacyAddress"],"sources":["../../src/zklogin/publickey.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromBase64, toBase64, toHex } from '@mysten/bcs';\nimport { blake2b } from '@noble/hashes/blake2.js';\nimport { bytesToHex } from '@noble/hashes/utils.js';\n\nimport { PublicKey } from '../cryptography/publickey.js';\nimport type { PublicKeyInitData } from '../cryptography/publickey.js';\nimport { SIGNATURE_SCHEME_TO_FLAG } from '../cryptography/signature-scheme.js';\nimport { normalizeSuiAddress, SUI_ADDRESS_LENGTH } from '../utils/sui-types.js';\nimport type { ZkLoginSignatureInputs } from './bcs.js';\nimport { extractClaimValue } from './jwt-utils.js';\nimport { parseZkLoginSignature } from './signature.js';\nimport { normalizeZkLoginIssuer, toBigEndianBytes, toPaddedBigEndianBytes } from './utils.js';\nimport type { ClientWithCoreApi } from '../client/core.js';\n\n/**\n * A zkLogin public identifier\n */\nexport class ZkLoginPublicIdentifier extends PublicKey {\n\t#data: Uint8Array<ArrayBuffer>;\n\t#client?: ClientWithCoreApi;\n\t#legacyAddress: boolean;\n\n\t/**\n\t * Create a new ZkLoginPublicIdentifier object\n\t * @param value zkLogin public identifier as buffer or base-64 encoded string\n\t */\n\tconstructor(value: PublicKeyInitData, { client }: { client?: ClientWithCoreApi } = {}) {\n\t\tsuper();\n\n\t\tthis.#client = client;\n\n\t\tif (typeof value === 'string') {\n\t\t\tthis.#data = fromBase64(value);\n\t\t} else if (value instanceof Uint8Array) {\n\t\t\tthis.#data = value as Uint8Array<ArrayBuffer>;\n\t\t} else {\n\t\t\tthis.#data = Uint8Array.from(value);\n\t\t}\n\t\tthis.#legacyAddress = this.#data.length !== this.#data[0] + 1 + 32;\n\n\t\tif (this.#legacyAddress) {\n\t\t\tthis.#data = normalizeZkLoginPublicKeyBytes(this.#data, false);\n\t\t}\n\t}\n\n\tstatic fromBytes(\n\t\tbytes: Uint8Array,\n\t\t{\n\t\t\tclient,\n\t\t\taddress,\n\t\t\tlegacyAddress,\n\t\t}: { client?: ClientWithCoreApi; address?: string; legacyAddress?: boolean } = {},\n\t) {\n\t\tlet publicKey: ZkLoginPublicIdentifier;\n\n\t\tif (legacyAddress === true) {\n\t\t\tpublicKey = new ZkLoginPublicIdentifier(normalizeZkLoginPublicKeyBytes(bytes, true), {\n\t\t\t\tclient,\n\t\t\t});\n\t\t} else if (legacyAddress === false) {\n\t\t\tpublicKey = new ZkLoginPublicIdentifier(normalizeZkLoginPublicKeyBytes(bytes, false), {\n\t\t\t\tclient,\n\t\t\t});\n\t\t} else if (address) {\n\t\t\tpublicKey = new ZkLoginPublicIdentifier(normalizeZkLoginPublicKeyBytes(bytes, false), {\n\t\t\t\tclient,\n\t\t\t});\n\n\t\t\tif (publicKey.toSuiAddress() !== address) {\n\t\t\t\tpublicKey = new ZkLoginPublicIdentifier(normalizeZkLoginPublicKeyBytes(bytes, true), {\n\t\t\t\t\tclient,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tpublicKey = new ZkLoginPublicIdentifier(bytes, {\n\t\t\t\tclient,\n\t\t\t});\n\t\t}\n\n\t\tif (address && publicKey.toSuiAddress() !== address) {\n\t\t\tthrow new Error('Public key bytes do not match the provided address');\n\t\t}\n\n\t\treturn publicKey;\n\t}\n\n\tstatic fromProof(address: string, proof: ZkLoginSignatureInputs) {\n\t\tconst { issBase64Details, addressSeed } = proof;\n\t\tconst iss = extractClaimValue<string>(issBase64Details, 'iss');\n\n\t\tconst legacyPublicKey = toZkLoginPublicIdentifier(BigInt(addressSeed), iss, {\n\t\t\tlegacyAddress: true,\n\t\t});\n\n\t\tif (legacyPublicKey.toSuiAddress() === address) {\n\t\t\treturn legacyPublicKey;\n\t\t}\n\n\t\tconst publicKey = toZkLoginPublicIdentifier(BigInt(addressSeed), iss, {\n\t\t\tlegacyAddress: false,\n\t\t});\n\n\t\tif (publicKey.toSuiAddress() !== address) {\n\t\t\tthrow new Error('Proof does not match address');\n\t\t}\n\n\t\treturn publicKey;\n\t}\n\n\t/**\n\t * Checks if two zkLogin public identifiers are equal\n\t */\n\toverride equals(publicKey: ZkLoginPublicIdentifier): boolean {\n\t\treturn super.equals(publicKey);\n\t}\n\n\toverride toSuiAddress(): string {\n\t\tif (this.#legacyAddress) {\n\t\t\treturn this.#toLegacyAddress();\n\t\t}\n\n\t\treturn super.toSuiAddress();\n\t}\n\n\t#toLegacyAddress() {\n\t\tconst legacyBytes = normalizeZkLoginPublicKeyBytes(this.#data, true);\n\t\tconst addressBytes = new Uint8Array(legacyBytes.length + 1);\n\t\taddressBytes[0] = this.flag();\n\t\taddressBytes.set(legacyBytes, 1);\n\t\treturn normalizeSuiAddress(\n\t\t\tbytesToHex(blake2b(addressBytes, { dkLen: 32 })).slice(0, SUI_ADDRESS_LENGTH * 2),\n\t\t);\n\t}\n\n\t/**\n\t * Return the byte array representation of the zkLogin public identifier\n\t */\n\ttoRawBytes(): Uint8Array<ArrayBuffer> {\n\t\treturn this.#data;\n\t}\n\n\t/**\n\t * Return the Sui address associated with this ZkLogin public identifier\n\t */\n\tflag(): number {\n\t\treturn SIGNATURE_SCHEME_TO_FLAG['ZkLogin'];\n\t}\n\n\t/**\n\t * Verifies that the signature is valid for for the provided message\n\t */\n\tasync verify(_message: Uint8Array, _signature: Uint8Array | string): Promise<boolean> {\n\t\tthrow Error('does not support');\n\t}\n\n\t/**\n\t * Verifies that the signature is valid for for the provided PersonalMessage\n\t */\n\tverifyPersonalMessage(message: Uint8Array, signature: Uint8Array | string): Promise<boolean> {\n\t\tconst parsedSignature = parseSerializedZkLoginSignature(signature);\n\t\tconst address = new ZkLoginPublicIdentifier(parsedSignature.publicKey).toSuiAddress();\n\n\t\treturn graphqlVerifyZkLoginSignature({\n\t\t\taddress: address,\n\t\t\tbytes: toBase64(message),\n\t\t\tsignature: parsedSignature.serializedSignature,\n\t\t\tintentScope: 'PersonalMessage',\n\t\t\tclient: this.#client,\n\t\t});\n\t}\n\n\t/**\n\t * Verifies that the signature is valid for for the provided Transaction\n\t */\n\tverifyTransaction(transaction: Uint8Array, signature: Uint8Array | string): Promise<boolean> {\n\t\tconst parsedSignature = parseSerializedZkLoginSignature(signature);\n\t\tconst address = new ZkLoginPublicIdentifier(parsedSignature.publicKey).toSuiAddress();\n\t\treturn graphqlVerifyZkLoginSignature({\n\t\t\taddress: address,\n\t\t\tbytes: toBase64(transaction),\n\t\t\tsignature: parsedSignature.serializedSignature,\n\t\t\tintentScope: 'TransactionData',\n\t\t\tclient: this.#client,\n\t\t});\n\t}\n\n\t/**\n\t * Verifies that the public key is associated with the provided address\n\t */\n\toverride verifyAddress(address: string): boolean {\n\t\treturn address === super.toSuiAddress() || address === this.#toLegacyAddress();\n\t}\n}\n\n// Derive the public identifier for zklogin based on address seed and iss.\nexport function toZkLoginPublicIdentifier(\n\taddressSeed: bigint,\n\tiss: string,\n\toptions: { client?: ClientWithCoreApi; legacyAddress: boolean },\n): ZkLoginPublicIdentifier {\n\tif (options.legacyAddress === undefined) {\n\t\tthrow new Error('legacyAddress parameter must be specified');\n\t}\n\t// Consists of iss_bytes_len || iss_bytes || padded_32_byte_address_seed.\n\tconst addressSeedBytesBigEndian = options.legacyAddress\n\t\t? toBigEndianBytes(addressSeed, 32)\n\t\t: toPaddedBigEndianBytes(addressSeed, 32);\n\n\tconst issBytes = new TextEncoder().encode(normalizeZkLoginIssuer(iss));\n\tconst tmp = new Uint8Array(1 + issBytes.length + addressSeedBytesBigEndian.length);\n\ttmp.set([issBytes.length], 0);\n\ttmp.set(issBytes, 1);\n\ttmp.set(addressSeedBytesBigEndian, 1 + issBytes.length);\n\treturn new ZkLoginPublicIdentifier(tmp, options);\n}\n\nfunction normalizeZkLoginPublicKeyBytes(bytes: Uint8Array, legacyAddress: boolean) {\n\tconst issByteLength = bytes[0] + 1;\n\tconst addressSeed = BigInt(`0x${toHex(bytes.slice(issByteLength))}`);\n\tconst seedBytes = legacyAddress\n\t\t? toBigEndianBytes(addressSeed, 32)\n\t\t: toPaddedBigEndianBytes(addressSeed, 32);\n\tconst data = new Uint8Array(issByteLength + seedBytes.length);\n\tdata.set(bytes.slice(0, issByteLength), 0);\n\tdata.set(seedBytes, issByteLength);\n\treturn data;\n}\n\nasync function graphqlVerifyZkLoginSignature({\n\taddress,\n\tbytes,\n\tsignature,\n\tintentScope,\n\tclient,\n}: {\n\taddress: string;\n\tbytes: string;\n\tsignature: string;\n\tintentScope: 'PersonalMessage' | 'TransactionData';\n\tclient?: ClientWithCoreApi;\n}) {\n\tif (!client) {\n\t\tthrow new Error(\n\t\t\t'A Sui Client (GRPC, GraphQL, or JSON RPC) is required to verify zkLogin signatures',\n\t\t);\n\t}\n\tconst resp = await client.core.verifyZkLoginSignature({\n\t\tbytes,\n\t\tsignature,\n\t\tintentScope,\n\t\taddress: address,\n\t});\n\n\treturn resp.success === true && resp.errors.length === 0;\n}\n\nexport function parseSerializedZkLoginSignature(signature: Uint8Array | string) {\n\tconst bytes = typeof signature === 'string' ? fromBase64(signature) : signature;\n\n\tif (bytes[0] !== SIGNATURE_SCHEME_TO_FLAG.ZkLogin) {\n\t\tthrow new Error('Invalid signature scheme');\n\t}\n\n\tconst signatureBytes = bytes.slice(1);\n\tconst { inputs, maxEpoch, userSignature } = parseZkLoginSignature(signatureBytes);\n\tconst { issBase64Details, addressSeed } = inputs;\n\tconst iss = extractClaimValue<string>(issBase64Details, 'iss');\n\tconst publicIdentifier = toZkLoginPublicIdentifier(BigInt(addressSeed), iss, {\n\t\tlegacyAddress: false,\n\t});\n\treturn {\n\t\tserializedSignature: toBase64(bytes),\n\t\tsignatureScheme: 'ZkLogin' as const,\n\t\tzkLogin: {\n\t\t\tinputs,\n\t\t\tmaxEpoch,\n\t\t\tuserSignature,\n\t\t\tiss,\n\t\t\taddressSeed: BigInt(addressSeed),\n\t\t},\n\t\tsignature: bytes,\n\t\tpublicKey: publicIdentifier.toRawBytes(),\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"publickey.mjs","names":["#client","#data","#legacyAddress","#toLegacyAddress"],"sources":["../../src/zklogin/publickey.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromBase64, toBase64, toHex } from '@mysten/bcs';\nimport { blake2b } from '@noble/hashes/blake2.js';\nimport { bytesToHex } from '@noble/hashes/utils.js';\n\nimport { PublicKey } from '../cryptography/publickey.js';\nimport type { PublicKeyInitData } from '../cryptography/publickey.js';\nimport { SIGNATURE_SCHEME_TO_FLAG } from '../cryptography/signature-scheme.js';\nimport { normalizeSuiAddress, SUI_ADDRESS_LENGTH } from '../utils/sui-types.js';\nimport type { ZkLoginSignatureInputs } from './bcs.js';\nimport { extractClaimValue } from './jwt-utils.js';\nimport { parseZkLoginSignature } from './signature.js';\nimport { normalizeZkLoginIssuer, toBigEndianBytes, toPaddedBigEndianBytes } from './utils.js';\nimport type { ClientWithCoreApi } from '../client/core.js';\n\n/**\n * A zkLogin public identifier\n */\nexport class ZkLoginPublicIdentifier extends PublicKey {\n\t#data: Uint8Array<ArrayBuffer>;\n\t#client?: ClientWithCoreApi;\n\t#legacyAddress: boolean;\n\n\t/**\n\t * Create a new ZkLoginPublicIdentifier object\n\t * @param value zkLogin public identifier as buffer or base-64 encoded string\n\t */\n\tconstructor(value: PublicKeyInitData, { client }: { client?: ClientWithCoreApi } = {}) {\n\t\tsuper();\n\n\t\tthis.#client = client;\n\n\t\tif (typeof value === 'string') {\n\t\t\tthis.#data = fromBase64(value);\n\t\t} else if (value instanceof Uint8Array) {\n\t\t\tthis.#data = value as Uint8Array<ArrayBuffer>;\n\t\t} else {\n\t\t\tthis.#data = Uint8Array.from(value);\n\t\t}\n\t\tthis.#legacyAddress = this.#data.length !== this.#data[0] + 1 + 32;\n\n\t\tif (this.#legacyAddress) {\n\t\t\tthis.#data = normalizeZkLoginPublicKeyBytes(this.#data, false);\n\t\t}\n\t}\n\n\t/**\n\t * Whether this identifier resolves to the deprecated legacy address derivation.\n\t */\n\tget legacyAddress(): boolean {\n\t\treturn this.#legacyAddress;\n\t}\n\n\tstatic fromBytes(\n\t\tbytes: Uint8Array,\n\t\t{\n\t\t\tclient,\n\t\t\taddress,\n\t\t\tlegacyAddress,\n\t\t}: { client?: ClientWithCoreApi; address?: string; legacyAddress?: boolean } = {},\n\t) {\n\t\tlet publicKey: ZkLoginPublicIdentifier;\n\n\t\tif (legacyAddress === true) {\n\t\t\tpublicKey = new ZkLoginPublicIdentifier(normalizeZkLoginPublicKeyBytes(bytes, true), {\n\t\t\t\tclient,\n\t\t\t});\n\t\t} else if (legacyAddress === false) {\n\t\t\tpublicKey = new ZkLoginPublicIdentifier(normalizeZkLoginPublicKeyBytes(bytes, false), {\n\t\t\t\tclient,\n\t\t\t});\n\t\t} else if (address) {\n\t\t\tpublicKey = new ZkLoginPublicIdentifier(normalizeZkLoginPublicKeyBytes(bytes, false), {\n\t\t\t\tclient,\n\t\t\t});\n\n\t\t\tif (publicKey.toSuiAddress() !== address) {\n\t\t\t\tpublicKey = new ZkLoginPublicIdentifier(normalizeZkLoginPublicKeyBytes(bytes, true), {\n\t\t\t\t\tclient,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tpublicKey = new ZkLoginPublicIdentifier(bytes, {\n\t\t\t\tclient,\n\t\t\t});\n\t\t}\n\n\t\tif (address && publicKey.toSuiAddress() !== address) {\n\t\t\tthrow new Error('Public key bytes do not match the provided address');\n\t\t}\n\n\t\treturn publicKey;\n\t}\n\n\tstatic fromProof(address: string, proof: ZkLoginSignatureInputs) {\n\t\tconst { issBase64Details, addressSeed } = proof;\n\t\tconst iss = extractClaimValue<string>(issBase64Details, 'iss');\n\n\t\tconst legacyPublicKey = toZkLoginPublicIdentifier(BigInt(addressSeed), iss, {\n\t\t\tlegacyAddress: true,\n\t\t});\n\n\t\tif (legacyPublicKey.toSuiAddress() === address) {\n\t\t\treturn legacyPublicKey;\n\t\t}\n\n\t\tconst publicKey = toZkLoginPublicIdentifier(BigInt(addressSeed), iss, {\n\t\t\tlegacyAddress: false,\n\t\t});\n\n\t\tif (publicKey.toSuiAddress() !== address) {\n\t\t\tthrow new Error('Proof does not match address');\n\t\t}\n\n\t\treturn publicKey;\n\t}\n\n\t/**\n\t * Checks if two zkLogin public identifiers are equal\n\t */\n\toverride equals(publicKey: ZkLoginPublicIdentifier): boolean {\n\t\treturn super.equals(publicKey);\n\t}\n\n\toverride toSuiAddress(): string {\n\t\tif (this.#legacyAddress) {\n\t\t\treturn this.#toLegacyAddress();\n\t\t}\n\n\t\treturn super.toSuiAddress();\n\t}\n\n\t#toLegacyAddress() {\n\t\tconst legacyBytes = normalizeZkLoginPublicKeyBytes(this.#data, true);\n\t\tconst addressBytes = new Uint8Array(legacyBytes.length + 1);\n\t\taddressBytes[0] = this.flag();\n\t\taddressBytes.set(legacyBytes, 1);\n\t\treturn normalizeSuiAddress(\n\t\t\tbytesToHex(blake2b(addressBytes, { dkLen: 32 })).slice(0, SUI_ADDRESS_LENGTH * 2),\n\t\t);\n\t}\n\n\t/**\n\t * Return the byte array representation of the zkLogin public identifier\n\t */\n\ttoRawBytes(): Uint8Array<ArrayBuffer> {\n\t\treturn this.#data;\n\t}\n\n\t/**\n\t * Return the Sui address associated with this ZkLogin public identifier\n\t */\n\tflag(): number {\n\t\treturn SIGNATURE_SCHEME_TO_FLAG['ZkLogin'];\n\t}\n\n\t/**\n\t * Verifies that the signature is valid for for the provided message\n\t */\n\tasync verify(_message: Uint8Array, _signature: Uint8Array | string): Promise<boolean> {\n\t\tthrow Error('does not support');\n\t}\n\n\t/**\n\t * Verifies that the signature is valid for for the provided PersonalMessage\n\t */\n\tverifyPersonalMessage(message: Uint8Array, signature: Uint8Array | string): Promise<boolean> {\n\t\tconst parsedSignature = parseSerializedZkLoginSignature(signature);\n\t\tconst address = new ZkLoginPublicIdentifier(parsedSignature.publicKey).toSuiAddress();\n\n\t\treturn graphqlVerifyZkLoginSignature({\n\t\t\taddress: address,\n\t\t\tbytes: toBase64(message),\n\t\t\tsignature: parsedSignature.serializedSignature,\n\t\t\tintentScope: 'PersonalMessage',\n\t\t\tclient: this.#client,\n\t\t});\n\t}\n\n\t/**\n\t * Verifies that the signature is valid for for the provided Transaction\n\t */\n\tverifyTransaction(transaction: Uint8Array, signature: Uint8Array | string): Promise<boolean> {\n\t\tconst parsedSignature = parseSerializedZkLoginSignature(signature);\n\t\tconst address = new ZkLoginPublicIdentifier(parsedSignature.publicKey).toSuiAddress();\n\t\treturn graphqlVerifyZkLoginSignature({\n\t\t\taddress: address,\n\t\t\tbytes: toBase64(transaction),\n\t\t\tsignature: parsedSignature.serializedSignature,\n\t\t\tintentScope: 'TransactionData',\n\t\t\tclient: this.#client,\n\t\t});\n\t}\n\n\t/**\n\t * Verifies that the public key is associated with the provided address\n\t */\n\toverride verifyAddress(address: string): boolean {\n\t\treturn address === super.toSuiAddress() || address === this.#toLegacyAddress();\n\t}\n}\n\n// Derive the public identifier for zklogin based on address seed and iss.\nexport function toZkLoginPublicIdentifier(\n\taddressSeed: bigint,\n\tiss: string,\n\toptions: { client?: ClientWithCoreApi; legacyAddress: boolean },\n): ZkLoginPublicIdentifier {\n\tif (options.legacyAddress === undefined) {\n\t\tthrow new Error('legacyAddress parameter must be specified');\n\t}\n\t// Consists of iss_bytes_len || iss_bytes || padded_32_byte_address_seed.\n\tconst addressSeedBytesBigEndian = options.legacyAddress\n\t\t? toBigEndianBytes(addressSeed, 32)\n\t\t: toPaddedBigEndianBytes(addressSeed, 32);\n\n\tconst issBytes = new TextEncoder().encode(normalizeZkLoginIssuer(iss));\n\tconst tmp = new Uint8Array(1 + issBytes.length + addressSeedBytesBigEndian.length);\n\ttmp.set([issBytes.length], 0);\n\ttmp.set(issBytes, 1);\n\ttmp.set(addressSeedBytesBigEndian, 1 + issBytes.length);\n\treturn new ZkLoginPublicIdentifier(tmp, options);\n}\n\nfunction normalizeZkLoginPublicKeyBytes(bytes: Uint8Array, legacyAddress: boolean) {\n\tconst issByteLength = bytes[0] + 1;\n\tconst addressSeed = BigInt(`0x${toHex(bytes.slice(issByteLength))}`);\n\tconst seedBytes = legacyAddress\n\t\t? toBigEndianBytes(addressSeed, 32)\n\t\t: toPaddedBigEndianBytes(addressSeed, 32);\n\tconst data = new Uint8Array(issByteLength + seedBytes.length);\n\tdata.set(bytes.slice(0, issByteLength), 0);\n\tdata.set(seedBytes, issByteLength);\n\treturn data;\n}\n\nasync function graphqlVerifyZkLoginSignature({\n\taddress,\n\tbytes,\n\tsignature,\n\tintentScope,\n\tclient,\n}: {\n\taddress: string;\n\tbytes: string;\n\tsignature: string;\n\tintentScope: 'PersonalMessage' | 'TransactionData';\n\tclient?: ClientWithCoreApi;\n}) {\n\tif (!client) {\n\t\tthrow new Error(\n\t\t\t'A Sui Client (GRPC, GraphQL, or JSON RPC) is required to verify zkLogin signatures',\n\t\t);\n\t}\n\tconst resp = await client.core.verifyZkLoginSignature({\n\t\tbytes,\n\t\tsignature,\n\t\tintentScope,\n\t\taddress: address,\n\t});\n\n\treturn resp.success === true && resp.errors.length === 0;\n}\n\nexport function parseSerializedZkLoginSignature(signature: Uint8Array | string) {\n\tconst bytes = typeof signature === 'string' ? fromBase64(signature) : signature;\n\n\tif (bytes[0] !== SIGNATURE_SCHEME_TO_FLAG.ZkLogin) {\n\t\tthrow new Error('Invalid signature scheme');\n\t}\n\n\tconst signatureBytes = bytes.slice(1);\n\tconst { inputs, maxEpoch, userSignature } = parseZkLoginSignature(signatureBytes);\n\tconst { issBase64Details, addressSeed } = inputs;\n\tconst iss = extractClaimValue<string>(issBase64Details, 'iss');\n\tconst publicIdentifier = toZkLoginPublicIdentifier(BigInt(addressSeed), iss, {\n\t\tlegacyAddress: false,\n\t});\n\treturn {\n\t\tserializedSignature: toBase64(bytes),\n\t\tsignatureScheme: 'ZkLogin' as const,\n\t\tzkLogin: {\n\t\t\tinputs,\n\t\t\tmaxEpoch,\n\t\t\tuserSignature,\n\t\t\tiss,\n\t\t\taddressSeed: BigInt(addressSeed),\n\t\t},\n\t\tsignature: bytes,\n\t\tpublicKey: publicIdentifier.toRawBytes(),\n\t};\n}\n"],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { IntentScope } from "../cryptography/intent.mjs";
2
+ import { SignatureScheme } from "../cryptography/signature-scheme.mjs";
3
+ import { SignatureWithBytes, Signer } from "../cryptography/keypair.mjs";
4
+ import { ClientWithCoreApi } from "../client/core.mjs";
5
+ import { ZkLoginSignatureInputs } from "./bcs.mjs";
6
+ import { ZkLoginPublicIdentifier } from "./publickey.mjs";
7
+
8
+ //#region src/zklogin/signer.d.ts
9
+ interface ZkLoginSignerOptions {
10
+ /** The ephemeral signer whose signature is wrapped by the zkLogin proof. */
11
+ ephemeralSigner: Signer;
12
+ /** The maxEpoch the proof was generated for. */
13
+ maxEpoch: number;
14
+ /** The zkLogin proof inputs, including the `addressSeed`. */
15
+ inputs: ZkLoginSignatureInputs;
16
+ /**
17
+ * Whether this account uses the deprecated legacy address derivation. The zkLogin address is
18
+ * derived from the proof inputs; this flag disambiguates legacy vs. current derivation, matching
19
+ * the rest of the zkLogin address API (e.g. `jwtToAddress`, `toZkLoginPublicIdentifier`).
20
+ *
21
+ * A wrong flag silently yields a signer for the wrong address; pass `address` to guard against it.
22
+ */
23
+ legacyAddress: boolean;
24
+ /**
25
+ * The expected zkLogin address. When provided, the address derived from `inputs` + `legacyAddress`
26
+ * is validated against it and the constructor throws on mismatch — guarding against a wrong
27
+ * `legacyAddress` flag producing a signer for the wrong address.
28
+ */
29
+ address?: string;
30
+ /** Optional client, threaded into the derived public key so it can verify signatures. */
31
+ client?: ClientWithCoreApi;
32
+ }
33
+ /**
34
+ * A transport- and provider-agnostic zkLogin signer.
35
+ *
36
+ * It wraps any ephemeral {@link Signer} and, for every signing operation, transforms the ephemeral
37
+ * signature into a zkLogin signature using the supplied proof inputs and `maxEpoch`. Because every
38
+ * signing method on {@link Signer} funnels through `signWithIntent`, overriding that single method is
39
+ * enough to cover `signTransaction`, `signPersonalMessage`, and `signAndExecuteTransaction`.
40
+ */
41
+ declare class ZkLoginSigner extends Signer {
42
+ #private;
43
+ constructor(options: ZkLoginSignerOptions);
44
+ /**
45
+ * The single extension point: the ephemeral signature is produced with the requested intent and
46
+ * then wrapped in a zkLogin signature.
47
+ */
48
+ signWithIntent(bytes: Uint8Array, intent: IntentScope): Promise<SignatureWithBytes>;
49
+ sign(_data: Uint8Array): never;
50
+ getKeyScheme(): SignatureScheme;
51
+ getPublicKey(): ZkLoginPublicIdentifier;
52
+ }
53
+ //#endregion
54
+ export { ZkLoginSigner, ZkLoginSignerOptions };
55
+ //# sourceMappingURL=signer.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer.d.mts","names":[],"sources":["../../src/zklogin/signer.ts"],"mappings":";;;;;;;;UAaiB,oBAAA;EAAA;EAEhB,eAAA,EAAiB,MAAA;;EAEjB,QAAA;EAEQ;EAAR,MAAA,EAAQ,sBAAA;EAgBkB;;;;;;;EAR1B,aAAA;EAMA;;;;;EAAA,OAAA;EAa0B;EAX1B,MAAA,GAAS,iBAAA;AAAA;;;;;;;;;cAWG,aAAA,SAAsB,MAAA;EAAA;cAQtB,OAAA,EAAS,oBAAA;;;;;EAoCN,cAAA,CACd,KAAA,EAAO,UAAA,EACP,MAAA,EAAQ,WAAA,GACN,OAAA,CAAQ,kBAAA;EAcX,IAAA,CAAK,KAAA,EAAO,UAAA;EAMZ,YAAA,CAAA,GAAgB,eAAA;EAIhB,YAAA,CAAA,GAAgB,uBAAA;AAAA"}
@@ -0,0 +1,68 @@
1
+ import { extractClaimValue } from "./jwt-utils.mjs";
2
+ import { getZkLoginSignature } from "./signature.mjs";
3
+ import { toZkLoginPublicIdentifier } from "./publickey.mjs";
4
+ import { Signer } from "../cryptography/keypair.mjs";
5
+
6
+ //#region src/zklogin/signer.ts
7
+ /**
8
+ * A transport- and provider-agnostic zkLogin signer.
9
+ *
10
+ * It wraps any ephemeral {@link Signer} and, for every signing operation, transforms the ephemeral
11
+ * signature into a zkLogin signature using the supplied proof inputs and `maxEpoch`. Because every
12
+ * signing method on {@link Signer} funnels through `signWithIntent`, overriding that single method is
13
+ * enough to cover `signTransaction`, `signPersonalMessage`, and `signAndExecuteTransaction`.
14
+ */
15
+ var ZkLoginSigner = class extends Signer {
16
+ #ephemeralSigner;
17
+ #maxEpoch;
18
+ #inputs;
19
+ #legacyAddress;
20
+ #client;
21
+ #publicKey;
22
+ constructor(options) {
23
+ super();
24
+ this.#ephemeralSigner = options.ephemeralSigner;
25
+ this.#maxEpoch = options.maxEpoch;
26
+ this.#inputs = options.inputs;
27
+ this.#legacyAddress = options.legacyAddress;
28
+ this.#client = options.client;
29
+ if (options.address !== void 0) {
30
+ const derived = this.#derivePublicKey().toSuiAddress();
31
+ if (derived !== options.address) throw new Error(`zkLogin proof does not match the provided address (derived ${derived}, expected ${options.address}) — check the \`legacyAddress\` flag`);
32
+ }
33
+ }
34
+ #derivePublicKey() {
35
+ return this.#publicKey ??= toZkLoginPublicIdentifier(BigInt(this.#inputs.addressSeed), extractClaimValue(this.#inputs.issBase64Details, "iss"), {
36
+ legacyAddress: this.#legacyAddress,
37
+ client: this.#client
38
+ });
39
+ }
40
+ /**
41
+ * The single extension point: the ephemeral signature is produced with the requested intent and
42
+ * then wrapped in a zkLogin signature.
43
+ */
44
+ async signWithIntent(bytes, intent) {
45
+ const { bytes: signedBytes, signature: userSignature } = await this.#ephemeralSigner.signWithIntent(bytes, intent);
46
+ return {
47
+ bytes: signedBytes,
48
+ signature: getZkLoginSignature({
49
+ inputs: this.#inputs,
50
+ maxEpoch: this.#maxEpoch,
51
+ userSignature
52
+ })
53
+ };
54
+ }
55
+ sign(_data) {
56
+ throw new Error("ZkLoginSigner does not support signing directly. Use signTransaction or signPersonalMessage instead");
57
+ }
58
+ getKeyScheme() {
59
+ return "ZkLogin";
60
+ }
61
+ getPublicKey() {
62
+ return this.#derivePublicKey();
63
+ }
64
+ };
65
+
66
+ //#endregion
67
+ export { ZkLoginSigner };
68
+ //# sourceMappingURL=signer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer.mjs","names":["#ephemeralSigner","#maxEpoch","#inputs","#legacyAddress","#client","#derivePublicKey","#publicKey"],"sources":["../../src/zklogin/signer.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ClientWithCoreApi } from '../client/core.js';\nimport type { IntentScope } from '../cryptography/intent.js';\nimport type { SignatureWithBytes } from '../cryptography/keypair.js';\nimport { Signer } from '../cryptography/keypair.js';\nimport type { SignatureScheme } from '../cryptography/signature-scheme.js';\nimport type { ZkLoginSignatureInputs } from './bcs.js';\nimport { extractClaimValue } from './jwt-utils.js';\nimport { toZkLoginPublicIdentifier, ZkLoginPublicIdentifier } from './publickey.js';\nimport { getZkLoginSignature } from './signature.js';\n\nexport interface ZkLoginSignerOptions {\n\t/** The ephemeral signer whose signature is wrapped by the zkLogin proof. */\n\tephemeralSigner: Signer;\n\t/** The maxEpoch the proof was generated for. */\n\tmaxEpoch: number;\n\t/** The zkLogin proof inputs, including the `addressSeed`. */\n\tinputs: ZkLoginSignatureInputs;\n\t/**\n\t * Whether this account uses the deprecated legacy address derivation. The zkLogin address is\n\t * derived from the proof inputs; this flag disambiguates legacy vs. current derivation, matching\n\t * the rest of the zkLogin address API (e.g. `jwtToAddress`, `toZkLoginPublicIdentifier`).\n\t *\n\t * A wrong flag silently yields a signer for the wrong address; pass `address` to guard against it.\n\t */\n\tlegacyAddress: boolean;\n\t/**\n\t * The expected zkLogin address. When provided, the address derived from `inputs` + `legacyAddress`\n\t * is validated against it and the constructor throws on mismatch — guarding against a wrong\n\t * `legacyAddress` flag producing a signer for the wrong address.\n\t */\n\taddress?: string;\n\t/** Optional client, threaded into the derived public key so it can verify signatures. */\n\tclient?: ClientWithCoreApi;\n}\n\n/**\n * A transport- and provider-agnostic zkLogin signer.\n *\n * It wraps any ephemeral {@link Signer} and, for every signing operation, transforms the ephemeral\n * signature into a zkLogin signature using the supplied proof inputs and `maxEpoch`. Because every\n * signing method on {@link Signer} funnels through `signWithIntent`, overriding that single method is\n * enough to cover `signTransaction`, `signPersonalMessage`, and `signAndExecuteTransaction`.\n */\nexport class ZkLoginSigner extends Signer {\n\t#ephemeralSigner: Signer;\n\t#maxEpoch: number;\n\t#inputs: ZkLoginSignatureInputs;\n\t#legacyAddress: boolean;\n\t#client?: ClientWithCoreApi;\n\t#publicKey?: ZkLoginPublicIdentifier;\n\n\tconstructor(options: ZkLoginSignerOptions) {\n\t\tsuper();\n\t\tthis.#ephemeralSigner = options.ephemeralSigner;\n\t\tthis.#maxEpoch = options.maxEpoch;\n\t\tthis.#inputs = options.inputs;\n\t\tthis.#legacyAddress = options.legacyAddress;\n\t\tthis.#client = options.client;\n\n\t\tif (options.address !== undefined) {\n\t\t\tconst derived = this.#derivePublicKey().toSuiAddress();\n\t\t\tif (derived !== options.address) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`zkLogin proof does not match the provided address (derived ${derived}, expected ` +\n\t\t\t\t\t\t`${options.address}) — check the \\`legacyAddress\\` flag`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Shared derive-and-memoize used by both the constructor's address validation and getPublicKey().\n\t// It is `#private` (non-virtual) on purpose: the constructor must derive the *base* address even\n\t// when a subclass overrides getPublicKey() — calling the overridable getPublicKey() from the\n\t// constructor would dispatch to the subclass before its fields are initialized. Laziness also\n\t// means subclasses that override getPublicKey() (e.g. EnokiKeypair) never pay for this derivation.\n\t#derivePublicKey(): ZkLoginPublicIdentifier {\n\t\treturn (this.#publicKey ??= toZkLoginPublicIdentifier(\n\t\t\tBigInt(this.#inputs.addressSeed),\n\t\t\textractClaimValue<string>(this.#inputs.issBase64Details, 'iss'),\n\t\t\t{ legacyAddress: this.#legacyAddress, client: this.#client },\n\t\t));\n\t}\n\n\t/**\n\t * The single extension point: the ephemeral signature is produced with the requested intent and\n\t * then wrapped in a zkLogin signature.\n\t */\n\toverride async signWithIntent(\n\t\tbytes: Uint8Array,\n\t\tintent: IntentScope,\n\t): Promise<SignatureWithBytes> {\n\t\tconst { bytes: signedBytes, signature: userSignature } =\n\t\t\tawait this.#ephemeralSigner.signWithIntent(bytes, intent);\n\n\t\treturn {\n\t\t\tbytes: signedBytes,\n\t\t\tsignature: getZkLoginSignature({\n\t\t\t\tinputs: this.#inputs,\n\t\t\t\tmaxEpoch: this.#maxEpoch,\n\t\t\t\tuserSignature,\n\t\t\t}),\n\t\t};\n\t}\n\n\tsign(_data: Uint8Array): never {\n\t\tthrow new Error(\n\t\t\t'ZkLoginSigner does not support signing directly. Use signTransaction or signPersonalMessage instead',\n\t\t);\n\t}\n\n\tgetKeyScheme(): SignatureScheme {\n\t\treturn 'ZkLogin';\n\t}\n\n\tgetPublicKey(): ZkLoginPublicIdentifier {\n\t\treturn this.#derivePublicKey();\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;AA8CA,IAAa,gBAAb,cAAmC,OAAO;CACzC;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,SAA+B;AAC1C,SAAO;AACP,QAAKA,kBAAmB,QAAQ;AAChC,QAAKC,WAAY,QAAQ;AACzB,QAAKC,SAAU,QAAQ;AACvB,QAAKC,gBAAiB,QAAQ;AAC9B,QAAKC,SAAU,QAAQ;AAEvB,MAAI,QAAQ,YAAY,QAAW;GAClC,MAAM,UAAU,MAAKC,iBAAkB,CAAC,cAAc;AACtD,OAAI,YAAY,QAAQ,QACvB,OAAM,IAAI,MACT,8DAA8D,QAAQ,aAClE,QAAQ,QAAQ,sCACpB;;;CAUJ,mBAA4C;AAC3C,SAAQ,MAAKC,cAAe,0BAC3B,OAAO,MAAKJ,OAAQ,YAAY,EAChC,kBAA0B,MAAKA,OAAQ,kBAAkB,MAAM,EAC/D;GAAE,eAAe,MAAKC;GAAgB,QAAQ,MAAKC;GAAS,CAC5D;;;;;;CAOF,MAAe,eACd,OACA,QAC8B;EAC9B,MAAM,EAAE,OAAO,aAAa,WAAW,kBACtC,MAAM,MAAKJ,gBAAiB,eAAe,OAAO,OAAO;AAE1D,SAAO;GACN,OAAO;GACP,WAAW,oBAAoB;IAC9B,QAAQ,MAAKE;IACb,UAAU,MAAKD;IACf;IACA,CAAC;GACF;;CAGF,KAAK,OAA0B;AAC9B,QAAM,IAAI,MACT,sGACA;;CAGF,eAAgC;AAC/B,SAAO;;CAGR,eAAwC;AACvC,SAAO,MAAKI,iBAAkB"}
@@ -185,7 +185,11 @@ The built-in mutation hooks have been removed. Use TanStack Query's `useMutation
185
185
 
186
186
  In the old dApp kit, you could optionally pass a `chain` parameter (for example, `sui:mainnet`) to
187
187
  methods like `signTransaction` and `signAndExecuteTransaction`. In the new dApp kit, use the
188
- `network` parameter instead - the chain is automatically derived from the network.
188
+ `network` parameter instead - the chain is automatically derived from the network. It is optional
189
+ and defaults to the active network, so you only need it when targeting a network other than the
190
+ active one (for example, an app that operates on both mainnet and testnet). Likewise, the
191
+ per-account `account` override is preserved as an optional parameter that defaults to the connected
192
+ account.
189
193
 
190
194
  ```diff
191
195
  - const { mutateAsync: signAndExecute } = useSignAndExecuteTransaction();
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "author": "Mysten Labs <build@mystenlabs.com>",
4
4
  "description": "Sui TypeScript API",
5
5
  "homepage": "https://sdk.mystenlabs.com",
6
- "version": "2.18.0",
6
+ "version": "2.20.0",
7
7
  "license": "Apache-2.0",
8
8
  "sideEffects": false,
9
9
  "files": [
@@ -168,8 +168,8 @@
168
168
  "graphql": "^16.14.2",
169
169
  "poseidon-lite": "0.2.1",
170
170
  "valibot": "^1.4.1",
171
- "@mysten/utils": "^0.4.0",
172
- "@mysten/bcs": "^2.1.0"
171
+ "@mysten/bcs": "^2.1.0",
172
+ "@mysten/utils": "^0.4.0"
173
173
  },
174
174
  "scripts": {
175
175
  "clean": "rm -rf tsconfig.tsbuildinfo ./dist",
@@ -5,6 +5,9 @@ export {
5
5
  verifySignature,
6
6
  verifyPersonalMessageSignature,
7
7
  verifyTransactionSignature,
8
+ isValidSignature,
9
+ isValidPersonalMessageSignature,
10
+ isValidTransactionSignature,
8
11
  publicKeyFromRawBytes,
9
12
  publicKeyFromSuiBytes,
10
13
  } from './verify.js';
@@ -13,24 +13,65 @@ import { MultiSigPublicKey } from '../multisig/publickey.js';
13
13
  import { ZkLoginPublicIdentifier } from '../zklogin/publickey.js';
14
14
  import type { ClientWithCoreApi } from '../client/core.js';
15
15
 
16
+ /**
17
+ * Whether `signature` is a valid signature over `bytes` (and, if `options.address`
18
+ * is given, was produced by that address). Returns `false` for a malformed or
19
+ * cryptographically invalid signature, or one that doesn't match the address;
20
+ * only an *environmental* failure (e.g. a zkLogin JWK/epoch lookup) throws, so a
21
+ * network blip is never reported as an invalid signature.
22
+ */
23
+ export async function isValidSignature(
24
+ bytes: Uint8Array,
25
+ signature: string,
26
+ options: { address?: string } = {},
27
+ ): Promise<boolean> {
28
+ const parsed = tryParseSignature(signature);
29
+ if (!parsed) return false;
30
+ if (!(await parsed.publicKey.verify(bytes, parsed.serializedSignature))) return false;
31
+ return options.address ? parsed.publicKey.verifyAddress(options.address) : true;
32
+ }
33
+
34
+ /** Like {@link isValidSignature}, for a personal message. */
35
+ export async function isValidPersonalMessageSignature(
36
+ message: Uint8Array,
37
+ signature: string,
38
+ options: { client?: ClientWithCoreApi; address?: string } = {},
39
+ ): Promise<boolean> {
40
+ const parsed = tryParseSignature(signature, { client: options.client });
41
+ if (!parsed) return false;
42
+ if (!(await parsed.publicKey.verifyPersonalMessage(message, parsed.serializedSignature))) {
43
+ return false;
44
+ }
45
+ return options.address ? parsed.publicKey.verifyAddress(options.address) : true;
46
+ }
47
+
48
+ /** Like {@link isValidSignature}, for transaction bytes. */
49
+ export async function isValidTransactionSignature(
50
+ transaction: Uint8Array,
51
+ signature: string,
52
+ options: { client?: ClientWithCoreApi; address?: string } = {},
53
+ ): Promise<boolean> {
54
+ const parsed = tryParseSignature(signature, { client: options.client });
55
+ if (!parsed) return false;
56
+ if (!(await parsed.publicKey.verifyTransaction(transaction, parsed.serializedSignature))) {
57
+ return false;
58
+ }
59
+ return options.address ? parsed.publicKey.verifyAddress(options.address) : true;
60
+ }
61
+
16
62
  export async function verifySignature(
17
63
  bytes: Uint8Array,
18
64
  signature: string,
19
- options?: {
20
- address?: string;
21
- },
65
+ options: { address?: string } = {},
22
66
  ): Promise<PublicKey> {
23
- const parsedSignature = parseSignature(signature);
24
-
25
- if (!(await parsedSignature.publicKey.verify(bytes, parsedSignature.serializedSignature))) {
67
+ const { publicKey } = parseSignature(signature);
68
+ if (!(await isValidSignature(bytes, signature))) {
26
69
  throw new Error(`Signature is not valid for the provided data`);
27
70
  }
28
-
29
- if (options?.address && !parsedSignature.publicKey.verifyAddress(options.address)) {
71
+ if (options.address && !publicKey.verifyAddress(options.address)) {
30
72
  throw new Error(`Signature is not valid for the provided address`);
31
73
  }
32
-
33
- return parsedSignature.publicKey;
74
+ return publicKey;
34
75
  }
35
76
 
36
77
  export async function verifyPersonalMessageSignature(
@@ -38,22 +79,14 @@ export async function verifyPersonalMessageSignature(
38
79
  signature: string,
39
80
  options: { client?: ClientWithCoreApi; address?: string } = {},
40
81
  ): Promise<PublicKey> {
41
- const parsedSignature = parseSignature(signature, options);
42
-
43
- if (
44
- !(await parsedSignature.publicKey.verifyPersonalMessage(
45
- message,
46
- parsedSignature.serializedSignature,
47
- ))
48
- ) {
82
+ const { publicKey } = parseSignature(signature, options);
83
+ if (!(await isValidPersonalMessageSignature(message, signature, { client: options.client }))) {
49
84
  throw new Error(`Signature is not valid for the provided message`);
50
85
  }
51
-
52
- if (options?.address && !parsedSignature.publicKey.verifyAddress(options.address)) {
86
+ if (options.address && !publicKey.verifyAddress(options.address)) {
53
87
  throw new Error(`Signature is not valid for the provided address`);
54
88
  }
55
-
56
- return parsedSignature.publicKey;
89
+ return publicKey;
57
90
  }
58
91
 
59
92
  export async function verifyTransactionSignature(
@@ -61,22 +94,14 @@ export async function verifyTransactionSignature(
61
94
  signature: string,
62
95
  options: { client?: ClientWithCoreApi; address?: string } = {},
63
96
  ): Promise<PublicKey> {
64
- const parsedSignature = parseSignature(signature, options);
65
-
66
- if (
67
- !(await parsedSignature.publicKey.verifyTransaction(
68
- transaction,
69
- parsedSignature.serializedSignature,
70
- ))
71
- ) {
97
+ const { publicKey } = parseSignature(signature, options);
98
+ if (!(await isValidTransactionSignature(transaction, signature, { client: options.client }))) {
72
99
  throw new Error(`Signature is not valid for the provided Transaction`);
73
100
  }
74
-
75
- if (options?.address && !parsedSignature.publicKey.verifyAddress(options.address)) {
101
+ if (options.address && !publicKey.verifyAddress(options.address)) {
76
102
  throw new Error(`Signature is not valid for the provided address`);
77
103
  }
78
-
79
- return parsedSignature.publicKey;
104
+ return publicKey;
80
105
  }
81
106
 
82
107
  function parseSignature(signature: string, options: { client?: ClientWithCoreApi } = {}) {
@@ -100,6 +125,15 @@ function parseSignature(signature: string, options: { client?: ClientWithCoreApi
100
125
  };
101
126
  }
102
127
 
128
+ /** {@link parseSignature}, returning `null` instead of throwing on a malformed signature. */
129
+ function tryParseSignature(signature: string, options: { client?: ClientWithCoreApi } = {}) {
130
+ try {
131
+ return parseSignature(signature, options);
132
+ } catch {
133
+ return null;
134
+ }
135
+ }
136
+
103
137
  export function publicKeyFromRawBytes(
104
138
  signatureScheme: SignatureScheme,
105
139
  bytes: Uint8Array,
package/src/version.ts CHANGED
@@ -3,4 +3,4 @@
3
3
 
4
4
  // This file is generated by genversion.mjs. Do not edit it directly.
5
5
 
6
- export const PACKAGE_VERSION = '2.18.0';
6
+ export const PACKAGE_VERSION = '2.20.0';
@@ -12,6 +12,8 @@ export {
12
12
  export { computeZkLoginAddressFromSeed, computeZkLoginAddress, jwtToAddress } from './address.js';
13
13
  export type { ComputeZkLoginAddressOptions } from './address.js';
14
14
  export { toZkLoginPublicIdentifier, ZkLoginPublicIdentifier } from './publickey.js';
15
+ export { ZkLoginSigner } from './signer.js';
16
+ export type { ZkLoginSignerOptions } from './signer.js';
15
17
  export type { ZkLoginSignatureInputs } from './bcs.js';
16
18
  export { poseidonHash } from './poseidon.js';
17
19
  export { generateNonce, generateRandomness } from './nonce.js';
@@ -46,6 +46,13 @@ export class ZkLoginPublicIdentifier extends PublicKey {
46
46
  }
47
47
  }
48
48
 
49
+ /**
50
+ * Whether this identifier resolves to the deprecated legacy address derivation.
51
+ */
52
+ get legacyAddress(): boolean {
53
+ return this.#legacyAddress;
54
+ }
55
+
49
56
  static fromBytes(
50
57
  bytes: Uint8Array,
51
58
  {
@@ -0,0 +1,121 @@
1
+ // Copyright (c) Mysten Labs, Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { ClientWithCoreApi } from '../client/core.js';
5
+ import type { IntentScope } from '../cryptography/intent.js';
6
+ import type { SignatureWithBytes } from '../cryptography/keypair.js';
7
+ import { Signer } from '../cryptography/keypair.js';
8
+ import type { SignatureScheme } from '../cryptography/signature-scheme.js';
9
+ import type { ZkLoginSignatureInputs } from './bcs.js';
10
+ import { extractClaimValue } from './jwt-utils.js';
11
+ import { toZkLoginPublicIdentifier, ZkLoginPublicIdentifier } from './publickey.js';
12
+ import { getZkLoginSignature } from './signature.js';
13
+
14
+ export interface ZkLoginSignerOptions {
15
+ /** The ephemeral signer whose signature is wrapped by the zkLogin proof. */
16
+ ephemeralSigner: Signer;
17
+ /** The maxEpoch the proof was generated for. */
18
+ maxEpoch: number;
19
+ /** The zkLogin proof inputs, including the `addressSeed`. */
20
+ inputs: ZkLoginSignatureInputs;
21
+ /**
22
+ * Whether this account uses the deprecated legacy address derivation. The zkLogin address is
23
+ * derived from the proof inputs; this flag disambiguates legacy vs. current derivation, matching
24
+ * the rest of the zkLogin address API (e.g. `jwtToAddress`, `toZkLoginPublicIdentifier`).
25
+ *
26
+ * A wrong flag silently yields a signer for the wrong address; pass `address` to guard against it.
27
+ */
28
+ legacyAddress: boolean;
29
+ /**
30
+ * The expected zkLogin address. When provided, the address derived from `inputs` + `legacyAddress`
31
+ * is validated against it and the constructor throws on mismatch — guarding against a wrong
32
+ * `legacyAddress` flag producing a signer for the wrong address.
33
+ */
34
+ address?: string;
35
+ /** Optional client, threaded into the derived public key so it can verify signatures. */
36
+ client?: ClientWithCoreApi;
37
+ }
38
+
39
+ /**
40
+ * A transport- and provider-agnostic zkLogin signer.
41
+ *
42
+ * It wraps any ephemeral {@link Signer} and, for every signing operation, transforms the ephemeral
43
+ * signature into a zkLogin signature using the supplied proof inputs and `maxEpoch`. Because every
44
+ * signing method on {@link Signer} funnels through `signWithIntent`, overriding that single method is
45
+ * enough to cover `signTransaction`, `signPersonalMessage`, and `signAndExecuteTransaction`.
46
+ */
47
+ export class ZkLoginSigner extends Signer {
48
+ #ephemeralSigner: Signer;
49
+ #maxEpoch: number;
50
+ #inputs: ZkLoginSignatureInputs;
51
+ #legacyAddress: boolean;
52
+ #client?: ClientWithCoreApi;
53
+ #publicKey?: ZkLoginPublicIdentifier;
54
+
55
+ constructor(options: ZkLoginSignerOptions) {
56
+ super();
57
+ this.#ephemeralSigner = options.ephemeralSigner;
58
+ this.#maxEpoch = options.maxEpoch;
59
+ this.#inputs = options.inputs;
60
+ this.#legacyAddress = options.legacyAddress;
61
+ this.#client = options.client;
62
+
63
+ if (options.address !== undefined) {
64
+ const derived = this.#derivePublicKey().toSuiAddress();
65
+ if (derived !== options.address) {
66
+ throw new Error(
67
+ `zkLogin proof does not match the provided address (derived ${derived}, expected ` +
68
+ `${options.address}) — check the \`legacyAddress\` flag`,
69
+ );
70
+ }
71
+ }
72
+ }
73
+
74
+ // Shared derive-and-memoize used by both the constructor's address validation and getPublicKey().
75
+ // It is `#private` (non-virtual) on purpose: the constructor must derive the *base* address even
76
+ // when a subclass overrides getPublicKey() — calling the overridable getPublicKey() from the
77
+ // constructor would dispatch to the subclass before its fields are initialized. Laziness also
78
+ // means subclasses that override getPublicKey() (e.g. EnokiKeypair) never pay for this derivation.
79
+ #derivePublicKey(): ZkLoginPublicIdentifier {
80
+ return (this.#publicKey ??= toZkLoginPublicIdentifier(
81
+ BigInt(this.#inputs.addressSeed),
82
+ extractClaimValue<string>(this.#inputs.issBase64Details, 'iss'),
83
+ { legacyAddress: this.#legacyAddress, client: this.#client },
84
+ ));
85
+ }
86
+
87
+ /**
88
+ * The single extension point: the ephemeral signature is produced with the requested intent and
89
+ * then wrapped in a zkLogin signature.
90
+ */
91
+ override async signWithIntent(
92
+ bytes: Uint8Array,
93
+ intent: IntentScope,
94
+ ): Promise<SignatureWithBytes> {
95
+ const { bytes: signedBytes, signature: userSignature } =
96
+ await this.#ephemeralSigner.signWithIntent(bytes, intent);
97
+
98
+ return {
99
+ bytes: signedBytes,
100
+ signature: getZkLoginSignature({
101
+ inputs: this.#inputs,
102
+ maxEpoch: this.#maxEpoch,
103
+ userSignature,
104
+ }),
105
+ };
106
+ }
107
+
108
+ sign(_data: Uint8Array): never {
109
+ throw new Error(
110
+ 'ZkLoginSigner does not support signing directly. Use signTransaction or signPersonalMessage instead',
111
+ );
112
+ }
113
+
114
+ getKeyScheme(): SignatureScheme {
115
+ return 'ZkLogin';
116
+ }
117
+
118
+ getPublicKey(): ZkLoginPublicIdentifier {
119
+ return this.#derivePublicKey();
120
+ }
121
+ }