@mysten/sui 2.20.0 → 2.20.2
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 +21 -0
- package/dist/bcs/bcs.d.mts +6 -6
- package/dist/bcs/index.d.mts +20 -20
- package/dist/graphql/core.d.mts.map +1 -1
- package/dist/graphql/core.mjs +5 -1
- package/dist/graphql/core.mjs.map +1 -1
- package/dist/grpc/core.d.mts.map +1 -1
- package/dist/grpc/core.mjs +1 -0
- package/dist/grpc/core.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/ledger_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/move_package_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/name_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/state_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/subscription_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/transaction_execution_service.client.d.mts +4 -4
- package/dist/transactions/Transaction.d.mts +9 -9
- package/dist/transactions/Transaction.d.mts.map +1 -1
- package/dist/transactions/data/v1.d.mts +220 -220
- package/dist/transactions/data/v1.d.mts.map +1 -1
- package/dist/transactions/data/v2.d.mts +16 -16
- package/dist/transactions/data/v2.d.mts.map +1 -1
- package/dist/transactions/intents/CoinWithBalance.d.mts.map +1 -1
- package/dist/transactions/intents/CoinWithBalance.mjs +7 -3
- package/dist/transactions/intents/CoinWithBalance.mjs.map +1 -1
- package/dist/version.mjs +1 -1
- package/dist/version.mjs.map +1 -1
- package/dist/zklogin/bcs.d.mts +14 -14
- package/dist/zklogin/bcs.d.mts.map +1 -1
- package/docs/cryptography/index.md +225 -0
- package/docs/cryptography/keypairs.md +36 -143
- package/docs/cryptography/signers/aws-kms.md +110 -0
- package/docs/cryptography/signers/gcp-kms.md +91 -0
- package/docs/cryptography/signers/index.md +78 -0
- package/docs/cryptography/signers/ledger.md +76 -0
- package/docs/cryptography/{multisig.md → signers/multisig.md} +2 -2
- package/docs/cryptography/{passkey.md → signers/passkey.md} +1 -1
- package/docs/cryptography/{webcrypto-signer.md → signers/webcrypto.md} +6 -6
- package/docs/index.md +4 -5
- package/docs/llms-index.md +9 -4
- package/docs/migrations/sui-2.0/index.md +14 -1
- package/docs/zklogin.md +2 -2
- package/package.json +1 -1
- package/src/graphql/core.ts +5 -1
- package/src/grpc/core.ts +1 -0
- package/src/transactions/intents/CoinWithBalance.ts +21 -6
- package/src/version.ts +1 -1
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
# Key pairs
|
|
2
2
|
|
|
3
|
-
> Create
|
|
3
|
+
> Create Ed25519, Secp256k1, and Secp256r1 keypairs and derive them from mnemonics and secret keys
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
|
|
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
|
-
|
|
46
|
-
const
|
|
36
|
+
// or, a Keypair from an existing secret key (Uint8Array)
|
|
37
|
+
const fromSecret = Ed25519Keypair.fromSecretKey(secretKey);
|
|
47
38
|
```
|
|
48
39
|
|
|
49
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
145
|
-
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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
|
-
|
|
175
|
-
[
|
|
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
|
|
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
|
-
|
|
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.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Signers
|
|
2
|
+
|
|
3
|
+
> Signer implementations beyond keypairs — cloud KMS, Ledger, Web Crypto, passkeys, and multisig
|
|
4
|
+
|
|
5
|
+
In addition to the in-process [keypairs](/sui/cryptography/keypairs) built into `@mysten/sui`, the
|
|
6
|
+
SDK ecosystem ships more implementations of the [`Signer`](/sui/cryptography) interface. Some keep
|
|
7
|
+
the private key outside your application — in a cloud key-management service (KMS), on a hardware
|
|
8
|
+
wallet, or as a non-extractable browser key — while others, like
|
|
9
|
+
[multisig](/sui/cryptography/signers/multisig), combine several signers together. Because each one
|
|
10
|
+
extends the same `Signer` base class, it works anywhere a keypair does.
|
|
11
|
+
|
|
12
|
+
## External signers
|
|
13
|
+
|
|
14
|
+
These signers hold the key material outside your process. Each is published as its **own package**,
|
|
15
|
+
so you install only the one you need:
|
|
16
|
+
|
|
17
|
+
| Signer | Package | Scheme | Key lives in |
|
|
18
|
+
| ----------------- | -------------------------- | ---------------------- | --------------------------------------------------------------- |
|
|
19
|
+
| `AwsKmsSigner` | `@mysten/aws-kms-signer` | Secp256k1 or Secp256r1 | [AWS KMS](/sui/cryptography/signers/aws-kms) |
|
|
20
|
+
| `GcpKmsSigner` | `@mysten/gcp-kms-signer` | Secp256k1 or Secp256r1 | [GCP KMS](/sui/cryptography/signers/gcp-kms) |
|
|
21
|
+
| `LedgerSigner` | `@mysten/ledger-signer` | Ed25519 | [Ledger hardware wallet](/sui/cryptography/signers/ledger) |
|
|
22
|
+
| `WebCryptoSigner` | `@mysten/webcrypto-signer` | Secp256r1 | [Browser Web Crypto store](/sui/cryptography/signers/webcrypto) |
|
|
23
|
+
|
|
24
|
+
For the AWS and GCP signers, the curve of the underlying KMS key determines the signature scheme
|
|
25
|
+
(`ECC_NIST_P256` → `Secp256r1`, `ECC_SECG_P256K1` → `Secp256k1`).
|
|
26
|
+
|
|
27
|
+
> Each signer above is its own npm package — import directly from `@mysten/aws-kms-signer`,
|
|
28
|
+
> `@mysten/ledger-signer`, and so on, and depend only on the ones you use. The `@mysten/signers`
|
|
29
|
+
> package is a convenience umbrella that re-exports all four under subpaths (`@mysten/signers/aws`,
|
|
30
|
+
> `@mysten/signers/gcp`, `@mysten/signers/ledger`, `@mysten/signers/webcrypto`) if you would rather
|
|
31
|
+
> depend on a single package. The individual pages below use the standalone packages.
|
|
32
|
+
|
|
33
|
+
## Other Signer implementations
|
|
34
|
+
|
|
35
|
+
Two more `Signer` implementations live in `@mysten/sui` itself rather than in a standalone package:
|
|
36
|
+
|
|
37
|
+
- **[Passkey](/sui/cryptography/signers/passkey)**: sign with a WebAuthn passkey (biometric or
|
|
38
|
+
platform authenticator) through `PasskeyKeypair`.
|
|
39
|
+
- **[Multi-signature](/sui/cryptography/signers/multisig)**: combine signatures from several public
|
|
40
|
+
keys under a configurable threshold with `MultiSigPublicKey`. Its `getSigner` method returns a
|
|
41
|
+
`MultiSigSigner` you can use anywhere a keypair works. The underlying keys can be keypairs, KMS
|
|
42
|
+
signers, passkeys, or zkLogin identifiers.
|
|
43
|
+
|
|
44
|
+
## Shared interface
|
|
45
|
+
|
|
46
|
+
Because every signer extends `Signer`, the signing API is identical regardless of where the key is
|
|
47
|
+
held; only the way you construct the signer differs:
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// Derive the address
|
|
51
|
+
const address = signer.getPublicKey().toSuiAddress();
|
|
52
|
+
|
|
53
|
+
// Sign a personal message
|
|
54
|
+
const message = new TextEncoder().encode('hello world');
|
|
55
|
+
const { signature } = await signer.signPersonalMessage(message);
|
|
56
|
+
|
|
57
|
+
// Sign and execute a transaction (resolves to a discriminated union)
|
|
58
|
+
const result = await client.signAndExecuteTransaction({ transaction, signer });
|
|
59
|
+
if (result.FailedTransaction) {
|
|
60
|
+
throw new Error('Transaction failed to execute');
|
|
61
|
+
}
|
|
62
|
+
console.log(result.Transaction.digest);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
See [Cryptography](/sui/cryptography) for the full signing and verification API that all signers
|
|
66
|
+
share.
|
|
67
|
+
|
|
68
|
+
## Construction
|
|
69
|
+
|
|
70
|
+
Each external signer exposes a static factory rather than a public constructor, because preparing
|
|
71
|
+
the signer requires an async round-trip to fetch the public key from the KMS or device:
|
|
72
|
+
|
|
73
|
+
- `AwsKmsSigner.fromKeyId(keyId, options)`. See [AWS KMS Signer](/sui/cryptography/signers/aws-kms).
|
|
74
|
+
- `GcpKmsSigner.fromOptions(options)`. See [GCP KMS Signer](/sui/cryptography/signers/gcp-kms).
|
|
75
|
+
- `LedgerSigner.fromDerivationPath(path, ledgerClient, suiClient)`. See
|
|
76
|
+
[Ledger Signer](/sui/cryptography/signers/ledger).
|
|
77
|
+
- `WebCryptoSigner.generate()` and `WebCryptoSigner.import(exported)`. See
|
|
78
|
+
[Web Crypto Signer](/sui/cryptography/signers/webcrypto).
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Ledger Signer
|
|
2
|
+
|
|
3
|
+
> Sign Sui transactions with a Ledger hardware wallet
|
|
4
|
+
|
|
5
|
+
The `LedgerSigner` signs Sui transactions and personal messages with a
|
|
6
|
+
[Ledger](https://www.ledger.com/) hardware wallet. The private key never leaves the device; you
|
|
7
|
+
confirm each signature on the Ledger. The Ledger signer uses the `Ed25519` scheme.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```sh npm2yarn
|
|
12
|
+
npm i @mysten/ledger-signer @mysten/ledgerjs-hw-app-sui
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
You also need a
|
|
16
|
+
[Ledger transport](https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledgerjs) for your
|
|
17
|
+
environment, for example `@ledgerhq/hw-transport-node-hid` in Node.js or
|
|
18
|
+
`@ledgerhq/hw-transport-webhid` in the browser.
|
|
19
|
+
|
|
20
|
+
## Creating a signer
|
|
21
|
+
|
|
22
|
+
Open a transport, wrap it in a `SuiLedgerClient`, then construct the signer with
|
|
23
|
+
`LedgerSigner.fromDerivationPath`. This is async: it fetches the public key from the device so the
|
|
24
|
+
signer can derive the Sui address.
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
|
|
28
|
+
const transport = await Transport.open(undefined);
|
|
29
|
+
const ledgerClient = new SuiLedgerClient(transport);
|
|
30
|
+
const suiClient = new SuiGrpcClient({
|
|
31
|
+
network: 'testnet',
|
|
32
|
+
baseUrl: 'https://fullnode.testnet.sui.io:443',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const signer = await LedgerSigner.fromDerivationPath(
|
|
36
|
+
"m/44'/784'/0'/0'/0'",
|
|
37
|
+
ledgerClient,
|
|
38
|
+
suiClient,
|
|
39
|
+
);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Parameters
|
|
43
|
+
|
|
44
|
+
`fromDerivationPath(derivationPath, ledgerClient, suiClient)`
|
|
45
|
+
|
|
46
|
+
| Parameter | Type | Description |
|
|
47
|
+
| ---------------- | ------------------- | ----------------------------------------------------- |
|
|
48
|
+
| `derivationPath` | `string` | BIP-32 derivation path (Sui uses coin type `784`) |
|
|
49
|
+
| `ledgerClient` | `SuiLedgerClient` | A `SuiLedgerClient` wrapping an open Ledger transport |
|
|
50
|
+
| `suiClient` | `ClientWithCoreApi` | A Sui client used to resolve transaction data |
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
Derive the address, then sign a transaction or personal message. The user confirms each signature on
|
|
55
|
+
the device.
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
|
|
59
|
+
// Derive the Sui address
|
|
60
|
+
const address = signer.toSuiAddress();
|
|
61
|
+
|
|
62
|
+
// Build and sign a transaction
|
|
63
|
+
const transaction = new Transaction();
|
|
64
|
+
const transactionBytes = await transaction.build({ client: suiClient });
|
|
65
|
+
const { signature } = await signer.signTransaction(transactionBytes);
|
|
66
|
+
|
|
67
|
+
// Or sign a personal message
|
|
68
|
+
const message = new TextEncoder().encode('Hello, Ledger Signer!');
|
|
69
|
+
await signer.signPersonalMessage(message);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
> **Warning:** The Ledger signer supports only `signTransaction` and `signPersonalMessage`. It does not support
|
|
73
|
+
> the generic `sign` and `signWithIntent` methods, which throw an error because the device only
|
|
74
|
+
> signs recognized transaction and message payloads.
|
|
75
|
+
|
|
76
|
+
See [Cryptography](/sui/cryptography) for the signing and verification API shared by all signers.
|
|
@@ -6,8 +6,8 @@ The Sui TypeScript SDK provides a `MultiSigPublicKey` class to support
|
|
|
6
6
|
[Multi-Signature](https://docs.sui.io/concepts/cryptography/transaction-auth/multisig) (MultiSig)
|
|
7
7
|
transaction and personal message signing.
|
|
8
8
|
|
|
9
|
-
This class implements the same interface as the `PublicKey` classes that [Keypairs](
|
|
10
|
-
and you call the same methods to verify signatures for `PersonalMessages` and `Transactions`.
|
|
9
|
+
This class implements the same interface as the `PublicKey` classes that [Keypairs](../keypairs)
|
|
10
|
+
uses and you call the same methods to verify signatures for `PersonalMessages` and `Transactions`.
|
|
11
11
|
|
|
12
12
|
## Creating a MultiSigPublicKey
|
|
13
13
|
|
|
@@ -90,7 +90,7 @@ work.
|
|
|
90
90
|
|
|
91
91
|
The usage for a passkey keypair is the same as any other keypair. You can derive the public key,
|
|
92
92
|
derive the address, sign personal messages, sign transactions, and verify signatures. See the
|
|
93
|
-
[Key pairs](
|
|
93
|
+
[Key pairs](../keypairs) documentation for more details.
|
|
94
94
|
|
|
95
95
|
```typescript
|
|
96
96
|
const publicKey = keypair.getPublicKey();
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# Web Crypto Signer
|
|
2
2
|
|
|
3
|
-
> Sign transactions using the Web Crypto API for secure browser-based key management
|
|
3
|
+
> Sign transactions using the Web Crypto API for secure browser-based key management
|
|
4
4
|
|
|
5
5
|
For cases where you need to create keypairs directly within client apps, you can use the Web Crypto
|
|
6
6
|
Signer. This signer leverages the
|
|
7
7
|
[Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) to provide a
|
|
8
|
-
secure and efficient way to generate and manage cryptographic keys in the browser.
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
secure and efficient way to generate and manage cryptographic keys in the browser. It generates
|
|
9
|
+
`Secp256r1` keys that you can persist between sessions, and that client-side code (including
|
|
10
|
+
extensions) cannot extract.
|
|
11
11
|
|
|
12
12
|
Common use cases for the Web Crypto Signer include:
|
|
13
13
|
|
|
@@ -68,8 +68,8 @@ const keypair = await WebCryptoSigner.import(exported);
|
|
|
68
68
|
## Usage
|
|
69
69
|
|
|
70
70
|
The usage for a Web Crypto signer is the same as any other keypair. You can derive the public key,
|
|
71
|
-
derive the address, sign personal messages, sign transactions, and verify signatures. See
|
|
72
|
-
[
|
|
71
|
+
derive the address, sign personal messages, sign transactions, and verify signatures. See
|
|
72
|
+
[Cryptography](/sui/cryptography) for more details.
|
|
73
73
|
|
|
74
74
|
```typescript
|
|
75
75
|
const publicKey = keypair.getPublicKey();
|
package/docs/index.md
CHANGED
|
@@ -34,11 +34,10 @@ what you need to keep your code light and compact.
|
|
|
34
34
|
with transactions.
|
|
35
35
|
- [`@mysten/sui/keypairs/*`](/sui/cryptography/keypairs): Modular exports for specific KeyPair
|
|
36
36
|
implementations.
|
|
37
|
-
- [`@mysten/sui/verify`](/sui/cryptography
|
|
38
|
-
|
|
39
|
-
- [`@mysten/sui/cryptography`](/sui/cryptography
|
|
40
|
-
|
|
41
|
-
- [`@mysten/sui/multisig`](/sui/cryptography/multisig): Utilities for working with multisig
|
|
37
|
+
- [`@mysten/sui/verify`](/sui/cryptography#verifying-signatures): Methods for verifying transactions
|
|
38
|
+
and messages.
|
|
39
|
+
- [`@mysten/sui/cryptography`](/sui/cryptography): Shared types and classes for cryptography.
|
|
40
|
+
- [`@mysten/sui/multisig`](/sui/cryptography/signers/multisig): Utilities for working with multisig
|
|
42
41
|
signatures.
|
|
43
42
|
- [`@mysten/sui/utils`](/sui/utils): Utilities for formatting and parsing various Sui types.
|
|
44
43
|
- [`@mysten/sui/faucet`](#faucet): Methods for requesting SUI from a faucet.
|