@mysten/docs 0.1.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 (108) hide show
  1. package/README.md +24 -0
  2. package/dist/bcs/index.md +358 -0
  3. package/dist/bcs/llms-index.md +4 -0
  4. package/dist/codegen/index.md +441 -0
  5. package/dist/codegen/llms-index.md +4 -0
  6. package/dist/dapp-kit/actions/connect-wallet.md +69 -0
  7. package/dist/dapp-kit/actions/disconnect-wallet.md +38 -0
  8. package/dist/dapp-kit/actions/sign-and-execute-transaction.md +96 -0
  9. package/dist/dapp-kit/actions/sign-personal-message.md +58 -0
  10. package/dist/dapp-kit/actions/sign-transaction.md +65 -0
  11. package/dist/dapp-kit/actions/switch-account.md +37 -0
  12. package/dist/dapp-kit/actions/switch-network.md +37 -0
  13. package/dist/dapp-kit/dapp-kit-instance.md +162 -0
  14. package/dist/dapp-kit/getting-started/create-dapp.md +151 -0
  15. package/dist/dapp-kit/getting-started/next-js.md +162 -0
  16. package/dist/dapp-kit/getting-started/react.md +172 -0
  17. package/dist/dapp-kit/getting-started/vue.md +193 -0
  18. package/dist/dapp-kit/index.md +70 -0
  19. package/dist/dapp-kit/llms-index.md +26 -0
  20. package/dist/dapp-kit/react/components/connect-button.md +42 -0
  21. package/dist/dapp-kit/react/components/connect-modal.md +51 -0
  22. package/dist/dapp-kit/react/components/index.md +13 -0
  23. package/dist/dapp-kit/react/dapp-kit-provider.md +86 -0
  24. package/dist/dapp-kit/react/hooks/index.md +25 -0
  25. package/dist/dapp-kit/react/hooks/use-current-account.md +33 -0
  26. package/dist/dapp-kit/react/hooks/use-current-client.md +36 -0
  27. package/dist/dapp-kit/react/hooks/use-current-network.md +28 -0
  28. package/dist/dapp-kit/react/hooks/use-current-wallet.md +36 -0
  29. package/dist/dapp-kit/react/hooks/use-dapp-kit.md +100 -0
  30. package/dist/dapp-kit/react/hooks/use-wallet-connection.md +48 -0
  31. package/dist/dapp-kit/react/hooks/use-wallets.md +33 -0
  32. package/dist/dapp-kit/state.md +169 -0
  33. package/dist/dapp-kit/theming.md +196 -0
  34. package/dist/dapp-kit/web-components/connect-button.md +89 -0
  35. package/dist/dapp-kit/web-components/connect-modal.md +177 -0
  36. package/dist/kiosk/advanced-examples.md +101 -0
  37. package/dist/kiosk/from-v1.md +320 -0
  38. package/dist/kiosk/index.md +22 -0
  39. package/dist/kiosk/kiosk-client/introduction.md +52 -0
  40. package/dist/kiosk/kiosk-client/kiosk-transaction/examples.md +119 -0
  41. package/dist/kiosk/kiosk-client/kiosk-transaction/kiosk-transaction.md +103 -0
  42. package/dist/kiosk/kiosk-client/kiosk-transaction/managing.md +235 -0
  43. package/dist/kiosk/kiosk-client/kiosk-transaction/purchasing.md +110 -0
  44. package/dist/kiosk/kiosk-client/querying.md +237 -0
  45. package/dist/kiosk/kiosk-client/transfer-policy-transaction/introduction.md +79 -0
  46. package/dist/kiosk/kiosk-client/transfer-policy-transaction/using-the-manager.md +115 -0
  47. package/dist/kiosk/llms-index.md +8 -0
  48. package/dist/llms-index.md +125 -0
  49. package/dist/payment-kit/getting-started.md +256 -0
  50. package/dist/payment-kit/index.md +132 -0
  51. package/dist/payment-kit/llms-index.md +8 -0
  52. package/dist/payment-kit/payment-kit-sdk.md +747 -0
  53. package/dist/payment-kit/payment-processing.md +372 -0
  54. package/dist/payment-kit/registry-management.md +529 -0
  55. package/dist/seal/index.md +85 -0
  56. package/dist/seal/llms-index.md +4 -0
  57. package/dist/slush-wallet/dapp.md +95 -0
  58. package/dist/slush-wallet/deep-linking.md +465 -0
  59. package/dist/slush-wallet/index.md +7 -0
  60. package/dist/slush-wallet/llms-index.md +6 -0
  61. package/dist/sui/bcs.md +134 -0
  62. package/dist/sui/clients/core.md +606 -0
  63. package/dist/sui/clients/graphql.md +101 -0
  64. package/dist/sui/clients/grpc.md +155 -0
  65. package/dist/sui/clients/index.md +95 -0
  66. package/dist/sui/clients/json-rpc.md +239 -0
  67. package/dist/sui/cryptography/keypairs.md +267 -0
  68. package/dist/sui/cryptography/multisig.md +194 -0
  69. package/dist/sui/cryptography/passkey.md +111 -0
  70. package/dist/sui/cryptography/webcrypto-signer.md +81 -0
  71. package/dist/sui/executors.md +148 -0
  72. package/dist/sui/faucet.md +26 -0
  73. package/dist/sui/hello-sui.md +115 -0
  74. package/dist/sui/index.md +53 -0
  75. package/dist/sui/install.md +61 -0
  76. package/dist/sui/llm-docs.md +32 -0
  77. package/dist/sui/llms-index.md +44 -0
  78. package/dist/sui/migrations/0.38.md +58 -0
  79. package/dist/sui/migrations/sui-1.0.md +455 -0
  80. package/dist/sui/migrations/sui-2.0/agent-prompt.md +42 -0
  81. package/dist/sui/migrations/sui-2.0/dapp-kit.md +350 -0
  82. package/dist/sui/migrations/sui-2.0/deepbook-v3.md +33 -0
  83. package/dist/sui/migrations/sui-2.0/index.md +158 -0
  84. package/dist/sui/migrations/sui-2.0/json-rpc-migration.md +386 -0
  85. package/dist/sui/migrations/sui-2.0/kiosk.md +120 -0
  86. package/dist/sui/migrations/sui-2.0/sdk-maintainers.md +90 -0
  87. package/dist/sui/migrations/sui-2.0/seal.md +14 -0
  88. package/dist/sui/migrations/sui-2.0/sui.md +341 -0
  89. package/dist/sui/migrations/sui-2.0/suins.md +43 -0
  90. package/dist/sui/migrations/sui-2.0/wallet-builders.md +66 -0
  91. package/dist/sui/migrations/sui-2.0/walrus.md +41 -0
  92. package/dist/sui/migrations/sui-2.0/zksend.md +95 -0
  93. package/dist/sui/plugins.md +258 -0
  94. package/dist/sui/sdk-building.md +344 -0
  95. package/dist/sui/transaction-building/basics.md +299 -0
  96. package/dist/sui/transaction-building/gas.md +62 -0
  97. package/dist/sui/transaction-building/intents.md +62 -0
  98. package/dist/sui/transaction-building/offline.md +73 -0
  99. package/dist/sui/transaction-building/sponsored-transactions.md +22 -0
  100. package/dist/sui/utils/derived_objects.md +59 -0
  101. package/dist/sui/utils/index.md +52 -0
  102. package/dist/sui/zklogin.md +83 -0
  103. package/dist/walrus/index.md +527 -0
  104. package/dist/walrus/llms-index.md +4 -0
  105. package/dist/zksend/index.md +27 -0
  106. package/dist/zksend/link-builder.md +192 -0
  107. package/dist/zksend/llms-index.md +5 -0
  108. package/package.json +66 -0
