@supanovaapp/sdk 0.2.10 → 0.2.12
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 +180 -7
- package/dist/index.cjs.js +435 -435
- package/dist/index.esm.js +23185 -23059
- package/package.json +9 -1
- package/dist/index.d.ts +0 -1507
package/README.md
CHANGED
|
@@ -15,6 +15,9 @@ For a quick overview of the code, check out the demo application in the `/demo`
|
|
|
15
15
|
- **Automatic Polling** - Transaction completion tracking
|
|
16
16
|
- **TypeScript Support** - Full type safety and IntelliSense
|
|
17
17
|
- **React Hooks** - Simple and intuitive API
|
|
18
|
+
- **Cost Estimation** - Real-time transaction cost estimation before signing
|
|
19
|
+
- **Incoming Transfers** - Accept or reject incoming Canton token transfers
|
|
20
|
+
- **Invite Codes** - Support for invite-based registration
|
|
18
21
|
|
|
19
22
|
## Installation
|
|
20
23
|
|
|
@@ -196,6 +199,8 @@ After successful authentication, `authenticated` becomes `true` and `user` objec
|
|
|
196
199
|
|
|
197
200
|
#### Register Canton Wallet
|
|
198
201
|
|
|
202
|
+
Register your Canton wallet with optional invite code support:
|
|
203
|
+
|
|
199
204
|
```tsx
|
|
200
205
|
import { useCanton } from '@supa/sdk';
|
|
201
206
|
|
|
@@ -204,7 +209,12 @@ function CantonWallet() {
|
|
|
204
209
|
|
|
205
210
|
const handleRegister = async () => {
|
|
206
211
|
try {
|
|
212
|
+
// Register without invite code
|
|
207
213
|
await registerCanton();
|
|
214
|
+
|
|
215
|
+
// Or with invite code
|
|
216
|
+
await registerCanton('your-invite-code');
|
|
217
|
+
|
|
208
218
|
console.log('Canton wallet registered!');
|
|
209
219
|
} catch (error) {
|
|
210
220
|
console.error('Registration failed:', error);
|
|
@@ -221,11 +231,15 @@ function CantonWallet() {
|
|
|
221
231
|
<div>
|
|
222
232
|
<p>Party ID: {cantonUser?.partyId}</p>
|
|
223
233
|
<p>Email: {cantonUser?.email}</p>
|
|
234
|
+
<p>Transfer Preapproval: {cantonUser?.transferPreapprovalSet ? 'Enabled' : 'Disabled'}</p>
|
|
224
235
|
</div>
|
|
225
236
|
);
|
|
226
237
|
}
|
|
227
238
|
```
|
|
228
239
|
|
|
240
|
+
**Parameters:**
|
|
241
|
+
- `inviteCode` (optional) - Invite code for registration
|
|
242
|
+
|
|
229
243
|
#### Get Active Contracts
|
|
230
244
|
|
|
231
245
|
```tsx
|
|
@@ -279,8 +293,11 @@ if (cantonBalances) {
|
|
|
279
293
|
|
|
280
294
|
#### Send Canton Coin
|
|
281
295
|
|
|
296
|
+
Send Canton Coin with cost estimation support:
|
|
297
|
+
|
|
282
298
|
```tsx
|
|
283
299
|
const { sendCantonCoin } = useCanton();
|
|
300
|
+
const [costEstimation, setCostEstimation] = useState(null);
|
|
284
301
|
|
|
285
302
|
try {
|
|
286
303
|
const result = await sendCantonCoin(
|
|
@@ -290,6 +307,15 @@ try {
|
|
|
290
307
|
{
|
|
291
308
|
timeout: 30000, // completion timeout (ms)
|
|
292
309
|
pollInterval: 1000, // polling interval (ms)
|
|
310
|
+
onCostEstimation: (cost) => {
|
|
311
|
+
// Called before signing with cost estimation
|
|
312
|
+
if (cost) {
|
|
313
|
+
setCostEstimation(cost);
|
|
314
|
+
console.log('Request cost:', cost.confirmationRequestTrafficCostEstimation);
|
|
315
|
+
console.log('Response cost:', cost.confirmationResponseTrafficCostEstimation);
|
|
316
|
+
console.log('Total cost:', cost.totalTrafficCostEstimation, 'μunits');
|
|
317
|
+
}
|
|
318
|
+
}
|
|
293
319
|
}
|
|
294
320
|
);
|
|
295
321
|
console.log('Canton Coin sent successfully:', result);
|
|
@@ -303,10 +329,22 @@ try {
|
|
|
303
329
|
}
|
|
304
330
|
```
|
|
305
331
|
|
|
332
|
+
**Cost Estimation Object:**
|
|
333
|
+
```typescript
|
|
334
|
+
interface CantonCostEstimationDto {
|
|
335
|
+
estimationTimestamp: string; // ISO 8601 timestamp
|
|
336
|
+
confirmationRequestTrafficCostEstimation: number; // in micro-units
|
|
337
|
+
confirmationResponseTrafficCostEstimation: number; // in micro-units
|
|
338
|
+
totalTrafficCostEstimation: number; // total in micro-units
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
306
342
|
**Note**: The amount cannot have more than 10 decimal places. Transfers are only supported to wallets with preapproved transfers enabled.
|
|
307
343
|
|
|
308
344
|
#### Submit a Transaction
|
|
309
345
|
|
|
346
|
+
Submit Canton transactions with cost estimation:
|
|
347
|
+
|
|
310
348
|
```tsx
|
|
311
349
|
const { sendTransaction } = useCanton();
|
|
312
350
|
|
|
@@ -318,6 +356,12 @@ try {
|
|
|
318
356
|
const result = await sendTransaction(commands, disclosedContracts, {
|
|
319
357
|
timeout: 30000, // completion timeout (ms)
|
|
320
358
|
pollInterval: 1000, // polling interval (ms)
|
|
359
|
+
onCostEstimation: (cost) => {
|
|
360
|
+
// Cost estimation callback (called before signing)
|
|
361
|
+
if (cost) {
|
|
362
|
+
console.log('Transaction cost:', cost.totalTrafficCostEstimation, 'μunits');
|
|
363
|
+
}
|
|
364
|
+
}
|
|
321
365
|
});
|
|
322
366
|
console.log('Transaction successful:', result);
|
|
323
367
|
} catch (error) {
|
|
@@ -327,9 +371,131 @@ try {
|
|
|
327
371
|
|
|
328
372
|
The SDK automatically:
|
|
329
373
|
1. Prepares the transaction
|
|
330
|
-
2.
|
|
331
|
-
3.
|
|
332
|
-
4.
|
|
374
|
+
2. Calls `onCostEstimation` callback if provided
|
|
375
|
+
3. Shows confirmation modal
|
|
376
|
+
4. Signs with user approval
|
|
377
|
+
5. Submits and polls for completion
|
|
378
|
+
|
|
379
|
+
#### Incoming Transfers
|
|
380
|
+
|
|
381
|
+
Manage incoming Canton token transfers:
|
|
382
|
+
|
|
383
|
+
**Get Pending Incoming Transfers:**
|
|
384
|
+
|
|
385
|
+
```tsx
|
|
386
|
+
const { getPendingIncomingTransfers } = useCanton();
|
|
387
|
+
|
|
388
|
+
try {
|
|
389
|
+
const incomingTransfers = await getPendingIncomingTransfers();
|
|
390
|
+
|
|
391
|
+
incomingTransfers.forEach(transfer => {
|
|
392
|
+
console.log('From:', transfer.sender);
|
|
393
|
+
console.log('Amount:', transfer.amount);
|
|
394
|
+
console.log('Token:', transfer.instrument.id); // 'Amulet', 'CBTC', etc.
|
|
395
|
+
console.log('Expires:', transfer.executeBefore);
|
|
396
|
+
console.log('Contract ID:', transfer.contractId); // Use this to respond
|
|
397
|
+
});
|
|
398
|
+
} catch (error) {
|
|
399
|
+
console.error('Failed to fetch incoming transfers:', error);
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Respond to Incoming Transfer:**
|
|
404
|
+
|
|
405
|
+
```tsx
|
|
406
|
+
const { respondToIncomingTransfer } = useCanton();
|
|
407
|
+
|
|
408
|
+
// Accept a transfer
|
|
409
|
+
try {
|
|
410
|
+
const result = await respondToIncomingTransfer(
|
|
411
|
+
contractId, // From getPendingIncomingTransfers()
|
|
412
|
+
true, // true = accept, false = reject
|
|
413
|
+
{
|
|
414
|
+
onCostEstimation: (cost) => {
|
|
415
|
+
console.log('Response cost:', cost?.totalTrafficCostEstimation);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
);
|
|
419
|
+
console.log('Transfer accepted:', result);
|
|
420
|
+
} catch (error) {
|
|
421
|
+
console.error('Failed to respond:', error);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Reject a transfer
|
|
425
|
+
await respondToIncomingTransfer(contractId, false);
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**Complete Example with UI:**
|
|
429
|
+
|
|
430
|
+
```tsx
|
|
431
|
+
function IncomingTransfers() {
|
|
432
|
+
const { getPendingIncomingTransfers, respondToIncomingTransfer } = useCanton();
|
|
433
|
+
const [transfers, setTransfers] = useState([]);
|
|
434
|
+
const [loading, setLoading] = useState(false);
|
|
435
|
+
|
|
436
|
+
const loadTransfers = async () => {
|
|
437
|
+
setLoading(true);
|
|
438
|
+
try {
|
|
439
|
+
const incoming = await getPendingIncomingTransfers();
|
|
440
|
+
setTransfers(incoming);
|
|
441
|
+
} finally {
|
|
442
|
+
setLoading(false);
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
const handleAccept = async (contractId) => {
|
|
447
|
+
try {
|
|
448
|
+
await respondToIncomingTransfer(contractId, true);
|
|
449
|
+
await loadTransfers(); // Refresh list
|
|
450
|
+
} catch (error) {
|
|
451
|
+
console.error('Failed to accept:', error);
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
|
|
455
|
+
const handleReject = async (contractId) => {
|
|
456
|
+
try {
|
|
457
|
+
await respondToIncomingTransfer(contractId, false);
|
|
458
|
+
await loadTransfers(); // Refresh list
|
|
459
|
+
} catch (error) {
|
|
460
|
+
console.error('Failed to reject:', error);
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
return (
|
|
465
|
+
<div>
|
|
466
|
+
<button onClick={loadTransfers} disabled={loading}>
|
|
467
|
+
{loading ? 'Loading...' : 'Refresh Transfers'}
|
|
468
|
+
</button>
|
|
469
|
+
|
|
470
|
+
{transfers.map(transfer => (
|
|
471
|
+
<div key={transfer.contractId}>
|
|
472
|
+
<p>From: {transfer.sender}</p>
|
|
473
|
+
<p>Amount: {transfer.amount} {transfer.instrument.id}</p>
|
|
474
|
+
<p>Expires: {new Date(transfer.executeBefore).toLocaleString()}</p>
|
|
475
|
+
<button onClick={() => handleAccept(transfer.contractId)}>Accept</button>
|
|
476
|
+
<button onClick={() => handleReject(transfer.contractId)}>Reject</button>
|
|
477
|
+
</div>
|
|
478
|
+
))}
|
|
479
|
+
</div>
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
**Incoming Transfer Object:**
|
|
485
|
+
```typescript
|
|
486
|
+
interface CantonIncomingTransferDto {
|
|
487
|
+
instrument: {
|
|
488
|
+
admin: string; // Token administrator party ID
|
|
489
|
+
id: string; // Token ID ('Amulet', 'CBTC', etc.)
|
|
490
|
+
};
|
|
491
|
+
contractId: string; // Use this to accept/reject
|
|
492
|
+
sender: string; // Sender party ID
|
|
493
|
+
receiver: string; // Your party ID
|
|
494
|
+
amount: string; // Transfer amount
|
|
495
|
+
requestedAt: string; // ISO 8601 timestamp
|
|
496
|
+
executeBefore: string; // ISO 8601 expiration timestamp
|
|
497
|
+
}
|
|
498
|
+
```
|
|
333
499
|
|
|
334
500
|
#### Sign a Message
|
|
335
501
|
|
|
@@ -348,7 +514,7 @@ try {
|
|
|
348
514
|
|
|
349
515
|
### 4. Devnet Operations
|
|
350
516
|
|
|
351
|
-
Request test tokens from the devnet faucet:
|
|
517
|
+
Request test tokens from the devnet faucet with cost estimation:
|
|
352
518
|
|
|
353
519
|
```tsx
|
|
354
520
|
const { tapDevnet } = useCanton();
|
|
@@ -357,6 +523,11 @@ try {
|
|
|
357
523
|
const result = await tapDevnet('1000', {
|
|
358
524
|
timeout: 30000,
|
|
359
525
|
pollInterval: 1000,
|
|
526
|
+
onCostEstimation: (cost) => {
|
|
527
|
+
if (cost) {
|
|
528
|
+
console.log('Faucet request cost:', cost.totalTrafficCostEstimation, 'μunits');
|
|
529
|
+
}
|
|
530
|
+
}
|
|
360
531
|
});
|
|
361
532
|
console.log('Tokens received:', result);
|
|
362
533
|
} catch (error) {
|
|
@@ -407,7 +578,7 @@ await sendTransaction(command, contracts, {
|
|
|
407
578
|
| Hook | Purpose | Key Methods |
|
|
408
579
|
|------|---------|-------------|
|
|
409
580
|
| `useAuth` | Authentication | `login`, `logout`, `authenticated`, `user` |
|
|
410
|
-
| `useCanton` | Canton Network | `registerCanton`, `getBalances`, `sendCantonCoin`, `signMessage`, `sendTransaction`, `getActiveContracts`, `tapDevnet` |
|
|
581
|
+
| `useCanton` | Canton Network | `registerCanton`, `getBalances`, `sendCantonCoin`, `signMessage`, `sendTransaction`, `getActiveContracts`, `tapDevnet`, `getPendingIncomingTransfers`, `respondToIncomingTransfer` |
|
|
411
582
|
| `useSignMessage` | Enhanced message signing | `signMessage` with custom modals |
|
|
412
583
|
| `useSendTransaction` | Enhanced transactions | `sendTransaction` with custom modals |
|
|
413
584
|
| `useConfirmModal` | Generic modals | `confirm`, `signMessageConfirm`, `signTransactionConfirm` |
|
|
@@ -435,6 +606,9 @@ import type {
|
|
|
435
606
|
CantonLockedUtxoDto,
|
|
436
607
|
CantonUnlockedUtxoDto,
|
|
437
608
|
CantonPrepareAmuletTransferRequestDto,
|
|
609
|
+
CantonCostEstimationDto,
|
|
610
|
+
CantonIncomingTransferDto,
|
|
611
|
+
CantonPrepareResponseIncomingTransferRequestDto,
|
|
438
612
|
|
|
439
613
|
// Option Types
|
|
440
614
|
SignMessageOptions,
|
|
@@ -545,7 +719,7 @@ npm publish
|
|
|
545
719
|
|
|
546
720
|
### EVM Smart Wallets
|
|
547
721
|
|
|
548
|
-
Supa SDK supports Privy Smart Wallets for EVM chains
|
|
722
|
+
Supa SDK supports Privy Smart Wallets for EVM chains based on privy provider
|
|
549
723
|
|
|
550
724
|
```tsx
|
|
551
725
|
<SupaProvider
|
|
@@ -555,7 +729,6 @@ Supa SDK supports Privy Smart Wallets for EVM chains with gas sponsorship capabi
|
|
|
555
729
|
smartWallets: {
|
|
556
730
|
enabled: true,
|
|
557
731
|
paymasterContext: {
|
|
558
|
-
mode: 'SPONSORED',
|
|
559
732
|
// ... paymaster configuration
|
|
560
733
|
}
|
|
561
734
|
}
|