@mysten/sui 2.19.0 → 2.20.1

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 (41) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/bcs/bcs.d.mts +6 -6
  3. package/dist/grpc/proto/sui/forking/v1alpha/forking_service.client.d.mts +4 -4
  4. package/dist/grpc/proto/sui/rpc/v2/move_package_service.client.d.mts +4 -4
  5. package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.client.d.mts +4 -4
  6. package/dist/transactions/intents/CoinWithBalance.d.mts.map +1 -1
  7. package/dist/transactions/intents/CoinWithBalance.mjs +7 -3
  8. package/dist/transactions/intents/CoinWithBalance.mjs.map +1 -1
  9. package/dist/version.mjs +1 -1
  10. package/dist/version.mjs.map +1 -1
  11. package/dist/zklogin/bcs.d.mts +14 -14
  12. package/dist/zklogin/bcs.d.mts.map +1 -1
  13. package/dist/zklogin/index.d.mts +2 -1
  14. package/dist/zklogin/index.mjs +2 -1
  15. package/dist/zklogin/publickey.d.mts +4 -0
  16. package/dist/zklogin/publickey.d.mts.map +1 -1
  17. package/dist/zklogin/publickey.mjs +6 -0
  18. package/dist/zklogin/publickey.mjs.map +1 -1
  19. package/dist/zklogin/signer.d.mts +55 -0
  20. package/dist/zklogin/signer.d.mts.map +1 -0
  21. package/dist/zklogin/signer.mjs +68 -0
  22. package/dist/zklogin/signer.mjs.map +1 -0
  23. package/docs/cryptography/index.md +225 -0
  24. package/docs/cryptography/keypairs.md +36 -143
  25. package/docs/cryptography/signers/aws-kms.md +110 -0
  26. package/docs/cryptography/signers/gcp-kms.md +91 -0
  27. package/docs/cryptography/signers/index.md +78 -0
  28. package/docs/cryptography/signers/ledger.md +76 -0
  29. package/docs/cryptography/{multisig.md → signers/multisig.md} +2 -2
  30. package/docs/cryptography/{passkey.md → signers/passkey.md} +1 -1
  31. package/docs/cryptography/{webcrypto-signer.md → signers/webcrypto.md} +6 -6
  32. package/docs/index.md +4 -5
  33. package/docs/llms-index.md +9 -4
  34. package/docs/migrations/sui-2.0/index.md +14 -1
  35. package/docs/zklogin.md +2 -2
  36. package/package.json +1 -1
  37. package/src/transactions/intents/CoinWithBalance.ts +21 -6
  38. package/src/version.ts +1 -1
  39. package/src/zklogin/index.ts +2 -0
  40. package/src/zklogin/publickey.ts +7 -0
  41. package/src/zklogin/signer.ts +121 -0