@@ -0,0 +1,83 @@
1
+ # ZkLogin
2
+
3
+ > Zero-knowledge authentication with OAuth providers on Sui
4
+
5
+ Utilities for working with zkLogin. Currently contains functionality to create and parse zkLogin
6
+ signatures and compute zkLogin addresses.
7
+
8
+ To parse a serialized zkLogin signature
9
+
10
+ ```typescript
11
+
12
+ const parsedSignature = await parseZkLoginSignature('BQNNMTY4NjAxMzAyO....');
13
+ ```
14
+
15
+ Use `getZkLoginSignature` to serialize a zkLogin signature.
16
+
17
+ ```typescript
18
+
19
+ const serializedSignature = await getZkLoginSignature({ inputs, maxEpoch, userSignature });
20
+ ```
21
+
22
+ To compute the address for a given address seed and iss you can use `computeZkLoginAddressFromSeed`
23
+
24
+ ```typescript
25
+
26
+ const address = computeZkLoginAddressFromSeed(0n, 'https://accounts.google.com');
27
+ ```
28
+
29
+ To compute an address from jwt:
30
+
31
+ ```typescript
32
+
33
+ const address = jwtToAddress(jwtAsString, salt);
34
+ ```
35
+
36
+ To compute an address from a parsed jwt:
37
+
38
+ ```typescript
39
+
40
+ const address = computeZkLoginAddress({
41
+ claimName,
42
+ claimValue,
43
+ iss,
44
+ aud,
45
+ userSalt: BigInt(salt),
46
+ });
47
+ ```
48
+
49
+ To use zkLogin inside a multisig, see the [Multisig Guide](../sui/cryptography/multisig) for more
50
+ details.
51
+
52
+ ## Legacy addresses
53
+
54
+ When zklogin was first introduced, there was an inconsistency in how the address seed was computed.
55
+ For backwards compatibility reasons there are 2 valid addresses for a given set of inputs. Methods
56
+ that produce zklogin addresses all accept a `legacyAddress` boolean flag, either as their last
57
+ parameter, or in their options argument.
58
+
59
+ ```typescript
60
+
61
+ computeZkLoginAddress,
62
+ computeZkLoginAddressFromSeed,
63
+ jwtToAddress,
64
+ toZkLoginPublicIdentifier,
65
+ genAddressSeed,
66
+ } from '@mysten/sui/zklogin';
67
+
68
+ const address = jwtToAddress(jwtAsString, salt, true);
69
+ const address = computeZkLoginAddressFromSeed(0n, 'https://accounts.google.com', true);
70
+ const address = computeZkLoginAddress({
71
+ claimName,
72
+ claimValue,
73
+ iss,
74
+ aud,
75
+ userSalt: BigInt(salt),
76
+ legacyAddress: true,
77
+ });
78
+ const address = toZkLoginPublicIdentifier(
79
+ genAddressSeed(userSalt, claimName, claimValue, aud),
80
+ iss,
81
+ { legacyAddress: true },
82
+ ).toSuiAddress();
83
+ ```
@@ -0,0 +1,527 @@
1
+ # Walrus SDK
2
+
3
+ > Store and retrieve blobs on Walrus decentralized storage
4
+
5
+ ## Installation
6
+
7
+ ```bash npm2yarn
8
+ npm install --save @mysten/walrus @mysten/sui
9
+ ```
10
+
11
+ ## Setup
12
+
13
+ To use the walrus SDK you will need to create a Client from the typescript SDK, and extend it with
14
+ the walrus SDK.
15
+
16
+ ```ts
17
+
18
+ const client = new SuiGrpcClient({
19
+ network: 'testnet',
20
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
21
+ }).$extend(walrus());
22
+ ```
23
+
24
+ The walrus SDK currently includes all the relevant package and object IDs needed for connecting to
25
+ testnet. You can also manually configure the walrus sdk to use a different set of ids, allowing you
26
+ to connect to a different network or updated deployment of the walrus contracts.
27
+
28
+ ```ts
29
+
30
+ const client = new SuiGrpcClient({
31
+ network: 'testnet',
32
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
33
+ }).$extend(
34
+ walrus({
35
+ packageConfig: {
36
+ systemObjectId: '0x98ebc47370603fe81d9e15491b2f1443d619d1dab720d586e429ed233e1255c1',
37
+ stakingPoolId: '0x20266a17b4f1a216727f3eef5772f8d486a9e3b5e319af80a5b75809c035561d',
38
+ },
39
+ }),
40
+ );
41
+ ```
42
+
43
+ For some environments you may need to customize how data is fetched:
44
+
45
+ ```ts
46
+
47
+ const client = new SuiGrpcClient({
48
+ network: 'testnet',
49
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
50
+ }).$extend(
51
+ walrus({
52
+ storageNodeClientOptions: {
53
+ fetch: (url, options) => {
54
+ console.log('fetching', url);
55
+ return fetch(url, options);
56
+ },
57
+ timeout: 60_000,
58
+ },
59
+ }),
60
+ );
61
+ ```
62
+
63
+ This can be used to implement a fetch function with custom timeouts, rate limits, retry logic, or
64
+ any other desired behavior.
65
+
66
+ ## SDK Overview
67
+
68
+ The Walrus TS SDK is designed to work directly with walrus storage nodes, or with the walrus upload
69
+ relay. When using the walrus SDK without an upload relay, it is important to understand that reading
70
+ and writing walrus blobs requires a lot of requests (~2200 to write a blob, ~335 to read a blob).
71
+ The upload relay will reduce the number of requests needed to write a blob, but reads through the
72
+ walrus SDK will still require a lot of requests. For many applications, using publishers and
73
+ aggregators is recommended, but the TS SDK can be useful when building applications where the
74
+ application needs to directly interact with walrus or users need to pay for their own storage
75
+ directly.
76
+
77
+ The walrus sdk exposes high level methods for reading and writing blobs, as well as lower level
78
+ methods for the individual steps in the process that can be used to implement more complex flows
79
+ when you want more control to implement more optimized implementations.
80
+
81
+ ## WalrusFiles
82
+
83
+ The `WalrusFile` API provides a higher level abstraction so that applications don't need to worry
84
+ about how data is stored in walrus. Today it handles data stored directly in blobs, and data stored
85
+ in Quilts, but may be expanded to cover other storage patterns in the future.
86
+
87
+ ### Reading files
88
+
89
+ To read files, you can use the `getFiles` method. This method accepts both Blob IDs and Quilt IDs,
90
+ and will return a `WalrusFile`.
91
+
92
+ It is encouraged to always read files in batches when possible, which will allow the client to be
93
+ more efficient when loading multiple files from the same quilt.
94
+
95
+ ```ts
96
+ const [file1, file2] = await client.walrus.getFiles({ ids: [anyBlobId, orQuiltId] });
97
+ ```
98
+
99
+ A `WalrusFile` works like a `Response` object from the `fetch` API:
100
+
101
+ ```ts
102
+ // get contents as a Uint8Array
103
+ const bytes = await file1.bytes();
104
+ // Parse the contents as a `utf-8` string
105
+ const text = await file1.text();
106
+ // Parse the contents as JSON
107
+ const json = await file2.json();
108
+ ```
109
+
110
+ A `WalrusFile` may also have and `identifier` and `tags` properties if the file was stored in a
111
+ quilt.
112
+
113
+ ```ts
114
+ const identifier: string | null = await file1.getIdentifier();
115
+ const tags: Record<string, string> = await file1.getTags();
116
+ ```
117
+
118
+ ### WalrusBlobs
119
+
120
+ You can also get a `WalrusBlob` instead of a `WalrusFile` if you have the blobId:
121
+
122
+ ```ts
123
+ const blob = await client.walrus.getBlob({ blobId });
124
+ ```
125
+
126
+ If the blob is a quilt, you can read the files in the quilt:
127
+
128
+ ```ts
129
+ // Get all files:
130
+ const files = await blob.files();
131
+ // Get files by identifier
132
+ const [readme] = await blob.files({ identifiers: ['README.md'] });
133
+ // Get files by tag
134
+ const textFiles = await blob.files({ tags: [{ 'content-type': 'text/plain' }] });
135
+ // Get files by quilt id
136
+ const filesById = await blob.files({ ids: [quiltID] });
137
+ ```
138
+
139
+ ### Writing files
140
+
141
+ You can also construct a `WalrusFile` from a `Uint8Array`, `Blob`, or a `string` which can then be
142
+ stored on walrus:
143
+
144
+ ```ts
145
+ const file1 = WalrusFile.from({
146
+ contents: new Uint8Array([1, 2, 3]),
147
+ identifier: 'file1.bin',
148
+ });
149
+ const file2 = WalrusFile.from({
150
+ contents: new Blob([new Uint8Array([1, 2, 3])]),
151
+ identifier: 'file2.bin',
152
+ });
153
+ const file3 = WalrusFile.from({
154
+ contents: new TextEncoder().encode('Hello from the TS SDK!!!\n'),
155
+ identifier: 'README.md',
156
+ tags: {
157
+ 'content-type': 'text/plain',
158
+ },
159
+ });
160
+ ```
161
+
162
+ Once you have your files you can use the `writeFiles` method to write them to walrus.
163
+
164
+ Along with the files, you will also need to provide a `Signer` instance that signs and pays for the
165
+ transaction/storage fees. The signer's address will need to have sufficient `SUI` to cover the
166
+ transactions that register the blob, and certify its availability after it's been uploaded. The
167
+ Signer must own sufficient `WAL` to pay to store the blob for the specified number of epochs, as
168
+ well as the write fee for writing the blob.
169
+
170
+ The exact costs will depend on the size of the blobs, as well as the current gas and storage prices.
171
+
172
+ ```ts
173
+ const results: {
174
+ id: string;
175
+ blobId: string;
176
+ blobObject: Blob.$inferType;
177
+ }[] = await client.walrus.writeFiles({
178
+ files: [file1, file2, file3],
179
+ epochs: 3,
180
+ deletable: true,
181
+ signer: keypair,
182
+ });
183
+ ```
184
+
185
+ Currently, the provided files will all be written into a single quilt. Future versions of the SDK
186
+ may optimize how files are stored to be more efficient by splitting files into multiple quilts.
187
+
188
+ The current quilt encoding is less efficient for single files, so writing multiple files together is
189
+ recommended when possible. Writing raw blobs directly is also possible using the `writeBlob` API
190
+ (described below)
191
+
192
+ ### Writing files in browser environments
193
+
194
+ When the transactions to upload a blob are signed by a wallet in a browser, some wallets will use
195
+ popups to prompt the user for a signature. If the popups are not opened in direct response to a user
196
+ interaction, they may be blocked by the browser.
197
+
198
+ To avoid this, we need to ensure that we execute the transactions that register and certify the blob
199
+ in separate events handlers by creating separate buttons for the user to click for each step.
200
+
201
+ The `client.writeFilesFlow` method returns an object with a set of methods that break the write flow
202
+ into several smaller steps:
203
+
204
+ 1. `encode` - Encodes the files and generates a blobId
205
+ 2. `register` - returns a transaction that will register the blob on-chain
206
+ 3. `upload` - Uploads the data to storage nodes
207
+ 4. `certify` - returns a transaction that will certify the blob on-chain
208
+ 5. `listFiles` - returns a list of the created files
209
+
210
+ Here's a simplified example showing the core API usage with separate user interactions:
211
+
212
+ ```tsx
213
+ // Step 1: Create and encode the flow (can be done immediately when file is selected)
214
+ const flow = client.walrus.writeFilesFlow({
215
+ files: [
216
+ WalrusFile.from({
217
+ contents: new Uint8Array(fileData),
218
+ identifier: 'my-file.txt',
219
+ }),
220
+ ],
221
+ });
222
+
223
+ await flow.encode();
224
+
225
+ // Step 2: Register the blob (triggered by user clicking a register button after the encode step)
226
+ async function handleRegister() {
227
+ const registerTx = flow.register({
228
+ epochs: 3,
229
+ owner: currentAccount.address,
230
+ deletable: true,
231
+ });
232
+ const result = await signAndExecuteTransaction({ transaction: registerTx });
233
+
234
+ // Check transaction status
235
+ if (result.$kind === 'FailedTransaction') {
236
+ throw new Error(`Registration failed: ${result.FailedTransaction.status.error?.message}`);
237
+ }
238
+
239
+ // Step 3: Upload the data to storage nodes
240
+ // This can be done immediately after the register step, or as a separate step the user initiates
241
+ await flow.upload({ digest: result.Transaction.digest });
242
+ }
243
+
244
+ // Step 4: Certify the blob (triggered by user clicking a certify button after the blob is uploaded)
245
+ async function handleCertify() {
246
+ const certifyTx = flow.certify();
247
+
248
+ const result = await signAndExecuteTransaction({ transaction: certifyTx });
249
+
250
+ // Check transaction status
251
+ if (result.$kind === 'FailedTransaction') {
252
+ throw new Error(`Certification failed: ${result.FailedTransaction.status.error?.message}`);
253
+ }
254
+
255
+ // Step 5: Get the new files
256
+ const files = await flow.listFiles();
257
+ console.log('Uploaded files', files);
258
+ }
259
+ ```
260
+
261
+ This approach ensures that each transaction signing step is separated into different user
262
+ interactions, allowing wallet popups to work properly without being blocked by the browser.
263
+
264
+ ## Writing blobs with an upload relay
265
+
266
+ Writing blobs directly from a client requires a lot of requests to write data to all the storage
267
+ nodes. An upload relay can be used to offload the work of these writes to a server, reducing
268
+ complexity for the client.
269
+
270
+ To use an upload relay, you can add the `uploadRelay` option when adding the walrus extension:
271
+
272
+ ```ts
273
+ const client = new SuiGrpcClient({
274
+ network: 'testnet',
275
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
276
+ }).$extend(
277
+ walrus({
278
+ uploadRelay: {
279
+ host: 'https://upload-relay.testnet.walrus.space',
280
+ sendTip: {
281
+ max: 1_000,
282
+ },
283
+ },
284
+ }),
285
+ );
286
+ ```
287
+
288
+ The `host` option is required, and indicates the url for your upload relay. Upload relays may
289
+ require a tip to be included to cover the cost of writing the blob. You can configure a maximum tip
290
+ (paid in MIST) and the `WalrusClient` will automatically determine the required tip for your upload
291
+ relay, or you can manually configure the tip configuration as shown below.
292
+
293
+ The tip required by an upload relay can be found using the `tip-config` endpoint: (e.g.
294
+ `https://upload-relay.testnet.walrus.space/v1/tip-config`) and may either be a `const` or a `linear`
295
+ tip.
296
+
297
+ ### `const` tip
298
+
299
+ A `const` will send a fixed amount for each blob written to the upload relay.
300
+
301
+ ```ts
302
+ const client = new SuiGrpcClient({
303
+ network: 'testnet',
304
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
305
+ }).$extend(
306
+ walrus({
307
+ uploadRelay: {
308
+ host: 'https://upload-relay.testnet.walrus.space',
309
+ sendTip: {
310
+ address: '0x123...',
311
+ kind: {
312
+ const: 105,
313
+ },
314
+ },
315
+ },
316
+ }),
317
+ );
318
+ ```
319
+
320
+ ### `linear` tip
321
+
322
+ A `linear` tip will send a fixed amount for each blob written to the fan out proxy, plus a
323
+ multiplier based on the size of the blob.
324
+
325
+ ```ts
326
+ const client = new SuiGrpcClient({
327
+ network: 'testnet',
328
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
329
+ }).$extend(
330
+ walrus({
331
+ uploadRelay: {
332
+ host: 'https://upload-relay.testnet.walrus.space',
333
+ sendTip: {
334
+ address: '0x123...',
335
+ kind: {
336
+ linear: {
337
+ base: 105,
338
+ perEncodedKib: 10,
339
+ },
340
+ },
341
+ },
342
+ },
343
+ }),
344
+ );
345
+ ```
346
+
347
+ ## Interacting with blobs directly
348
+
349
+ In case you do not want to use the `WalrusFile` abstractions, you can use the `readBlob` and
350
+ `writeBlob` APIs directly
351
+
352
+ ### Reading blobs
353
+
354
+ The `readBlob` method will read a blob given the blobId and return Uint8Array containing the blobs
355
+ content:
356
+
357
+ ```ts
358
+ const blob = await client.walrus.readBlob({ blobId });
359
+ ```
360
+
361
+ ### Writing Blobs
362
+
363
+ The writeBlob method can be used to write a blob (as a `Uint8Array`) to walrus. You will need to
364
+ specify how long the blob should be stored for, and if the blob should be deletable.
365
+
366
+ ```ts
367
+ const file = new TextEncoder().encode('Hello from the TS SDK!!!\n');
368
+
369
+ const { blobId } = await client.walrus.writeBlob({
370
+ blob: file,
371
+ deletable: false,
372
+ epochs: 3,
373
+ signer: keypair,
374
+ });
375
+ ```
376
+
377
+ ## Full API
378
+
379
+ For a complete overview of the available methods on the `WalrusClient` you can reference type
380
+ [TypeDocs](/typedoc/classes/_mysten_walrus.WalrusClient.html)
381
+
382
+ ## Examples
383
+
384
+ There are a number of simple
385
+ [examples you can reference](https://github.com/MystenLabs/ts-sdks/tree/main/packages/walrus/examples)
386
+ in the `ts-sdks` repo that show things like building simple aggregators and publishers with the
387
+ walrus SDK
388
+
389
+ ## Error handling
390
+
391
+ The SDK exports all the error classes for different types of errors that can be thrown. Walrus is a
392
+ fault-tolerant distributed system, where many types of errors can be recovered from. During epoch
393
+ changes there may be times when the data cached in the `WalrusClient` can become invalid. Errors
394
+ that result from this situation will extend the `RetryableWalrusClientError` class.
395
+
396
+ You can check for these errors, and reset the client before retrying:
397
+
398
+ ```ts
399
+
400
+ if (error instanceof RetryableWalrusClientError) {
401
+ client.walrus.reset();
402
+
403
+ /* retry your operation */
404
+ }
405
+ ```
406
+
407
+ `RetryableWalrusClientError` are not guaranteed to succeed after resetting the client and retrying,
408
+ but this pattern can be used to handle some edge cases.
409
+
410
+ High level methods like `readBlob` already handle various error cases and will automatically retry
411
+ when hitting these methods, as well as handling cases where only a subset of nodes need to respond
412
+ successfully to read or publish a blob.
413
+
414
+ When using the lower level methods to build your own read or publish flows, it is recommended to
415
+ understand the number of shards/sliver that need to be successfully written or read for you
416
+ operation to succeed, and gracefully handle cases where some nodes may be in a bad state.
417
+
418
+ ### Network errors
419
+
420
+ Walrus is designed to handle some nodes being down, and the SDK will only throw errors when it can't
421
+ read from or write to enough storage nodes. When trying to troubleshoot problems, it can be
422
+ challenging to figure out what's going wrong when you don't see all the individual network errors.
423
+
424
+ You can pass an `onError` option in the storageNodeClientOptions to get the individual errors from
425
+ failed requests:
426
+
427
+ ```ts
428
+ const client = new SuiGrpcClient({
429
+ network: 'testnet',
430
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
431
+ }).$extend(
432
+ walrus({
433
+ storageNodeClientOptions: {
434
+ onError: (error) => console.log(error),
435
+ },
436
+ }),
437
+ );
438
+ ```
439
+
440
+ ## Configuring network requests
441
+
442
+ Reading and writing blobs directly from storage nodes requires a lot of requests. The walrus SDK
443
+ will issue all requests needed to complete these operations, but does not handling all the
444
+ complexities a robust aggregator or publisher might encounter.
445
+
446
+ By default, all requests are issued using the global `fetch` for whatever runtime the SDK is running
447
+ in.
448
+
449
+ This will not impose any limitations on concurrency, and will be subject to default timeouts and
450
+ behavior defined by your runtime. To customize how requests are made, you can provide a custom
451
+ `fetch` method:
452
+
453
+ ```ts
454
+
455
+ const client = new SuiGrpcClient({
456
+ network: 'testnet',
457
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
458
+ }).$extend(
459
+ walrus({
460
+ storageNodeClientOptions: {
461
+ timeout: 60_000,
462
+ fetch: (url, init) => {
463
+ // Some casting may be required because undici types may not exactly match the @node/types types
464
+ return fetch(url as RequestInfo, {
465
+ ...(init as RequestInit),
466
+ dispatcher: new Agent({
467
+ connectTimeout: 60_000,
468
+ }),
469
+ }) as unknown as Promise<Response>;
470
+ },
471
+ },
472
+ }),
473
+ );
474
+ ```
475
+
476
+ ## Loading the wasm module in vite or client side apps
477
+
478
+ The walrus SDK requires wasm bindings to encode and decode blobs. When running in node or bun and
479
+ some bundlers this will work without any additional configuration.
480
+
481
+ In some cases you may need to manually specify where the SDK loads the wasm bindings from.
482
+
483
+ In vite you can get the url for the wasm bindings by importing the wasm file with a `?url` suffix,
484
+ and then passed into the walrus client:
485
+
486
+ ```ts
487
+
488
+ const client = new SuiGrpcClient({
489
+ network: 'testnet',
490
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
491
+ }).$extend(
492
+ walrus({
493
+ wasmUrl: walrusWasmUrl,
494
+ }),
495
+ );
496
+ ```
497
+
498
+ If you are unable to get a url for the wasm file in your bundler or build system, you can self host
499
+ the wasm bindings, or load them from a CDN:
500
+
501
+ ```ts
502
+ const client = new SuiGrpcClient({
503
+ network: 'testnet',
504
+ baseUrl: 'https://fullnode.testnet.sui.io:443',
505
+ }).$extend(
506
+ walrus({
507
+ wasmUrl: 'https://unpkg.com/@mysten/walrus-wasm@latest/web/walrus_wasm_bg.wasm',
508
+ }),
509
+ );
510
+ ```
511
+
512
+ In next.js when using walrus in API routes, you may need to tell next.js to skip bundling for the
513
+ walrus packages:
514
+
515
+ ```ts
516
+ // next.config.ts
517
+ const nextConfig: NextConfig = {
518
+ serverExternalPackages: ['@mysten/walrus', '@mysten/walrus-wasm'],
519
+ };
520
+ ```
521
+
522
+ ## Known fetch limitations you might run into
523
+
524
+ - Some nodes can be slow to respond. When running in node, the default connectTimeout is 10 seconds
525
+ and can cause request timeouts
526
+ - In `bun` the `abort` signal will stop requests from responding, but they still wait for completion
527
+ before their promises reject
@@ -0,0 +1,4 @@
1
+ # Walrus
2
+ > Publish and Read blobs directly from walrus storage nodes
3
+
4
+ - [Walrus SDK](./index.md): Store and retrieve blobs on Walrus decentralized storage
@@ -0,0 +1,27 @@
1
+ # zkSend SDK
2
+
3
+ > Send Sui assets via shareable links with zkSend
4
+
5
+ The zkSend SDK provides tools for interacting with the zkSend primitive. It provides functionality
6
+ to create your own zkSend Claim Links, with support for any publicly transferrable asset.
7
+
8
+ ## Installation
9
+
10
+ ```sh npm2yarn
11
+ npm i @mysten/zksend @mysten/sui
12
+ ```
13
+
14
+ ## Setup
15
+
16
+ To use the zkSend SDK, create a Sui client and extend it with the zkSend extension:
17
+
18
+ ```ts
19
+
20
+ const client = new SuiGrpcClient({
21
+ network: 'mainnet',
22
+ baseUrl: 'https://fullnode.mainnet.sui.io:443',
23
+ }).$extend(zksend());
24
+ ```
25
+
26
+ The zkSend SDK supports mainnet and testnet networks. The extension automatically configures the
27
+ correct contract IDs based on the client's network.