@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 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. Shows confirmation modal
331
- 3. Signs with user approval
332
- 4. Submits and polls for completion
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 with gas sponsorship capabilities.
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
  }