atfi 1.0.0 → 1.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 +13 -1
- package/dist/index.d.mts +206 -37
- package/dist/index.d.ts +206 -37
- package/dist/index.js +243 -21
- package/dist/index.mjs +231 -20
- package/package.json +10 -1
package/README.md
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
# ATFi SDK
|
|
2
2
|
|
|
3
|
-
TypeScript SDK for interacting with ATFi commitment vaults on Base.
|
|
3
|
+
TypeScript SDK for interacting with ATFi commitment vaults on Base. Stake tokens, verify attendance, earn rewards.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/atfi)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Simulation-first** - Know results before wallet popup
|
|
11
|
+
- **Transaction callbacks** - Loading states for UX
|
|
12
|
+
- **Read-only mode** - Show data before wallet connection
|
|
13
|
+
- **User-centric queries** - Dashboard, registered events, claimable rewards
|
|
14
|
+
- **Real-time watching** - Subscribe to live vault events
|
|
15
|
+
- **TypeScript** - Full type safety
|
|
4
16
|
|
|
5
17
|
## Installation
|
|
6
18
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,47 +1,58 @@
|
|
|
1
1
|
import { Address, Hash, PublicClient, WalletClient } from 'viem';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
type Network = 'mainnet' | 'testnet';
|
|
4
|
+
interface NetworkConfig {
|
|
5
|
+
chainId: number;
|
|
6
|
+
name: string;
|
|
7
|
+
factory: Address;
|
|
8
|
+
morphoVault: Address | null;
|
|
9
|
+
supportsYield: boolean;
|
|
10
|
+
tokens: {
|
|
11
|
+
USDC: TokenConfig;
|
|
12
|
+
IDRX?: TokenConfig;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
interface TokenConfig {
|
|
16
|
+
address: Address;
|
|
17
|
+
decimals: number;
|
|
18
|
+
symbol: string;
|
|
19
|
+
supportsYield: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Network configurations for Base Mainnet and Sepolia Testnet
|
|
23
|
+
*/
|
|
24
|
+
declare const NETWORKS: Record<Network, NetworkConfig>;
|
|
25
|
+
declare const CHAIN_ID: number;
|
|
4
26
|
declare const CONTRACTS: {
|
|
5
|
-
readonly FACTORY:
|
|
6
|
-
readonly MORPHO_VAULT:
|
|
27
|
+
readonly FACTORY: `0x${string}`;
|
|
28
|
+
readonly MORPHO_VAULT: `0x${string}` | null;
|
|
7
29
|
};
|
|
8
30
|
declare const TOKENS: {
|
|
9
|
-
readonly USDC:
|
|
10
|
-
|
|
11
|
-
readonly decimals: 6;
|
|
12
|
-
readonly symbol: "USDC";
|
|
13
|
-
readonly supportsYield: true;
|
|
14
|
-
};
|
|
15
|
-
readonly IDRX: {
|
|
16
|
-
readonly address: Address;
|
|
17
|
-
readonly decimals: 2;
|
|
18
|
-
readonly symbol: "IDRX";
|
|
19
|
-
readonly supportsYield: false;
|
|
20
|
-
};
|
|
31
|
+
readonly USDC: TokenConfig;
|
|
32
|
+
readonly IDRX: TokenConfig;
|
|
21
33
|
};
|
|
22
34
|
type TokenSymbol = keyof typeof TOKENS;
|
|
35
|
+
/**
|
|
36
|
+
* Get network configuration by network name or chain ID
|
|
37
|
+
*/
|
|
38
|
+
declare function getNetworkConfig(networkOrChainId: Network | number): NetworkConfig | null;
|
|
39
|
+
/**
|
|
40
|
+
* Get token config by address (searches all networks)
|
|
41
|
+
*/
|
|
23
42
|
declare const getTokenByAddress: (address: Address) => {
|
|
24
43
|
symbol: TokenSymbol;
|
|
25
44
|
address: Address;
|
|
26
|
-
decimals:
|
|
27
|
-
supportsYield:
|
|
28
|
-
} | {
|
|
29
|
-
symbol: TokenSymbol;
|
|
30
|
-
address: Address;
|
|
31
|
-
decimals: 2;
|
|
32
|
-
supportsYield: false;
|
|
45
|
+
decimals: number;
|
|
46
|
+
supportsYield: boolean;
|
|
33
47
|
} | null;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
readonly symbol: "IDRX";
|
|
43
|
-
readonly supportsYield: false;
|
|
44
|
-
};
|
|
48
|
+
/**
|
|
49
|
+
* Get token config by symbol
|
|
50
|
+
*/
|
|
51
|
+
declare const getTokenBySymbol: (symbol: TokenSymbol) => TokenConfig;
|
|
52
|
+
/**
|
|
53
|
+
* Check if yield is available on a network
|
|
54
|
+
*/
|
|
55
|
+
declare function isYieldSupported(networkOrChainId: Network | number): boolean;
|
|
45
56
|
|
|
46
57
|
declare enum ParticipantStatus {
|
|
47
58
|
NOT_STAKED = 0,
|
|
@@ -186,6 +197,8 @@ interface EventSummary {
|
|
|
186
197
|
maxParticipants: number;
|
|
187
198
|
currentParticipants: number;
|
|
188
199
|
status: EventStatus;
|
|
200
|
+
tokenSymbol: string;
|
|
201
|
+
tokenDecimals: number;
|
|
189
202
|
}
|
|
190
203
|
interface ATFiSDKConfig {
|
|
191
204
|
/** Custom factory address (optional, defaults to mainnet) */
|
|
@@ -344,6 +357,26 @@ interface VaultWatchCallbacks {
|
|
|
344
357
|
/** Function to stop watching events */
|
|
345
358
|
type UnwatchFn = () => void;
|
|
346
359
|
|
|
360
|
+
/**
|
|
361
|
+
* Flexible public client type - accepts any viem-compatible client
|
|
362
|
+
* This allows SDK to work with different viem versions (e.g., from wagmi)
|
|
363
|
+
*/
|
|
364
|
+
type CompatiblePublicClient = PublicClient | {
|
|
365
|
+
readContract: any;
|
|
366
|
+
simulateContract: any;
|
|
367
|
+
waitForTransactionReceipt: any;
|
|
368
|
+
watchContractEvent: any;
|
|
369
|
+
estimateContractGas: any;
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* Flexible wallet client type - accepts any viem-compatible wallet
|
|
373
|
+
*/
|
|
374
|
+
type CompatibleWalletClient = WalletClient | {
|
|
375
|
+
account?: {
|
|
376
|
+
address: Address;
|
|
377
|
+
};
|
|
378
|
+
writeContract: any;
|
|
379
|
+
} | null;
|
|
347
380
|
/**
|
|
348
381
|
* ATFi SDK - TypeScript SDK for interacting with ATFi Protocol
|
|
349
382
|
*
|
|
@@ -357,7 +390,7 @@ type UnwatchFn = () => void;
|
|
|
357
390
|
*
|
|
358
391
|
* @example
|
|
359
392
|
* ```ts
|
|
360
|
-
* // Full mode (with wallet)
|
|
393
|
+
* // Full mode (with wallet) - works with wagmi clients directly!
|
|
361
394
|
* const sdk = new ATFiSDK(publicClient, walletClient);
|
|
362
395
|
*
|
|
363
396
|
* // Read-only mode (no wallet needed)
|
|
@@ -378,7 +411,13 @@ declare class ATFiSDK {
|
|
|
378
411
|
private walletClient;
|
|
379
412
|
private factoryAddress;
|
|
380
413
|
private _isReadOnly;
|
|
381
|
-
|
|
414
|
+
/**
|
|
415
|
+
* Create a new ATFi SDK instance
|
|
416
|
+
* @param publicClient - viem PublicClient (or wagmi's usePublicClient result)
|
|
417
|
+
* @param walletClient - viem WalletClient (or wagmi's useWalletClient result), optional for read-only
|
|
418
|
+
* @param config - Optional SDK configuration
|
|
419
|
+
*/
|
|
420
|
+
constructor(publicClient: CompatiblePublicClient, walletClient?: CompatibleWalletClient, config?: ATFiSDKConfig);
|
|
382
421
|
/**
|
|
383
422
|
* Create a read-only SDK instance (no wallet required)
|
|
384
423
|
* Use this to show event data before user connects wallet
|
|
@@ -390,7 +429,7 @@ declare class ATFiSDK {
|
|
|
390
429
|
* const info = await sdk.getEventInfo(vaultAddress);
|
|
391
430
|
* ```
|
|
392
431
|
*/
|
|
393
|
-
static readOnly(publicClient:
|
|
432
|
+
static readOnly(publicClient: CompatiblePublicClient, config?: ATFiSDKConfig): ATFiSDK;
|
|
394
433
|
/** Check if SDK is in read-only mode */
|
|
395
434
|
get isReadOnly(): boolean;
|
|
396
435
|
/** Get connected wallet address (null if read-only) */
|
|
@@ -592,6 +631,136 @@ declare class ATFiError extends Error {
|
|
|
592
631
|
*/
|
|
593
632
|
declare function parseContractError(error: unknown): ATFiError;
|
|
594
633
|
|
|
634
|
+
/**
|
|
635
|
+
* Shorten an address for display
|
|
636
|
+
* @param address Full address
|
|
637
|
+
* @param chars Number of characters to show on each side (default 4)
|
|
638
|
+
* @returns Shortened address like "0x1234...5678"
|
|
639
|
+
*
|
|
640
|
+
* @example
|
|
641
|
+
* shortenAddress('0x1234567890abcdef1234567890abcdef12345678')
|
|
642
|
+
* // => "0x1234...5678"
|
|
643
|
+
*/
|
|
644
|
+
declare function shortenAddress(address: Address | string, chars?: number): string;
|
|
645
|
+
/**
|
|
646
|
+
* Format amount for USD display
|
|
647
|
+
* @param amount Amount string or number
|
|
648
|
+
* @param decimals Decimal places (default 2)
|
|
649
|
+
* @returns Formatted string like "$10.50"
|
|
650
|
+
*
|
|
651
|
+
* @example
|
|
652
|
+
* formatUSD('1234.5')
|
|
653
|
+
* // => "$1,234.50"
|
|
654
|
+
*/
|
|
655
|
+
declare function formatUSD(amount: string | number, decimals?: number): string;
|
|
656
|
+
/**
|
|
657
|
+
* Format token amount with symbol
|
|
658
|
+
* @param amount Amount string or number
|
|
659
|
+
* @param symbol Token symbol
|
|
660
|
+
* @param decimals Decimal places (default 2)
|
|
661
|
+
* @returns Formatted string like "10.50 USDC"
|
|
662
|
+
*
|
|
663
|
+
* @example
|
|
664
|
+
* formatTokenAmount('1234.567', 'USDC')
|
|
665
|
+
* // => "1,234.57 USDC"
|
|
666
|
+
*/
|
|
667
|
+
declare function formatTokenAmount(amount: string | number, symbol: string, decimals?: number): string;
|
|
668
|
+
/**
|
|
669
|
+
* Format large numbers with abbreviations
|
|
670
|
+
* @param amount Amount to format
|
|
671
|
+
* @returns Abbreviated string like "1.2K", "3.4M"
|
|
672
|
+
*
|
|
673
|
+
* @example
|
|
674
|
+
* formatCompact(1234567)
|
|
675
|
+
* // => "1.2M"
|
|
676
|
+
*/
|
|
677
|
+
declare function formatCompact(amount: string | number): string;
|
|
678
|
+
/**
|
|
679
|
+
* Format percentage
|
|
680
|
+
* @param value Value to format (e.g., 0.15 for 15%)
|
|
681
|
+
* @param decimals Decimal places (default 2)
|
|
682
|
+
* @returns Formatted percentage like "15.00%"
|
|
683
|
+
*
|
|
684
|
+
* @example
|
|
685
|
+
* formatPercent(0.1567)
|
|
686
|
+
* // => "15.67%"
|
|
687
|
+
*/
|
|
688
|
+
declare function formatPercent(value: number, decimals?: number): string;
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Hook to create ATFi SDK from wagmi clients
|
|
692
|
+
*
|
|
693
|
+
* @example
|
|
694
|
+
* ```tsx
|
|
695
|
+
* import { usePublicClient, useWalletClient } from 'wagmi';
|
|
696
|
+
* import { useATFiSDK } from 'atfi/react';
|
|
697
|
+
*
|
|
698
|
+
* function MyComponent() {
|
|
699
|
+
* const publicClient = usePublicClient();
|
|
700
|
+
* const { data: walletClient } = useWalletClient();
|
|
701
|
+
* const { sdk, isReadOnly } = useATFiSDK(publicClient, walletClient);
|
|
702
|
+
*
|
|
703
|
+
* // Use sdk...
|
|
704
|
+
* }
|
|
705
|
+
* ```
|
|
706
|
+
*/
|
|
707
|
+
declare function useATFiSDK(publicClient: any, walletClient?: any, config?: ATFiSDKConfig): {
|
|
708
|
+
sdk: ATFiSDK | null;
|
|
709
|
+
isReadOnly: boolean;
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
interface UseEventInfoResult {
|
|
713
|
+
data: EventInfo | null;
|
|
714
|
+
isLoading: boolean;
|
|
715
|
+
error: Error | null;
|
|
716
|
+
refetch: () => Promise<void>;
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Hook to fetch and cache event info
|
|
720
|
+
*
|
|
721
|
+
* @example
|
|
722
|
+
* ```tsx
|
|
723
|
+
* const { data, isLoading, error, refetch } = useEventInfo(sdk, vaultAddress);
|
|
724
|
+
*
|
|
725
|
+
* if (isLoading) return <Spinner />;
|
|
726
|
+
* if (error) return <Error message={error.message} />;
|
|
727
|
+
*
|
|
728
|
+
* return <EventCard event={data} />;
|
|
729
|
+
* ```
|
|
730
|
+
*/
|
|
731
|
+
declare function useEventInfo(sdk: ATFiSDK | null, vaultAddress: Address | string | undefined): UseEventInfoResult;
|
|
732
|
+
|
|
733
|
+
interface WatchState {
|
|
734
|
+
participantCount: number;
|
|
735
|
+
verifiedCount: number;
|
|
736
|
+
isSettled: boolean;
|
|
737
|
+
lastClaim: {
|
|
738
|
+
participant: Address;
|
|
739
|
+
amount: string;
|
|
740
|
+
} | null;
|
|
741
|
+
}
|
|
742
|
+
interface UseWatchVaultResult extends WatchState {
|
|
743
|
+
isWatching: boolean;
|
|
744
|
+
}
|
|
745
|
+
/**
|
|
746
|
+
* Hook to watch vault events in real-time
|
|
747
|
+
* Automatically cleans up subscriptions on unmount
|
|
748
|
+
*
|
|
749
|
+
* @example
|
|
750
|
+
* ```tsx
|
|
751
|
+
* const { participantCount, verifiedCount, isSettled, isWatching } = useWatchVault(sdk, vaultAddress);
|
|
752
|
+
*
|
|
753
|
+
* return (
|
|
754
|
+
* <div>
|
|
755
|
+
* <p>Participants: {participantCount}</p>
|
|
756
|
+
* <p>Verified: {verifiedCount}</p>
|
|
757
|
+
* {isSettled && <ClaimButton />}
|
|
758
|
+
* </div>
|
|
759
|
+
* );
|
|
760
|
+
* ```
|
|
761
|
+
*/
|
|
762
|
+
declare function useWatchVault(sdk: ATFiSDK | null, vaultAddress: Address | string | undefined): UseWatchVaultResult;
|
|
763
|
+
|
|
595
764
|
declare const FactoryATFiABI: readonly [{
|
|
596
765
|
readonly inputs: readonly [{
|
|
597
766
|
readonly internalType: "address";
|
|
@@ -1754,4 +1923,4 @@ declare const ERC20ABI: readonly [{
|
|
|
1754
1923
|
readonly stateMutability: "view";
|
|
1755
1924
|
}];
|
|
1756
1925
|
|
|
1757
|
-
export { ATFiError, ATFiErrorCode, ATFiSDK, type ATFiSDKConfig, type ActionResult, CHAIN_ID, CONTRACTS, type ClaimAction, type ClaimParams, type ClaimResult, type CreateEventAction, type CreateEventParams, type CreateEventResult, ERC20ABI, type EventInfo, EventStatus, type EventSummary, FactoryATFiABI, type ParticipantInfo, ParticipantStatus, type RegisterAction, type RegisterParams, type RegisterResult, type SettleAction, type SettleEventParams, type SettleEventResult, type SimulateClaimResult, type SimulateCreateEventResult, type SimulateRegisterResult, type SimulateSettleResult, type SimulateStartEventResult, type SimulateVerifyResult, type SimulationBase, type StartEventAction, type StartEventParams, type StartEventResult, TOKENS, type TokenSymbol, type TransactionCallbacks, type UnwatchFn, type UserEventInfo, VaultATFiABI, type VaultWatchCallbacks, type VerifyAction, type VerifyParticipantParams, type VerifyParticipantResult, formatAmount, fromTokenUnits, getTokenByAddress, getTokenBySymbol, parseContractError, toTokenUnits };
|
|
1926
|
+
export { ATFiError, ATFiErrorCode, ATFiSDK, type ATFiSDKConfig, type ActionResult, CHAIN_ID, CONTRACTS, type ClaimAction, type ClaimParams, type ClaimResult, type CreateEventAction, type CreateEventParams, type CreateEventResult, ERC20ABI, type EventInfo, EventStatus, type EventSummary, FactoryATFiABI, NETWORKS, type Network, type NetworkConfig, type ParticipantInfo, ParticipantStatus, type RegisterAction, type RegisterParams, type RegisterResult, type SettleAction, type SettleEventParams, type SettleEventResult, type SimulateClaimResult, type SimulateCreateEventResult, type SimulateRegisterResult, type SimulateSettleResult, type SimulateStartEventResult, type SimulateVerifyResult, type SimulationBase, type StartEventAction, type StartEventParams, type StartEventResult, TOKENS, type TokenConfig, type TokenSymbol, type TransactionCallbacks, type UnwatchFn, type UserEventInfo, VaultATFiABI, type VaultWatchCallbacks, type VerifyAction, type VerifyParticipantParams, type VerifyParticipantResult, formatAmount, formatCompact, formatPercent, formatTokenAmount, formatUSD, fromTokenUnits, getNetworkConfig, getTokenByAddress, getTokenBySymbol, isYieldSupported, parseContractError, shortenAddress, toTokenUnits, useATFiSDK, useEventInfo, useWatchVault };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,47 +1,58 @@
|
|
|
1
1
|
import { Address, Hash, PublicClient, WalletClient } from 'viem';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
type Network = 'mainnet' | 'testnet';
|
|
4
|
+
interface NetworkConfig {
|
|
5
|
+
chainId: number;
|
|
6
|
+
name: string;
|
|
7
|
+
factory: Address;
|
|
8
|
+
morphoVault: Address | null;
|
|
9
|
+
supportsYield: boolean;
|
|
10
|
+
tokens: {
|
|
11
|
+
USDC: TokenConfig;
|
|
12
|
+
IDRX?: TokenConfig;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
interface TokenConfig {
|
|
16
|
+
address: Address;
|
|
17
|
+
decimals: number;
|
|
18
|
+
symbol: string;
|
|
19
|
+
supportsYield: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Network configurations for Base Mainnet and Sepolia Testnet
|
|
23
|
+
*/
|
|
24
|
+
declare const NETWORKS: Record<Network, NetworkConfig>;
|
|
25
|
+
declare const CHAIN_ID: number;
|
|
4
26
|
declare const CONTRACTS: {
|
|
5
|
-
readonly FACTORY:
|
|
6
|
-
readonly MORPHO_VAULT:
|
|
27
|
+
readonly FACTORY: `0x${string}`;
|
|
28
|
+
readonly MORPHO_VAULT: `0x${string}` | null;
|
|
7
29
|
};
|
|
8
30
|
declare const TOKENS: {
|
|
9
|
-
readonly USDC:
|
|
10
|
-
|
|
11
|
-
readonly decimals: 6;
|
|
12
|
-
readonly symbol: "USDC";
|
|
13
|
-
readonly supportsYield: true;
|
|
14
|
-
};
|
|
15
|
-
readonly IDRX: {
|
|
16
|
-
readonly address: Address;
|
|
17
|
-
readonly decimals: 2;
|
|
18
|
-
readonly symbol: "IDRX";
|
|
19
|
-
readonly supportsYield: false;
|
|
20
|
-
};
|
|
31
|
+
readonly USDC: TokenConfig;
|
|
32
|
+
readonly IDRX: TokenConfig;
|
|
21
33
|
};
|
|
22
34
|
type TokenSymbol = keyof typeof TOKENS;
|
|
35
|
+
/**
|
|
36
|
+
* Get network configuration by network name or chain ID
|
|
37
|
+
*/
|
|
38
|
+
declare function getNetworkConfig(networkOrChainId: Network | number): NetworkConfig | null;
|
|
39
|
+
/**
|
|
40
|
+
* Get token config by address (searches all networks)
|
|
41
|
+
*/
|
|
23
42
|
declare const getTokenByAddress: (address: Address) => {
|
|
24
43
|
symbol: TokenSymbol;
|
|
25
44
|
address: Address;
|
|
26
|
-
decimals:
|
|
27
|
-
supportsYield:
|
|
28
|
-
} | {
|
|
29
|
-
symbol: TokenSymbol;
|
|
30
|
-
address: Address;
|
|
31
|
-
decimals: 2;
|
|
32
|
-
supportsYield: false;
|
|
45
|
+
decimals: number;
|
|
46
|
+
supportsYield: boolean;
|
|
33
47
|
} | null;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
readonly symbol: "IDRX";
|
|
43
|
-
readonly supportsYield: false;
|
|
44
|
-
};
|
|
48
|
+
/**
|
|
49
|
+
* Get token config by symbol
|
|
50
|
+
*/
|
|
51
|
+
declare const getTokenBySymbol: (symbol: TokenSymbol) => TokenConfig;
|
|
52
|
+
/**
|
|
53
|
+
* Check if yield is available on a network
|
|
54
|
+
*/
|
|
55
|
+
declare function isYieldSupported(networkOrChainId: Network | number): boolean;
|
|
45
56
|
|
|
46
57
|
declare enum ParticipantStatus {
|
|
47
58
|
NOT_STAKED = 0,
|
|
@@ -186,6 +197,8 @@ interface EventSummary {
|
|
|
186
197
|
maxParticipants: number;
|
|
187
198
|
currentParticipants: number;
|
|
188
199
|
status: EventStatus;
|
|
200
|
+
tokenSymbol: string;
|
|
201
|
+
tokenDecimals: number;
|
|
189
202
|
}
|
|
190
203
|
interface ATFiSDKConfig {
|
|
191
204
|
/** Custom factory address (optional, defaults to mainnet) */
|
|
@@ -344,6 +357,26 @@ interface VaultWatchCallbacks {
|
|
|
344
357
|
/** Function to stop watching events */
|
|
345
358
|
type UnwatchFn = () => void;
|
|
346
359
|
|
|
360
|
+
/**
|
|
361
|
+
* Flexible public client type - accepts any viem-compatible client
|
|
362
|
+
* This allows SDK to work with different viem versions (e.g., from wagmi)
|
|
363
|
+
*/
|
|
364
|
+
type CompatiblePublicClient = PublicClient | {
|
|
365
|
+
readContract: any;
|
|
366
|
+
simulateContract: any;
|
|
367
|
+
waitForTransactionReceipt: any;
|
|
368
|
+
watchContractEvent: any;
|
|
369
|
+
estimateContractGas: any;
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* Flexible wallet client type - accepts any viem-compatible wallet
|
|
373
|
+
*/
|
|
374
|
+
type CompatibleWalletClient = WalletClient | {
|
|
375
|
+
account?: {
|
|
376
|
+
address: Address;
|
|
377
|
+
};
|
|
378
|
+
writeContract: any;
|
|
379
|
+
} | null;
|
|
347
380
|
/**
|
|
348
381
|
* ATFi SDK - TypeScript SDK for interacting with ATFi Protocol
|
|
349
382
|
*
|
|
@@ -357,7 +390,7 @@ type UnwatchFn = () => void;
|
|
|
357
390
|
*
|
|
358
391
|
* @example
|
|
359
392
|
* ```ts
|
|
360
|
-
* // Full mode (with wallet)
|
|
393
|
+
* // Full mode (with wallet) - works with wagmi clients directly!
|
|
361
394
|
* const sdk = new ATFiSDK(publicClient, walletClient);
|
|
362
395
|
*
|
|
363
396
|
* // Read-only mode (no wallet needed)
|
|
@@ -378,7 +411,13 @@ declare class ATFiSDK {
|
|
|
378
411
|
private walletClient;
|
|
379
412
|
private factoryAddress;
|
|
380
413
|
private _isReadOnly;
|
|
381
|
-
|
|
414
|
+
/**
|
|
415
|
+
* Create a new ATFi SDK instance
|
|
416
|
+
* @param publicClient - viem PublicClient (or wagmi's usePublicClient result)
|
|
417
|
+
* @param walletClient - viem WalletClient (or wagmi's useWalletClient result), optional for read-only
|
|
418
|
+
* @param config - Optional SDK configuration
|
|
419
|
+
*/
|
|
420
|
+
constructor(publicClient: CompatiblePublicClient, walletClient?: CompatibleWalletClient, config?: ATFiSDKConfig);
|
|
382
421
|
/**
|
|
383
422
|
* Create a read-only SDK instance (no wallet required)
|
|
384
423
|
* Use this to show event data before user connects wallet
|
|
@@ -390,7 +429,7 @@ declare class ATFiSDK {
|
|
|
390
429
|
* const info = await sdk.getEventInfo(vaultAddress);
|
|
391
430
|
* ```
|
|
392
431
|
*/
|
|
393
|
-
static readOnly(publicClient:
|
|
432
|
+
static readOnly(publicClient: CompatiblePublicClient, config?: ATFiSDKConfig): ATFiSDK;
|
|
394
433
|
/** Check if SDK is in read-only mode */
|
|
395
434
|
get isReadOnly(): boolean;
|
|
396
435
|
/** Get connected wallet address (null if read-only) */
|
|
@@ -592,6 +631,136 @@ declare class ATFiError extends Error {
|
|
|
592
631
|
*/
|
|
593
632
|
declare function parseContractError(error: unknown): ATFiError;
|
|
594
633
|
|
|
634
|
+
/**
|
|
635
|
+
* Shorten an address for display
|
|
636
|
+
* @param address Full address
|
|
637
|
+
* @param chars Number of characters to show on each side (default 4)
|
|
638
|
+
* @returns Shortened address like "0x1234...5678"
|
|
639
|
+
*
|
|
640
|
+
* @example
|
|
641
|
+
* shortenAddress('0x1234567890abcdef1234567890abcdef12345678')
|
|
642
|
+
* // => "0x1234...5678"
|
|
643
|
+
*/
|
|
644
|
+
declare function shortenAddress(address: Address | string, chars?: number): string;
|
|
645
|
+
/**
|
|
646
|
+
* Format amount for USD display
|
|
647
|
+
* @param amount Amount string or number
|
|
648
|
+
* @param decimals Decimal places (default 2)
|
|
649
|
+
* @returns Formatted string like "$10.50"
|
|
650
|
+
*
|
|
651
|
+
* @example
|
|
652
|
+
* formatUSD('1234.5')
|
|
653
|
+
* // => "$1,234.50"
|
|
654
|
+
*/
|
|
655
|
+
declare function formatUSD(amount: string | number, decimals?: number): string;
|
|
656
|
+
/**
|
|
657
|
+
* Format token amount with symbol
|
|
658
|
+
* @param amount Amount string or number
|
|
659
|
+
* @param symbol Token symbol
|
|
660
|
+
* @param decimals Decimal places (default 2)
|
|
661
|
+
* @returns Formatted string like "10.50 USDC"
|
|
662
|
+
*
|
|
663
|
+
* @example
|
|
664
|
+
* formatTokenAmount('1234.567', 'USDC')
|
|
665
|
+
* // => "1,234.57 USDC"
|
|
666
|
+
*/
|
|
667
|
+
declare function formatTokenAmount(amount: string | number, symbol: string, decimals?: number): string;
|
|
668
|
+
/**
|
|
669
|
+
* Format large numbers with abbreviations
|
|
670
|
+
* @param amount Amount to format
|
|
671
|
+
* @returns Abbreviated string like "1.2K", "3.4M"
|
|
672
|
+
*
|
|
673
|
+
* @example
|
|
674
|
+
* formatCompact(1234567)
|
|
675
|
+
* // => "1.2M"
|
|
676
|
+
*/
|
|
677
|
+
declare function formatCompact(amount: string | number): string;
|
|
678
|
+
/**
|
|
679
|
+
* Format percentage
|
|
680
|
+
* @param value Value to format (e.g., 0.15 for 15%)
|
|
681
|
+
* @param decimals Decimal places (default 2)
|
|
682
|
+
* @returns Formatted percentage like "15.00%"
|
|
683
|
+
*
|
|
684
|
+
* @example
|
|
685
|
+
* formatPercent(0.1567)
|
|
686
|
+
* // => "15.67%"
|
|
687
|
+
*/
|
|
688
|
+
declare function formatPercent(value: number, decimals?: number): string;
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Hook to create ATFi SDK from wagmi clients
|
|
692
|
+
*
|
|
693
|
+
* @example
|
|
694
|
+
* ```tsx
|
|
695
|
+
* import { usePublicClient, useWalletClient } from 'wagmi';
|
|
696
|
+
* import { useATFiSDK } from 'atfi/react';
|
|
697
|
+
*
|
|
698
|
+
* function MyComponent() {
|
|
699
|
+
* const publicClient = usePublicClient();
|
|
700
|
+
* const { data: walletClient } = useWalletClient();
|
|
701
|
+
* const { sdk, isReadOnly } = useATFiSDK(publicClient, walletClient);
|
|
702
|
+
*
|
|
703
|
+
* // Use sdk...
|
|
704
|
+
* }
|
|
705
|
+
* ```
|
|
706
|
+
*/
|
|
707
|
+
declare function useATFiSDK(publicClient: any, walletClient?: any, config?: ATFiSDKConfig): {
|
|
708
|
+
sdk: ATFiSDK | null;
|
|
709
|
+
isReadOnly: boolean;
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
interface UseEventInfoResult {
|
|
713
|
+
data: EventInfo | null;
|
|
714
|
+
isLoading: boolean;
|
|
715
|
+
error: Error | null;
|
|
716
|
+
refetch: () => Promise<void>;
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Hook to fetch and cache event info
|
|
720
|
+
*
|
|
721
|
+
* @example
|
|
722
|
+
* ```tsx
|
|
723
|
+
* const { data, isLoading, error, refetch } = useEventInfo(sdk, vaultAddress);
|
|
724
|
+
*
|
|
725
|
+
* if (isLoading) return <Spinner />;
|
|
726
|
+
* if (error) return <Error message={error.message} />;
|
|
727
|
+
*
|
|
728
|
+
* return <EventCard event={data} />;
|
|
729
|
+
* ```
|
|
730
|
+
*/
|
|
731
|
+
declare function useEventInfo(sdk: ATFiSDK | null, vaultAddress: Address | string | undefined): UseEventInfoResult;
|
|
732
|
+
|
|
733
|
+
interface WatchState {
|
|
734
|
+
participantCount: number;
|
|
735
|
+
verifiedCount: number;
|
|
736
|
+
isSettled: boolean;
|
|
737
|
+
lastClaim: {
|
|
738
|
+
participant: Address;
|
|
739
|
+
amount: string;
|
|
740
|
+
} | null;
|
|
741
|
+
}
|
|
742
|
+
interface UseWatchVaultResult extends WatchState {
|
|
743
|
+
isWatching: boolean;
|
|
744
|
+
}
|
|
745
|
+
/**
|
|
746
|
+
* Hook to watch vault events in real-time
|
|
747
|
+
* Automatically cleans up subscriptions on unmount
|
|
748
|
+
*
|
|
749
|
+
* @example
|
|
750
|
+
* ```tsx
|
|
751
|
+
* const { participantCount, verifiedCount, isSettled, isWatching } = useWatchVault(sdk, vaultAddress);
|
|
752
|
+
*
|
|
753
|
+
* return (
|
|
754
|
+
* <div>
|
|
755
|
+
* <p>Participants: {participantCount}</p>
|
|
756
|
+
* <p>Verified: {verifiedCount}</p>
|
|
757
|
+
* {isSettled && <ClaimButton />}
|
|
758
|
+
* </div>
|
|
759
|
+
* );
|
|
760
|
+
* ```
|
|
761
|
+
*/
|
|
762
|
+
declare function useWatchVault(sdk: ATFiSDK | null, vaultAddress: Address | string | undefined): UseWatchVaultResult;
|
|
763
|
+
|
|
595
764
|
declare const FactoryATFiABI: readonly [{
|
|
596
765
|
readonly inputs: readonly [{
|
|
597
766
|
readonly internalType: "address";
|
|
@@ -1754,4 +1923,4 @@ declare const ERC20ABI: readonly [{
|
|
|
1754
1923
|
readonly stateMutability: "view";
|
|
1755
1924
|
}];
|
|
1756
1925
|
|
|
1757
|
-
export { ATFiError, ATFiErrorCode, ATFiSDK, type ATFiSDKConfig, type ActionResult, CHAIN_ID, CONTRACTS, type ClaimAction, type ClaimParams, type ClaimResult, type CreateEventAction, type CreateEventParams, type CreateEventResult, ERC20ABI, type EventInfo, EventStatus, type EventSummary, FactoryATFiABI, type ParticipantInfo, ParticipantStatus, type RegisterAction, type RegisterParams, type RegisterResult, type SettleAction, type SettleEventParams, type SettleEventResult, type SimulateClaimResult, type SimulateCreateEventResult, type SimulateRegisterResult, type SimulateSettleResult, type SimulateStartEventResult, type SimulateVerifyResult, type SimulationBase, type StartEventAction, type StartEventParams, type StartEventResult, TOKENS, type TokenSymbol, type TransactionCallbacks, type UnwatchFn, type UserEventInfo, VaultATFiABI, type VaultWatchCallbacks, type VerifyAction, type VerifyParticipantParams, type VerifyParticipantResult, formatAmount, fromTokenUnits, getTokenByAddress, getTokenBySymbol, parseContractError, toTokenUnits };
|
|
1926
|
+
export { ATFiError, ATFiErrorCode, ATFiSDK, type ATFiSDKConfig, type ActionResult, CHAIN_ID, CONTRACTS, type ClaimAction, type ClaimParams, type ClaimResult, type CreateEventAction, type CreateEventParams, type CreateEventResult, ERC20ABI, type EventInfo, EventStatus, type EventSummary, FactoryATFiABI, NETWORKS, type Network, type NetworkConfig, type ParticipantInfo, ParticipantStatus, type RegisterAction, type RegisterParams, type RegisterResult, type SettleAction, type SettleEventParams, type SettleEventResult, type SimulateClaimResult, type SimulateCreateEventResult, type SimulateRegisterResult, type SimulateSettleResult, type SimulateStartEventResult, type SimulateVerifyResult, type SimulationBase, type StartEventAction, type StartEventParams, type StartEventResult, TOKENS, type TokenConfig, type TokenSymbol, type TransactionCallbacks, type UnwatchFn, type UserEventInfo, VaultATFiABI, type VaultWatchCallbacks, type VerifyAction, type VerifyParticipantParams, type VerifyParticipantResult, formatAmount, formatCompact, formatPercent, formatTokenAmount, formatUSD, fromTokenUnits, getNetworkConfig, getTokenByAddress, getTokenBySymbol, isYieldSupported, parseContractError, shortenAddress, toTokenUnits, useATFiSDK, useEventInfo, useWatchVault };
|
package/dist/index.js
CHANGED
|
@@ -28,15 +28,26 @@ __export(index_exports, {
|
|
|
28
28
|
ERC20ABI: () => ERC20ABI,
|
|
29
29
|
EventStatus: () => EventStatus,
|
|
30
30
|
FactoryATFiABI: () => FactoryATFiABI,
|
|
31
|
+
NETWORKS: () => NETWORKS,
|
|
31
32
|
ParticipantStatus: () => ParticipantStatus,
|
|
32
33
|
TOKENS: () => TOKENS,
|
|
33
34
|
VaultATFiABI: () => VaultATFiABI,
|
|
34
35
|
formatAmount: () => formatAmount,
|
|
36
|
+
formatCompact: () => formatCompact,
|
|
37
|
+
formatPercent: () => formatPercent,
|
|
38
|
+
formatTokenAmount: () => formatTokenAmount,
|
|
39
|
+
formatUSD: () => formatUSD,
|
|
35
40
|
fromTokenUnits: () => fromTokenUnits,
|
|
41
|
+
getNetworkConfig: () => getNetworkConfig,
|
|
36
42
|
getTokenByAddress: () => getTokenByAddress,
|
|
37
43
|
getTokenBySymbol: () => getTokenBySymbol,
|
|
44
|
+
isYieldSupported: () => isYieldSupported,
|
|
38
45
|
parseContractError: () => parseContractError,
|
|
39
|
-
|
|
46
|
+
shortenAddress: () => shortenAddress,
|
|
47
|
+
toTokenUnits: () => toTokenUnits,
|
|
48
|
+
useATFiSDK: () => useATFiSDK,
|
|
49
|
+
useEventInfo: () => useEventInfo,
|
|
50
|
+
useWatchVault: () => useWatchVault
|
|
40
51
|
});
|
|
41
52
|
module.exports = __toCommonJS(index_exports);
|
|
42
53
|
|
|
@@ -95,30 +106,74 @@ var ERC20ABI = [
|
|
|
95
106
|
];
|
|
96
107
|
|
|
97
108
|
// src/constants/addresses.ts
|
|
98
|
-
var
|
|
109
|
+
var NETWORKS = {
|
|
110
|
+
mainnet: {
|
|
111
|
+
chainId: 8453,
|
|
112
|
+
name: "Base",
|
|
113
|
+
factory: "0x0be05a5fa7116c1b33f2b0036eb0d9690db9075f",
|
|
114
|
+
morphoVault: "0x050cE30b927Da55177A4914EC73480238BAD56f0",
|
|
115
|
+
supportsYield: true,
|
|
116
|
+
tokens: {
|
|
117
|
+
USDC: {
|
|
118
|
+
address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
119
|
+
decimals: 6,
|
|
120
|
+
symbol: "USDC",
|
|
121
|
+
supportsYield: true
|
|
122
|
+
},
|
|
123
|
+
IDRX: {
|
|
124
|
+
address: "0x18Bc5bcC660cf2B9cE3cd51a404aFe1a0cBD3C22",
|
|
125
|
+
decimals: 2,
|
|
126
|
+
symbol: "IDRX",
|
|
127
|
+
supportsYield: false
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
testnet: {
|
|
132
|
+
chainId: 84532,
|
|
133
|
+
// Base Sepolia
|
|
134
|
+
name: "Base Sepolia",
|
|
135
|
+
factory: "0xf1EA206029549A8c4e2EB960F7ac43A98E922A49",
|
|
136
|
+
morphoVault: null,
|
|
137
|
+
// No Morpho on testnet
|
|
138
|
+
supportsYield: false,
|
|
139
|
+
tokens: {
|
|
140
|
+
USDC: {
|
|
141
|
+
address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
142
|
+
// Base Sepolia USDC
|
|
143
|
+
decimals: 6,
|
|
144
|
+
symbol: "USDC",
|
|
145
|
+
supportsYield: false
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
var CHAIN_ID = NETWORKS.mainnet.chainId;
|
|
99
151
|
var CONTRACTS = {
|
|
100
|
-
FACTORY:
|
|
101
|
-
MORPHO_VAULT:
|
|
152
|
+
FACTORY: NETWORKS.mainnet.factory,
|
|
153
|
+
MORPHO_VAULT: NETWORKS.mainnet.morphoVault
|
|
102
154
|
};
|
|
103
155
|
var TOKENS = {
|
|
104
|
-
USDC:
|
|
105
|
-
|
|
106
|
-
decimals: 6,
|
|
107
|
-
symbol: "USDC",
|
|
108
|
-
supportsYield: true
|
|
109
|
-
},
|
|
110
|
-
IDRX: {
|
|
111
|
-
address: "0x18Bc5bcC660cf2B9cE3cd51a404aFe1a0cBD3C22",
|
|
112
|
-
decimals: 2,
|
|
113
|
-
symbol: "IDRX",
|
|
114
|
-
supportsYield: false
|
|
115
|
-
}
|
|
156
|
+
USDC: NETWORKS.mainnet.tokens.USDC,
|
|
157
|
+
IDRX: NETWORKS.mainnet.tokens.IDRX
|
|
116
158
|
};
|
|
159
|
+
function getNetworkConfig(networkOrChainId) {
|
|
160
|
+
if (typeof networkOrChainId === "string") {
|
|
161
|
+
return NETWORKS[networkOrChainId] || null;
|
|
162
|
+
}
|
|
163
|
+
for (const config of Object.values(NETWORKS)) {
|
|
164
|
+
if (config.chainId === networkOrChainId) {
|
|
165
|
+
return config;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
117
170
|
var getTokenByAddress = (address) => {
|
|
118
171
|
const normalizedAddress = address.toLowerCase();
|
|
119
|
-
for (const
|
|
120
|
-
|
|
121
|
-
|
|
172
|
+
for (const network of Object.values(NETWORKS)) {
|
|
173
|
+
for (const [sym, token] of Object.entries(network.tokens)) {
|
|
174
|
+
if (token.address.toLowerCase() === normalizedAddress) {
|
|
175
|
+
return { ...token, symbol: sym };
|
|
176
|
+
}
|
|
122
177
|
}
|
|
123
178
|
}
|
|
124
179
|
return null;
|
|
@@ -126,6 +181,10 @@ var getTokenByAddress = (address) => {
|
|
|
126
181
|
var getTokenBySymbol = (symbol) => {
|
|
127
182
|
return TOKENS[symbol];
|
|
128
183
|
};
|
|
184
|
+
function isYieldSupported(networkOrChainId) {
|
|
185
|
+
const config = getNetworkConfig(networkOrChainId);
|
|
186
|
+
return config?.supportsYield ?? false;
|
|
187
|
+
}
|
|
129
188
|
|
|
130
189
|
// src/utils/decimals.ts
|
|
131
190
|
var import_viem = require("viem");
|
|
@@ -241,6 +300,12 @@ var EventStatus = /* @__PURE__ */ ((EventStatus2) => {
|
|
|
241
300
|
|
|
242
301
|
// src/ATFiSDK.ts
|
|
243
302
|
var ATFiSDK = class _ATFiSDK {
|
|
303
|
+
/**
|
|
304
|
+
* Create a new ATFi SDK instance
|
|
305
|
+
* @param publicClient - viem PublicClient (or wagmi's usePublicClient result)
|
|
306
|
+
* @param walletClient - viem WalletClient (or wagmi's useWalletClient result), optional for read-only
|
|
307
|
+
* @param config - Optional SDK configuration
|
|
308
|
+
*/
|
|
244
309
|
constructor(publicClient, walletClient, config) {
|
|
245
310
|
this.publicClient = publicClient;
|
|
246
311
|
this.walletClient = walletClient ? walletClient : null;
|
|
@@ -822,7 +887,9 @@ var ATFiSDK = class _ATFiSDK {
|
|
|
822
887
|
stakeAmount: info.stakeAmount,
|
|
823
888
|
maxParticipants: info.maxParticipants,
|
|
824
889
|
currentParticipants: info.currentParticipants,
|
|
825
|
-
status
|
|
890
|
+
status,
|
|
891
|
+
tokenSymbol: info.tokenSymbol,
|
|
892
|
+
tokenDecimals: info.tokenDecimals
|
|
826
893
|
};
|
|
827
894
|
});
|
|
828
895
|
}
|
|
@@ -1388,6 +1455,150 @@ var ATFiSDK = class _ATFiSDK {
|
|
|
1388
1455
|
return { txHash: hash, amountClaimed: fromTokenUnits(claimable, decimals) };
|
|
1389
1456
|
}
|
|
1390
1457
|
};
|
|
1458
|
+
|
|
1459
|
+
// src/utils/formatting.ts
|
|
1460
|
+
function shortenAddress(address, chars = 4) {
|
|
1461
|
+
if (!address) return "";
|
|
1462
|
+
const start = address.slice(0, chars + 2);
|
|
1463
|
+
const end = address.slice(-chars);
|
|
1464
|
+
return `${start}...${end}`;
|
|
1465
|
+
}
|
|
1466
|
+
function formatUSD(amount, decimals = 2) {
|
|
1467
|
+
const num = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
1468
|
+
if (isNaN(num)) return "$0.00";
|
|
1469
|
+
return new Intl.NumberFormat("en-US", {
|
|
1470
|
+
style: "currency",
|
|
1471
|
+
currency: "USD",
|
|
1472
|
+
minimumFractionDigits: decimals,
|
|
1473
|
+
maximumFractionDigits: decimals
|
|
1474
|
+
}).format(num);
|
|
1475
|
+
}
|
|
1476
|
+
function formatTokenAmount(amount, symbol, decimals = 2) {
|
|
1477
|
+
const num = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
1478
|
+
if (isNaN(num)) return `0 ${symbol}`;
|
|
1479
|
+
const formatted = new Intl.NumberFormat("en-US", {
|
|
1480
|
+
minimumFractionDigits: decimals,
|
|
1481
|
+
maximumFractionDigits: decimals
|
|
1482
|
+
}).format(num);
|
|
1483
|
+
return `${formatted} ${symbol}`;
|
|
1484
|
+
}
|
|
1485
|
+
function formatCompact(amount) {
|
|
1486
|
+
const num = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
1487
|
+
if (isNaN(num)) return "0";
|
|
1488
|
+
return new Intl.NumberFormat("en-US", {
|
|
1489
|
+
notation: "compact",
|
|
1490
|
+
maximumFractionDigits: 1
|
|
1491
|
+
}).format(num);
|
|
1492
|
+
}
|
|
1493
|
+
function formatPercent(value, decimals = 2) {
|
|
1494
|
+
return `${(value * 100).toFixed(decimals)}%`;
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
// src/react/useATFiSDK.ts
|
|
1498
|
+
var import_react = require("react");
|
|
1499
|
+
function useATFiSDK(publicClient, walletClient, config) {
|
|
1500
|
+
const sdk = (0, import_react.useMemo)(() => {
|
|
1501
|
+
if (!publicClient) return null;
|
|
1502
|
+
if (walletClient) {
|
|
1503
|
+
return new ATFiSDK(publicClient, walletClient, config);
|
|
1504
|
+
}
|
|
1505
|
+
return ATFiSDK.readOnly(publicClient, config);
|
|
1506
|
+
}, [publicClient, walletClient, config]);
|
|
1507
|
+
return {
|
|
1508
|
+
sdk,
|
|
1509
|
+
isReadOnly: !walletClient
|
|
1510
|
+
};
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
// src/react/useEventInfo.ts
|
|
1514
|
+
var import_react2 = require("react");
|
|
1515
|
+
function useEventInfo(sdk, vaultAddress) {
|
|
1516
|
+
const [data, setData] = (0, import_react2.useState)(null);
|
|
1517
|
+
const [isLoading, setIsLoading] = (0, import_react2.useState)(false);
|
|
1518
|
+
const [error, setError] = (0, import_react2.useState)(null);
|
|
1519
|
+
const fetchData = (0, import_react2.useCallback)(async () => {
|
|
1520
|
+
if (!sdk || !vaultAddress) {
|
|
1521
|
+
setData(null);
|
|
1522
|
+
return;
|
|
1523
|
+
}
|
|
1524
|
+
setIsLoading(true);
|
|
1525
|
+
setError(null);
|
|
1526
|
+
try {
|
|
1527
|
+
const info = await sdk.getEventInfo(vaultAddress);
|
|
1528
|
+
setData(info);
|
|
1529
|
+
} catch (err) {
|
|
1530
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch event info"));
|
|
1531
|
+
setData(null);
|
|
1532
|
+
} finally {
|
|
1533
|
+
setIsLoading(false);
|
|
1534
|
+
}
|
|
1535
|
+
}, [sdk, vaultAddress]);
|
|
1536
|
+
(0, import_react2.useEffect)(() => {
|
|
1537
|
+
fetchData();
|
|
1538
|
+
}, [fetchData]);
|
|
1539
|
+
return {
|
|
1540
|
+
data,
|
|
1541
|
+
isLoading,
|
|
1542
|
+
error,
|
|
1543
|
+
refetch: fetchData
|
|
1544
|
+
};
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
// src/react/useWatchVault.ts
|
|
1548
|
+
var import_react3 = require("react");
|
|
1549
|
+
function useWatchVault(sdk, vaultAddress) {
|
|
1550
|
+
const [state, setState] = (0, import_react3.useState)({
|
|
1551
|
+
participantCount: 0,
|
|
1552
|
+
verifiedCount: 0,
|
|
1553
|
+
isSettled: false,
|
|
1554
|
+
lastClaim: null
|
|
1555
|
+
});
|
|
1556
|
+
const [isWatching, setIsWatching] = (0, import_react3.useState)(false);
|
|
1557
|
+
const unwatchRef = (0, import_react3.useRef)(null);
|
|
1558
|
+
(0, import_react3.useEffect)(() => {
|
|
1559
|
+
if (!sdk || !vaultAddress) {
|
|
1560
|
+
setIsWatching(false);
|
|
1561
|
+
return;
|
|
1562
|
+
}
|
|
1563
|
+
if (unwatchRef.current) {
|
|
1564
|
+
unwatchRef.current();
|
|
1565
|
+
}
|
|
1566
|
+
try {
|
|
1567
|
+
unwatchRef.current = sdk.watchVault(vaultAddress, {
|
|
1568
|
+
onParticipantJoined: (_participant, totalParticipants) => {
|
|
1569
|
+
setState((prev) => ({ ...prev, participantCount: totalParticipants }));
|
|
1570
|
+
},
|
|
1571
|
+
onParticipantVerified: (_participant, totalVerified) => {
|
|
1572
|
+
setState((prev) => ({ ...prev, verifiedCount: totalVerified }));
|
|
1573
|
+
},
|
|
1574
|
+
onSettled: () => {
|
|
1575
|
+
setState((prev) => ({ ...prev, isSettled: true }));
|
|
1576
|
+
},
|
|
1577
|
+
onClaimed: (participant, amount) => {
|
|
1578
|
+
setState((prev) => ({ ...prev, lastClaim: { participant, amount } }));
|
|
1579
|
+
},
|
|
1580
|
+
onError: (error) => {
|
|
1581
|
+
console.error("[useWatchVault]", error);
|
|
1582
|
+
}
|
|
1583
|
+
});
|
|
1584
|
+
setIsWatching(true);
|
|
1585
|
+
} catch (err) {
|
|
1586
|
+
console.error("[useWatchVault] Failed to start watching:", err);
|
|
1587
|
+
setIsWatching(false);
|
|
1588
|
+
}
|
|
1589
|
+
return () => {
|
|
1590
|
+
if (unwatchRef.current) {
|
|
1591
|
+
unwatchRef.current();
|
|
1592
|
+
unwatchRef.current = null;
|
|
1593
|
+
}
|
|
1594
|
+
setIsWatching(false);
|
|
1595
|
+
};
|
|
1596
|
+
}, [sdk, vaultAddress]);
|
|
1597
|
+
return {
|
|
1598
|
+
...state,
|
|
1599
|
+
isWatching
|
|
1600
|
+
};
|
|
1601
|
+
}
|
|
1391
1602
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1392
1603
|
0 && (module.exports = {
|
|
1393
1604
|
ATFiError,
|
|
@@ -1398,13 +1609,24 @@ var ATFiSDK = class _ATFiSDK {
|
|
|
1398
1609
|
ERC20ABI,
|
|
1399
1610
|
EventStatus,
|
|
1400
1611
|
FactoryATFiABI,
|
|
1612
|
+
NETWORKS,
|
|
1401
1613
|
ParticipantStatus,
|
|
1402
1614
|
TOKENS,
|
|
1403
1615
|
VaultATFiABI,
|
|
1404
1616
|
formatAmount,
|
|
1617
|
+
formatCompact,
|
|
1618
|
+
formatPercent,
|
|
1619
|
+
formatTokenAmount,
|
|
1620
|
+
formatUSD,
|
|
1405
1621
|
fromTokenUnits,
|
|
1622
|
+
getNetworkConfig,
|
|
1406
1623
|
getTokenByAddress,
|
|
1407
1624
|
getTokenBySymbol,
|
|
1625
|
+
isYieldSupported,
|
|
1408
1626
|
parseContractError,
|
|
1409
|
-
|
|
1627
|
+
shortenAddress,
|
|
1628
|
+
toTokenUnits,
|
|
1629
|
+
useATFiSDK,
|
|
1630
|
+
useEventInfo,
|
|
1631
|
+
useWatchVault
|
|
1410
1632
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -55,30 +55,74 @@ var ERC20ABI = [
|
|
|
55
55
|
];
|
|
56
56
|
|
|
57
57
|
// src/constants/addresses.ts
|
|
58
|
-
var
|
|
58
|
+
var NETWORKS = {
|
|
59
|
+
mainnet: {
|
|
60
|
+
chainId: 8453,
|
|
61
|
+
name: "Base",
|
|
62
|
+
factory: "0x0be05a5fa7116c1b33f2b0036eb0d9690db9075f",
|
|
63
|
+
morphoVault: "0x050cE30b927Da55177A4914EC73480238BAD56f0",
|
|
64
|
+
supportsYield: true,
|
|
65
|
+
tokens: {
|
|
66
|
+
USDC: {
|
|
67
|
+
address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
68
|
+
decimals: 6,
|
|
69
|
+
symbol: "USDC",
|
|
70
|
+
supportsYield: true
|
|
71
|
+
},
|
|
72
|
+
IDRX: {
|
|
73
|
+
address: "0x18Bc5bcC660cf2B9cE3cd51a404aFe1a0cBD3C22",
|
|
74
|
+
decimals: 2,
|
|
75
|
+
symbol: "IDRX",
|
|
76
|
+
supportsYield: false
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
testnet: {
|
|
81
|
+
chainId: 84532,
|
|
82
|
+
// Base Sepolia
|
|
83
|
+
name: "Base Sepolia",
|
|
84
|
+
factory: "0xf1EA206029549A8c4e2EB960F7ac43A98E922A49",
|
|
85
|
+
morphoVault: null,
|
|
86
|
+
// No Morpho on testnet
|
|
87
|
+
supportsYield: false,
|
|
88
|
+
tokens: {
|
|
89
|
+
USDC: {
|
|
90
|
+
address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
91
|
+
// Base Sepolia USDC
|
|
92
|
+
decimals: 6,
|
|
93
|
+
symbol: "USDC",
|
|
94
|
+
supportsYield: false
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
var CHAIN_ID = NETWORKS.mainnet.chainId;
|
|
59
100
|
var CONTRACTS = {
|
|
60
|
-
FACTORY:
|
|
61
|
-
MORPHO_VAULT:
|
|
101
|
+
FACTORY: NETWORKS.mainnet.factory,
|
|
102
|
+
MORPHO_VAULT: NETWORKS.mainnet.morphoVault
|
|
62
103
|
};
|
|
63
104
|
var TOKENS = {
|
|
64
|
-
USDC:
|
|
65
|
-
|
|
66
|
-
decimals: 6,
|
|
67
|
-
symbol: "USDC",
|
|
68
|
-
supportsYield: true
|
|
69
|
-
},
|
|
70
|
-
IDRX: {
|
|
71
|
-
address: "0x18Bc5bcC660cf2B9cE3cd51a404aFe1a0cBD3C22",
|
|
72
|
-
decimals: 2,
|
|
73
|
-
symbol: "IDRX",
|
|
74
|
-
supportsYield: false
|
|
75
|
-
}
|
|
105
|
+
USDC: NETWORKS.mainnet.tokens.USDC,
|
|
106
|
+
IDRX: NETWORKS.mainnet.tokens.IDRX
|
|
76
107
|
};
|
|
108
|
+
function getNetworkConfig(networkOrChainId) {
|
|
109
|
+
if (typeof networkOrChainId === "string") {
|
|
110
|
+
return NETWORKS[networkOrChainId] || null;
|
|
111
|
+
}
|
|
112
|
+
for (const config of Object.values(NETWORKS)) {
|
|
113
|
+
if (config.chainId === networkOrChainId) {
|
|
114
|
+
return config;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
77
119
|
var getTokenByAddress = (address) => {
|
|
78
120
|
const normalizedAddress = address.toLowerCase();
|
|
79
|
-
for (const
|
|
80
|
-
|
|
81
|
-
|
|
121
|
+
for (const network of Object.values(NETWORKS)) {
|
|
122
|
+
for (const [sym, token] of Object.entries(network.tokens)) {
|
|
123
|
+
if (token.address.toLowerCase() === normalizedAddress) {
|
|
124
|
+
return { ...token, symbol: sym };
|
|
125
|
+
}
|
|
82
126
|
}
|
|
83
127
|
}
|
|
84
128
|
return null;
|
|
@@ -86,6 +130,10 @@ var getTokenByAddress = (address) => {
|
|
|
86
130
|
var getTokenBySymbol = (symbol) => {
|
|
87
131
|
return TOKENS[symbol];
|
|
88
132
|
};
|
|
133
|
+
function isYieldSupported(networkOrChainId) {
|
|
134
|
+
const config = getNetworkConfig(networkOrChainId);
|
|
135
|
+
return config?.supportsYield ?? false;
|
|
136
|
+
}
|
|
89
137
|
|
|
90
138
|
// src/utils/decimals.ts
|
|
91
139
|
import { parseUnits, formatUnits } from "viem";
|
|
@@ -201,6 +249,12 @@ var EventStatus = /* @__PURE__ */ ((EventStatus2) => {
|
|
|
201
249
|
|
|
202
250
|
// src/ATFiSDK.ts
|
|
203
251
|
var ATFiSDK = class _ATFiSDK {
|
|
252
|
+
/**
|
|
253
|
+
* Create a new ATFi SDK instance
|
|
254
|
+
* @param publicClient - viem PublicClient (or wagmi's usePublicClient result)
|
|
255
|
+
* @param walletClient - viem WalletClient (or wagmi's useWalletClient result), optional for read-only
|
|
256
|
+
* @param config - Optional SDK configuration
|
|
257
|
+
*/
|
|
204
258
|
constructor(publicClient, walletClient, config) {
|
|
205
259
|
this.publicClient = publicClient;
|
|
206
260
|
this.walletClient = walletClient ? walletClient : null;
|
|
@@ -782,7 +836,9 @@ var ATFiSDK = class _ATFiSDK {
|
|
|
782
836
|
stakeAmount: info.stakeAmount,
|
|
783
837
|
maxParticipants: info.maxParticipants,
|
|
784
838
|
currentParticipants: info.currentParticipants,
|
|
785
|
-
status
|
|
839
|
+
status,
|
|
840
|
+
tokenSymbol: info.tokenSymbol,
|
|
841
|
+
tokenDecimals: info.tokenDecimals
|
|
786
842
|
};
|
|
787
843
|
});
|
|
788
844
|
}
|
|
@@ -1348,6 +1404,150 @@ var ATFiSDK = class _ATFiSDK {
|
|
|
1348
1404
|
return { txHash: hash, amountClaimed: fromTokenUnits(claimable, decimals) };
|
|
1349
1405
|
}
|
|
1350
1406
|
};
|
|
1407
|
+
|
|
1408
|
+
// src/utils/formatting.ts
|
|
1409
|
+
function shortenAddress(address, chars = 4) {
|
|
1410
|
+
if (!address) return "";
|
|
1411
|
+
const start = address.slice(0, chars + 2);
|
|
1412
|
+
const end = address.slice(-chars);
|
|
1413
|
+
return `${start}...${end}`;
|
|
1414
|
+
}
|
|
1415
|
+
function formatUSD(amount, decimals = 2) {
|
|
1416
|
+
const num = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
1417
|
+
if (isNaN(num)) return "$0.00";
|
|
1418
|
+
return new Intl.NumberFormat("en-US", {
|
|
1419
|
+
style: "currency",
|
|
1420
|
+
currency: "USD",
|
|
1421
|
+
minimumFractionDigits: decimals,
|
|
1422
|
+
maximumFractionDigits: decimals
|
|
1423
|
+
}).format(num);
|
|
1424
|
+
}
|
|
1425
|
+
function formatTokenAmount(amount, symbol, decimals = 2) {
|
|
1426
|
+
const num = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
1427
|
+
if (isNaN(num)) return `0 ${symbol}`;
|
|
1428
|
+
const formatted = new Intl.NumberFormat("en-US", {
|
|
1429
|
+
minimumFractionDigits: decimals,
|
|
1430
|
+
maximumFractionDigits: decimals
|
|
1431
|
+
}).format(num);
|
|
1432
|
+
return `${formatted} ${symbol}`;
|
|
1433
|
+
}
|
|
1434
|
+
function formatCompact(amount) {
|
|
1435
|
+
const num = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
1436
|
+
if (isNaN(num)) return "0";
|
|
1437
|
+
return new Intl.NumberFormat("en-US", {
|
|
1438
|
+
notation: "compact",
|
|
1439
|
+
maximumFractionDigits: 1
|
|
1440
|
+
}).format(num);
|
|
1441
|
+
}
|
|
1442
|
+
function formatPercent(value, decimals = 2) {
|
|
1443
|
+
return `${(value * 100).toFixed(decimals)}%`;
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
// src/react/useATFiSDK.ts
|
|
1447
|
+
import { useMemo } from "react";
|
|
1448
|
+
function useATFiSDK(publicClient, walletClient, config) {
|
|
1449
|
+
const sdk = useMemo(() => {
|
|
1450
|
+
if (!publicClient) return null;
|
|
1451
|
+
if (walletClient) {
|
|
1452
|
+
return new ATFiSDK(publicClient, walletClient, config);
|
|
1453
|
+
}
|
|
1454
|
+
return ATFiSDK.readOnly(publicClient, config);
|
|
1455
|
+
}, [publicClient, walletClient, config]);
|
|
1456
|
+
return {
|
|
1457
|
+
sdk,
|
|
1458
|
+
isReadOnly: !walletClient
|
|
1459
|
+
};
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
// src/react/useEventInfo.ts
|
|
1463
|
+
import { useState, useEffect, useCallback } from "react";
|
|
1464
|
+
function useEventInfo(sdk, vaultAddress) {
|
|
1465
|
+
const [data, setData] = useState(null);
|
|
1466
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
1467
|
+
const [error, setError] = useState(null);
|
|
1468
|
+
const fetchData = useCallback(async () => {
|
|
1469
|
+
if (!sdk || !vaultAddress) {
|
|
1470
|
+
setData(null);
|
|
1471
|
+
return;
|
|
1472
|
+
}
|
|
1473
|
+
setIsLoading(true);
|
|
1474
|
+
setError(null);
|
|
1475
|
+
try {
|
|
1476
|
+
const info = await sdk.getEventInfo(vaultAddress);
|
|
1477
|
+
setData(info);
|
|
1478
|
+
} catch (err) {
|
|
1479
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch event info"));
|
|
1480
|
+
setData(null);
|
|
1481
|
+
} finally {
|
|
1482
|
+
setIsLoading(false);
|
|
1483
|
+
}
|
|
1484
|
+
}, [sdk, vaultAddress]);
|
|
1485
|
+
useEffect(() => {
|
|
1486
|
+
fetchData();
|
|
1487
|
+
}, [fetchData]);
|
|
1488
|
+
return {
|
|
1489
|
+
data,
|
|
1490
|
+
isLoading,
|
|
1491
|
+
error,
|
|
1492
|
+
refetch: fetchData
|
|
1493
|
+
};
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
// src/react/useWatchVault.ts
|
|
1497
|
+
import { useState as useState2, useEffect as useEffect2, useRef } from "react";
|
|
1498
|
+
function useWatchVault(sdk, vaultAddress) {
|
|
1499
|
+
const [state, setState] = useState2({
|
|
1500
|
+
participantCount: 0,
|
|
1501
|
+
verifiedCount: 0,
|
|
1502
|
+
isSettled: false,
|
|
1503
|
+
lastClaim: null
|
|
1504
|
+
});
|
|
1505
|
+
const [isWatching, setIsWatching] = useState2(false);
|
|
1506
|
+
const unwatchRef = useRef(null);
|
|
1507
|
+
useEffect2(() => {
|
|
1508
|
+
if (!sdk || !vaultAddress) {
|
|
1509
|
+
setIsWatching(false);
|
|
1510
|
+
return;
|
|
1511
|
+
}
|
|
1512
|
+
if (unwatchRef.current) {
|
|
1513
|
+
unwatchRef.current();
|
|
1514
|
+
}
|
|
1515
|
+
try {
|
|
1516
|
+
unwatchRef.current = sdk.watchVault(vaultAddress, {
|
|
1517
|
+
onParticipantJoined: (_participant, totalParticipants) => {
|
|
1518
|
+
setState((prev) => ({ ...prev, participantCount: totalParticipants }));
|
|
1519
|
+
},
|
|
1520
|
+
onParticipantVerified: (_participant, totalVerified) => {
|
|
1521
|
+
setState((prev) => ({ ...prev, verifiedCount: totalVerified }));
|
|
1522
|
+
},
|
|
1523
|
+
onSettled: () => {
|
|
1524
|
+
setState((prev) => ({ ...prev, isSettled: true }));
|
|
1525
|
+
},
|
|
1526
|
+
onClaimed: (participant, amount) => {
|
|
1527
|
+
setState((prev) => ({ ...prev, lastClaim: { participant, amount } }));
|
|
1528
|
+
},
|
|
1529
|
+
onError: (error) => {
|
|
1530
|
+
console.error("[useWatchVault]", error);
|
|
1531
|
+
}
|
|
1532
|
+
});
|
|
1533
|
+
setIsWatching(true);
|
|
1534
|
+
} catch (err) {
|
|
1535
|
+
console.error("[useWatchVault] Failed to start watching:", err);
|
|
1536
|
+
setIsWatching(false);
|
|
1537
|
+
}
|
|
1538
|
+
return () => {
|
|
1539
|
+
if (unwatchRef.current) {
|
|
1540
|
+
unwatchRef.current();
|
|
1541
|
+
unwatchRef.current = null;
|
|
1542
|
+
}
|
|
1543
|
+
setIsWatching(false);
|
|
1544
|
+
};
|
|
1545
|
+
}, [sdk, vaultAddress]);
|
|
1546
|
+
return {
|
|
1547
|
+
...state,
|
|
1548
|
+
isWatching
|
|
1549
|
+
};
|
|
1550
|
+
}
|
|
1351
1551
|
export {
|
|
1352
1552
|
ATFiError,
|
|
1353
1553
|
ATFiErrorCode,
|
|
@@ -1357,13 +1557,24 @@ export {
|
|
|
1357
1557
|
ERC20ABI,
|
|
1358
1558
|
EventStatus,
|
|
1359
1559
|
FactoryATFiABI,
|
|
1560
|
+
NETWORKS,
|
|
1360
1561
|
ParticipantStatus,
|
|
1361
1562
|
TOKENS,
|
|
1362
1563
|
VaultATFiABI,
|
|
1363
1564
|
formatAmount,
|
|
1565
|
+
formatCompact,
|
|
1566
|
+
formatPercent,
|
|
1567
|
+
formatTokenAmount,
|
|
1568
|
+
formatUSD,
|
|
1364
1569
|
fromTokenUnits,
|
|
1570
|
+
getNetworkConfig,
|
|
1365
1571
|
getTokenByAddress,
|
|
1366
1572
|
getTokenBySymbol,
|
|
1573
|
+
isYieldSupported,
|
|
1367
1574
|
parseContractError,
|
|
1368
|
-
|
|
1575
|
+
shortenAddress,
|
|
1576
|
+
toTokenUnits,
|
|
1577
|
+
useATFiSDK,
|
|
1578
|
+
useEventInfo,
|
|
1579
|
+
useWatchVault
|
|
1369
1580
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atfi",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "TypeScript SDK for ATFi commitment vaults on Base",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -18,8 +18,17 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"viem": "^2.21.0"
|
|
20
20
|
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"react": ">=17.0.0"
|
|
23
|
+
},
|
|
24
|
+
"peerDependenciesMeta": {
|
|
25
|
+
"react": {
|
|
26
|
+
"optional": true
|
|
27
|
+
}
|
|
28
|
+
},
|
|
21
29
|
"devDependencies": {
|
|
22
30
|
"@types/node": "^20.0.0",
|
|
31
|
+
"@types/react": "^18.0.0",
|
|
23
32
|
"tsup": "^8.0.0",
|
|
24
33
|
"typescript": "^5.0.0",
|
|
25
34
|
"vitest": "^1.0.0"
|