@mysten/signers 0.2.6 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @mysten/signers
2
2
 
3
+ ## 0.2.8
4
+
5
+ ### Patch Changes
6
+
7
+ - @mysten/sui@1.29.1
8
+
9
+ ## 0.2.7
10
+
11
+ ### Patch Changes
12
+
13
+ - 8356318: Fix broken message signing for the Ledger signer
14
+
3
15
  ## 0.2.6
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -174,18 +174,18 @@ cryptographic operations.
174
174
  import Transport from '@ledgerhq/hw-transport-node-hid';
175
175
  import SuiLedgerClient from '@mysten/ledgerjs-hw-app-sui';
176
176
  import { LedgerSigner } from '@mysten/signers/ledger';
177
- import { SuiClient } from '@mysten/sui/client';
177
+ import { getFullnodeUrl, SuiClient } from '@mysten/sui/client';
178
178
  import { Transaction } from '@mysten/sui/transactions';
179
179
 
180
180
  const transport = await Transport.open(undefined);
181
181
  const ledgerClient = new SuiLedgerClient(transport);
182
- const suiClient = new SuiClient({ url: getNetworkUrl('testnet') });
182
+ const suiClient = new SuiClient({ url: getFullnodeUrl('testnet') });
183
183
 
184
- const signer = await LedgerSigner.fromDerivationPath({
185
- derivationPath: "m/44'/784'/0'/0'/0'",
184
+ const signer = await LedgerSigner.fromDerivationPath(
185
+ "m/44'/784'/0'/0'/0'",
186
186
  ledgerClient,
187
187
  suiClient,
188
- });
188
+ );
189
189
 
190
190
  // Log the Sui address:
191
191
  console.log(signer.toSuiAddress());
@@ -34,6 +34,7 @@ var import_ed25519 = require("@mysten/sui/keypairs/ed25519");
34
34
  var import_transactions = require("@mysten/sui/transactions");
35
35
  var import_utils = require("@mysten/sui/utils");
36
36
  var import_bcs = require("./bcs.js");
37
+ var import_bcs2 = require("@mysten/sui/bcs");
37
38
  var _derivationPath, _publicKey, _ledgerClient, _suiClient, _LedgerSigner_instances, getClearSigningOptions_fn;