@@ -0,0 +1,225 @@
1
+ # Cryptography
2
+
3
+ > Sign and verify Sui transactions and messages with keypairs and external signers
4
+
5
+ A signature authorizes every transaction and personal message on Sui. The Sui TypeScript SDK exposes
6
+ a single abstraction for producing those signatures, the `Signer`, along with several
7
+ implementations of it, from in-process keypairs to hardware wallets and cloud key-management
8
+ services (KMS). This page walks through the concepts shared by every signer; the subpages cover each
9
+ implementation in detail.
10
+
11
+ ## Signing schemes
12
+
13
+ A signer always produces a signature under a signature scheme, which determines the curve and
14
+ signature format. Sui supports three schemes, each with a corresponding `Keypair` class:
15
+
16
+ | Scheme | Class | Import |
17
+ | --------------- | ------------------ | -------------------------------- |
18
+ | Ed25519 | `Ed25519Keypair` | `@mysten/sui/keypairs/ed25519` |
19
+ | ECDSA Secp256k1 | `Secp256k1Keypair` | `@mysten/sui/keypairs/secp256k1` |
20
+ | ECDSA Secp256r1 | `Secp256r1Keypair` | `@mysten/sui/keypairs/secp256r1` |
21
+
22
+ For background on the schemes themselves, see the
23
+ [Signatures](https://docs.sui.io/concepts/cryptography/transaction-auth/signatures) concept topic. A
24
+ signer's scheme determines the format of its public key and the Sui address it derives.
25
+
26
+ ## The Signer interface
27
+
28
+ `Signer` is an abstract class exported from `@mysten/sui/cryptography`. Every signer, whether it
29
+ holds the private key in memory, on a Ledger device, or in AWS KMS, implements the same interface,
30
+ so the rest of your code doesn't need to know where the key lives.
31
+
32
+ Implementations provide three primitives:
33
+
34
+ | Method | Description |
35
+ | ---------------- | ------------------------------------------------------------------ |
36
+ | `getPublicKey()` | Returns the `PublicKey` for deriving the address and verifying |
37
+ | `getKeyScheme()` | Returns the signature scheme (`ED25519`, `Secp256k1`, `Secp256r1`) |
38
+ | `sign(bytes)` | Signs raw bytes and returns the signature |
39
+
40
+ On top of those, `Signer` provides the methods you typically call:
41
+
42
+ | Method | Description |
43
+ | ----------------------------- | ------------------------------------------------ |
44
+ | `toSuiAddress()` | The Sui address derived from the public key |
45
+ | `signTransaction(bytes)` | Signs transaction bytes with the correct intent |
46
+ | `signPersonalMessage(bytes)` | Signs a personal message |
47
+ | `signAndExecuteTransaction()` | Signs and submits a transaction through a client |
48
+
49
+ There are two broad families of signer:
50
+
51
+ - **Key pairs** hold the private key in process. `Keypair` extends `Signer` and adds secret-key
52
+ import and export (`getSecretKey`, `fromSecretKey`). This is the easiest option for scripts,
53
+ backends, and tests. See [Key pairs](/sui/cryptography/keypairs).
54
+ - **External signers** keep the private key outside your application, in a KMS, on a hardware
55
+ wallet, or as a non-extractable browser key. They extend `Signer` directly. See
56
+ [Signers](/sui/cryptography/signers).
57
+
58
+ Because both families share the `Signer` interface, you can pass any signer wherever the SDK accepts
59
+ one, for example as the `signer` argument to a client's `signAndExecuteTransaction`.
60
+
61
+ ## Public keys and addresses
62
+
63
+ Every signer exposes a `PublicKey` through `getPublicKey()`. You use the public key to derive the
64
+ signer's Sui address and to verify signatures:
65
+
66
+ ```typescript
67
+
68
+ const keypair = new Ed25519Keypair();
69
+
70
+ // Derive the address directly from the signer...
71
+ const address = keypair.toSuiAddress();
72
+
73
+ // ...or from its public key
74
+ const publicKey = keypair.getPublicKey();
75
+ const sameAddress = publicKey.toSuiAddress();
76
+ ```
77
+
78
+ ## Signing messages and transactions
79
+
80
+ The signing API is identical for every signer; only construction differs. Use `signPersonalMessage`
81
+ to sign arbitrary bytes and `signTransaction` to sign built transaction bytes:
82
+
83
+ ```typescript
84
+ const message = new TextEncoder().encode('hello world');
85
+ const { signature } = await keypair.signPersonalMessage(message);
86
+ ```
87
+
88
+ Both `signPersonalMessage` and `signTransaction` resolve to `{ bytes, signature }`, where
89
+ `signature` is the serialized signature string used for execution and verification, and `bytes` is
90
+ the base64 payload that the signer signed.
91
+
92
+ To sign and submit a transaction in one step, pass the signer to a client:
93
+
94
+ ```typescript
95
+
96
+ const client = new SuiGrpcClient({
97
+ network: 'testnet',
98
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
99
+ });
100
+
101
+ const result = await client.signAndExecuteTransaction({
102
+ transaction,
103
+ signer: keypair,
104
+ });
105
+
106
+ // signAndExecuteTransaction resolves to a discriminated union, so check for failure first
107
+ if (result.FailedTransaction) {
108
+ throw new Error('Transaction failed to execute');
109
+ }
110
+
111
+ console.log('Digest:', result.Transaction.digest);
112
+ ```
113
+
114
+ ## Verifying signatures
115
+
116
+ Verification confirms a signature is valid for a given message and that the expected key produced
117
+ it. The `@mysten/sui/verify` module verifies a signature against a message and recovers the
118
+ `PublicKey` that produced it, without needing the original signer.
119
+
120
+ ```typescript
121
+
122
+ const keypair = new Ed25519Keypair();
123
+ const message = new TextEncoder().encode('hello world');
124
+ const { signature } = await keypair.signPersonalMessage(message);
125
+
126
+ const publicKey = await verifyPersonalMessageSignature(message, signature);
127
+
128
+ if (!publicKey.verifyAddress(keypair.toSuiAddress())) {
129
+ throw new Error('Signature was valid, but was signed by a different key pair');
130
+ }
131
+ ```
132
+
133
+ ### Verifying that a signature is valid for a specific address
134
+
135
+ `verifyPersonalMessageSignature` and `verifyTransactionSignature` accept an optional `address` and
136
+ throw if the signature is not valid for it:
137
+
138
+ ```typescript
139
+
140
+ const keypair = new Ed25519Keypair();
141
+ const message = new TextEncoder().encode('hello world');
142
+ const { signature } = await keypair.signPersonalMessage(message);
143
+
144
+ await verifyPersonalMessageSignature(message, signature, {
145
+ address: keypair.toSuiAddress(),
146
+ });
147
+ ```
148
+
149
+ ### Verifying transaction signatures
150
+
151
+ Verifying transaction signatures works the same way, using `verifyTransactionSignature`:
152
+
153
+ ```typescript
154
+
155
+ const client = new SuiGrpcClient({
156
+ network: 'testnet',
157
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
158
+ });
159
+ const tx = new Transaction();
160
+ // ... add some transactions...
161
+ const bytes = await tx.build({ client });
162
+
163
+ const keypair = new Ed25519Keypair();
164
+ const { signature } = await keypair.signTransaction(bytes);
165
+
166
+ await verifyTransactionSignature(bytes, signature, {
167
+ // optionally verify that the signature is valid for a specific address
168
+ address: keypair.toSuiAddress(),
169
+ });
170
+ ```
171
+
172
+ ### Verifying zkLogin signatures
173
+
174
+ You can't verify zkLogin signatures purely on the client. When verifying a zkLogin signature, the
175
+ SDK uses the GraphQL API. This works for Mainnet signatures without any additional configuration.
176
+ For Testnet signatures, provide a Testnet GraphQL client:
177
+
178
+ ```typescript
179
+
180
+ const publicKey = await verifyPersonalMessageSignature(message, zkSignature, {
181
+ client: new SuiGraphQLClient({
182
+ url: 'https://graphql.testnet.sui.io/graphql',
183
+ }),
184
+ });
185
+ ```
186
+
187
+ For some zkLogin accounts, there are two valid addresses for a given set of inputs, so comparing the
188
+ address from `publicKey.toSuiAddress()` directly against an expected address can fail. Instead, pass
189
+ the expected address during verification, or use `publicKey.verifyAddress(address)`:
190
+
191
+ ```typescript
192
+
193
+ const publicKey = await verifyPersonalMessageSignature(message, zkSignature, {
194
+ client: new SuiGraphQLClient({
195
+ url: 'https://graphql.testnet.sui.io/graphql',
196
+ }),
197
+ // Throws if the signature is not valid for the provided address
198
+ address: '0x...expectedAddress',
199
+ });
200
+ // or
201
+
202
+ if (!publicKey.verifyAddress('0x...expectedAddress')) {
203
+ throw new Error('Signature was valid, but was signed by a different key pair');
204
+ }
205
+ ```
206
+
207
+ Both methods check the signature against the standard and
208
+ [legacy versions of the zkLogin address](https://sdk.mystenlabs.com/sui/zklogin#legacy-addresses).
209
+
210
+ ## Choosing an implementation
211
+
212
+ - **[Key pairs](/sui/cryptography/keypairs)**: `Ed25519Keypair`, `Secp256k1Keypair`, and
213
+ `Secp256r1Keypair` hold the private key in process. The easiest option when you manage the secret
214
+ key yourself. Covers deriving keypairs from mnemonics and secret keys.
215
+ - **[Signers](/sui/cryptography/signers)**: other implementations of the `Signer` interface,
216
+ including signer packages that keep the private key outside your application — cloud KMS
217
+ ([AWS](/sui/cryptography/signers/aws-kms), [GCP](/sui/cryptography/signers/gcp-kms)), a
218
+ [Ledger](/sui/cryptography/signers/ledger) hardware wallet, and non-extractable browser keys with
219
+ the [Web Crypto](/sui/cryptography/signers/webcrypto) signer — as well as
220
+ [passkeys](/sui/cryptography/signers/passkey) and
221
+ [multi-signature](/sui/cryptography/signers/multisig).
222
+
223
+ If you just need to sign in a script or server and are comfortable managing the secret key yourself,
224
+ start with [Key pairs](/sui/cryptography/keypairs). If the key must never live in your application's
225
+ memory, use one of the external [signers](/sui/cryptography/signers).
@@ -1,11 +1,14 @@
1
1
  # Key pairs
2
2
 
3
- > Create and manage Ed25519, Secp256k1, and Secp256r1 keypairs for Sui transaction signing.
3
+ > Create Ed25519, Secp256k1, and Secp256r1 keypairs and derive them from mnemonics and secret keys
4
4
 
5
- The Sui TypeScript SDK provides `Keypair` classes that handle logic for signing and verification
6
- using the cryptographic key pairs associated with a Sui address.
5
+ A `Keypair` holds a Sui private key in process and signs with it. It is the easiest
6
+ [`Signer`](/sui/cryptography) to use. It is ideal for scripts, backends, and tests where you manage
7
+ the secret key yourself. For the signing and verification API shared by all signers, see
8
+ [Cryptography](/sui/cryptography); this page focuses on creating keypairs and deriving them from
9
+ mnemonics and secret keys.
7
10
 
8
- The Sui TypeScript SDK supports three signing schemes:
11
+ Each signing scheme has a corresponding `Keypair` class:
9
12
 
10
13
  | Sign scheme | Class name | Import folder |
11
14
  | --------------- | ------------------ | -------------------------------- |
@@ -13,9 +16,6 @@ The Sui TypeScript SDK supports three signing schemes:
13
16
  | ECDSA Secp256k1 | `Secp256k1Keypair` | `@mysten/sui/keypairs/secp256k1` |
14
17
  | ECDSA Secp256r1 | `Secp256r1Keypair` | `@mysten/sui/keypairs/secp256r1` |
15
18
 
16
- For information on these schemes, see the
17
- [Signatures](https://docs.sui.io/concepts/cryptography/transaction-auth/signatures) topic.
18
-
19
19
  To use, import the key pair class your project uses from the `@mysten/sui/keypairs` folder. For
20
20
  example, to use the Ed25519 scheme, import the `Ed25519Keypair` class from
21
21
  `@mysten/sui/keypairs/ed25519`.
@@ -24,155 +24,55 @@ example, to use the Ed25519 scheme, import the `Ed25519Keypair` class from
24
24
 
25
25
  ```
26
26
 
27
+ ## Creating a key pair
28
+
27
29
  To create a random key pair (which identifies a Sui address), instantiate a new `Keypair` class. To
28
30
  reference a key pair from an existing secret key, pass the secret to the `fromSecretKey` function.
29
31
 
30
32
  ```typescript
31
33
  // random Keypair
32
34
  const keypair = new Ed25519Keypair();
33
- // Keypair from an existing secret key (Uint8Array)
34
- const keypair = Ed25519Keypair.fromSecretKey(secretKey);
35
- ```
36
-
37
- With your key pair created, you can reference it when performing actions on the network. For
38
- example, you can use it to sign transactions, like the following code that creates and signs a
39
- personal message using the public key from the key pair created in the previous code:
40
-
41
- ```typescript
42
- const publicKey = keypair.getPublicKey();
43
- const message = new TextEncoder().encode('hello world');
44
35
 
45
- const { signature } = await keypair.signPersonalMessage(message);
46
- const isValid = await publicKey.verifyPersonalMessage(message, signature);
36
+ // or, a Keypair from an existing secret key (Uint8Array)
37
+ const fromSecret = Ed25519Keypair.fromSecretKey(secretKey);
47
38
  ```
48
39
 
49
- ## Public keys
50
-
51
- Each `Keypair` has an associated `PublicKey` class. You use the public key to verify signatures or
52
- to retrieve its associated Sui address. You can access a `Keypair` from its `PublicKey` or construct
53
- it from the bytes (as a `Uint8Array`) of the `PublicKey`, as in the following code:
40
+ With your key pair created, you can derive its address and sign with it. The following signs a
41
+ personal message and verifies it with the public key:
54
42
 
55
43
  ```typescript
56
-
57
- const keypair = new Ed25519Keypair();
58
-
59
- // method 1
60
- const bytes = keypair.getPublicKey().toRawBytes();
61
- const publicKey = new Ed25519PublicKey(bytes);
62
- const address = publicKey.toSuiAddress();
63
-
64
- // method 2
65
- const address = keypair.getPublicKey().toSuiAddress();
66
- // or use `toSuiAddress()` directly
44
+ const publicKey = keypair.getPublicKey();
67
45
  const address = keypair.toSuiAddress();
68
- ```
69
-
70
- ## Verifying signatures without a key pair
71
-
72
- When you have an existing public key, you can use it to verify a signature. Verification ensures the
73
- signature is valid for the provided message and is signed with the appropriate secret key.
74
46
 
75
- The following code creates a key pair in the Ed25519 scheme, creates and signs a message with it,
76
- then verifies the message to retrieve the public key. The code then uses `toSuiAddress()` to check
77
- if the address associated with the public key matches the address that the key pair defines.
78
-
79
- ```typescript
80
-
81
- const keypair = new Ed25519Keypair();
82
47
  const message = new TextEncoder().encode('hello world');
83
48
  const { signature } = await keypair.signPersonalMessage(message);
84
-
85
- const publicKey = await verifyPersonalMessageSignature(message, signature);
86
-
87
- if (!publicKey.verifyAddress(keypair.toSuiAddress())) {
88
- throw new Error('Signature was valid, but was signed by a different key pair');
89
- }
90
- ```
91
-
92
- ## Verifying that a signature is valid for a specific address
93
-
94
- `verifyPersonalMessageSignature` and `verifyTransactionSignature` accept an optional `address`, and
95
- will throw an error if the signature is not valid for the provided address.
96
-
97
- ```typescript
98
-
99
- const keypair = new Ed25519Keypair();
100
- const message = new TextEncoder().encode('hello world');
101
- const { signature } = await keypair.signPersonalMessage(message);
102
-
103
- await verifyPersonalMessageSignature(message, signature, {
104
- address: keypair.toSuiAddress(),
105
- });
106
- ```
107
-
108
- ## Verifying transaction signatures
109
-
110
- Verifying transaction signatures is similar to personal message signature verification, except you
111
- use `verifyTransactionSignature`:
112
-
113
- ```typescript
114
- // import SuiGrpcClient to create a network client
115
-
116
- // create a client connected to testnet
117
- const client = new SuiGrpcClient({
118
- network: 'testnet',
119
- baseUrl: 'https://fullnode.testnet.sui.io:443',
120
- });
121
- const tx = new Transaction();
122
- // ... add some transactions...
123
- const bytes = await tx.build({ client });
124
-
125
- const keypair = new Ed25519Keypair();
126
- const { signature } = await keypair.signTransaction(bytes);
127
-
128
- await verifyTransactionSignature(bytes, signature, {
129
- // optionally verify that the signature is valid for a specific address
130
- address: keypair.toSuiAddress(),
131
- });
49
+ const isValid = await publicKey.verifyPersonalMessage(message, signature);
132
50
  ```
133
51
 
134
- ## Verifying zkLogin signatures
52
+ See [Cryptography](/sui/cryptography) for the full signing and verification API, including
53
+ [verifying signatures](/sui/cryptography#verifying-signatures) without the original key pair.
135
54
 
136
- ZkLogin signatures can't be verified purely on the client. When verifying a zkLogin signature, the
137
- SDK uses the GraphQL API to verify the signature. This works for Mainnet signatures without any
138
- additional configuration.
55
+ ## Public keys
139
56
 
140
- For Testnet signatures, you need to provide a Testnet GraphQL Client:
57
+ Each `Keypair` has an associated `PublicKey`, which you use to verify signatures or to retrieve its
58
+ Sui address. Access it from a `Keypair` with `getPublicKey()`. To recreate a keypair, and therefore
59
+ its public key, from saved key material, reconstruct it from the secret key:
141
60
 
142
61
  ```typescript
143
62
 
144
- const publicKey = await verifyPersonalMessageSignature(message, zkSignature, {
145
- client: new SuiGraphQLClient({
146
- url: 'https://graphql.testnet.sui.io/graphql',
147
- }),
148
- });
149
- ```
150
-
151
- For some zklogin accounts, there are two valid addresses for a given set of inputs. This means you
152
- might run into issues if you try to compare the address returned by `publicKey.toSuiAddress()`
153
- directly with an expected address.
154
-
155
- Instead, you can either pass in the expected address during verification, or use the
156
- `publicKey.verifyAddress(address)` method:
157
-
158
- ```typescript
63
+ // Recreate the keypair from its secret key (Uint8Array)
64
+ const keypair = Ed25519Keypair.fromSecretKey(secretKey);
159
65
 
160
- const publicKey = await verifyPersonalMessageSignature(message, zkSignature, {
161
- client: new SuiGraphQLClient({
162
- url: 'https://graphql.testnet.sui.io/graphql',
163
- }),
164
- // Pass in the expected address, and the verification method will throw an error if the signature is not valid for the provided address
165
- address: '0x...expectedAddress',
166
- });
167
- // or
168
-
169
- if (!publicKey.verifyAddress('0x...expectedAddress')) {
170
- throw new Error('Signature was valid, but was signed by a different key pair');
171
- }
66
+ // Access the public key and derive the address
67
+ const publicKey = keypair.getPublicKey();
68
+ const address = publicKey.toSuiAddress();
69
+ // or derive the address directly from the keypair
70
+ const sameAddress = keypair.toSuiAddress();
172
71
  ```
173
72
 
174
- Both of these methods will check the signature against both the standard and
175
- [legacy versions of the zklogin address](https://sdk.mystenlabs.com/sui/zklogin#legacy-addresses).
73
+ See
74
+ [Deriving a `Keypair` from a Bech32 encoded secret key](#deriving-a-keypair-from-a-bech32-encoded-secret-key)
75
+ for working with encoded secret-key formats.
176
76
 
177
77
  ## Deriving a key pair from a mnemonic
178
78
 
@@ -199,14 +99,16 @@ const keypair = Ed25519Keypair.fromSecretKey(secretKey);
199
99
  ```
200
100
 
201
101
  You can also use the `decodeSuiPrivateKey` function to decode the secret key and determine the
202
- keyScheme, and get the keypairs private key bytes, which can be used to instantiate the appropriate
203
- `Keypair` class.
102
+ keyScheme, and get the key pair's private key bytes, which you can use to instantiate the
103
+ appropriate `Keypair` class.
204
104
 
205
105
  ```typescript
206
106
 
107
+ const encoded = 'suiprivkey1qzse89atw7d3zum8ujep76d2cxmgduyuast0y9fu23xcl0mpafgkktllhyc';
207
108
  const { scheme, secretKey } = decodeSuiPrivateKey(encoded);
208
109
 
209
110
  // use scheme to choose the correct key pair
111
+ let keypair;
210
112
  switch (scheme) {
211
113
  case 'ED25519':
212
114
  keypair = Ed25519Keypair.fromSecretKey(secretKey);
@@ -225,16 +127,7 @@ switch (scheme) {
225
127
  See [SIP-15](https://github.com/sui-foundation/sips/blob/main/sips/sip-15.md) for additional context
226
128
  and motivation.
227
129
 
228
- If you know your keypair scheme, you can use the `fromSecretKey` method of the appropriate keypair
229
- to directly derive the keypair from the secret key.
230
-
231
- ```typescript
232
- const secretKey = 'suiprivkey1qzse89atw7d3zum8ujep76d2cxmgduyuast0y9fu23xcl0mpafgkktllhyc';
233
-
234
- const keypair = Ed25519Keypair.fromSecretKey(secretKey);
235
- ```
236
-
237
- You can also export a keypair to a Bech32 encoded secret key using the `getSecretKey` method.
130
+ You can export a keypair to a Bech32 encoded secret key using the `getSecretKey` method.
238
131
 
239
132
  ```typescript
240
133
  const secretKey = keypair.getSecretKey();
@@ -0,0 +1,110 @@
1
+ # AWS KMS Signer
2
+
3
+ > Sign Sui transactions with a key stored in AWS Key Management Service
4
+
5
+ The `AwsKmsSigner` signs Sui transactions using a key held in
6
+ [AWS Key Management Service](https://aws.amazon.com/kms/). The private key never leaves AWS; the
7
+ signer sends the message to KMS and receives the signature back.
8
+
9
+ AWS KMS supports the `Ed25519`, `Secp256k1`, and `Secp256r1` schemes. The curve of the KMS key
10
+ determines the signature scheme (`ECC_NIST_EDWARDS25519` → `Ed25519`, `ECC_SECG_P256K1` →
11
+ `Secp256k1`, `ECC_NIST_P256` → `Secp256r1`). `Ed25519` is Sui's native scheme.
12
+
13
+ > **Warning:** The AWS KMS Signer requires Node.js >= 22 (the package's `engines.node` constraint) and relies on
14
+ > the global Web Crypto API.
15
+
16
+ ## Installation
17
+
18
+ ```sh npm2yarn
19
+ npm i @mysten/aws-kms-signer
20
+ ```
21
+
22
+ ## Creating a signer
23
+
24
+ Construct the signer with `AwsKmsSigner.fromKeyId`, passing the KMS key ID and the AWS credentials
25
+ and region. This is async: it fetches the public key from KMS so the signer can derive the Sui
26
+ address.
27
+
28
+ ```typescript
29
+
30
+ const { AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, AWS_KMS_KEY_ID } = process.env;
31
+
32
+ const signer = await AwsKmsSigner.fromKeyId(AWS_KMS_KEY_ID, {
33
+ region: AWS_REGION,
34
+ accessKeyId: AWS_ACCESS_KEY_ID,
35
+ secretAccessKey: AWS_SECRET_ACCESS_KEY,
36
+ });
37
+ ```
38
+
39
+ ### Parameters
40
+
41
+ `fromKeyId(keyId, options)`
42
+
43
+ | Parameter | Type | Description |
44
+ | ------------------------- | ----------------------- | ---------------------------------------------------------------- |
45
+ | `keyId` | `string` | The AWS KMS key ID |
46
+ | `options.region` | `string` | The AWS region the key lives in |
47
+ | `options.accessKeyId` | `string` | The AWS access key ID (omit when using `credentials`) |
48
+ | `options.secretAccessKey` | `string` | The AWS secret access key (omit when using `credentials`) |
49
+ | `options.credentials` | `AwsCredentialProvider` | Optional async provider resolved before each request (see below) |
50
+
51
+ You must supply either static `accessKeyId`/`secretAccessKey` **or** a `credentials` provider.
52
+
53
+ ### Using a credential provider
54
+
55
+ Instead of static keys, pass an async `credentials` provider (any function returning
56
+ `{ accessKeyId, secretAccessKey, sessionToken? }`). This is structurally compatible with the
57
+ providers from
58
+ [`@aws-sdk/credential-providers`](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html),
59
+ so the standard AWS credential chain (SSO, IAM roles, and container/instance metadata) works out of
60
+ the box. Credentials are resolved before each request, so temporary credentials refresh
61
+ automatically once their session nears expiry.
62
+
63
+ ```typescript
64
+
65
+ const signer = await AwsKmsSigner.fromKeyId(process.env.AWS_KMS_KEY_ID, {
66
+ region: process.env.AWS_REGION,
67
+ credentials: fromNodeProviderChain(),
68
+ });
69
+ ```
70
+
71
+ `@aws-sdk/credential-providers` is **not** a dependency of this package, so install it yourself if
72
+ you want the AWS-provided resolvers. This keeps the signer lightweight for edge, browser, and Worker
73
+ runtimes, where you can instead pass static credentials or a custom resolver.
74
+
75
+ ## Usage
76
+
77
+ Once created, the signer behaves like any other [`Signer`](/sui/cryptography): derive the address,
78
+ sign messages, and sign or execute transactions.
79
+
80
+ ```typescript
81
+ // Derive the Sui address
82
+ const address = signer.getPublicKey().toSuiAddress();
83
+
84
+ // Sign a personal message
85
+ const message = new TextEncoder().encode('Hello, AWS KMS Signer!');
86
+ const { signature } = await signer.signPersonalMessage(message);
87
+
88
+ // Verify the signature
89
+ const isValid = await signer.getPublicKey().verifyPersonalMessage(message, signature);
90
+ console.log(isValid); // true
91
+ ```
92
+
93
+ To sign and submit a transaction, pass the signer to a client:
94
+
95
+ ```typescript
96
+
97
+ const client = new SuiGrpcClient({
98
+ network: 'testnet',
99
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
100
+ });
101
+
102
+ const result = await client.signAndExecuteTransaction({ transaction, signer });
103
+ if (result.FailedTransaction) {
104
+ throw new Error('Transaction failed to execute');
105
+ }
106
+ console.log(result.Transaction.digest);
107
+ ```
108
+
109
+ See [Cryptography](/sui/cryptography) for the full signing and verification API shared by all
110
+ signers.
@@ -0,0 +1,91 @@
1
+ # GCP KMS Signer
2
+
3
+ > Sign Sui transactions with a key stored in Google Cloud Key Management Service
4
+
5
+ The `GcpKmsSigner` signs Sui transactions using a key held in
6
+ [Google Cloud KMS](https://cloud.google.com/kms). The private key never leaves GCP; the signer sends
7
+ the message digest to KMS and receives the signature back.
8
+
9
+ GCP KMS supports the `Secp256k1` and `Secp256r1` schemes. The curve of the KMS key determines the
10
+ signature scheme (`EC_SIGN_SECP256K1_SHA256` → `Secp256k1`, `EC_SIGN_P256_SHA256` → `Secp256r1`).
11
+
12
+ ## Installation
13
+
14
+ ```sh npm2yarn
15
+ npm i @mysten/gcp-kms-signer
16
+ ```
17
+
18
+ ## Creating a signer
19
+
20
+ Construct the signer with `GcpKmsSigner.fromOptions`, identifying the key by its project, location,
21
+ key ring, key, and version. This is async: it fetches the public key from KMS so the signer can
22
+ derive the Sui address.
23
+
24
+ ```typescript
25
+
26
+ const signer = await GcpKmsSigner.fromOptions({
27
+ projectId: 'your-google-project-id',
28
+ location: 'your-google-location',
29
+ keyRing: 'your-google-keyring',
30
+ cryptoKey: 'your-google-key-name',
31
+ cryptoKeyVersion: 'your-google-key-version',
32
+ });
33
+ ```
34
+
35
+ ### Parameters
36
+
37
+ `fromOptions(options)`
38
+
39
+ | Parameter | Type | Description |
40
+ | ------------------ | -------- | --------------------- |
41
+ | `projectId` | `string` | The GCP project ID |
42
+ | `location` | `string` | The GCP location |
43
+ | `keyRing` | `string` | The GCP key ring name |
44
+ | `cryptoKey` | `string` | The GCP key name |
45
+ | `cryptoKeyVersion` | `string` | The GCP key version |
46
+
47
+ If you already have a fully-qualified KMS version name, construct the signer directly with
48
+ `GcpKmsSigner.fromVersionName`:
49
+
50
+ ```typescript
51
+ const signer = await GcpKmsSigner.fromVersionName(
52
+ 'projects/p/locations/l/keyRings/r/cryptoKeys/k/cryptoKeyVersions/1',
53
+ );
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ Once created, the signer behaves like any other [`Signer`](/sui/cryptography): derive the address,
59
+ sign messages, and sign or execute transactions.
60
+
61
+ ```typescript
62
+ // Derive the Sui address
63
+ const address = signer.getPublicKey().toSuiAddress();
64
+
65
+ // Sign a personal message
66
+ const message = new TextEncoder().encode('Hello, GCP KMS Signer!');
67
+ const { signature } = await signer.signPersonalMessage(message);
68
+
69
+ // Verify the signature
70
+ const isValid = await signer.getPublicKey().verifyPersonalMessage(message, signature);
71
+ console.log(isValid); // true
72
+ ```
73
+
74
+ To sign and submit a transaction, pass the signer to a client:
75
+
76
+ ```typescript
77
+
78
+ const client = new SuiGrpcClient({
79
+ network: 'testnet',
80
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
81
+ });
82
+
83
+ const result = await client.signAndExecuteTransaction({ transaction, signer });
84
+ if (result.FailedTransaction) {
85
+ throw new Error('Transaction failed to execute');
86
+ }
87
+ console.log(result.Transaction.digest);
88
+ ```
89
+
90
+ See [Cryptography](/sui/cryptography) for the full signing and verification API shared by all
91
+ signers.