@zyfai/sdk 0.1.5 → 0.1.7
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 +76 -16
- package/dist/index.d.mts +24 -6
- package/dist/index.d.ts +24 -6
- package/dist/index.js +122 -41
- package/dist/index.mjs +122 -41
- package/package.json +10 -2
package/README.md
CHANGED
|
@@ -65,7 +65,7 @@ const sdk = new ZyfaiSDK({
|
|
|
65
65
|
|
|
66
66
|
### Connect Account
|
|
67
67
|
|
|
68
|
-
The SDK accepts either a private key or a modern wallet provider
|
|
68
|
+
The SDK accepts either a private key or a modern wallet provider. **The SDK automatically authenticates the user via SIWE (Sign-In with Ethereum) when connecting.**
|
|
69
69
|
|
|
70
70
|
```typescript
|
|
71
71
|
// Option 1: With private key (chainId required)
|
|
@@ -84,7 +84,25 @@ const userAddress = "0xUser...";
|
|
|
84
84
|
await sdk.deploySafe(userAddress, 42161);
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
**Note:**
|
|
87
|
+
**Note:**
|
|
88
|
+
- When using a wallet provider, the SDK automatically detects the chain from the provider. You can optionally specify `chainId` to override.
|
|
89
|
+
- The SDK automatically performs SIWE authentication when connecting, so you don't need to call any additional authentication methods.
|
|
90
|
+
|
|
91
|
+
### Disconnect Account
|
|
92
|
+
|
|
93
|
+
Disconnect the current account and clear all authentication state:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
// Disconnect account and clear JWT token
|
|
97
|
+
await sdk.disconnectAccount();
|
|
98
|
+
console.log("Account disconnected and authentication cleared");
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
This method:
|
|
102
|
+
- Clears the wallet connection
|
|
103
|
+
- Resets authentication state
|
|
104
|
+
- Clears the JWT token
|
|
105
|
+
- Resets session key tracking
|
|
88
106
|
|
|
89
107
|
## Core Features
|
|
90
108
|
|
|
@@ -164,7 +182,7 @@ new ZyfaiSDK(config: SDKConfig | string)
|
|
|
164
182
|
|
|
165
183
|
##### `connectAccount(account: string | any, chainId?: SupportedChainId): Promise<Address>`
|
|
166
184
|
|
|
167
|
-
Connect account for signing transactions. Accepts either a private key string or a modern wallet provider.
|
|
185
|
+
Connect account for signing transactions and authenticate via SIWE. Accepts either a private key string or a modern wallet provider.
|
|
168
186
|
|
|
169
187
|
**Parameters:**
|
|
170
188
|
|
|
@@ -176,6 +194,11 @@ Connect account for signing transactions. Accepts either a private key string or
|
|
|
176
194
|
|
|
177
195
|
**Returns:** Connected wallet address
|
|
178
196
|
|
|
197
|
+
**Automatic Actions:**
|
|
198
|
+
- Connects the wallet
|
|
199
|
+
- Authenticates via SIWE (Sign-In with Ethereum)
|
|
200
|
+
- Stores JWT token for authenticated endpoints
|
|
201
|
+
|
|
179
202
|
**Examples:**
|
|
180
203
|
|
|
181
204
|
```typescript
|
|
@@ -187,6 +210,25 @@ const provider = await connector.getProvider();
|
|
|
187
210
|
await sdk.connectAccount(provider); // Uses provider's current chain
|
|
188
211
|
```
|
|
189
212
|
|
|
213
|
+
##### `disconnectAccount(): Promise<void>`
|
|
214
|
+
|
|
215
|
+
Disconnect account and clear all authentication state.
|
|
216
|
+
|
|
217
|
+
**Returns:** Promise that resolves when disconnection is complete
|
|
218
|
+
|
|
219
|
+
**Actions:**
|
|
220
|
+
- Clears wallet connection
|
|
221
|
+
- Resets authentication state
|
|
222
|
+
- Clears JWT token
|
|
223
|
+
- Resets session key tracking
|
|
224
|
+
|
|
225
|
+
**Example:**
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
await sdk.disconnectAccount();
|
|
229
|
+
console.log("Disconnected and cleared");
|
|
230
|
+
```
|
|
231
|
+
|
|
190
232
|
##### `getSmartWalletAddress(userAddress: string, chainId: SupportedChainId): Promise<SmartWalletResponse>`
|
|
191
233
|
|
|
192
234
|
Get the Smart Wallet (Safe) address for a user.
|
|
@@ -235,7 +277,7 @@ The SDK automatically fetches optimal session configuration from ZyFAI API:
|
|
|
235
277
|
|
|
236
278
|
```typescript
|
|
237
279
|
// SDK automatically:
|
|
238
|
-
// 1.
|
|
280
|
+
// 1. Uses existing SIWE authentication (from connectAccount)
|
|
239
281
|
// 2. Checks if user already has an active session key (returns early if so)
|
|
240
282
|
// 3. Calculates the deterministic Safe address
|
|
241
283
|
// 4. Retrieves personalized config via /session-keys/config
|
|
@@ -257,9 +299,9 @@ console.log("User ID:", result.userId);
|
|
|
257
299
|
|
|
258
300
|
**Important**:
|
|
259
301
|
|
|
260
|
-
-
|
|
261
|
-
- The SDK proactively checks if the user already has an active session key
|
|
262
|
-
- The user record must have `smartWallet` and `chainId` set (automatically handled after calling `deploySafe`
|
|
302
|
+
- User must be authenticated (automatically done via `connectAccount()`)
|
|
303
|
+
- The SDK proactively checks if the user already has an active session key and returns early without requiring any signature if one exists
|
|
304
|
+
- The user record must have `smartWallet` and `chainId` set (automatically handled after calling `deploySafe`)
|
|
263
305
|
- When `alreadyActive` is `true`, `sessionKeyAddress` and `signature` are not available in the response
|
|
264
306
|
|
|
265
307
|
### 4. Deposit Funds
|
|
@@ -286,7 +328,7 @@ The SDK automatically authenticates via SIWE before logging the deposit with ZyF
|
|
|
286
328
|
|
|
287
329
|
### 5. Withdraw Funds
|
|
288
330
|
|
|
289
|
-
|
|
331
|
+
Initiate a withdrawal from your Safe. **Note: Withdrawals are processed asynchronously by the backend.**
|
|
290
332
|
|
|
291
333
|
```typescript
|
|
292
334
|
// Full withdrawal
|
|
@@ -301,13 +343,22 @@ const result = await sdk.withdrawFunds(
|
|
|
301
343
|
);
|
|
302
344
|
|
|
303
345
|
if (result.success) {
|
|
304
|
-
console.log("Withdrawal
|
|
305
|
-
console.log("
|
|
346
|
+
console.log("Withdrawal initiated!");
|
|
347
|
+
console.log("Message:", result.message); // e.g., "Withdrawal request sent"
|
|
348
|
+
if (result.txHash) {
|
|
349
|
+
console.log("Transaction Hash:", result.txHash);
|
|
350
|
+
} else {
|
|
351
|
+
console.log("Transaction will be processed asynchronously");
|
|
352
|
+
}
|
|
306
353
|
}
|
|
307
354
|
```
|
|
308
355
|
|
|
309
|
-
**
|
|
310
|
-
|
|
356
|
+
**Important Notes:**
|
|
357
|
+
- Amount must be in least decimal units. For USDC (6 decimals): 1 USDC = 1000000
|
|
358
|
+
- The SDK authenticates via SIWE before calling the withdrawal endpoints
|
|
359
|
+
- Withdrawals are processed asynchronously - the `txHash` may not be immediately available
|
|
360
|
+
- Check the `message` field for the withdrawal status
|
|
361
|
+
- Use `getHistory()` to track the withdrawal transaction once it's processed
|
|
311
362
|
|
|
312
363
|
### 6. Get Available Protocols
|
|
313
364
|
|
|
@@ -549,7 +600,7 @@ async function main() {
|
|
|
549
600
|
bundlerApiKey: process.env.BUNDLER_API_KEY!,
|
|
550
601
|
});
|
|
551
602
|
|
|
552
|
-
// Connect account (
|
|
603
|
+
// Connect account (automatically authenticates via SIWE)
|
|
553
604
|
await sdk.connectAccount(process.env.PRIVATE_KEY!, 42161);
|
|
554
605
|
|
|
555
606
|
const userAddress = "0xUser..."; // User's EOA address
|
|
@@ -598,9 +649,10 @@ function SafeDeployment() {
|
|
|
598
649
|
try {
|
|
599
650
|
// Client passes the wallet provider from their frontend
|
|
600
651
|
// e.g., from wagmi: const provider = await connector.getProvider();
|
|
652
|
+
// connectAccount automatically authenticates via SIWE
|
|
601
653
|
const address = await sdk.connectAccount(walletProvider); // chainId auto-detected
|
|
602
654
|
setUserAddress(address);
|
|
603
|
-
console.log("Connected:", address);
|
|
655
|
+
console.log("Connected and authenticated:", address);
|
|
604
656
|
|
|
605
657
|
// Get Safe address for this user
|
|
606
658
|
const walletInfo = await sdk.getSmartWalletAddress(address, 42161);
|
|
@@ -720,7 +772,7 @@ CHAIN_ID=8453
|
|
|
720
772
|
|
|
721
773
|
### "No account connected" Error
|
|
722
774
|
|
|
723
|
-
Make sure to call `connectAccount()` before calling other methods that require signing.
|
|
775
|
+
Make sure to call `connectAccount()` before calling other methods that require signing. Note that `connectAccount()` automatically authenticates the user via SIWE.
|
|
724
776
|
|
|
725
777
|
### "Unsupported chain" Error
|
|
726
778
|
|
|
@@ -728,18 +780,26 @@ Check that the chain ID is in the supported chains list: Arbitrum (42161), Base
|
|
|
728
780
|
|
|
729
781
|
### SIWE Authentication Issues in Browser
|
|
730
782
|
|
|
731
|
-
The SDK automatically detects browser vs Node.js environments
|
|
783
|
+
The SDK automatically performs SIWE authentication when you call `connectAccount()`. The SDK automatically detects browser vs Node.js environments:
|
|
732
784
|
- **Browser**: Uses `window.location.origin` for the SIWE message domain/uri to match the browser's automatic `Origin` header
|
|
733
785
|
- **Node.js**: Uses the API endpoint URL
|
|
734
786
|
|
|
735
787
|
If you encounter SIWE authentication failures in a browser, ensure:
|
|
736
788
|
1. Your frontend origin is allowed by the API's CORS configuration
|
|
737
789
|
2. You're using the correct `environment` setting (`staging` or `production`)
|
|
790
|
+
3. The user approves the SIWE signature request in their wallet
|
|
738
791
|
|
|
739
792
|
### Session Key Already Exists
|
|
740
793
|
|
|
741
794
|
If `createSessionKey` returns `{ alreadyActive: true }`, the user already has an active session key. This is not an error - the SDK proactively checks before attempting to create a new one.
|
|
742
795
|
|
|
796
|
+
### Withdrawal Transaction Hash Not Available
|
|
797
|
+
|
|
798
|
+
If `withdrawFunds` returns without a `txHash`, the withdrawal is being processed asynchronously by the backend. You can:
|
|
799
|
+
1. Check the `message` field for status information
|
|
800
|
+
2. Use `getHistory()` to track when the withdrawal transaction is processed
|
|
801
|
+
3. The transaction will appear in the history once it's been executed
|
|
802
|
+
|
|
743
803
|
### Data API CORS Errors
|
|
744
804
|
|
|
745
805
|
Some Data API endpoints may require server-side CORS configuration. If you see CORS errors for endpoints like `onchain-earnings`, `calculate-onchain-earnings`, or `opportunities`, contact ZyFAI support to ensure your origin is whitelisted.
|
package/dist/index.d.mts
CHANGED
|
@@ -54,8 +54,6 @@ interface AddSessionKeyResponse {
|
|
|
54
54
|
}
|
|
55
55
|
interface SessionKeyResponse {
|
|
56
56
|
success: boolean;
|
|
57
|
-
/** Session key address (not available when alreadyActive is true) */
|
|
58
|
-
sessionKeyAddress?: Address;
|
|
59
57
|
/** Signature (not available when alreadyActive is true) */
|
|
60
58
|
signature?: Hex;
|
|
61
59
|
sessionNonces?: bigint[];
|
|
@@ -347,7 +345,8 @@ interface DepositResponse {
|
|
|
347
345
|
}
|
|
348
346
|
interface WithdrawResponse {
|
|
349
347
|
success: boolean;
|
|
350
|
-
|
|
348
|
+
message: string;
|
|
349
|
+
txHash?: string;
|
|
351
350
|
type: "full" | "partial";
|
|
352
351
|
amount: string;
|
|
353
352
|
receiver: string;
|
|
@@ -409,10 +408,10 @@ declare class ZyfaiSDK {
|
|
|
409
408
|
private signer;
|
|
410
409
|
private walletClient;
|
|
411
410
|
private bundlerApiKey?;
|
|
412
|
-
private isAuthenticated;
|
|
413
411
|
private authenticatedUserId;
|
|
414
412
|
private hasActiveSessionKey;
|
|
415
413
|
private environment;
|
|
414
|
+
private currentProvider;
|
|
416
415
|
constructor(config: SDKConfig | string);
|
|
417
416
|
/**
|
|
418
417
|
* Authenticate user with SIWE (Sign-In with Ethereum) & JWT token
|
|
@@ -438,6 +437,12 @@ declare class ZyfaiSDK {
|
|
|
438
437
|
* ```
|
|
439
438
|
*/
|
|
440
439
|
updateUserProfile(request: UpdateUserProfileRequest): Promise<UpdateUserProfileResponse>;
|
|
440
|
+
/**
|
|
441
|
+
* Handle account changes from wallet provider
|
|
442
|
+
* Resets authentication state when wallet is switched
|
|
443
|
+
* @private
|
|
444
|
+
*/
|
|
445
|
+
private handleAccountsChanged;
|
|
441
446
|
/**
|
|
442
447
|
* Connect account for signing transactions
|
|
443
448
|
* Accepts either a private key string or a modern wallet provider
|
|
@@ -456,6 +461,17 @@ declare class ZyfaiSDK {
|
|
|
456
461
|
* await sdk.connectAccount(provider);
|
|
457
462
|
*/
|
|
458
463
|
connectAccount(account: string | any, chainId?: SupportedChainId): Promise<Address>;
|
|
464
|
+
/**
|
|
465
|
+
* Disconnect account and clear authentication state
|
|
466
|
+
* Resets wallet connection, JWT token, and all authentication-related state
|
|
467
|
+
*
|
|
468
|
+
* @example
|
|
469
|
+
* ```typescript
|
|
470
|
+
* await sdk.disconnectAccount();
|
|
471
|
+
* console.log("Account disconnected");
|
|
472
|
+
* ```
|
|
473
|
+
*/
|
|
474
|
+
disconnectAccount(): Promise<void>;
|
|
459
475
|
/**
|
|
460
476
|
* Get wallet client (throws if not connected)
|
|
461
477
|
* @private
|
|
@@ -531,18 +547,20 @@ declare class ZyfaiSDK {
|
|
|
531
547
|
depositFunds(userAddress: string, chainId: SupportedChainId, tokenAddress: string, amount: string): Promise<DepositResponse>;
|
|
532
548
|
/**
|
|
533
549
|
* Withdraw funds from Safe smart wallet
|
|
534
|
-
*
|
|
550
|
+
* Initiates a withdrawal request to the ZyFAI API
|
|
551
|
+
* Note: The withdrawal is processed asynchronously, so txHash may not be immediately available
|
|
535
552
|
*
|
|
536
553
|
* @param userAddress - User's address (owner of the Safe)
|
|
537
554
|
* @param chainId - Target chain ID
|
|
538
555
|
* @param amount - Optional: Amount in least decimal units to withdraw (partial withdrawal). If not specified, withdraws all funds
|
|
539
556
|
* @param receiver - Optional: Receiver address. If not specified, sends to Safe owner
|
|
540
|
-
* @returns Withdraw response with transaction hash
|
|
557
|
+
* @returns Withdraw response with message and optional transaction hash (available once processed)
|
|
541
558
|
*
|
|
542
559
|
* @example
|
|
543
560
|
* ```typescript
|
|
544
561
|
* // Full withdrawal
|
|
545
562
|
* const result = await sdk.withdrawFunds("0xUser...", 42161);
|
|
563
|
+
* console.log(result.message); // "Withdrawal request sent"
|
|
546
564
|
*
|
|
547
565
|
* // Partial withdrawal of 50 USDC (6 decimals)
|
|
548
566
|
* const result = await sdk.withdrawFunds(
|
package/dist/index.d.ts
CHANGED
|
@@ -54,8 +54,6 @@ interface AddSessionKeyResponse {
|
|
|
54
54
|
}
|
|
55
55
|
interface SessionKeyResponse {
|
|
56
56
|
success: boolean;
|
|
57
|
-
/** Session key address (not available when alreadyActive is true) */
|
|
58
|
-
sessionKeyAddress?: Address;
|
|
59
57
|
/** Signature (not available when alreadyActive is true) */
|
|
60
58
|
signature?: Hex;
|
|
61
59
|
sessionNonces?: bigint[];
|
|
@@ -347,7 +345,8 @@ interface DepositResponse {
|
|
|
347
345
|
}
|
|
348
346
|
interface WithdrawResponse {
|
|
349
347
|
success: boolean;
|
|
350
|
-
|
|
348
|
+
message: string;
|
|
349
|
+
txHash?: string;
|
|
351
350
|
type: "full" | "partial";
|
|
352
351
|
amount: string;
|
|
353
352
|
receiver: string;
|
|
@@ -409,10 +408,10 @@ declare class ZyfaiSDK {
|
|
|
409
408
|
private signer;
|
|
410
409
|
private walletClient;
|
|
411
410
|
private bundlerApiKey?;
|
|
412
|
-
private isAuthenticated;
|
|
413
411
|
private authenticatedUserId;
|
|
414
412
|
private hasActiveSessionKey;
|
|
415
413
|
private environment;
|
|
414
|
+
private currentProvider;
|
|
416
415
|
constructor(config: SDKConfig | string);
|
|
417
416
|
/**
|
|
418
417
|
* Authenticate user with SIWE (Sign-In with Ethereum) & JWT token
|
|
@@ -438,6 +437,12 @@ declare class ZyfaiSDK {
|
|
|
438
437
|
* ```
|
|
439
438
|
*/
|
|
440
439
|
updateUserProfile(request: UpdateUserProfileRequest): Promise<UpdateUserProfileResponse>;
|
|
440
|
+
/**
|
|
441
|
+
* Handle account changes from wallet provider
|
|
442
|
+
* Resets authentication state when wallet is switched
|
|
443
|
+
* @private
|
|
444
|
+
*/
|
|
445
|
+
private handleAccountsChanged;
|
|
441
446
|
/**
|
|
442
447
|
* Connect account for signing transactions
|
|
443
448
|
* Accepts either a private key string or a modern wallet provider
|
|
@@ -456,6 +461,17 @@ declare class ZyfaiSDK {
|
|
|
456
461
|
* await sdk.connectAccount(provider);
|
|
457
462
|
*/
|
|
458
463
|
connectAccount(account: string | any, chainId?: SupportedChainId): Promise<Address>;
|
|
464
|
+
/**
|
|
465
|
+
* Disconnect account and clear authentication state
|
|
466
|
+
* Resets wallet connection, JWT token, and all authentication-related state
|
|
467
|
+
*
|
|
468
|
+
* @example
|
|
469
|
+
* ```typescript
|
|
470
|
+
* await sdk.disconnectAccount();
|
|
471
|
+
* console.log("Account disconnected");
|
|
472
|
+
* ```
|
|
473
|
+
*/
|
|
474
|
+
disconnectAccount(): Promise<void>;
|
|
459
475
|
/**
|
|
460
476
|
* Get wallet client (throws if not connected)
|
|
461
477
|
* @private
|
|
@@ -531,18 +547,20 @@ declare class ZyfaiSDK {
|
|
|
531
547
|
depositFunds(userAddress: string, chainId: SupportedChainId, tokenAddress: string, amount: string): Promise<DepositResponse>;
|
|
532
548
|
/**
|
|
533
549
|
* Withdraw funds from Safe smart wallet
|
|
534
|
-
*
|
|
550
|
+
* Initiates a withdrawal request to the ZyFAI API
|
|
551
|
+
* Note: The withdrawal is processed asynchronously, so txHash may not be immediately available
|
|
535
552
|
*
|
|
536
553
|
* @param userAddress - User's address (owner of the Safe)
|
|
537
554
|
* @param chainId - Target chain ID
|
|
538
555
|
* @param amount - Optional: Amount in least decimal units to withdraw (partial withdrawal). If not specified, withdraws all funds
|
|
539
556
|
* @param receiver - Optional: Receiver address. If not specified, sends to Safe owner
|
|
540
|
-
* @returns Withdraw response with transaction hash
|
|
557
|
+
* @returns Withdraw response with message and optional transaction hash (available once processed)
|
|
541
558
|
*
|
|
542
559
|
* @example
|
|
543
560
|
* ```typescript
|
|
544
561
|
* // Full withdrawal
|
|
545
562
|
* const result = await sdk.withdrawFunds("0xUser...", 42161);
|
|
563
|
+
* console.log(result.message); // "Withdrawal request sent"
|
|
546
564
|
*
|
|
547
565
|
* // Partial withdrawal of 50 USDC (6 decimals)
|
|
548
566
|
* const result = await sdk.withdrawFunds(
|
package/dist/index.js
CHANGED
|
@@ -620,14 +620,15 @@ var signSessionKey = async (config, sessions, allPublicClients) => {
|
|
|
620
620
|
// src/core/ZyfaiSDK.ts
|
|
621
621
|
var import_siwe = require("siwe");
|
|
622
622
|
var ZyfaiSDK = class {
|
|
623
|
-
//
|
|
623
|
+
// Store reference to current provider for event handling
|
|
624
624
|
constructor(config) {
|
|
625
625
|
this.signer = null;
|
|
626
626
|
this.walletClient = null;
|
|
627
|
-
this.isAuthenticated = false;
|
|
628
627
|
this.authenticatedUserId = null;
|
|
629
|
-
//
|
|
628
|
+
// If non-null, user is authenticated
|
|
630
629
|
this.hasActiveSessionKey = false;
|
|
630
|
+
// TODO: The environment should be removed. Having the same key for staging and production is not ideal, but for now it's fine.
|
|
631
|
+
this.currentProvider = null;
|
|
631
632
|
const sdkConfig = typeof config === "string" ? { apiKey: config } : config;
|
|
632
633
|
const { apiKey, dataApiKey, environment, bundlerApiKey } = sdkConfig;
|
|
633
634
|
if (!apiKey) {
|
|
@@ -646,7 +647,7 @@ var ZyfaiSDK = class {
|
|
|
646
647
|
*/
|
|
647
648
|
async authenticateUser() {
|
|
648
649
|
try {
|
|
649
|
-
if (this.
|
|
650
|
+
if (this.authenticatedUserId !== null) {
|
|
650
651
|
return;
|
|
651
652
|
}
|
|
652
653
|
const walletClient = this.getWalletClient();
|
|
@@ -685,14 +686,13 @@ var ZyfaiSDK = class {
|
|
|
685
686
|
signature
|
|
686
687
|
}
|
|
687
688
|
);
|
|
688
|
-
const authToken = loginResponse.accessToken
|
|
689
|
+
const authToken = loginResponse.accessToken;
|
|
689
690
|
if (!authToken) {
|
|
690
691
|
throw new Error("Authentication response missing access token");
|
|
691
692
|
}
|
|
692
693
|
this.httpClient.setAuthToken(authToken);
|
|
693
694
|
this.authenticatedUserId = loginResponse.userId || null;
|
|
694
695
|
this.hasActiveSessionKey = loginResponse.hasActiveSessionKey || false;
|
|
695
|
-
this.isAuthenticated = true;
|
|
696
696
|
} catch (error) {
|
|
697
697
|
throw new Error(
|
|
698
698
|
`Failed to authenticate user: ${error.message}`
|
|
@@ -733,6 +733,43 @@ var ZyfaiSDK = class {
|
|
|
733
733
|
);
|
|
734
734
|
}
|
|
735
735
|
}
|
|
736
|
+
/**
|
|
737
|
+
* Handle account changes from wallet provider
|
|
738
|
+
* Resets authentication state when wallet is switched
|
|
739
|
+
* @private
|
|
740
|
+
*/
|
|
741
|
+
async handleAccountsChanged(accounts) {
|
|
742
|
+
if (!accounts || accounts.length === 0) {
|
|
743
|
+
await this.disconnectAccount();
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
const newAddress = accounts[0];
|
|
747
|
+
const currentAddress = this.walletClient?.account?.address;
|
|
748
|
+
if (currentAddress && newAddress.toLowerCase() === currentAddress.toLowerCase()) {
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
this.authenticatedUserId = null;
|
|
752
|
+
this.hasActiveSessionKey = false;
|
|
753
|
+
this.httpClient.clearAuthToken();
|
|
754
|
+
if (this.walletClient && this.currentProvider) {
|
|
755
|
+
const chainConfig = getChainConfig(
|
|
756
|
+
this.walletClient.chain?.id || 42161
|
|
757
|
+
);
|
|
758
|
+
this.walletClient = (0, import_viem4.createWalletClient)({
|
|
759
|
+
account: newAddress,
|
|
760
|
+
chain: chainConfig.chain,
|
|
761
|
+
transport: (0, import_viem4.custom)(this.currentProvider)
|
|
762
|
+
});
|
|
763
|
+
try {
|
|
764
|
+
await this.authenticateUser();
|
|
765
|
+
} catch (error) {
|
|
766
|
+
console.warn(
|
|
767
|
+
"Failed to authenticate after wallet switch:",
|
|
768
|
+
error.message
|
|
769
|
+
);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
736
773
|
/**
|
|
737
774
|
* Connect account for signing transactions
|
|
738
775
|
* Accepts either a private key string or a modern wallet provider
|
|
@@ -754,9 +791,16 @@ var ZyfaiSDK = class {
|
|
|
754
791
|
if (!isSupportedChain(chainId)) {
|
|
755
792
|
throw new Error(`Unsupported chain ID: ${chainId}`);
|
|
756
793
|
}
|
|
757
|
-
this.
|
|
794
|
+
this.authenticatedUserId = null;
|
|
758
795
|
this.httpClient.clearAuthToken();
|
|
796
|
+
if (this.currentProvider?.removeAllListeners) {
|
|
797
|
+
try {
|
|
798
|
+
this.currentProvider.removeAllListeners("accountsChanged");
|
|
799
|
+
} catch (error) {
|
|
800
|
+
}
|
|
801
|
+
}
|
|
759
802
|
const chainConfig = getChainConfig(chainId);
|
|
803
|
+
let connectedAddress;
|
|
760
804
|
if (typeof account === "string") {
|
|
761
805
|
let privateKey = account;
|
|
762
806
|
if (!privateKey.startsWith("0x")) {
|
|
@@ -768,39 +812,72 @@ var ZyfaiSDK = class {
|
|
|
768
812
|
chain: chainConfig.chain,
|
|
769
813
|
transport: (0, import_viem4.http)(chainConfig.rpcUrl)
|
|
770
814
|
});
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
815
|
+
connectedAddress = this.signer.address;
|
|
816
|
+
this.currentProvider = null;
|
|
817
|
+
} else {
|
|
818
|
+
const provider = account;
|
|
819
|
+
if (!provider) {
|
|
820
|
+
throw new Error(
|
|
821
|
+
"Invalid account parameter. Expected private key string or wallet provider."
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
if (provider.request) {
|
|
825
|
+
const accounts = await provider.request({
|
|
826
|
+
method: "eth_requestAccounts"
|
|
827
|
+
});
|
|
828
|
+
if (!accounts || accounts.length === 0) {
|
|
829
|
+
throw new Error("No accounts found in wallet provider");
|
|
830
|
+
}
|
|
831
|
+
this.walletClient = (0, import_viem4.createWalletClient)({
|
|
832
|
+
account: accounts[0],
|
|
833
|
+
chain: chainConfig.chain,
|
|
834
|
+
transport: (0, import_viem4.custom)(provider)
|
|
835
|
+
});
|
|
836
|
+
connectedAddress = accounts[0];
|
|
837
|
+
this.currentProvider = provider;
|
|
838
|
+
if (provider.on) {
|
|
839
|
+
provider.on("accountsChanged", this.handleAccountsChanged.bind(this));
|
|
840
|
+
}
|
|
841
|
+
} else if (provider.account && provider.transport) {
|
|
842
|
+
this.walletClient = (0, import_viem4.createWalletClient)({
|
|
843
|
+
account: provider.account,
|
|
844
|
+
chain: chainConfig.chain,
|
|
845
|
+
transport: provider.transport
|
|
846
|
+
});
|
|
847
|
+
connectedAddress = provider.account.address;
|
|
848
|
+
this.currentProvider = null;
|
|
849
|
+
} else {
|
|
850
|
+
throw new Error(
|
|
851
|
+
"Invalid wallet provider. Expected EIP-1193 provider or viem WalletClient."
|
|
852
|
+
);
|
|
785
853
|
}
|
|
786
|
-
this.walletClient = (0, import_viem4.createWalletClient)({
|
|
787
|
-
account: accounts[0],
|
|
788
|
-
chain: chainConfig.chain,
|
|
789
|
-
transport: (0, import_viem4.custom)(provider)
|
|
790
|
-
});
|
|
791
|
-
return accounts[0];
|
|
792
854
|
}
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
855
|
+
await this.authenticateUser();
|
|
856
|
+
return connectedAddress;
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Disconnect account and clear authentication state
|
|
860
|
+
* Resets wallet connection, JWT token, and all authentication-related state
|
|
861
|
+
*
|
|
862
|
+
* @example
|
|
863
|
+
* ```typescript
|
|
864
|
+
* await sdk.disconnectAccount();
|
|
865
|
+
* console.log("Account disconnected");
|
|
866
|
+
* ```
|
|
867
|
+
*/
|
|
868
|
+
async disconnectAccount() {
|
|
869
|
+
if (this.currentProvider?.removeAllListeners) {
|
|
870
|
+
try {
|
|
871
|
+
this.currentProvider.removeAllListeners("accountsChanged");
|
|
872
|
+
} catch (error) {
|
|
873
|
+
}
|
|
800
874
|
}
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
875
|
+
this.signer = null;
|
|
876
|
+
this.walletClient = null;
|
|
877
|
+
this.currentProvider = null;
|
|
878
|
+
this.authenticatedUserId = null;
|
|
879
|
+
this.hasActiveSessionKey = false;
|
|
880
|
+
this.httpClient.clearAuthToken();
|
|
804
881
|
}
|
|
805
882
|
/**
|
|
806
883
|
* Get wallet client (throws if not connected)
|
|
@@ -1050,7 +1127,6 @@ var ZyfaiSDK = class {
|
|
|
1050
1127
|
});
|
|
1051
1128
|
return {
|
|
1052
1129
|
success: true,
|
|
1053
|
-
sessionKeyAddress: safeAddress,
|
|
1054
1130
|
signature,
|
|
1055
1131
|
sessionNonces
|
|
1056
1132
|
};
|
|
@@ -1172,18 +1248,20 @@ var ZyfaiSDK = class {
|
|
|
1172
1248
|
}
|
|
1173
1249
|
/**
|
|
1174
1250
|
* Withdraw funds from Safe smart wallet
|
|
1175
|
-
*
|
|
1251
|
+
* Initiates a withdrawal request to the ZyFAI API
|
|
1252
|
+
* Note: The withdrawal is processed asynchronously, so txHash may not be immediately available
|
|
1176
1253
|
*
|
|
1177
1254
|
* @param userAddress - User's address (owner of the Safe)
|
|
1178
1255
|
* @param chainId - Target chain ID
|
|
1179
1256
|
* @param amount - Optional: Amount in least decimal units to withdraw (partial withdrawal). If not specified, withdraws all funds
|
|
1180
1257
|
* @param receiver - Optional: Receiver address. If not specified, sends to Safe owner
|
|
1181
|
-
* @returns Withdraw response with transaction hash
|
|
1258
|
+
* @returns Withdraw response with message and optional transaction hash (available once processed)
|
|
1182
1259
|
*
|
|
1183
1260
|
* @example
|
|
1184
1261
|
* ```typescript
|
|
1185
1262
|
* // Full withdrawal
|
|
1186
1263
|
* const result = await sdk.withdrawFunds("0xUser...", 42161);
|
|
1264
|
+
* console.log(result.message); // "Withdrawal request sent"
|
|
1187
1265
|
*
|
|
1188
1266
|
* // Partial withdrawal of 50 USDC (6 decimals)
|
|
1189
1267
|
* const result = await sdk.withdrawFunds(
|
|
@@ -1234,9 +1312,12 @@ var ZyfaiSDK = class {
|
|
|
1234
1312
|
});
|
|
1235
1313
|
}
|
|
1236
1314
|
const success = response?.success ?? true;
|
|
1315
|
+
const message = response?.message || "Withdrawal request sent";
|
|
1316
|
+
const txHash = response?.txHash || response?.transactionHash;
|
|
1237
1317
|
return {
|
|
1238
1318
|
success,
|
|
1239
|
-
|
|
1319
|
+
message,
|
|
1320
|
+
txHash,
|
|
1240
1321
|
type: amount ? "partial" : "full",
|
|
1241
1322
|
amount: amount || "all",
|
|
1242
1323
|
receiver: receiver || userAddress,
|
package/dist/index.mjs
CHANGED
|
@@ -599,14 +599,15 @@ var signSessionKey = async (config, sessions, allPublicClients) => {
|
|
|
599
599
|
// src/core/ZyfaiSDK.ts
|
|
600
600
|
import { SiweMessage } from "siwe";
|
|
601
601
|
var ZyfaiSDK = class {
|
|
602
|
-
//
|
|
602
|
+
// Store reference to current provider for event handling
|
|
603
603
|
constructor(config) {
|
|
604
604
|
this.signer = null;
|
|
605
605
|
this.walletClient = null;
|
|
606
|
-
this.isAuthenticated = false;
|
|
607
606
|
this.authenticatedUserId = null;
|
|
608
|
-
//
|
|
607
|
+
// If non-null, user is authenticated
|
|
609
608
|
this.hasActiveSessionKey = false;
|
|
609
|
+
// TODO: The environment should be removed. Having the same key for staging and production is not ideal, but for now it's fine.
|
|
610
|
+
this.currentProvider = null;
|
|
610
611
|
const sdkConfig = typeof config === "string" ? { apiKey: config } : config;
|
|
611
612
|
const { apiKey, dataApiKey, environment, bundlerApiKey } = sdkConfig;
|
|
612
613
|
if (!apiKey) {
|
|
@@ -625,7 +626,7 @@ var ZyfaiSDK = class {
|
|
|
625
626
|
*/
|
|
626
627
|
async authenticateUser() {
|
|
627
628
|
try {
|
|
628
|
-
if (this.
|
|
629
|
+
if (this.authenticatedUserId !== null) {
|
|
629
630
|
return;
|
|
630
631
|
}
|
|
631
632
|
const walletClient = this.getWalletClient();
|
|
@@ -664,14 +665,13 @@ var ZyfaiSDK = class {
|
|
|
664
665
|
signature
|
|
665
666
|
}
|
|
666
667
|
);
|
|
667
|
-
const authToken = loginResponse.accessToken
|
|
668
|
+
const authToken = loginResponse.accessToken;
|
|
668
669
|
if (!authToken) {
|
|
669
670
|
throw new Error("Authentication response missing access token");
|
|
670
671
|
}
|
|
671
672
|
this.httpClient.setAuthToken(authToken);
|
|
672
673
|
this.authenticatedUserId = loginResponse.userId || null;
|
|
673
674
|
this.hasActiveSessionKey = loginResponse.hasActiveSessionKey || false;
|
|
674
|
-
this.isAuthenticated = true;
|
|
675
675
|
} catch (error) {
|
|
676
676
|
throw new Error(
|
|
677
677
|
`Failed to authenticate user: ${error.message}`
|
|
@@ -712,6 +712,43 @@ var ZyfaiSDK = class {
|
|
|
712
712
|
);
|
|
713
713
|
}
|
|
714
714
|
}
|
|
715
|
+
/**
|
|
716
|
+
* Handle account changes from wallet provider
|
|
717
|
+
* Resets authentication state when wallet is switched
|
|
718
|
+
* @private
|
|
719
|
+
*/
|
|
720
|
+
async handleAccountsChanged(accounts) {
|
|
721
|
+
if (!accounts || accounts.length === 0) {
|
|
722
|
+
await this.disconnectAccount();
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
const newAddress = accounts[0];
|
|
726
|
+
const currentAddress = this.walletClient?.account?.address;
|
|
727
|
+
if (currentAddress && newAddress.toLowerCase() === currentAddress.toLowerCase()) {
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
this.authenticatedUserId = null;
|
|
731
|
+
this.hasActiveSessionKey = false;
|
|
732
|
+
this.httpClient.clearAuthToken();
|
|
733
|
+
if (this.walletClient && this.currentProvider) {
|
|
734
|
+
const chainConfig = getChainConfig(
|
|
735
|
+
this.walletClient.chain?.id || 42161
|
|
736
|
+
);
|
|
737
|
+
this.walletClient = createWalletClient({
|
|
738
|
+
account: newAddress,
|
|
739
|
+
chain: chainConfig.chain,
|
|
740
|
+
transport: custom(this.currentProvider)
|
|
741
|
+
});
|
|
742
|
+
try {
|
|
743
|
+
await this.authenticateUser();
|
|
744
|
+
} catch (error) {
|
|
745
|
+
console.warn(
|
|
746
|
+
"Failed to authenticate after wallet switch:",
|
|
747
|
+
error.message
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}
|
|
715
752
|
/**
|
|
716
753
|
* Connect account for signing transactions
|
|
717
754
|
* Accepts either a private key string or a modern wallet provider
|
|
@@ -733,9 +770,16 @@ var ZyfaiSDK = class {
|
|
|
733
770
|
if (!isSupportedChain(chainId)) {
|
|
734
771
|
throw new Error(`Unsupported chain ID: ${chainId}`);
|
|
735
772
|
}
|
|
736
|
-
this.
|
|
773
|
+
this.authenticatedUserId = null;
|
|
737
774
|
this.httpClient.clearAuthToken();
|
|
775
|
+
if (this.currentProvider?.removeAllListeners) {
|
|
776
|
+
try {
|
|
777
|
+
this.currentProvider.removeAllListeners("accountsChanged");
|
|
778
|
+
} catch (error) {
|
|
779
|
+
}
|
|
780
|
+
}
|
|
738
781
|
const chainConfig = getChainConfig(chainId);
|
|
782
|
+
let connectedAddress;
|
|
739
783
|
if (typeof account === "string") {
|
|
740
784
|
let privateKey = account;
|
|
741
785
|
if (!privateKey.startsWith("0x")) {
|
|
@@ -747,39 +791,72 @@ var ZyfaiSDK = class {
|
|
|
747
791
|
chain: chainConfig.chain,
|
|
748
792
|
transport: http3(chainConfig.rpcUrl)
|
|
749
793
|
});
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
794
|
+
connectedAddress = this.signer.address;
|
|
795
|
+
this.currentProvider = null;
|
|
796
|
+
} else {
|
|
797
|
+
const provider = account;
|
|
798
|
+
if (!provider) {
|
|
799
|
+
throw new Error(
|
|
800
|
+
"Invalid account parameter. Expected private key string or wallet provider."
|
|
801
|
+
);
|
|
802
|
+
}
|
|
803
|
+
if (provider.request) {
|
|
804
|
+
const accounts = await provider.request({
|
|
805
|
+
method: "eth_requestAccounts"
|
|
806
|
+
});
|
|
807
|
+
if (!accounts || accounts.length === 0) {
|
|
808
|
+
throw new Error("No accounts found in wallet provider");
|
|
809
|
+
}
|
|
810
|
+
this.walletClient = createWalletClient({
|
|
811
|
+
account: accounts[0],
|
|
812
|
+
chain: chainConfig.chain,
|
|
813
|
+
transport: custom(provider)
|
|
814
|
+
});
|
|
815
|
+
connectedAddress = accounts[0];
|
|
816
|
+
this.currentProvider = provider;
|
|
817
|
+
if (provider.on) {
|
|
818
|
+
provider.on("accountsChanged", this.handleAccountsChanged.bind(this));
|
|
819
|
+
}
|
|
820
|
+
} else if (provider.account && provider.transport) {
|
|
821
|
+
this.walletClient = createWalletClient({
|
|
822
|
+
account: provider.account,
|
|
823
|
+
chain: chainConfig.chain,
|
|
824
|
+
transport: provider.transport
|
|
825
|
+
});
|
|
826
|
+
connectedAddress = provider.account.address;
|
|
827
|
+
this.currentProvider = null;
|
|
828
|
+
} else {
|
|
829
|
+
throw new Error(
|
|
830
|
+
"Invalid wallet provider. Expected EIP-1193 provider or viem WalletClient."
|
|
831
|
+
);
|
|
764
832
|
}
|
|
765
|
-
this.walletClient = createWalletClient({
|
|
766
|
-
account: accounts[0],
|
|
767
|
-
chain: chainConfig.chain,
|
|
768
|
-
transport: custom(provider)
|
|
769
|
-
});
|
|
770
|
-
return accounts[0];
|
|
771
833
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
834
|
+
await this.authenticateUser();
|
|
835
|
+
return connectedAddress;
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Disconnect account and clear authentication state
|
|
839
|
+
* Resets wallet connection, JWT token, and all authentication-related state
|
|
840
|
+
*
|
|
841
|
+
* @example
|
|
842
|
+
* ```typescript
|
|
843
|
+
* await sdk.disconnectAccount();
|
|
844
|
+
* console.log("Account disconnected");
|
|
845
|
+
* ```
|
|
846
|
+
*/
|
|
847
|
+
async disconnectAccount() {
|
|
848
|
+
if (this.currentProvider?.removeAllListeners) {
|
|
849
|
+
try {
|
|
850
|
+
this.currentProvider.removeAllListeners("accountsChanged");
|
|
851
|
+
} catch (error) {
|
|
852
|
+
}
|
|
779
853
|
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
854
|
+
this.signer = null;
|
|
855
|
+
this.walletClient = null;
|
|
856
|
+
this.currentProvider = null;
|
|
857
|
+
this.authenticatedUserId = null;
|
|
858
|
+
this.hasActiveSessionKey = false;
|
|
859
|
+
this.httpClient.clearAuthToken();
|
|
783
860
|
}
|
|
784
861
|
/**
|
|
785
862
|
* Get wallet client (throws if not connected)
|
|
@@ -1029,7 +1106,6 @@ var ZyfaiSDK = class {
|
|
|
1029
1106
|
});
|
|
1030
1107
|
return {
|
|
1031
1108
|
success: true,
|
|
1032
|
-
sessionKeyAddress: safeAddress,
|
|
1033
1109
|
signature,
|
|
1034
1110
|
sessionNonces
|
|
1035
1111
|
};
|
|
@@ -1151,18 +1227,20 @@ var ZyfaiSDK = class {
|
|
|
1151
1227
|
}
|
|
1152
1228
|
/**
|
|
1153
1229
|
* Withdraw funds from Safe smart wallet
|
|
1154
|
-
*
|
|
1230
|
+
* Initiates a withdrawal request to the ZyFAI API
|
|
1231
|
+
* Note: The withdrawal is processed asynchronously, so txHash may not be immediately available
|
|
1155
1232
|
*
|
|
1156
1233
|
* @param userAddress - User's address (owner of the Safe)
|
|
1157
1234
|
* @param chainId - Target chain ID
|
|
1158
1235
|
* @param amount - Optional: Amount in least decimal units to withdraw (partial withdrawal). If not specified, withdraws all funds
|
|
1159
1236
|
* @param receiver - Optional: Receiver address. If not specified, sends to Safe owner
|
|
1160
|
-
* @returns Withdraw response with transaction hash
|
|
1237
|
+
* @returns Withdraw response with message and optional transaction hash (available once processed)
|
|
1161
1238
|
*
|
|
1162
1239
|
* @example
|
|
1163
1240
|
* ```typescript
|
|
1164
1241
|
* // Full withdrawal
|
|
1165
1242
|
* const result = await sdk.withdrawFunds("0xUser...", 42161);
|
|
1243
|
+
* console.log(result.message); // "Withdrawal request sent"
|
|
1166
1244
|
*
|
|
1167
1245
|
* // Partial withdrawal of 50 USDC (6 decimals)
|
|
1168
1246
|
* const result = await sdk.withdrawFunds(
|
|
@@ -1213,9 +1291,12 @@ var ZyfaiSDK = class {
|
|
|
1213
1291
|
});
|
|
1214
1292
|
}
|
|
1215
1293
|
const success = response?.success ?? true;
|
|
1294
|
+
const message = response?.message || "Withdrawal request sent";
|
|
1295
|
+
const txHash = response?.txHash || response?.transactionHash;
|
|
1216
1296
|
return {
|
|
1217
1297
|
success,
|
|
1218
|
-
|
|
1298
|
+
message,
|
|
1299
|
+
txHash,
|
|
1219
1300
|
type: amount ? "partial" : "full",
|
|
1220
1301
|
amount: amount || "all",
|
|
1221
1302
|
receiver: receiver || userAddress,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zyfai/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "TypeScript SDK for ZyFAI Yield Optimization Engine - Deploy Safe smart wallets, manage session keys, and interact with DeFi protocols",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -28,7 +28,13 @@
|
|
|
28
28
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
29
29
|
"lint": "eslint src --ext .ts",
|
|
30
30
|
"test": "jest",
|
|
31
|
-
"prepublishOnly": "npm run build"
|
|
31
|
+
"prepublishOnly": "npm run build",
|
|
32
|
+
"docs": "typedoc",
|
|
33
|
+
"docs:watch": "typedoc --watch",
|
|
34
|
+
"docs:json": "typedoc --json docs/api.json",
|
|
35
|
+
"docs:dev": "cd website && pnpm start",
|
|
36
|
+
"docs:build": "pnpm docs && cd website && pnpm build",
|
|
37
|
+
"docs:serve": "cd website && pnpm serve"
|
|
32
38
|
},
|
|
33
39
|
"keywords": [
|
|
34
40
|
"zyfai",
|
|
@@ -70,6 +76,8 @@
|
|
|
70
76
|
"@types/node": "^20.0.0",
|
|
71
77
|
"dotenv": "^17.2.3",
|
|
72
78
|
"tsup": "^8.0.0",
|
|
79
|
+
"typedoc": "^0.28.15",
|
|
80
|
+
"typedoc-plugin-markdown": "^4.9.0",
|
|
73
81
|
"typescript": "^5.3.0"
|
|
74
82
|
},
|
|
75
83
|
"peerDependencies": {
|