38
39
  const _LedgerSigner = class _LedgerSigner extends import_cryptography.Signer {
39
40
  /**
@@ -97,7 +98,10 @@ const _LedgerSigner = class _LedgerSigner extends import_cryptography.Signer {
97
98
  * @returns The signed message bytes and signature.
98
99
  */
99
100
  async signPersonalMessage(bytes) {
100
- const intentMessage = (0, import_cryptography.messageWithIntent)("PersonalMessage", bytes);
101
+ const intentMessage = (0, import_cryptography.messageWithIntent)(
102
+ "PersonalMessage",
103
+ import_bcs2.bcs.byteVector().serialize(bytes).toBytes()
104
+ );
101
105
  const { signature } = await __privateGet(this, _ledgerClient).signTransaction(
102
106
  __privateGet(this, _derivationPath),
103
107
  intentMessage
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/ledger/index.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type SuiLedgerClient from '@mysten/ledgerjs-hw-app-sui';\nimport type { SuiClient } from '@mysten/sui/client';\nimport type { SignatureWithBytes } from '@mysten/sui/cryptography';\nimport { messageWithIntent, Signer, toSerializedSignature } from '@mysten/sui/cryptography';\nimport { Ed25519PublicKey } from '@mysten/sui/keypairs/ed25519';\nimport { Transaction } from '@mysten/sui/transactions';\nimport { toBase64 } from '@mysten/sui/utils';\n\nimport { SuiMoveObject } from './bcs.js';\n\n/**\n * Configuration options for initializing the LedgerSigner.\n */\nexport interface LedgerSignerOptions {\n\tpublicKey: Ed25519PublicKey;\n\tderivationPath: string;\n\tledgerClient: SuiLedgerClient;\n\tsuiClient: SuiClient;\n}\n\n/**\n * Ledger integrates with the Sui blockchain to provide signing capabilities using Ledger devices.\n */\nexport class LedgerSigner extends Signer {\n\t#derivationPath: string;\n\t#publicKey: Ed25519PublicKey;\n\t#ledgerClient: SuiLedgerClient;\n\t#suiClient: SuiClient;\n\n\t/**\n\t * Creates an instance of LedgerSigner. It's expected to call the static `fromDerivationPath` method to create an instance.\n\t * @example\n\t * ```\n\t * const signer = await LedgerSigner.fromDerivationPath(derivationPath, options);\n\t * ```\n\t */\n\tconstructor({ publicKey, derivationPath, ledgerClient, suiClient }: LedgerSignerOptions) {\n\t\tsuper();\n\t\tthis.#publicKey = publicKey;\n\t\tthis.#derivationPath = derivationPath;\n\t\tthis.#ledgerClient = ledgerClient;\n\t\tthis.#suiClient = suiClient;\n\t}\n\n\t/**\n\t * Retrieves the key scheme used by this signer.\n\t */\n\toverride getKeyScheme() {\n\t\treturn 'ED25519' as const;\n\t}\n\n\t/**\n\t * Retrieves the public key associated with this signer.\n\t * @returns The Ed25519PublicKey instance.\n\t */\n\toverride getPublicKey() {\n\t\treturn this.#publicKey;\n\t}\n\n\t/**\n\t * Signs the provided transaction bytes.\n\t * @returns The signed transaction bytes and signature.\n\t */\n\toverride async signTransaction(bytes: Uint8Array): Promise<SignatureWithBytes> {\n\t\tconst transactionOptions = await this.#getClearSigningOptions(bytes).catch(() => ({\n\t\t\t// Fail gracefully so network errors or serialization issues don't break transaction signing:\n\t\t\tbcsObjects: [],\n\t\t}));\n\n\t\tconst intentMessage = messageWithIntent('TransactionData', bytes);\n\t\tconst { signature } = await this.#ledgerClient.signTransaction(\n\t\t\tthis.#derivationPath,\n\t\t\tintentMessage,\n\t\t\ttransactionOptions,\n\t\t);\n\n\t\treturn {\n\t\t\tbytes: toBase64(bytes),\n\t\t\tsignature: toSerializedSignature({\n\t\t\t\tsignature,\n\t\t\t\tsignatureScheme: this.getKeyScheme(),\n\t\t\t\tpublicKey: this.#publicKey,\n\t\t\t}),\n\t\t};\n\t}\n\n\t/**\n\t * Signs the provided personal message.\n\t * @returns The signed message bytes and signature.\n\t */\n\toverride async signPersonalMessage(bytes: Uint8Array): Promise<SignatureWithBytes> {\n\t\tconst intentMessage = messageWithIntent('PersonalMessage', bytes);\n\t\tconst { signature } = await this.#ledgerClient.signTransaction(\n\t\t\tthis.#derivationPath,\n\t\t\tintentMessage,\n\t\t);\n\n\t\treturn {\n\t\t\tbytes: toBase64(bytes),\n\t\t\tsignature: toSerializedSignature({\n\t\t\t\tsignature,\n\t\t\t\tsignatureScheme: this.getKeyScheme(),\n\t\t\t\tpublicKey: this.#publicKey,\n\t\t\t}),\n\t\t};\n\t}\n\n\t/**\n\t * Prepares the signer by fetching and setting the public key from a Ledger device.\n\t * It is recommended to initialize an `LedgerSigner` instance using this function.\n\t * @returns A promise that resolves once a `LedgerSigner` instance is prepared (public key is set).\n\t */\n\tstatic async fromDerivationPath(\n\t\tderivationPath: string,\n\t\tledgerClient: SuiLedgerClient,\n\t\tsuiClient: SuiClient,\n\t) {\n\t\tconst { publicKey } = await ledgerClient.getPublicKey(derivationPath);\n\t\tif (!publicKey) {\n\t\t\tthrow new Error('Failed to get public key from Ledger.');\n\t\t}\n\n\t\treturn new LedgerSigner({\n\t\t\tderivationPath,\n\t\t\tpublicKey: new Ed25519PublicKey(publicKey),\n\t\t\tledgerClient,\n\t\t\tsuiClient,\n\t\t});\n\t}\n\n\tasync #getClearSigningOptions(transactionBytes: Uint8Array) {\n\t\tconst transaction = Transaction.from(transactionBytes);\n\t\tconst data = transaction.getData();\n\n\t\tconst gasObjectIds = data.gasData.payment?.map((object) => object.objectId) ?? [];\n\t\tconst inputObjectIds = data.inputs\n\t\t\t.map((input) => {\n\t\t\t\treturn input.$kind === 'Object' && input.Object.$kind === 'ImmOrOwnedObject'\n\t\t\t\t\t? input.Object.ImmOrOwnedObject.objectId\n\t\t\t\t\t: null;\n\t\t\t})\n\t\t\t.filter((objectId): objectId is string => !!objectId);\n\n\t\tconst objects = await this.#suiClient.multiGetObjects({\n\t\t\tids: [...gasObjectIds, ...inputObjectIds],\n\t\t\toptions: {\n\t\t\t\tshowBcs: true,\n\t\t\t\tshowPreviousTransaction: true,\n\t\t\t\tshowStorageRebate: true,\n\t\t\t\tshowOwner: true,\n\t\t\t},\n\t\t});\n\n\t\t// NOTE: We should probably get rid of this manual serialization logic in favor of using the\n\t\t// already serialized object bytes from the GraphQL API once there is more mainstream support\n\t\t// for it + we can enforce the transport type on the Sui client.\n\t\tconst bcsObjects = objects\n\t\t\t.map((object) => {\n\t\t\t\tif (object.error || !object.data || object.data.bcs?.dataType !== 'moveObject') {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn SuiMoveObject.serialize({\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tMoveObject: {\n\t\t\t\t\t\t\ttype: object.data.bcs.type,\n\t\t\t\t\t\t\thasPublicTransfer: object.data.bcs.hasPublicTransfer,\n\t\t\t\t\t\t\tversion: object.data.bcs.version,\n\t\t\t\t\t\t\tcontents: object.data.bcs.bcsBytes,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\towner: object.data.owner!,\n\t\t\t\t\tpreviousTransaction: object.data.previousTransaction!,\n\t\t\t\t\tstorageRebate: object.data.storageRebate!,\n\t\t\t\t}).toBytes();\n\t\t\t})\n\t\t\t.filter((bcsBytes): bcsBytes is Uint8Array => !!bcsBytes);\n\n\t\treturn { bcsObjects };\n\t}\n\n\t/**\n\t * Generic signing is not supported by Ledger.\n\t * @throws Always throws an error indicating generic signing is unsupported.\n\t */\n\toverride sign(): never {\n\t\tthrow new Error('Ledger Signer does not support generic signing.');\n\t}\n\n\t/**\n\t * Generic signing is not supported by Ledger.\n\t * @throws Always throws an error indicating generic signing is unsupported.\n\t */\n\toverride signWithIntent(): never {\n\t\tthrow new Error('Ledger Signer does not support generic signing.');\n\t}\n}\n"],
5
- "mappings": "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",
6
- "names": []
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type SuiLedgerClient from '@mysten/ledgerjs-hw-app-sui';\nimport type { SuiClient } from '@mysten/sui/client';\nimport type { SignatureWithBytes } from '@mysten/sui/cryptography';\nimport { messageWithIntent, Signer, toSerializedSignature } from '@mysten/sui/cryptography';\nimport { Ed25519PublicKey } from '@mysten/sui/keypairs/ed25519';\nimport { Transaction } from '@mysten/sui/transactions';\nimport { toBase64 } from '@mysten/sui/utils';\n\nimport { SuiMoveObject } from './bcs.js';\nimport { bcs } from '@mysten/sui/bcs';\n\n/**\n * Configuration options for initializing the LedgerSigner.\n */\nexport interface LedgerSignerOptions {\n\tpublicKey: Ed25519PublicKey;\n\tderivationPath: string;\n\tledgerClient: SuiLedgerClient;\n\tsuiClient: SuiClient;\n}\n\n/**\n * Ledger integrates with the Sui blockchain to provide signing capabilities using Ledger devices.\n */\nexport class LedgerSigner extends Signer {\n\t#derivationPath: string;\n\t#publicKey: Ed25519PublicKey;\n\t#ledgerClient: SuiLedgerClient;\n\t#suiClient: SuiClient;\n\n\t/**\n\t * Creates an instance of LedgerSigner. It's expected to call the static `fromDerivationPath` method to create an instance.\n\t * @example\n\t * ```\n\t * const signer = await LedgerSigner.fromDerivationPath(derivationPath, options);\n\t * ```\n\t */\n\tconstructor({ publicKey, derivationPath, ledgerClient, suiClient }: LedgerSignerOptions) {\n\t\tsuper();\n\t\tthis.#publicKey = publicKey;\n\t\tthis.#derivationPath = derivationPath;\n\t\tthis.#ledgerClient = ledgerClient;\n\t\tthis.#suiClient = suiClient;\n\t}\n\n\t/**\n\t * Retrieves the key scheme used by this signer.\n\t */\n\toverride getKeyScheme() {\n\t\treturn 'ED25519' as const;\n\t}\n\n\t/**\n\t * Retrieves the public key associated with this signer.\n\t * @returns The Ed25519PublicKey instance.\n\t */\n\toverride getPublicKey() {\n\t\treturn this.#publicKey;\n\t}\n\n\t/**\n\t * Signs the provided transaction bytes.\n\t * @returns The signed transaction bytes and signature.\n\t */\n\toverride async signTransaction(bytes: Uint8Array): Promise<SignatureWithBytes> {\n\t\tconst transactionOptions = await this.#getClearSigningOptions(bytes).catch(() => ({\n\t\t\t// Fail gracefully so network errors or serialization issues don't break transaction signing:\n\t\t\tbcsObjects: [],\n\t\t}));\n\n\t\tconst intentMessage = messageWithIntent('TransactionData', bytes);\n\t\tconst { signature } = await this.#ledgerClient.signTransaction(\n\t\t\tthis.#derivationPath,\n\t\t\tintentMessage,\n\t\t\ttransactionOptions,\n\t\t);\n\n\t\treturn {\n\t\t\tbytes: toBase64(bytes),\n\t\t\tsignature: toSerializedSignature({\n\t\t\t\tsignature,\n\t\t\t\tsignatureScheme: this.getKeyScheme(),\n\t\t\t\tpublicKey: this.#publicKey,\n\t\t\t}),\n\t\t};\n\t}\n\n\t/**\n\t * Signs the provided personal message.\n\t * @returns The signed message bytes and signature.\n\t */\n\toverride async signPersonalMessage(bytes: Uint8Array): Promise<SignatureWithBytes> {\n\t\tconst intentMessage = messageWithIntent(\n\t\t\t'PersonalMessage',\n\t\t\tbcs.byteVector().serialize(bytes).toBytes(),\n\t\t);\n\t\tconst { signature } = await this.#ledgerClient.signTransaction(\n\t\t\tthis.#derivationPath,\n\t\t\tintentMessage,\n\t\t);\n\n\t\treturn {\n\t\t\tbytes: toBase64(bytes),\n\t\t\tsignature: toSerializedSignature({\n\t\t\t\tsignature,\n\t\t\t\tsignatureScheme: this.getKeyScheme(),\n\t\t\t\tpublicKey: this.#publicKey,\n\t\t\t}),\n\t\t};\n\t}\n\n\t/**\n\t * Prepares the signer by fetching and setting the public key from a Ledger device.\n\t * It is recommended to initialize an `LedgerSigner` instance using this function.\n\t * @returns A promise that resolves once a `LedgerSigner` instance is prepared (public key is set).\n\t */\n\tstatic async fromDerivationPath(\n\t\tderivationPath: string,\n\t\tledgerClient: SuiLedgerClient,\n\t\tsuiClient: SuiClient,\n\t) {\n\t\tconst { publicKey } = await ledgerClient.getPublicKey(derivationPath);\n\t\tif (!publicKey) {\n\t\t\tthrow new Error('Failed to get public key from Ledger.');\n\t\t}\n\n\t\treturn new LedgerSigner({\n\t\t\tderivationPath,\n\t\t\tpublicKey: new Ed25519PublicKey(publicKey),\n\t\t\tledgerClient,\n\t\t\tsuiClient,\n\t\t});\n\t}\n\n\tasync #getClearSigningOptions(transactionBytes: Uint8Array) {\n\t\tconst transaction = Transaction.from(transactionBytes);\n\t\tconst data = transaction.getData();\n\n\t\tconst gasObjectIds = data.gasData.payment?.map((object) => object.objectId) ?? [];\n\t\tconst inputObjectIds = data.inputs\n\t\t\t.map((input) => {\n\t\t\t\treturn input.$kind === 'Object' && input.Object.$kind === 'ImmOrOwnedObject'\n\t\t\t\t\t? input.Object.ImmOrOwnedObject.objectId\n\t\t\t\t\t: null;\n\t\t\t})\n\t\t\t.filter((objectId): objectId is string => !!objectId);\n\n\t\tconst objects = await this.#suiClient.multiGetObjects({\n\t\t\tids: [...gasObjectIds, ...inputObjectIds],\n\t\t\toptions: {\n\t\t\t\tshowBcs: true,\n\t\t\t\tshowPreviousTransaction: true,\n\t\t\t\tshowStorageRebate: true,\n\t\t\t\tshowOwner: true,\n\t\t\t},\n\t\t});\n\n\t\t// NOTE: We should probably get rid of this manual serialization logic in favor of using the\n\t\t// already serialized object bytes from the GraphQL API once there is more mainstream support\n\t\t// for it + we can enforce the transport type on the Sui client.\n\t\tconst bcsObjects = objects\n\t\t\t.map((object) => {\n\t\t\t\tif (object.error || !object.data || object.data.bcs?.dataType !== 'moveObject') {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn SuiMoveObject.serialize({\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tMoveObject: {\n\t\t\t\t\t\t\ttype: object.data.bcs.type,\n\t\t\t\t\t\t\thasPublicTransfer: object.data.bcs.hasPublicTransfer,\n\t\t\t\t\t\t\tversion: object.data.bcs.version,\n\t\t\t\t\t\t\tcontents: object.data.bcs.bcsBytes,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\towner: object.data.owner!,\n\t\t\t\t\tpreviousTransaction: object.data.previousTransaction!,\n\t\t\t\t\tstorageRebate: object.data.storageRebate!,\n\t\t\t\t}).toBytes();\n\t\t\t})\n\t\t\t.filter((bcsBytes): bcsBytes is Uint8Array => !!bcsBytes);\n\n\t\treturn { bcsObjects };\n\t}\n\n\t/**\n\t * Generic signing is not supported by Ledger.\n\t * @throws Always throws an error indicating generic signing is unsupported.\n\t */\n\toverride sign(): never {\n\t\tthrow new Error('Ledger Signer does not support generic signing.');\n\t}\n\n\t/**\n\t * Generic signing is not supported by Ledger.\n\t * @throws Always throws an error indicating generic signing is unsupported.\n\t */\n\toverride signWithIntent(): never {\n\t\tthrow new Error('Ledger Signer does not support generic signing.');\n\t}\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_bcs"]
7
7
  }
@@ -12,6 +12,7 @@ import { Ed25519PublicKey } from "@mysten/sui/keypairs/ed25519";
12
12
  import { Transaction } from "@mysten/sui/transactions";
13
13
  import { toBase64 } from "@mysten/sui/utils";
14
14
  import { SuiMoveObject } from "./bcs.js";
15
+ import { bcs } from "@mysten/sui/bcs";
15
16
  const _LedgerSigner = class _LedgerSigner extends Signer {
16
17
  /**
17
18
  * Creates an instance of LedgerSigner. It's expected to call the static `fromDerivationPath` method to create an instance.
@@ -74,7 +75,10 @@ const _LedgerSigner = class _LedgerSigner extends Signer {
74
75
  * @returns The signed message bytes and signature.
75
76
  */
76
77
  async signPersonalMessage(bytes) {
77
- const intentMessage = messageWithIntent("PersonalMessage", bytes);
78
+ const intentMessage = messageWithIntent(
79
+ "PersonalMessage",
80
+ bcs.byteVector().serialize(bytes).toBytes()
81
+ );
78
82
  const { signature } = await __privateGet(this, _ledgerClient).signTransaction(
79
83
  __privateGet(this, _derivationPath),
80
84
  intentMessage
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/ledger/index.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type SuiLedgerClient from '@mysten/ledgerjs-hw-app-sui';\nimport type { SuiClient } from '@mysten/sui/client';\nimport type { SignatureWithBytes } from '@mysten/sui/cryptography';\nimport { messageWithIntent, Signer, toSerializedSignature } from '@mysten/sui/cryptography';\nimport { Ed25519PublicKey } from '@mysten/sui/keypairs/ed25519';\nimport { Transaction } from '@mysten/sui/transactions';\nimport { toBase64 } from '@mysten/sui/utils';\n\nimport { SuiMoveObject } from './bcs.js';\n\n/**\n * Configuration options for initializing the LedgerSigner.\n */\nexport interface LedgerSignerOptions {\n\tpublicKey: Ed25519PublicKey;\n\tderivationPath: string;\n\tledgerClient: SuiLedgerClient;\n\tsuiClient: SuiClient;\n}\n\n/**\n * Ledger integrates with the Sui blockchain to provide signing capabilities using Ledger devices.\n */\nexport class LedgerSigner extends Signer {\n\t#derivationPath: string;\n\t#publicKey: Ed25519PublicKey;\n\t#ledgerClient: SuiLedgerClient;\n\t#suiClient: SuiClient;\n\n\t/**\n\t * Creates an instance of LedgerSigner. It's expected to call the static `fromDerivationPath` method to create an instance.\n\t * @example\n\t * ```\n\t * const signer = await LedgerSigner.fromDerivationPath(derivationPath, options);\n\t * ```\n\t */\n\tconstructor({ publicKey, derivationPath, ledgerClient, suiClient }: LedgerSignerOptions) {\n\t\tsuper();\n\t\tthis.#publicKey = publicKey;\n\t\tthis.#derivationPath = derivationPath;\n\t\tthis.#ledgerClient = ledgerClient;\n\t\tthis.#suiClient = suiClient;\n\t}\n\n\t/**\n\t * Retrieves the key scheme used by this signer.\n\t */\n\toverride getKeyScheme() {\n\t\treturn 'ED25519' as const;\n\t}\n\n\t/**\n\t * Retrieves the public key associated with this signer.\n\t * @returns The Ed25519PublicKey instance.\n\t */\n\toverride getPublicKey() {\n\t\treturn this.#publicKey;\n\t}\n\n\t/**\n\t * Signs the provided transaction bytes.\n\t * @returns The signed transaction bytes and signature.\n\t */\n\toverride async signTransaction(bytes: Uint8Array): Promise<SignatureWithBytes> {\n\t\tconst transactionOptions = await this.#getClearSigningOptions(bytes).catch(() => ({\n\t\t\t// Fail gracefully so network errors or serialization issues don't break transaction signing:\n\t\t\tbcsObjects: [],\n\t\t}));\n\n\t\tconst intentMessage = messageWithIntent('TransactionData', bytes);\n\t\tconst { signature } = await this.#ledgerClient.signTransaction(\n\t\t\tthis.#derivationPath,\n\t\t\tintentMessage,\n\t\t\ttransactionOptions,\n\t\t);\n\n\t\treturn {\n\t\t\tbytes: toBase64(bytes),\n\t\t\tsignature: toSerializedSignature({\n\t\t\t\tsignature,\n\t\t\t\tsignatureScheme: this.getKeyScheme(),\n\t\t\t\tpublicKey: this.#publicKey,\n\t\t\t}),\n\t\t};\n\t}\n\n\t/**\n\t * Signs the provided personal message.\n\t * @returns The signed message bytes and signature.\n\t */\n\toverride async signPersonalMessage(bytes: Uint8Array): Promise<SignatureWithBytes> {\n\t\tconst intentMessage = messageWithIntent('PersonalMessage', bytes);\n\t\tconst { signature } = await this.#ledgerClient.signTransaction(\n\t\t\tthis.#derivationPath,\n\t\t\tintentMessage,\n\t\t);\n\n\t\treturn {\n\t\t\tbytes: toBase64(bytes),\n\t\t\tsignature: toSerializedSignature({\n\t\t\t\tsignature,\n\t\t\t\tsignatureScheme: this.getKeyScheme(),\n\t\t\t\tpublicKey: this.#publicKey,\n\t\t\t}),\n\t\t};\n\t}\n\n\t/**\n\t * Prepares the signer by fetching and setting the public key from a Ledger device.\n\t * It is recommended to initialize an `LedgerSigner` instance using this function.\n\t * @returns A promise that resolves once a `LedgerSigner` instance is prepared (public key is set).\n\t */\n\tstatic async fromDerivationPath(\n\t\tderivationPath: string,\n\t\tledgerClient: SuiLedgerClient,\n\t\tsuiClient: SuiClient,\n\t) {\n\t\tconst { publicKey } = await ledgerClient.getPublicKey(derivationPath);\n\t\tif (!publicKey) {\n\t\t\tthrow new Error('Failed to get public key from Ledger.');\n\t\t}\n\n\t\treturn new LedgerSigner({\n\t\t\tderivationPath,\n\t\t\tpublicKey: new Ed25519PublicKey(publicKey),\n\t\t\tledgerClient,\n\t\t\tsuiClient,\n\t\t});\n\t}\n\n\tasync #getClearSigningOptions(transactionBytes: Uint8Array) {\n\t\tconst transaction = Transaction.from(transactionBytes);\n\t\tconst data = transaction.getData();\n\n\t\tconst gasObjectIds = data.gasData.payment?.map((object) => object.objectId) ?? [];\n\t\tconst inputObjectIds = data.inputs\n\t\t\t.map((input) => {\n\t\t\t\treturn input.$kind === 'Object' && input.Object.$kind === 'ImmOrOwnedObject'\n\t\t\t\t\t? input.Object.ImmOrOwnedObject.objectId\n\t\t\t\t\t: null;\n\t\t\t})\n\t\t\t.filter((objectId): objectId is string => !!objectId);\n\n\t\tconst objects = await this.#suiClient.multiGetObjects({\n\t\t\tids: [...gasObjectIds, ...inputObjectIds],\n\t\t\toptions: {\n\t\t\t\tshowBcs: true,\n\t\t\t\tshowPreviousTransaction: true,\n\t\t\t\tshowStorageRebate: true,\n\t\t\t\tshowOwner: true,\n\t\t\t},\n\t\t});\n\n\t\t// NOTE: We should probably get rid of this manual serialization logic in favor of using the\n\t\t// already serialized object bytes from the GraphQL API once there is more mainstream support\n\t\t// for it + we can enforce the transport type on the Sui client.\n\t\tconst bcsObjects = objects\n\t\t\t.map((object) => {\n\t\t\t\tif (object.error || !object.data || object.data.bcs?.dataType !== 'moveObject') {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn SuiMoveObject.serialize({\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tMoveObject: {\n\t\t\t\t\t\t\ttype: object.data.bcs.type,\n\t\t\t\t\t\t\thasPublicTransfer: object.data.bcs.hasPublicTransfer,\n\t\t\t\t\t\t\tversion: object.data.bcs.version,\n\t\t\t\t\t\t\tcontents: object.data.bcs.bcsBytes,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\towner: object.data.owner!,\n\t\t\t\t\tpreviousTransaction: object.data.previousTransaction!,\n\t\t\t\t\tstorageRebate: object.data.storageRebate!,\n\t\t\t\t}).toBytes();\n\t\t\t})\n\t\t\t.filter((bcsBytes): bcsBytes is Uint8Array => !!bcsBytes);\n\n\t\treturn { bcsObjects };\n\t}\n\n\t/**\n\t * Generic signing is not supported by Ledger.\n\t * @throws Always throws an error indicating generic signing is unsupported.\n\t */\n\toverride sign(): never {\n\t\tthrow new Error('Ledger Signer does not support generic signing.');\n\t}\n\n\t/**\n\t * Generic signing is not supported by Ledger.\n\t * @throws Always throws an error indicating generic signing is unsupported.\n\t */\n\toverride signWithIntent(): never {\n\t\tthrow new Error('Ledger Signer does not support generic signing.');\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type SuiLedgerClient from '@mysten/ledgerjs-hw-app-sui';\nimport type { SuiClient } from '@mysten/sui/client';\nimport type { SignatureWithBytes } from '@mysten/sui/cryptography';\nimport { messageWithIntent, Signer, toSerializedSignature } from '@mysten/sui/cryptography';\nimport { Ed25519PublicKey } from '@mysten/sui/keypairs/ed25519';\nimport { Transaction } from '@mysten/sui/transactions';\nimport { toBase64 } from '@mysten/sui/utils';\n\nimport { SuiMoveObject } from './bcs.js';\nimport { bcs } from '@mysten/sui/bcs';\n\n/**\n * Configuration options for initializing the LedgerSigner.\n */\nexport interface LedgerSignerOptions {\n\tpublicKey: Ed25519PublicKey;\n\tderivationPath: string;\n\tledgerClient: SuiLedgerClient;\n\tsuiClient: SuiClient;\n}\n\n/**\n * Ledger integrates with the Sui blockchain to provide signing capabilities using Ledger devices.\n */\nexport class LedgerSigner extends Signer {\n\t#derivationPath: string;\n\t#publicKey: Ed25519PublicKey;\n\t#ledgerClient: SuiLedgerClient;\n\t#suiClient: SuiClient;\n\n\t/**\n\t * Creates an instance of LedgerSigner. It's expected to call the static `fromDerivationPath` method to create an instance.\n\t * @example\n\t * ```\n\t * const signer = await LedgerSigner.fromDerivationPath(derivationPath, options);\n\t * ```\n\t */\n\tconstructor({ publicKey, derivationPath, ledgerClient, suiClient }: LedgerSignerOptions) {\n\t\tsuper();\n\t\tthis.#publicKey = publicKey;\n\t\tthis.#derivationPath = derivationPath;\n\t\tthis.#ledgerClient = ledgerClient;\n\t\tthis.#suiClient = suiClient;\n\t}\n\n\t/**\n\t * Retrieves the key scheme used by this signer.\n\t */\n\toverride getKeyScheme() {\n\t\treturn 'ED25519' as const;\n\t}\n\n\t/**\n\t * Retrieves the public key associated with this signer.\n\t * @returns The Ed25519PublicKey instance.\n\t */\n\toverride getPublicKey() {\n\t\treturn this.#publicKey;\n\t}\n\n\t/**\n\t * Signs the provided transaction bytes.\n\t * @returns The signed transaction bytes and signature.\n\t */\n\toverride async signTransaction(bytes: Uint8Array): Promise<SignatureWithBytes> {\n\t\tconst transactionOptions = await this.#getClearSigningOptions(bytes).catch(() => ({\n\t\t\t// Fail gracefully so network errors or serialization issues don't break transaction signing:\n\t\t\tbcsObjects: [],\n\t\t}));\n\n\t\tconst intentMessage = messageWithIntent('TransactionData', bytes);\n\t\tconst { signature } = await this.#ledgerClient.signTransaction(\n\t\t\tthis.#derivationPath,\n\t\t\tintentMessage,\n\t\t\ttransactionOptions,\n\t\t);\n\n\t\treturn {\n\t\t\tbytes: toBase64(bytes),\n\t\t\tsignature: toSerializedSignature({\n\t\t\t\tsignature,\n\t\t\t\tsignatureScheme: this.getKeyScheme(),\n\t\t\t\tpublicKey: this.#publicKey,\n\t\t\t}),\n\t\t};\n\t}\n\n\t/**\n\t * Signs the provided personal message.\n\t * @returns The signed message bytes and signature.\n\t */\n\toverride async signPersonalMessage(bytes: Uint8Array): Promise<SignatureWithBytes> {\n\t\tconst intentMessage = messageWithIntent(\n\t\t\t'PersonalMessage',\n\t\t\tbcs.byteVector().serialize(bytes).toBytes(),\n\t\t);\n\t\tconst { signature } = await this.#ledgerClient.signTransaction(\n\t\t\tthis.#derivationPath,\n\t\t\tintentMessage,\n\t\t);\n\n\t\treturn {\n\t\t\tbytes: toBase64(bytes),\n\t\t\tsignature: toSerializedSignature({\n\t\t\t\tsignature,\n\t\t\t\tsignatureScheme: this.getKeyScheme(),\n\t\t\t\tpublicKey: this.#publicKey,\n\t\t\t}),\n\t\t};\n\t}\n\n\t/**\n\t * Prepares the signer by fetching and setting the public key from a Ledger device.\n\t * It is recommended to initialize an `LedgerSigner` instance using this function.\n\t * @returns A promise that resolves once a `LedgerSigner` instance is prepared (public key is set).\n\t */\n\tstatic async fromDerivationPath(\n\t\tderivationPath: string,\n\t\tledgerClient: SuiLedgerClient,\n\t\tsuiClient: SuiClient,\n\t) {\n\t\tconst { publicKey } = await ledgerClient.getPublicKey(derivationPath);\n\t\tif (!publicKey) {\n\t\t\tthrow new Error('Failed to get public key from Ledger.');\n\t\t}\n\n\t\treturn new LedgerSigner({\n\t\t\tderivationPath,\n\t\t\tpublicKey: new Ed25519PublicKey(publicKey),\n\t\t\tledgerClient,\n\t\t\tsuiClient,\n\t\t});\n\t}\n\n\tasync #getClearSigningOptions(transactionBytes: Uint8Array) {\n\t\tconst transaction = Transaction.from(transactionBytes);\n\t\tconst data = transaction.getData();\n\n\t\tconst gasObjectIds = data.gasData.payment?.map((object) => object.objectId) ?? [];\n\t\tconst inputObjectIds = data.inputs\n\t\t\t.map((input) => {\n\t\t\t\treturn input.$kind === 'Object' && input.Object.$kind === 'ImmOrOwnedObject'\n\t\t\t\t\t? input.Object.ImmOrOwnedObject.objectId\n\t\t\t\t\t: null;\n\t\t\t})\n\t\t\t.filter((objectId): objectId is string => !!objectId);\n\n\t\tconst objects = await this.#suiClient.multiGetObjects({\n\t\t\tids: [...gasObjectIds, ...inputObjectIds],\n\t\t\toptions: {\n\t\t\t\tshowBcs: true,\n\t\t\t\tshowPreviousTransaction: true,\n\t\t\t\tshowStorageRebate: true,\n\t\t\t\tshowOwner: true,\n\t\t\t},\n\t\t});\n\n\t\t// NOTE: We should probably get rid of this manual serialization logic in favor of using the\n\t\t// already serialized object bytes from the GraphQL API once there is more mainstream support\n\t\t// for it + we can enforce the transport type on the Sui client.\n\t\tconst bcsObjects = objects\n\t\t\t.map((object) => {\n\t\t\t\tif (object.error || !object.data || object.data.bcs?.dataType !== 'moveObject') {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn SuiMoveObject.serialize({\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tMoveObject: {\n\t\t\t\t\t\t\ttype: object.data.bcs.type,\n\t\t\t\t\t\t\thasPublicTransfer: object.data.bcs.hasPublicTransfer,\n\t\t\t\t\t\t\tversion: object.data.bcs.version,\n\t\t\t\t\t\t\tcontents: object.data.bcs.bcsBytes,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\towner: object.data.owner!,\n\t\t\t\t\tpreviousTransaction: object.data.previousTransaction!,\n\t\t\t\t\tstorageRebate: object.data.storageRebate!,\n\t\t\t\t}).toBytes();\n\t\t\t})\n\t\t\t.filter((bcsBytes): bcsBytes is Uint8Array => !!bcsBytes);\n\n\t\treturn { bcsObjects };\n\t}\n\n\t/**\n\t * Generic signing is not supported by Ledger.\n\t * @throws Always throws an error indicating generic signing is unsupported.\n\t */\n\toverride sign(): never {\n\t\tthrow new Error('Ledger Signer does not support generic signing.');\n\t}\n\n\t/**\n\t * Generic signing is not supported by Ledger.\n\t * @throws Always throws an error indicating generic signing is unsupported.\n\t */\n\toverride signWithIntent(): never {\n\t\tthrow new Error('Ledger Signer does not support generic signing.');\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }