@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.
- package/README.md +24 -0
- package/dist/bcs/index.md +358 -0
- package/dist/bcs/llms-index.md +4 -0
- package/dist/codegen/index.md +441 -0
- package/dist/codegen/llms-index.md +4 -0
- package/dist/dapp-kit/actions/connect-wallet.md +69 -0
- package/dist/dapp-kit/actions/disconnect-wallet.md +38 -0
- package/dist/dapp-kit/actions/sign-and-execute-transaction.md +96 -0
- package/dist/dapp-kit/actions/sign-personal-message.md +58 -0
- package/dist/dapp-kit/actions/sign-transaction.md +65 -0
- package/dist/dapp-kit/actions/switch-account.md +37 -0
- package/dist/dapp-kit/actions/switch-network.md +37 -0
- package/dist/dapp-kit/dapp-kit-instance.md +162 -0
- package/dist/dapp-kit/getting-started/create-dapp.md +151 -0
- package/dist/dapp-kit/getting-started/next-js.md +162 -0
- package/dist/dapp-kit/getting-started/react.md +172 -0
- package/dist/dapp-kit/getting-started/vue.md +193 -0
- package/dist/dapp-kit/index.md +70 -0
- package/dist/dapp-kit/llms-index.md +26 -0
- package/dist/dapp-kit/react/components/connect-button.md +42 -0
- package/dist/dapp-kit/react/components/connect-modal.md +51 -0
- package/dist/dapp-kit/react/components/index.md +13 -0
- package/dist/dapp-kit/react/dapp-kit-provider.md +86 -0
- package/dist/dapp-kit/react/hooks/index.md +25 -0
- package/dist/dapp-kit/react/hooks/use-current-account.md +33 -0
- package/dist/dapp-kit/react/hooks/use-current-client.md +36 -0
- package/dist/dapp-kit/react/hooks/use-current-network.md +28 -0
- package/dist/dapp-kit/react/hooks/use-current-wallet.md +36 -0
- package/dist/dapp-kit/react/hooks/use-dapp-kit.md +100 -0
- package/dist/dapp-kit/react/hooks/use-wallet-connection.md +48 -0
- package/dist/dapp-kit/react/hooks/use-wallets.md +33 -0
- package/dist/dapp-kit/state.md +169 -0
- package/dist/dapp-kit/theming.md +196 -0
- package/dist/dapp-kit/web-components/connect-button.md +89 -0
- package/dist/dapp-kit/web-components/connect-modal.md +177 -0
- package/dist/kiosk/advanced-examples.md +101 -0
- package/dist/kiosk/from-v1.md +320 -0
- package/dist/kiosk/index.md +22 -0
- package/dist/kiosk/kiosk-client/introduction.md +52 -0
- package/dist/kiosk/kiosk-client/kiosk-transaction/examples.md +119 -0
- package/dist/kiosk/kiosk-client/kiosk-transaction/kiosk-transaction.md +103 -0
- package/dist/kiosk/kiosk-client/kiosk-transaction/managing.md +235 -0
- package/dist/kiosk/kiosk-client/kiosk-transaction/purchasing.md +110 -0
- package/dist/kiosk/kiosk-client/querying.md +237 -0
- package/dist/kiosk/kiosk-client/transfer-policy-transaction/introduction.md +79 -0
- package/dist/kiosk/kiosk-client/transfer-policy-transaction/using-the-manager.md +115 -0
- package/dist/kiosk/llms-index.md +8 -0
- package/dist/llms-index.md +125 -0
- package/dist/payment-kit/getting-started.md +256 -0
- package/dist/payment-kit/index.md +132 -0
- package/dist/payment-kit/llms-index.md +8 -0
- package/dist/payment-kit/payment-kit-sdk.md +747 -0
- package/dist/payment-kit/payment-processing.md +372 -0
- package/dist/payment-kit/registry-management.md +529 -0
- package/dist/seal/index.md +85 -0
- package/dist/seal/llms-index.md +4 -0
- package/dist/slush-wallet/dapp.md +95 -0
- package/dist/slush-wallet/deep-linking.md +465 -0
- package/dist/slush-wallet/index.md +7 -0
- package/dist/slush-wallet/llms-index.md +6 -0
- package/dist/sui/bcs.md +134 -0
- package/dist/sui/clients/core.md +606 -0
- package/dist/sui/clients/graphql.md +101 -0
- package/dist/sui/clients/grpc.md +155 -0
- package/dist/sui/clients/index.md +95 -0
- package/dist/sui/clients/json-rpc.md +239 -0
- package/dist/sui/cryptography/keypairs.md +267 -0
- package/dist/sui/cryptography/multisig.md +194 -0
- package/dist/sui/cryptography/passkey.md +111 -0
- package/dist/sui/cryptography/webcrypto-signer.md +81 -0
- package/dist/sui/executors.md +148 -0
- package/dist/sui/faucet.md +26 -0
- package/dist/sui/hello-sui.md +115 -0
- package/dist/sui/index.md +53 -0
- package/dist/sui/install.md +61 -0
- package/dist/sui/llm-docs.md +32 -0
- package/dist/sui/llms-index.md +44 -0
- package/dist/sui/migrations/0.38.md +58 -0
- package/dist/sui/migrations/sui-1.0.md +455 -0
- package/dist/sui/migrations/sui-2.0/agent-prompt.md +42 -0
- package/dist/sui/migrations/sui-2.0/dapp-kit.md +350 -0
- package/dist/sui/migrations/sui-2.0/deepbook-v3.md +33 -0
- package/dist/sui/migrations/sui-2.0/index.md +158 -0
- package/dist/sui/migrations/sui-2.0/json-rpc-migration.md +386 -0
- package/dist/sui/migrations/sui-2.0/kiosk.md +120 -0
- package/dist/sui/migrations/sui-2.0/sdk-maintainers.md +90 -0
- package/dist/sui/migrations/sui-2.0/seal.md +14 -0
- package/dist/sui/migrations/sui-2.0/sui.md +341 -0
- package/dist/sui/migrations/sui-2.0/suins.md +43 -0
- package/dist/sui/migrations/sui-2.0/wallet-builders.md +66 -0
- package/dist/sui/migrations/sui-2.0/walrus.md +41 -0
- package/dist/sui/migrations/sui-2.0/zksend.md +95 -0
- package/dist/sui/plugins.md +258 -0
- package/dist/sui/sdk-building.md +344 -0
- package/dist/sui/transaction-building/basics.md +299 -0
- package/dist/sui/transaction-building/gas.md +62 -0
- package/dist/sui/transaction-building/intents.md +62 -0
- package/dist/sui/transaction-building/offline.md +73 -0
- package/dist/sui/transaction-building/sponsored-transactions.md +22 -0
- package/dist/sui/utils/derived_objects.md +59 -0
- package/dist/sui/utils/index.md +52 -0
- package/dist/sui/zklogin.md +83 -0
- package/dist/walrus/index.md +527 -0
- package/dist/walrus/llms-index.md +4 -0
- package/dist/zksend/index.md +27 -0
- package/dist/zksend/link-builder.md +192 -0
- package/dist/zksend/llms-index.md +5 -0
- package/package.json +66 -0
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
# Registry Management
|
|
2
|
+
|
|
3
|
+
> Manage payment registries and accepted coin types
|
|
4
|
+
|
|
5
|
+
> **Note:** This package is in active development and should be used with caution. APIs are experimental and
|
|
6
|
+
> subject to breaking changes without notice. We recommend thoroughly testing any implementation
|
|
7
|
+
> before using in production environments.
|
|
8
|
+
|
|
9
|
+
Payment registries are the core of Payment Kit's duplicate prevention and payment tracking system.
|
|
10
|
+
This guide covers creating, configuring, and managing payment registries.
|
|
11
|
+
|
|
12
|
+
## Understanding Payment Registries
|
|
13
|
+
|
|
14
|
+
A `PaymentRegistry` is an on-chain object that:
|
|
15
|
+
|
|
16
|
+
- Stores `PaymentRecord` dynamic fields for each unique payment
|
|
17
|
+
- Manages configuration settings (expiration, fund management)
|
|
18
|
+
- Can be owned and administered by a specific account
|
|
19
|
+
- Provides namespaced payment tracking
|
|
20
|
+
|
|
21
|
+
### Default Registry
|
|
22
|
+
|
|
23
|
+
Payment Kit provides a default registry that's ready to use:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
// Use the default registry
|
|
27
|
+
const tx = client.paymentKit.tx.processRegistryPayment({
|
|
28
|
+
nonce: crypto.randomUUID(),
|
|
29
|
+
coinType: '0x2::sui::SUI',
|
|
30
|
+
amount: 1000000000,
|
|
31
|
+
receiver,
|
|
32
|
+
sender: senderAddress,
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### When to Create a Custom Registry
|
|
37
|
+
|
|
38
|
+
Consider creating your own registry when:
|
|
39
|
+
|
|
40
|
+
- You want isolated payment tracking for your application
|
|
41
|
+
- You need custom expiration policies
|
|
42
|
+
- You want to manage funds centrally
|
|
43
|
+
- You need better indexing of your payments
|
|
44
|
+
- You want to avoid potential congestion on the default registry
|
|
45
|
+
|
|
46
|
+
## Creating a Registry
|
|
47
|
+
|
|
48
|
+
### Basic Registry Creation
|
|
49
|
+
|
|
50
|
+
Creating a registry is simple - you only need to provide a unique name:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// Create a new registry
|
|
54
|
+
const tx = client.paymentKit.tx.createRegistry({
|
|
55
|
+
registryName: 'my-app-payments',
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const result = await client.signAndExecuteTransaction({
|
|
59
|
+
transaction: tx,
|
|
60
|
+
signer: keypair,
|
|
61
|
+
options: {
|
|
62
|
+
showEffects: true,
|
|
63
|
+
showObjectChanges: true,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Check transaction status
|
|
68
|
+
if (result.$kind === 'FailedTransaction') {
|
|
69
|
+
throw new Error(`Registry creation failed: ${result.FailedTransaction.status.error?.message}`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log('Registry created!');
|
|
73
|
+
console.log('Transaction:', result.Transaction.digest);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### What Gets Created
|
|
77
|
+
|
|
78
|
+
When you create a registry, two objects are created:
|
|
79
|
+
|
|
80
|
+
1. **PaymentRegistry**: The registry object that stores payment records
|
|
81
|
+
2. **RegistryAdminCap**: A capability object that grants admin permissions
|
|
82
|
+
|
|
83
|
+
### Extracting the Admin Capability
|
|
84
|
+
|
|
85
|
+
The `RegistryAdminCap` is crucial for configuring your registry:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
// Find the admin cap in the transaction result
|
|
89
|
+
const adminCapObject = result.Transaction.objectChanges?.find(
|
|
90
|
+
(change) => change.type === 'created' && change.objectType.includes('RegistryAdminCap'),
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
if (adminCapObject && 'objectId' in adminCapObject) {
|
|
94
|
+
const adminCapId = adminCapObject.objectId;
|
|
95
|
+
|
|
96
|
+
console.log('Admin Capability ID:', adminCapId);
|
|
97
|
+
|
|
98
|
+
// Store this ID - you'll need it to configure the registry
|
|
99
|
+
await database.saveAdminCap({
|
|
100
|
+
registryName: 'my-app-payments',
|
|
101
|
+
adminCapId: adminCapId,
|
|
102
|
+
owner: senderAddress,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Deriving the Registry ID
|
|
108
|
+
|
|
109
|
+
Payment Kit derives registry IDs deterministically from the registry name:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
// You can compute the registry ID without querying the chain
|
|
113
|
+
const registryName = 'random-registry-name';
|
|
114
|
+
const registryId = client.paymentKit.getRegistryIdFromName(registryName);
|
|
115
|
+
|
|
116
|
+
console.log('Registry ID:', registryId);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
This allows you to reference registries by name throughout your application.
|
|
120
|
+
|
|
121
|
+
## Registry Configuration
|
|
122
|
+
|
|
123
|
+
Registries have two main configuration options:
|
|
124
|
+
|
|
125
|
+
### 1. Epoch Expiration Duration
|
|
126
|
+
|
|
127
|
+
Controls how long payment records persist before they can be deleted.
|
|
128
|
+
|
|
129
|
+
**Default**: 30 epochs (~30 days on mainnet)
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
// Set expiration to 60 epochs
|
|
133
|
+
const tx = client.paymentKit.tx.setConfigEpochExpirationDuration({
|
|
134
|
+
registryName: 'my-app-payments',
|
|
135
|
+
epochExpirationDuration: 60,
|
|
136
|
+
adminCapId: adminCapId,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const result = await client.signAndExecuteTransaction({
|
|
140
|
+
transaction: tx,
|
|
141
|
+
signer: keypair,
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// Check transaction status
|
|
145
|
+
if (result.$kind === 'FailedTransaction') {
|
|
146
|
+
throw new Error(`Configuration update failed: ${result.FailedTransaction.status.error?.message}`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
console.log('Expiration set to 60 epochs');
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**How It Works:**
|
|
153
|
+
|
|
154
|
+
When a payment is recorded, it stores the current epoch. After the expiration duration has passed,
|
|
155
|
+
anyone can delete the record to reclaim storage fees:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
// Current epoch: 1000
|
|
159
|
+
// Payment recorded at epoch: 1000
|
|
160
|
+
// Expiration duration: 30
|
|
161
|
+
// Can be deleted after epoch: 1030
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Use Cases:**
|
|
165
|
+
|
|
166
|
+
- **Short expiration (7-14 epochs)**: High-volume, time-sensitive payments (subscriptions, tickets)
|
|
167
|
+
- **Medium expiration (30-60 epochs)**: Standard e-commerce transactions
|
|
168
|
+
- **Long expiration (180+ epochs)**: Important financial records requiring long-term verification
|
|
169
|
+
|
|
170
|
+
### 2. Registry Managed Funds
|
|
171
|
+
|
|
172
|
+
Controls whether payments must be sent to the registry itself for later withdrawal.
|
|
173
|
+
|
|
174
|
+
**Default**: Disabled (funds go directly to receivers)
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
// Enable registry-managed funds
|
|
178
|
+
const tx = client.paymentKit.tx.setConfigRegistryManagedFunds({
|
|
179
|
+
registryName: 'my-app-payments',
|
|
180
|
+
registryManagedFunds: true,
|
|
181
|
+
adminCapId: adminCapId,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
await client.signAndExecuteTransaction({
|
|
185
|
+
transaction: tx,
|
|
186
|
+
signer: keypair,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
console.log('Registry now manages funds');
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**How It Works:**
|
|
193
|
+
|
|
194
|
+
When enabled:
|
|
195
|
+
|
|
196
|
+
- All payments must specify the registry as the receiver
|
|
197
|
+
- Coins are transferred to the registry object
|
|
198
|
+
- Registry admin can withdraw accumulated funds later
|
|
199
|
+
- Simplifies coin merging for high-throughput scenarios
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
// With registry-managed funds enabled
|
|
203
|
+
const registryId = getRegistryIdFromName('my-app-payments', namespaceId);
|
|
204
|
+
|
|
205
|
+
const tx = client.paymentKit.tx.processRegistryPayment({
|
|
206
|
+
nonce: crypto.randomUUID(),
|
|
207
|
+
coinType: '0x2::sui::SUI',
|
|
208
|
+
amount: 1000000000,
|
|
209
|
+
receiver: registryId, // Must be the registry itself
|
|
210
|
+
sender: senderAddress,
|
|
211
|
+
registryName: 'my-app-payments',
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Use Cases:**
|
|
216
|
+
|
|
217
|
+
- Platforms collecting payments on behalf of sellers
|
|
218
|
+
- Applications that need to batch process payouts
|
|
219
|
+
- Scenarios with very high transaction volumes
|
|
220
|
+
- Simplified accounting and reconciliation
|
|
221
|
+
|
|
222
|
+
### Configuring Both Settings
|
|
223
|
+
|
|
224
|
+
You can configure both settings independently:
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
|
|
228
|
+
const tx = new Transaction();
|
|
229
|
+
|
|
230
|
+
// Set expiration duration
|
|
231
|
+
tx.add(
|
|
232
|
+
client.paymentKit.calls.setConfigEpochExpirationDuration({
|
|
233
|
+
registryName: 'my-app-payments',
|
|
234
|
+
epochExpirationDuration: 90,
|
|
235
|
+
adminCapId: adminCapId,
|
|
236
|
+
}),
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
// Enable managed funds
|
|
240
|
+
tx.add(
|
|
241
|
+
client.paymentKit.calls.setConfigRegistryManagedFunds({
|
|
242
|
+
registryName: 'my-app-payments',
|
|
243
|
+
registryManagedFunds: true,
|
|
244
|
+
adminCapId: adminCapId,
|
|
245
|
+
}),
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
// Apply both configurations in one transaction
|
|
249
|
+
await client.signAndExecuteTransaction({
|
|
250
|
+
transaction: tx,
|
|
251
|
+
signer: keypair,
|
|
252
|
+
});
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Withdrawing Funds from a Registry
|
|
256
|
+
|
|
257
|
+
If you've enabled registry-managed funds, you can withdraw accumulated coins:
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
// Withdraw all SUI from the registry
|
|
261
|
+
const tx = client.paymentKit.tx.withdrawFromRegistry({
|
|
262
|
+
coinType: '0x2::sui::SUI',
|
|
263
|
+
registryName: 'my-app-payments',
|
|
264
|
+
adminCapId: adminCapId,
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
const result = await client.signAndExecuteTransaction({
|
|
268
|
+
transaction: tx,
|
|
269
|
+
signer: keypair,
|
|
270
|
+
options: {
|
|
271
|
+
showEffects: true,
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
console.log('Funds withdrawn!');
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Important Notes:**
|
|
279
|
+
|
|
280
|
+
- Only the admin cap owner can withdraw funds
|
|
281
|
+
- You must specify the coin type to withdraw
|
|
282
|
+
- All coins of that type are withdrawn in one operation
|
|
283
|
+
- The withdrawn coins are sent to the transaction sender
|
|
284
|
+
|
|
285
|
+
### Withdrawing Multiple Coin Types
|
|
286
|
+
|
|
287
|
+
If your registry accumulates different coin types:
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
const tx = new Transaction();
|
|
291
|
+
|
|
292
|
+
// Withdraw SUI
|
|
293
|
+
tx.add(
|
|
294
|
+
client.paymentKit.calls.withdrawFromRegistry({
|
|
295
|
+
coinType: '0x2::sui::SUI',
|
|
296
|
+
registryName: 'my-app-payments',
|
|
297
|
+
adminCapId: adminCapId,
|
|
298
|
+
}),
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
// Withdraw custom token
|
|
302
|
+
tx.add(
|
|
303
|
+
client.paymentKit.calls.withdrawFromRegistry({
|
|
304
|
+
coinType: '0xabc123::my_token::MY_TOKEN',
|
|
305
|
+
registryName: 'my-app-payments',
|
|
306
|
+
adminCapId: adminCapId,
|
|
307
|
+
}),
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
await client.signAndExecuteTransaction({
|
|
311
|
+
transaction: tx,
|
|
312
|
+
signer: keypair,
|
|
313
|
+
});
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## Deleting Expired Payment Records
|
|
317
|
+
|
|
318
|
+
After the expiration period, payment records can be deleted to reclaim storage fees:
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
// Delete an expired payment record
|
|
322
|
+
const tx = client.paymentKit.tx.deletePaymentRecord({
|
|
323
|
+
nonce: crypto.randomUUID(),
|
|
324
|
+
coinType: '0x2::sui::SUI',
|
|
325
|
+
amount: 1000000000,
|
|
326
|
+
receiver,
|
|
327
|
+
registryName: 'my-app-payments',
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
const result = await client.signAndExecuteTransaction({
|
|
331
|
+
transaction: tx,
|
|
332
|
+
signer: keypair,
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
console.log('Record deleted, storage rebate received');
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Key Points:**
|
|
339
|
+
|
|
340
|
+
- Records can only be deleted after expiration
|
|
341
|
+
- Anyone can delete expired records (permissionless cleanup)
|
|
342
|
+
- The deleter receives a small storage rebate
|
|
343
|
+
- This incentivizes automatic cleanup of old records
|
|
344
|
+
|
|
345
|
+
### Checking If a Record Can Be Deleted
|
|
346
|
+
|
|
347
|
+
```ts
|
|
348
|
+
// Get the payment record
|
|
349
|
+
const record = await client.paymentKit.getPaymentRecord({
|
|
350
|
+
nonce: crypto.randomUUID(),
|
|
351
|
+
coinType: '0x2::sui::SUI',
|
|
352
|
+
amount: 1000000000,
|
|
353
|
+
receiver,
|
|
354
|
+
registryName: 'my-app-payments',
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
if (record) {
|
|
358
|
+
const recordEpoch = parseInt(record.epochAtTimeOfRecord);
|
|
359
|
+
const currentEpoch = await client.core
|
|
360
|
+
.getLatestSuiSystemState()
|
|
361
|
+
.then((state) => Number(state.epoch));
|
|
362
|
+
|
|
363
|
+
const expirationDuration = 30; // Your registry's setting
|
|
364
|
+
const canDelete = currentEpoch >= recordEpoch + expirationDuration;
|
|
365
|
+
|
|
366
|
+
console.log('Record epoch:', recordEpoch);
|
|
367
|
+
console.log('Current epoch:', currentEpoch);
|
|
368
|
+
console.log('Can delete:', canDelete);
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
## Using Registry ID Directly
|
|
373
|
+
|
|
374
|
+
If you know the registry ID, you can use it instead of the name:
|
|
375
|
+
|
|
376
|
+
```ts
|
|
377
|
+
const registryId = '0x123abc...';
|
|
378
|
+
|
|
379
|
+
// Process payment using registry ID
|
|
380
|
+
const tx = client.paymentKit.tx.processRegistryPayment({
|
|
381
|
+
nonce: crypto.randomUUID(),
|
|
382
|
+
coinType: '0x2::sui::SUI',
|
|
383
|
+
amount: 1000000000,
|
|
384
|
+
receiver,
|
|
385
|
+
sender: senderAddress,
|
|
386
|
+
registryId: registryId, // Use ID instead of name
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
// Query using registry ID
|
|
390
|
+
const record = await client.paymentKit.getPaymentRecord({
|
|
391
|
+
nonce: crypto.randomUUID(),
|
|
392
|
+
coinType: '0x2::sui::SUI',
|
|
393
|
+
amount: 1000000000,
|
|
394
|
+
receiver,
|
|
395
|
+
registryId: registryId,
|
|
396
|
+
});
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## Complete Registry Setup Example
|
|
400
|
+
|
|
401
|
+
Here's a complete workflow for setting up a custom registry:
|
|
402
|
+
|
|
403
|
+
```ts
|
|
404
|
+
|
|
405
|
+
const client = new SuiGrpcClient({
|
|
406
|
+
network: 'testnet',
|
|
407
|
+
baseUrl: 'https://fullnode.testnet.sui.io:443',
|
|
408
|
+
}).$extend(paymentKit());
|
|
409
|
+
|
|
410
|
+
const keypair = Ed25519Keypair.generate();
|
|
411
|
+
const registryName = 'my-marketplace-registry';
|
|
412
|
+
|
|
413
|
+
// Step 1: Create the registry
|
|
414
|
+
console.log('Creating registry...');
|
|
415
|
+
const createTx = client.paymentKit.tx.createRegistry({
|
|
416
|
+
registryName: registryName,
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
const createResult = await client.signAndExecuteTransaction({
|
|
420
|
+
transaction: createTx,
|
|
421
|
+
signer: keypair,
|
|
422
|
+
options: {
|
|
423
|
+
showEffects: true,
|
|
424
|
+
showObjectChanges: true,
|
|
425
|
+
},
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
// Check transaction status
|
|
429
|
+
if (createResult.$kind === 'FailedTransaction') {
|
|
430
|
+
throw new Error(
|
|
431
|
+
`Registry creation failed: ${createResult.FailedTransaction.status.error?.message}`,
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// Step 2: Extract the admin cap
|
|
436
|
+
const adminCapObject = createResult.Transaction.objectChanges?.find(
|
|
437
|
+
(change) => change.type === 'created' && change.objectType.includes('RegistryAdminCap'),
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
const adminCapId = adminCapObject && 'objectId' in adminCapObject ? adminCapObject.objectId : '';
|
|
441
|
+
|
|
442
|
+
console.log('Registry created!');
|
|
443
|
+
console.log('Admin Cap ID:', adminCapId);
|
|
444
|
+
|
|
445
|
+
// Step 3: Configure the registry
|
|
446
|
+
console.log('Configuring registry...');
|
|
447
|
+
const configTx = new Transaction();
|
|
448
|
+
|
|
449
|
+
// Set 60-epoch expiration
|
|
450
|
+
configTx.add(
|
|
451
|
+
client.paymentKit.calls.setConfigEpochExpirationDuration({
|
|
452
|
+
registryName: registryName,
|
|
453
|
+
epochExpirationDuration: 60,
|
|
454
|
+
adminCapId: adminCapId,
|
|
455
|
+
}),
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
// Enable managed funds
|
|
459
|
+
configTx.add(
|
|
460
|
+
client.paymentKit.calls.setConfigRegistryManagedFunds({
|
|
461
|
+
registryName: registryName,
|
|
462
|
+
registryManagedFunds: true,
|
|
463
|
+
adminCapId: adminCapId,
|
|
464
|
+
}),
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
const configResult = await client.signAndExecuteTransaction({
|
|
468
|
+
transaction: configTx,
|
|
469
|
+
signer: keypair,
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// Check transaction status
|
|
473
|
+
if (configResult.$kind === 'FailedTransaction') {
|
|
474
|
+
throw new Error(`Configuration failed: ${configResult.FailedTransaction.status.error?.message}`);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
console.log('Registry configured!');
|
|
478
|
+
console.log('Ready to process payments');
|
|
479
|
+
|
|
480
|
+
// Step 4: Process a payment
|
|
481
|
+
const registryId = getRegistryIdFromName(registryName, namespaceId);
|
|
482
|
+
|
|
483
|
+
const paymentTx = client.paymentKit.tx.processRegistryPayment({
|
|
484
|
+
nonce: crypto.randomUUID(),
|
|
485
|
+
coinType: '0x2::sui::SUI',
|
|
486
|
+
amount: 1000000000,
|
|
487
|
+
receiver: registryId, // Funds go to registry
|
|
488
|
+
sender: keypair.getPublicKey().toSuiAddress(),
|
|
489
|
+
registryName: registryName,
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
const paymentResult = await client.signAndExecuteTransaction({
|
|
493
|
+
transaction: paymentTx,
|
|
494
|
+
signer: keypair,
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
// Check transaction status
|
|
498
|
+
if (paymentResult.$kind === 'FailedTransaction') {
|
|
499
|
+
throw new Error(`Payment failed: ${paymentResult.FailedTransaction.status.error?.message}`);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
console.log('First payment processed:', paymentResult.Transaction.digest);
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
## Best Practices
|
|
506
|
+
|
|
507
|
+
1. **Store Admin Caps Securely**: Treat your admin capability like private keys - they control your
|
|
508
|
+
registry
|
|
509
|
+
|
|
510
|
+
2. **Use Descriptive Names**: Choose registry names that clearly identify their purpose (e.g.,
|
|
511
|
+
`acme-subscriptions`, `store-123-payments`)
|
|
512
|
+
|
|
513
|
+
3. **Set Appropriate Expiration**: Balance storage costs with verification needs
|
|
514
|
+
- Short expiration = lower storage costs
|
|
515
|
+
- Long expiration = longer verification period
|
|
516
|
+
|
|
517
|
+
4. **Monitor Registry Growth**: Track the number of payment records to anticipate storage costs
|
|
518
|
+
|
|
519
|
+
5. **Plan Fund Management**: Decide upfront whether to use registry-managed funds based on your
|
|
520
|
+
withdrawal patterns
|
|
521
|
+
|
|
522
|
+
6. **Document Your Configuration**: Keep records of your registry settings for operational
|
|
523
|
+
consistency
|
|
524
|
+
|
|
525
|
+
7. **Test Thoroughly**: Always test registry operations on testnet before mainnet deployment
|
|
526
|
+
|
|
527
|
+
## Next Steps
|
|
528
|
+
|
|
529
|
+
- [SDK API Reference](./payment-kit-sdk) - Complete SDK API documentation
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Seal SDK
|
|
2
|
+
|
|
3
|
+
> Decentralized secrets management with threshold encryption on Sui
|
|
4
|
+
|
|
5
|
+
> **Note:** This is a beta version of Seal. See https://github.com/MystenLabs/seal for more details.
|
|
6
|
+
|
|
7
|
+
The Seal SDK provides threshold encryption capabilities for Sui applications, enabling secure data
|
|
8
|
+
encryption with configurable key servers.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash npm2yarn
|
|
13
|
+
npm install --save @mysten/seal @mysten/sui
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
To use the Seal SDK, create a Sui client and extend it with the Seal extension:
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
|
|
22
|
+
const client = new SuiGrpcClient({
|
|
23
|
+
network: 'testnet',
|
|
24
|
+
baseUrl: 'https://fullnode.testnet.sui.io:443',
|
|
25
|
+
}).$extend(
|
|
26
|
+
seal({
|
|
27
|
+
serverConfigs: [
|
|
28
|
+
{ objectId: '0x...keyserver1', weight: 1 },
|
|
29
|
+
{ objectId: '0x...keyserver2', weight: 1 },
|
|
30
|
+
],
|
|
31
|
+
}),
|
|
32
|
+
);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Configuration Options
|
|
36
|
+
|
|
37
|
+
The `seal()` function accepts the following options:
|
|
38
|
+
|
|
39
|
+
- **`serverConfigs`** (required) - Array of key server configurations with `objectId` and `weight`
|
|
40
|
+
- **`verifyKeyServers`** (optional) - Whether to verify key server authenticity (default: `true`)
|
|
41
|
+
- **`timeout`** (optional) - Timeout in milliseconds for network requests (default: `10000`)
|
|
42
|
+
|
|
43
|
+
## Basic Usage
|
|
44
|
+
|
|
45
|
+
### Encrypting Data
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
const data = new Uint8Array([1, 2, 3]);
|
|
49
|
+
|
|
50
|
+
const { encryptedObject } = await client.seal.encrypt({
|
|
51
|
+
threshold: 2, // Number of key servers needed to decrypt
|
|
52
|
+
packageId: '0x...your-package-id',
|
|
53
|
+
id: '0x...your-object-id',
|
|
54
|
+
data,
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Decrypting Data
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
|
|
62
|
+
// Create a session key for decryption
|
|
63
|
+
const sessionKey = await SessionKey.create({
|
|
64
|
+
address: senderAddress,
|
|
65
|
+
packageId: '0x...your-package-id',
|
|
66
|
+
ttlMin: 10, // Time-to-live in minutes
|
|
67
|
+
signer: keypair,
|
|
68
|
+
suiClient: client,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Build transaction bytes that call seal_approve
|
|
72
|
+
const txBytes = await buildApprovalTransaction(/* ... */);
|
|
73
|
+
|
|
74
|
+
// Decrypt the data
|
|
75
|
+
const decryptedData = await client.seal.decrypt({
|
|
76
|
+
data: encryptedObject,
|
|
77
|
+
sessionKey,
|
|
78
|
+
txBytes,
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Resources
|
|
83
|
+
|
|
84
|
+
For detailed documentation on threshold encryption and key server setup, see the
|
|
85
|
+
[Seal repository](https://github.com/MystenLabs/seal).
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# dApp Integration
|
|
2
|
+
|
|
3
|
+
> Connect your dApp to Slush Wallet
|
|
4
|
+
|
|
5
|
+
> **Note:** If you are using `dapp-kit`, you do not need to install any additional packages to integrate with
|
|
6
|
+
> the Slush wallet. [Read how to integrate with dapp-kit.](/dapp-kit/legacy/slush)
|
|
7
|
+
|
|
8
|
+
Using the Slush Wallet SDK, you can allow users to connect to the Slush wallet from your dApp. The
|
|
9
|
+
wallet is provided through the [Wallet Standard](https://docs.sui.io/standards/wallet-standard), and
|
|
10
|
+
should appear automatically in your existing wallet connection UI.
|
|
11
|
+
|
|
12
|
+
> The Slush Wallet SDK is only needed if you want to support the Slush web wallet in your dApp. If
|
|
13
|
+
> you want to integrate with the Slush browser extension or native mobile wallet, you do not need to
|
|
14
|
+
> install any additional packages - they will work automatically through the Wallet Standard.
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
To use the Slush web wallet, you will need to register it in your application, using
|
|
19
|
+
`registerSlushWallet`. This only needs to be done once, and should be done as early as possible in
|
|
20
|
+
your application's lifecycle.
|
|
21
|
+
|
|
22
|
+
`registerSlushWallet` takes two arguments:
|
|
23
|
+
|
|
24
|
+
- `name`: The name of your dApp. This will be shown to the user when they are asked to approve the
|
|
25
|
+
connection in Slush.
|
|
26
|
+
- `options`: An optional object with the following properties:
|
|
27
|
+
- `origin`: The origin of the Slush website. Defaults to `https://[TODO]`.
|
|
28
|
+
- `network`: The network that you would like the Slush wallet to use. Defaults to `mainnet`,
|
|
29
|
+
supports `mainnet` and `testnet`.
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
|
|
33
|
+
registerSlushWallet('Your dApp Name');
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Supported features
|
|
37
|
+
|
|
38
|
+
The Slush wallet currently supports the following features:
|
|
39
|
+
|
|
40
|
+
- `signTransaction`
|
|
41
|
+
- `signAndExecuteTransaction`
|
|
42
|
+
- `signPersonalMessage`
|
|
43
|
+
|
|
44
|
+
## Detecting the Slush wallet
|
|
45
|
+
|
|
46
|
+
If you'd like to detect whether the user is connected to the Slush wallet, you can use the `id` or
|
|
47
|
+
`name` property on the wallet
|
|
48
|
+
|
|
49
|
+
For example, if you are using `dapp-kit`, you can use the `useCurrentWallet` hook to get the current
|
|
50
|
+
wallet, and check if it is the Slush wallet.
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
|
|
54
|
+
function SlushOnly() {
|
|
55
|
+
const { currentWallet } = useCurrentWallet();
|
|
56
|
+
const walletIsSlushWallet = currentWallet?.name === SLUSH_WALLET_NAME;
|
|
57
|
+
|
|
58
|
+
// rest of component logic...
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
# Migration from Stashed Wallet -> Slush Wallet
|
|
63
|
+
|
|
64
|
+
If you're currently using `@mysten/zksend`'s `registerStashedWallet` directly, you should migrate to
|
|
65
|
+
the `@mysten/slush-wallet` package to ensure compatibility with the new Slush experience.
|
|
66
|
+
|
|
67
|
+
## ๐ Installation
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pnpm install @mysten/slush-wallet
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## ๐ Migration
|
|
74
|
+
|
|
75
|
+
If you're using `registerStashedWallet`, switch to `registerSlushWallet`:
|
|
76
|
+
|
|
77
|
+
**Before:**
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
|
|
81
|
+
registerStashedWallet(...);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**After:**
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
|
|
88
|
+
registerSlushWallet(...);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
If you're using dapp-kit, update to the latest dapp-kit version and change the `stashedWallet` prop
|
|
92
|
+
on WalletProvider to `slushWallet`
|
|
93
|
+
|
|
94
|
+
> Note: In the connect modal, users with the Slush Wallet extension installed will only see the
|
|
95
|
+
> extension. If they donโt have it, the connection will default to the Slush web app.
|