Skip to content

Commit 070ba31

Browse files
jon-mystenJon Zhu
andauthored
docs: quick doc fixes (#513)
Co-authored-by: Jon Zhu <[email protected]>
1 parent d842a10 commit 070ba31

2 files changed

Lines changed: 79 additions & 81 deletions

File tree

docs/content/UsingSeal.mdx

Lines changed: 79 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,85 @@ The `encryptedBytes` returned from the encryption call can be parsed using `Encr
240240

241241
:::
242242

243+
## Decryption
244+
245+
Decryption involves a few additional steps:
246+
247+
- The app must create a `SessionKey` object to access the decryption keys for a specific package.
248+
- The user must approve the request by signing it in their wallet. This grants time-limited access to the associated keys.
249+
- The app stores the resulting signature in the `SessionKey` to complete its initialization.
250+
251+
Once initialized, the session key can be used to retrieve multiple decryption keys for the specified package without requiring further user confirmation.
252+
```typescript
253+
const sessionKey = await SessionKey.create({
254+
address: suiAddress,
255+
packageId: fromHEX(packageId),
256+
ttlMin: 10, // TTL of 10 minutes
257+
suiClient: new SuiClient({ url: getFullnodeUrl('testnet') }),
258+
});
259+
const message = sessionKey.getPersonalMessage();
260+
const { signature } = await keypair.signPersonalMessage(message); // User confirms in wallet
261+
sessionKey.setPersonalMessageSignature(signature); // Initialization complete
262+
```
263+
264+
:::note[Notes on Session Key]
265+
266+
1. You can also optionally initialize a `SessionKey` with a passed in `Signer` in the constructor. This is useful for classes that extend `Signer`, for example, `EnokiSigner`.
267+
2. You can optionally set an `mvr_name` value in the `SessionKey`. This should be the [Move Package Registry](https://www.moveregistry.com/) name for the package. Seal requires the MVR name to be registered to the first version of the package for this to work. If this is set, the message shown to the user in the wallet would use the much more readable MVR package name instead of `packageId`.
268+
3. You can optionally store the `SessionKey` object in [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) instead of localStorage if you would like to persist the `SessionKey` across tabs. See usage for `import` and `export` methods in the `SessionKey` class.
269+
270+
:::
271+
272+
The simplest way to perform decryption is to call the client's `decrypt` function. This function expects a `Transaction` object that invokes the relevant `seal_approve*` functions. The transaction must meet the following requirements:
273+
274+
- It can only call `seal_approve*` functions.
275+
- All calls must be to the same package.
276+
```typescript
277+
// Create the Transaction for evaluating the seal_approve function.
278+
const tx = new Transaction();
279+
tx.moveCall({
280+
target: `${packageId}::${moduleName}::seal_approve`,
281+
arguments: [
282+
tx.pure.vector("u8", fromHEX(id)),
283+
// other arguments
284+
]
285+
});
286+
const txBytes = tx.build( { client: suiClient, onlyTransactionKind: true })
287+
const decryptedBytes = await client.decrypt({
288+
data: encryptedBytes,
289+
sessionKey,
290+
txBytes,
291+
});
292+
```
293+
294+
Seal evaluates the transaction as if the user sent it. In Move, `TxContext::sender()` returns the account that signed with the session key.
295+
296+
:::tip
297+
298+
To debug a transaction, call `dryRunTransactionBlock` directly with the transaction block.
299+
300+
:::
301+
302+
The `SealClient` caches keys retrieved from Seal key servers to optimize performance during subsequent decryptions, especially when the same ID is used across multiple encryptions. Reusing the same client instance helps reduce backend calls and improve latency. Refer to overall [Performance Recommendations](#optimizing-performance).
303+
304+
To retrieve multiple keys more efficiently, use the `fetchKeys` function with a multi-command PTB. This approach is recommended when multiple keys are required, as it reduces the number of requests to the key servers. Because key servers can apply rate limiting, developers should design their applications and access policies to minimize the frequency of key retrieval requests.
305+
```typescript
306+
await client.fetchKeys({
307+
ids: [id1, id2],
308+
txBytes: txBytesWithTwoSealApproveCalls,
309+
sessionKey,
310+
threshold: 2,
311+
});
312+
```
313+
314+
Check out the [integration tests](https://github.com/MystenLabs/ts-sdks/blob/main/packages/seal/test/unit/integration.test.ts) for a full end-to-end example. You can also explore the [example app](https://github.com/MystenLabs/seal/tree/main/examples) to see how to implement allowlist and NFT-gated content access in practice.
315+
316+
:::tip
317+
318+
If a key server request fails with an `InvalidParameter` error, the cause can be a recently created on-chain object in the PTB input. The key server's full node might not have indexed it yet. Wait a few seconds and retry the request, as subsequent attempts should succeed once the node is in sync.
319+
320+
:::
321+
243322
### On-chain decryption
244323

245324
Seal supports on-chain HMAC-CTR decryption in Move through the [`seal::bf_mac_encryption`](https://github.com/MystenLabs/seal/tree/main/move/seal/sources/bf_hmac_encryption.move) package. This enables Move packages to decrypt Seal-encrypted objects and use the results in on-chain logic such as auctions, secure voting (see [voting.move](https://github.com/MystenLabs/seal/tree/main/move/patterns/sources/voting.move)), or other verifiable workflows.
@@ -350,85 +429,6 @@ const decrypted = tx.moveCall({
350429
// The decryption result is in an option to be consumed if successful, `none` otherwise.
351430
```
352431

353-
## Decryption
354-
355-
Decryption involves a few additional steps:
356-
357-
- The app must create a `SessionKey` object to access the decryption keys for a specific package.
358-
- The user must approve the request by signing it in their wallet. This grants time-limited access to the associated keys.
359-
- The app stores the resulting signature in the `SessionKey` to complete its initialization.
360-
361-
Once initialized, the session key can be used to retrieve multiple decryption keys for the specified package without requiring further user confirmation.
362-
```typescript
363-
const sessionKey = await SessionKey.create({
364-
address: suiAddress,
365-
packageId: fromHEX(packageId),
366-
ttlMin: 10, // TTL of 10 minutes
367-
suiClient: new SuiClient({ url: getFullnodeUrl('testnet') }),
368-
});
369-
const message = sessionKey.getPersonalMessage();
370-
const { signature } = await keypair.signPersonalMessage(message); // User confirms in wallet
371-
sessionKey.setPersonalMessageSignature(signature); // Initialization complete
372-
```
373-
374-
:::note[Notes on Session Key]
375-
376-
1. You can also optionally initialize a `SessionKey` with a passed in `Signer` in the constructor. This is useful for classes that extend `Signer`, for example, `EnokiSigner`.
377-
2. You can optionally set an `mvr_name` value in the `SessionKey`. This should be the [Move Package Registry](https://www.moveregistry.com/) name for the package. Seal requires the MVR name to be registered to the first version of the package for this to work. If this is set, the message shown to the user in the wallet would use the much more readable MVR package name instead of `packageId`.
378-
3. You can optionally store the `SessionKey` object in [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) instead of localStorage if you would like to persist the `SessionKey` across tabs. See usage for `import` and `export` methods in the `SessionKey` class.
379-
380-
:::
381-
382-
The simplest way to perform decryption is to call the client's `decrypt` function. This function expects a `Transaction` object that invokes the relevant `seal_approve*` functions. The transaction must meet the following requirements:
383-
384-
- It can only call `seal_approve*` functions.
385-
- All calls must be to the same package.
386-
```typescript
387-
// Create the Transaction for evaluating the seal_approve function.
388-
const tx = new Transaction();
389-
tx.moveCall({
390-
target: `${packageId}::${moduleName}::seal_approve`,
391-
arguments: [
392-
tx.pure.vector("u8", fromHEX(id)),
393-
// other arguments
394-
]
395-
});
396-
const txBytes = tx.build( { client: suiClient, onlyTransactionKind: true })
397-
const decryptedBytes = await client.decrypt({
398-
data: encryptedBytes,
399-
sessionKey,
400-
txBytes,
401-
});
402-
```
403-
404-
Seal evaluates the transaction as if the user sent it. In Move, `TxContext::sender()` returns the account that signed with the session key.
405-
406-
:::tip
407-
408-
To debug a transaction, call `dryRunTransactionBlock` directly with the transaction block.
409-
410-
:::
411-
412-
The `SealClient` caches keys retrieved from Seal key servers to optimize performance during subsequent decryptions, especially when the same ID is used across multiple encryptions. Reusing the same client instance helps reduce backend calls and improve latency. Refer to overall [Performance Recommendations](#optimizing-performance).
413-
414-
To retrieve multiple keys more efficiently, use the `fetchKeys` function with a multi-command PTB. This approach is recommended when multiple keys are required, as it reduces the number of requests to the key servers. Because key servers can apply rate limiting, developers should design their applications and access policies to minimize the frequency of key retrieval requests.
415-
```typescript
416-
await client.fetchKeys({
417-
ids: [id1, id2],
418-
txBytes: txBytesWithTwoSealApproveCalls,
419-
sessionKey,
420-
threshold: 2,
421-
});
422-
```
423-
424-
Check out the [integration tests](https://github.com/MystenLabs/ts-sdks/blob/main/packages/seal/test/unit/integration.test.ts) for a full end-to-end example. You can also explore the [example app](https://github.com/MystenLabs/seal/tree/main/examples) to see how to implement allowlist and NFT-gated content access in practice.
425-
426-
:::tip
427-
428-
If a key server request fails with an `InvalidParameter` error, the cause can be a recently created on-chain object in the PTB input. The key server's full node might not have indexed it yet. Wait a few seconds and retry the request, as subsequent attempts should succeed once the node is in sync.
429-
430-
:::
431-
432432
## Optimizing performance
433433

434434
To reduce latency and improve efficiency when using the Seal SDK, apply the following strategies based on your use case:

docs/site/sidebars.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@ const sidebars = {
1212
type: `doc`,
1313
id: `index`,
1414
},
15-
collapsed: false,
1615
items: [
1716
`ServerOverview`,
1817
]
1918
},
2019
'GettingStarted',
21-
'ServerOverview',
2220
{
2321
type: 'category',
2422
label: 'Developer Guide',

0 commit comments

Comments
 (0)