atfi 1.0.0

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/dist/index.mjs ADDED
@@ -0,0 +1,1369 @@
1
+ // src/ATFiSDK.ts
2
+ import {
3
+ decodeEventLog
4
+ } from "viem";
5
+
6
+ // src/abis/FactoryATFi.ts
7
+ var FactoryATFiABI = [{ "inputs": [{ "internalType": "address", "name": "_treasury", "type": "address" }, { "internalType": "address", "name": "_morphoVault", "type": "address" }, { "internalType": "address", "name": "_usdcToken", "type": "address" }], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [], "name": "EnforcedPause", "type": "error" }, { "inputs": [], "name": "ExceedsMaxParticipants", "type": "error" }, { "inputs": [], "name": "ExpectedPause", "type": "error" }, { "inputs": [], "name": "InvalidStakeAmount", "type": "error" }, { "inputs": [], "name": "InvalidTokenAddress", "type": "error" }, { "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], "name": "OwnableInvalidOwner", "type": "error" }, { "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], "name": "OwnableUnauthorizedAccount", "type": "error" }, { "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" }, { "inputs": [], "name": "TokenNotSupported", "type": "error" }, { "inputs": [], "name": "YieldOnlySupportsUSDC", "type": "error" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "token", "type": "address" }, { "indexed": false, "internalType": "bool", "name": "status", "type": "bool" }], "name": "AssetTokenRegistered", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }], "name": "OwnershipTransferred", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }], "name": "Paused", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "address", "name": "account", "type": "address" }], "name": "Unpaused", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "uint256", "name": "vaultId", "type": "uint256" }, { "indexed": true, "internalType": "address", "name": "vault", "type": "address" }, { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": false, "internalType": "address", "name": "assetToken", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "stakeAmount", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "maxParticipants", "type": "uint256" }, { "indexed": false, "internalType": "address", "name": "yieldVault", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" }], "name": "VaultCreated", "type": "event" }, { "inputs": [{ "internalType": "address", "name": "assetToken", "type": "address" }, { "internalType": "uint256", "name": "stakeAmount", "type": "uint256" }, { "internalType": "uint256", "name": "maxParticipants", "type": "uint256" }], "name": "createVault", "outputs": [{ "internalType": "uint256", "name": "vaultId", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "assetToken", "type": "address" }, { "internalType": "uint256", "name": "stakeAmount", "type": "uint256" }, { "internalType": "uint256", "name": "maxParticipants", "type": "uint256" }], "name": "createVaultNoYield", "outputs": [{ "internalType": "uint256", "name": "vaultId", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "vaultId", "type": "uint256" }], "name": "getVault", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getVaultCount", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "token", "type": "address" }], "name": "isTokenSupported", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "vault", "type": "address" }], "name": "isValidVault", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "", "type": "address" }], "name": "isVault", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "morphoVault", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "owner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "pause", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "paused", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "token", "type": "address" }, { "internalType": "bool", "name": "supported", "type": "bool" }], "name": "registerAssetToken", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_morphoVault", "type": "address" }], "name": "setMorphoVault", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "", "type": "address" }], "name": "supportedAssetTokens", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "treasury", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "unpause", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "usdcToken", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "vaultIdCounter", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "name": "vaults", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }];
8
+
9
+ // src/abis/VaultATFi.ts
10
+ var VaultATFiABI = [{ "inputs": [{ "internalType": "uint256", "name": "_vaultId", "type": "uint256" }, { "internalType": "address", "name": "_owner", "type": "address" }, { "internalType": "address", "name": "_factory", "type": "address" }, { "internalType": "address", "name": "_assetToken", "type": "address" }, { "internalType": "uint256", "name": "_stakeAmount", "type": "uint256" }, { "internalType": "uint256", "name": "_maxParticipants", "type": "uint256" }, { "internalType": "address", "name": "_treasury", "type": "address" }, { "internalType": "address", "name": "_yieldVault", "type": "address" }], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [], "name": "AlreadyClaimed", "type": "error" }, { "inputs": [], "name": "AlreadyStaked", "type": "error" }, { "inputs": [], "name": "AlreadyVerified", "type": "error" }, { "inputs": [], "name": "EventAlreadyStarted", "type": "error" }, { "inputs": [], "name": "InvalidAddress", "type": "error" }, { "inputs": [], "name": "InvalidMaxParticipants", "type": "error" }, { "inputs": [], "name": "InvalidStakeAmount", "type": "error" }, { "inputs": [], "name": "InvalidYieldVault", "type": "error" }, { "inputs": [], "name": "MaxParticipantsReached", "type": "error" }, { "inputs": [], "name": "NoAssetsToDeposit", "type": "error" }, { "inputs": [], "name": "NoParticipants", "type": "error" }, { "inputs": [], "name": "NotStaked", "type": "error" }, { "inputs": [], "name": "NotVerified", "type": "error" }, { "inputs": [], "name": "NothingToClaim", "type": "error" }, { "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], "name": "OwnableInvalidOwner", "type": "error" }, { "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], "name": "OwnableUnauthorizedAccount", "type": "error" }, { "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" }, { "inputs": [{ "internalType": "address", "name": "token", "type": "address" }], "name": "SafeERC20FailedOperation", "type": "error" }, { "inputs": [], "name": "StakingClosedError", "type": "error" }, { "inputs": [], "name": "VaultAlreadySettled", "type": "error" }, { "inputs": [], "name": "VaultNotSettled", "type": "error" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "participant", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "Claimed", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "shares", "type": "uint256" }], "name": "DepositedToYield", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "uint256", "name": "totalStaked", "type": "uint256" }], "name": "EventStarted", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }], "name": "OwnershipTransferred", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "uint256", "name": "totalYield", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "protocolFee", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "noShowFee", "type": "uint256" }], "name": "Settled", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "participant", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "Staked", "type": "event" }, { "anonymous": false, "inputs": [], "name": "StakingClosed", "type": "event" }, { "anonymous": false, "inputs": [], "name": "StakingOpened", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "participant", "type": "address" }], "name": "Verified", "type": "event" }, { "inputs": [], "name": "assetToken", "outputs": [{ "internalType": "contract IERC20", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "claim", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "closeStaking", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "depositToYield", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "depositedAmount", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "eventStarted", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "factory", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "participant", "type": "address" }], "name": "getClaimable", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getCurrentBalance", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getParticipantCount", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getProtocolFees", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }, { "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "participant", "type": "address" }], "name": "getStatus", "outputs": [{ "internalType": "enum ICommitmentVault.Status", "name": "", "type": "uint8" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getVaultInfo", "outputs": [{ "internalType": "address", "name": "_assetToken", "type": "address" }, { "internalType": "uint256", "name": "_stakeAmount", "type": "uint256" }, { "internalType": "uint256", "name": "_maxParticipants", "type": "uint256" }, { "internalType": "uint256", "name": "_currentParticipants", "type": "uint256" }, { "internalType": "bool", "name": "_stakingOpen", "type": "bool" }, { "internalType": "bool", "name": "_eventStarted", "type": "bool" }, { "internalType": "bool", "name": "_settled", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getVerifiedCount", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getYieldInfo", "outputs": [{ "internalType": "bool", "name": "_hasYield", "type": "bool" }, { "internalType": "uint256", "name": "currentBalance", "type": "uint256" }, { "internalType": "uint256", "name": "deposited", "type": "uint256" }, { "internalType": "uint256", "name": "estimatedYield", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "hasYield", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "isEventStarted", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "isSettled", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "isStakingClosed", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "maxParticipants", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "openStaking", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "owner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "name": "participantList", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "", "type": "address" }], "name": "participants", "outputs": [{ "internalType": "bool", "name": "hasStaked", "type": "bool" }, { "internalType": "bool", "name": "isVerified", "type": "bool" }, { "internalType": "bool", "name": "hasClaimed", "type": "bool" }, { "internalType": "uint256", "name": "claimableAmount", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "settle", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "settled", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "sharesHeld", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "stake", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "stakeAmount", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "stakingOpen", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalProtocolFees", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalStaked", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalYieldEarned", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "treasury", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "vaultId", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "verifiedCount", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "participant", "type": "address" }], "name": "verify", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address[]", "name": "_participants", "type": "address[]" }], "name": "verifyBatch", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "yieldVault", "outputs": [{ "internalType": "contract IERC4626", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }];
11
+
12
+ // src/abis/index.ts
13
+ var ERC20ABI = [
14
+ {
15
+ type: "function",
16
+ name: "approve",
17
+ inputs: [
18
+ { name: "spender", type: "address" },
19
+ { name: "amount", type: "uint256" }
20
+ ],
21
+ outputs: [{ type: "bool" }],
22
+ stateMutability: "nonpayable"
23
+ },
24
+ {
25
+ type: "function",
26
+ name: "allowance",
27
+ inputs: [
28
+ { name: "owner", type: "address" },
29
+ { name: "spender", type: "address" }
30
+ ],
31
+ outputs: [{ type: "uint256" }],
32
+ stateMutability: "view"
33
+ },
34
+ {
35
+ type: "function",
36
+ name: "balanceOf",
37
+ inputs: [{ name: "account", type: "address" }],
38
+ outputs: [{ type: "uint256" }],
39
+ stateMutability: "view"
40
+ },
41
+ {
42
+ type: "function",
43
+ name: "decimals",
44
+ inputs: [],
45
+ outputs: [{ type: "uint8" }],
46
+ stateMutability: "view"
47
+ },
48
+ {
49
+ type: "function",
50
+ name: "symbol",
51
+ inputs: [],
52
+ outputs: [{ type: "string" }],
53
+ stateMutability: "view"
54
+ }
55
+ ];
56
+
57
+ // src/constants/addresses.ts
58
+ var CHAIN_ID = 8453;
59
+ var CONTRACTS = {
60
+ FACTORY: "0x0be05a5fa7116c1b33f2b0036eb0d9690db9075f",
61
+ MORPHO_VAULT: "0x050cE30b927Da55177A4914EC73480238BAD56f0"
62
+ };
63
+ var TOKENS = {
64
+ USDC: {
65
+ address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
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
+ }
76
+ };
77
+ var getTokenByAddress = (address) => {
78
+ const normalizedAddress = address.toLowerCase();
79
+ for (const [sym, token] of Object.entries(TOKENS)) {
80
+ if (token.address.toLowerCase() === normalizedAddress) {
81
+ return { ...token, symbol: sym };
82
+ }
83
+ }
84
+ return null;
85
+ };
86
+ var getTokenBySymbol = (symbol) => {
87
+ return TOKENS[symbol];
88
+ };
89
+
90
+ // src/utils/decimals.ts
91
+ import { parseUnits, formatUnits } from "viem";
92
+ function toTokenUnits(amount, decimals) {
93
+ return parseUnits(amount, decimals);
94
+ }
95
+ function fromTokenUnits(amount, decimals) {
96
+ return formatUnits(amount, decimals);
97
+ }
98
+ function formatAmount(amount, decimals = 2) {
99
+ const num = parseFloat(amount);
100
+ if (isNaN(num)) return "0";
101
+ return num.toFixed(decimals);
102
+ }
103
+
104
+ // src/utils/errors.ts
105
+ var ATFiErrorCode = /* @__PURE__ */ ((ATFiErrorCode2) => {
106
+ ATFiErrorCode2["INVALID_AMOUNT"] = "INVALID_AMOUNT";
107
+ ATFiErrorCode2["INVALID_ADDRESS"] = "INVALID_ADDRESS";
108
+ ATFiErrorCode2["TOKEN_NOT_SUPPORTED"] = "TOKEN_NOT_SUPPORTED";
109
+ ATFiErrorCode2["YIELD_ONLY_USDC"] = "YIELD_ONLY_USDC";
110
+ ATFiErrorCode2["STAKING_CLOSED"] = "STAKING_CLOSED";
111
+ ATFiErrorCode2["EVENT_ALREADY_STARTED"] = "EVENT_ALREADY_STARTED";
112
+ ATFiErrorCode2["EVENT_NOT_STARTED"] = "EVENT_NOT_STARTED";
113
+ ATFiErrorCode2["ALREADY_STAKED"] = "ALREADY_STAKED";
114
+ ATFiErrorCode2["NOT_STAKED"] = "NOT_STAKED";
115
+ ATFiErrorCode2["ALREADY_VERIFIED"] = "ALREADY_VERIFIED";
116
+ ATFiErrorCode2["NOT_VERIFIED"] = "NOT_VERIFIED";
117
+ ATFiErrorCode2["VAULT_NOT_SETTLED"] = "VAULT_NOT_SETTLED";
118
+ ATFiErrorCode2["VAULT_ALREADY_SETTLED"] = "VAULT_ALREADY_SETTLED";
119
+ ATFiErrorCode2["ALREADY_CLAIMED"] = "ALREADY_CLAIMED";
120
+ ATFiErrorCode2["NOTHING_TO_CLAIM"] = "NOTHING_TO_CLAIM";
121
+ ATFiErrorCode2["MAX_PARTICIPANTS_REACHED"] = "MAX_PARTICIPANTS_REACHED";
122
+ ATFiErrorCode2["NOT_OWNER"] = "NOT_OWNER";
123
+ ATFiErrorCode2["INSUFFICIENT_BALANCE"] = "INSUFFICIENT_BALANCE";
124
+ ATFiErrorCode2["INSUFFICIENT_ALLOWANCE"] = "INSUFFICIENT_ALLOWANCE";
125
+ ATFiErrorCode2["TRANSACTION_FAILED"] = "TRANSACTION_FAILED";
126
+ ATFiErrorCode2["CONTRACT_ERROR"] = "CONTRACT_ERROR";
127
+ ATFiErrorCode2["VAULT_NOT_FOUND"] = "VAULT_NOT_FOUND";
128
+ return ATFiErrorCode2;
129
+ })(ATFiErrorCode || {});
130
+ var ATFiError = class extends Error {
131
+ constructor(message, code, details) {
132
+ super(message);
133
+ this.code = code;
134
+ this.details = details;
135
+ this.name = "ATFiError";
136
+ }
137
+ };
138
+ var CONTRACT_ERROR_MAP = {
139
+ AlreadyClaimed: "ALREADY_CLAIMED" /* ALREADY_CLAIMED */,
140
+ AlreadyStaked: "ALREADY_STAKED" /* ALREADY_STAKED */,
141
+ AlreadyVerified: "ALREADY_VERIFIED" /* ALREADY_VERIFIED */,
142
+ EventAlreadyStarted: "EVENT_ALREADY_STARTED" /* EVENT_ALREADY_STARTED */,
143
+ InvalidAddress: "INVALID_ADDRESS" /* INVALID_ADDRESS */,
144
+ InvalidStakeAmount: "INVALID_AMOUNT" /* INVALID_AMOUNT */,
145
+ InvalidMaxParticipants: "INVALID_AMOUNT" /* INVALID_AMOUNT */,
146
+ MaxParticipantsReached: "MAX_PARTICIPANTS_REACHED" /* MAX_PARTICIPANTS_REACHED */,
147
+ NoAssetsToDeposit: "INVALID_AMOUNT" /* INVALID_AMOUNT */,
148
+ NoParticipants: "INVALID_AMOUNT" /* INVALID_AMOUNT */,
149
+ NotStaked: "NOT_STAKED" /* NOT_STAKED */,
150
+ NotVerified: "NOT_VERIFIED" /* NOT_VERIFIED */,
151
+ NothingToClaim: "NOTHING_TO_CLAIM" /* NOTHING_TO_CLAIM */,
152
+ StakingClosedError: "STAKING_CLOSED" /* STAKING_CLOSED */,
153
+ TokenNotSupported: "TOKEN_NOT_SUPPORTED" /* TOKEN_NOT_SUPPORTED */,
154
+ VaultAlreadySettled: "VAULT_ALREADY_SETTLED" /* VAULT_ALREADY_SETTLED */,
155
+ VaultNotSettled: "VAULT_NOT_SETTLED" /* VAULT_NOT_SETTLED */,
156
+ YieldOnlySupportsUSDC: "YIELD_ONLY_USDC" /* YIELD_ONLY_USDC */,
157
+ OwnableUnauthorizedAccount: "NOT_OWNER" /* NOT_OWNER */
158
+ };
159
+ function parseContractError(error) {
160
+ if (error instanceof ATFiError) {
161
+ return error;
162
+ }
163
+ const errorString = String(error);
164
+ for (const [errorName, code] of Object.entries(CONTRACT_ERROR_MAP)) {
165
+ if (errorString.includes(errorName)) {
166
+ return new ATFiError(
167
+ `Contract error: ${errorName}`,
168
+ code,
169
+ error
170
+ );
171
+ }
172
+ }
173
+ if (errorString.includes("insufficient funds") || errorString.includes("exceeds balance")) {
174
+ return new ATFiError(
175
+ "Insufficient balance",
176
+ "INSUFFICIENT_BALANCE" /* INSUFFICIENT_BALANCE */,
177
+ error
178
+ );
179
+ }
180
+ return new ATFiError(
181
+ "Transaction failed",
182
+ "TRANSACTION_FAILED" /* TRANSACTION_FAILED */,
183
+ error
184
+ );
185
+ }
186
+
187
+ // src/types/index.ts
188
+ var ParticipantStatus = /* @__PURE__ */ ((ParticipantStatus3) => {
189
+ ParticipantStatus3[ParticipantStatus3["NOT_STAKED"] = 0] = "NOT_STAKED";
190
+ ParticipantStatus3[ParticipantStatus3["STAKED"] = 1] = "STAKED";
191
+ ParticipantStatus3[ParticipantStatus3["VERIFIED"] = 2] = "VERIFIED";
192
+ ParticipantStatus3[ParticipantStatus3["CLAIMED"] = 3] = "CLAIMED";
193
+ return ParticipantStatus3;
194
+ })(ParticipantStatus || {});
195
+ var EventStatus = /* @__PURE__ */ ((EventStatus2) => {
196
+ EventStatus2["OPEN"] = "OPEN";
197
+ EventStatus2["STARTED"] = "STARTED";
198
+ EventStatus2["SETTLED"] = "SETTLED";
199
+ return EventStatus2;
200
+ })(EventStatus || {});
201
+
202
+ // src/ATFiSDK.ts
203
+ var ATFiSDK = class _ATFiSDK {
204
+ constructor(publicClient, walletClient, config) {
205
+ this.publicClient = publicClient;
206
+ this.walletClient = walletClient ? walletClient : null;
207
+ this.factoryAddress = config?.factoryAddress ?? CONTRACTS.FACTORY;
208
+ this._isReadOnly = !walletClient;
209
+ }
210
+ /**
211
+ * Create a read-only SDK instance (no wallet required)
212
+ * Use this to show event data before user connects wallet
213
+ *
214
+ * @example
215
+ * ```ts
216
+ * const sdk = ATFiSDK.readOnly(publicClient);
217
+ * const events = await sdk.getAllEvents();
218
+ * const info = await sdk.getEventInfo(vaultAddress);
219
+ * ```
220
+ */
221
+ static readOnly(publicClient, config) {
222
+ return new _ATFiSDK(publicClient, null, config);
223
+ }
224
+ /** Check if SDK is in read-only mode */
225
+ get isReadOnly() {
226
+ return this._isReadOnly;
227
+ }
228
+ /** Get connected wallet address (null if read-only) */
229
+ get address() {
230
+ return this.walletClient?.account?.address ?? null;
231
+ }
232
+ // ============ Token Helpers ============
233
+ /**
234
+ * Get token balance for connected wallet or any address
235
+ *
236
+ * @example
237
+ * ```ts
238
+ * const myBalance = await sdk.getTokenBalance('USDC');
239
+ * const otherBalance = await sdk.getTokenBalance('USDC', '0xOther...');
240
+ * ```
241
+ */
242
+ async getTokenBalance(token, address) {
243
+ const tokenInfo = getTokenBySymbol(token);
244
+ if (!tokenInfo) throw new ATFiError(`Token ${token} not supported`, "TOKEN_NOT_SUPPORTED" /* TOKEN_NOT_SUPPORTED */);
245
+ const targetAddress = address ?? this.walletClient?.account?.address;
246
+ if (!targetAddress) throw new ATFiError("No address provided and no wallet connected", "CONTRACT_ERROR" /* CONTRACT_ERROR */);
247
+ const balance = await this.publicClient.readContract({
248
+ address: tokenInfo.address,
249
+ abi: ERC20ABI,
250
+ functionName: "balanceOf",
251
+ args: [targetAddress]
252
+ });
253
+ return fromTokenUnits(balance, tokenInfo.decimals);
254
+ }
255
+ /**
256
+ * Get all supported token balances for an address
257
+ */
258
+ async getAllTokenBalances(address) {
259
+ const targetAddress = address ?? this.walletClient?.account?.address;
260
+ if (!targetAddress) throw new ATFiError("No address provided", "CONTRACT_ERROR" /* CONTRACT_ERROR */);
261
+ const [usdcBalance, idrxBalance] = await Promise.all([
262
+ this.publicClient.readContract({
263
+ address: TOKENS.USDC.address,
264
+ abi: ERC20ABI,
265
+ functionName: "balanceOf",
266
+ args: [targetAddress]
267
+ }),
268
+ this.publicClient.readContract({
269
+ address: TOKENS.IDRX.address,
270
+ abi: ERC20ABI,
271
+ functionName: "balanceOf",
272
+ args: [targetAddress]
273
+ })
274
+ ]);
275
+ return {
276
+ USDC: fromTokenUnits(usdcBalance, TOKENS.USDC.decimals),
277
+ IDRX: fromTokenUnits(idrxBalance, TOKENS.IDRX.decimals)
278
+ };
279
+ }
280
+ // ============ User-Centric Queries ============
281
+ /**
282
+ * Get all events created by an address
283
+ *
284
+ * @example
285
+ * ```ts
286
+ * const myEvents = await sdk.getEventsByOwner(myAddress);
287
+ * ```
288
+ */
289
+ async getEventsByOwner(ownerAddress) {
290
+ const allEvents = await this.getAllEvents();
291
+ const ownerEvents = [];
292
+ for (const event of allEvents) {
293
+ if (event.owner.toLowerCase() === ownerAddress.toLowerCase()) {
294
+ const info = await this.getEventInfo(event.vaultAddress);
295
+ ownerEvents.push(info);
296
+ }
297
+ }
298
+ return ownerEvents;
299
+ }
300
+ /**
301
+ * Get all events where user has registered (staked)
302
+ *
303
+ * @example
304
+ * ```ts
305
+ * const myRegistrations = await sdk.getRegisteredEvents(myAddress);
306
+ * ```
307
+ */
308
+ async getRegisteredEvents(participantAddress) {
309
+ const allEvents = await this.getAllEvents();
310
+ const registeredEvents = [];
311
+ for (const event of allEvents) {
312
+ const status = await this.getParticipantStatus(event.vaultAddress, participantAddress);
313
+ if (status.hasStaked) {
314
+ const info = await this.getEventInfo(event.vaultAddress);
315
+ registeredEvents.push({
316
+ ...info,
317
+ userStatus: {
318
+ isOwner: info.owner.toLowerCase() === participantAddress.toLowerCase(),
319
+ hasStaked: status.hasStaked,
320
+ isVerified: status.isVerified,
321
+ hasClaimed: status.hasClaimed,
322
+ claimableAmount: status.claimableAmount
323
+ }
324
+ });
325
+ }
326
+ }
327
+ return registeredEvents;
328
+ }
329
+ /**
330
+ * Get all events where user can claim rewards
331
+ *
332
+ * @example
333
+ * ```ts
334
+ * const claimable = await sdk.getClaimableEvents(myAddress);
335
+ * for (const event of claimable) {
336
+ * console.log(`Can claim ${event.userStatus.claimableAmount} from ${event.vaultAddress}`);
337
+ * }
338
+ * ```
339
+ */
340
+ async getClaimableEvents(participantAddress) {
341
+ const registered = await this.getRegisteredEvents(participantAddress);
342
+ return registered.filter(
343
+ (e) => e.settled && e.userStatus.isVerified && !e.userStatus.hasClaimed && parseFloat(e.userStatus.claimableAmount) > 0
344
+ );
345
+ }
346
+ /**
347
+ * Get user's complete dashboard data in one call
348
+ *
349
+ * @example
350
+ * ```ts
351
+ * const dashboard = await sdk.getUserDashboard(myAddress);
352
+ * console.log('Created:', dashboard.createdEvents.length);
353
+ * console.log('Registered:', dashboard.registeredEvents.length);
354
+ * console.log('Claimable:', dashboard.claimableEvents.length);
355
+ * ```
356
+ */
357
+ async getUserDashboard(userAddress) {
358
+ const [createdEvents, registeredEvents, tokenBalances] = await Promise.all([
359
+ this.getEventsByOwner(userAddress),
360
+ this.getRegisteredEvents(userAddress),
361
+ this.getAllTokenBalances(userAddress)
362
+ ]);
363
+ const claimableEvents = registeredEvents.filter(
364
+ (e) => e.settled && e.userStatus.isVerified && !e.userStatus.hasClaimed && parseFloat(e.userStatus.claimableAmount) > 0
365
+ );
366
+ const totalClaimable = claimableEvents.reduce((sum, e) => sum + parseFloat(e.userStatus.claimableAmount), 0).toFixed(6);
367
+ return {
368
+ createdEvents,
369
+ registeredEvents,
370
+ claimableEvents,
371
+ totalClaimable,
372
+ tokenBalances
373
+ };
374
+ }
375
+ // ============ Event Watching (Real-time) ============
376
+ /**
377
+ * Watch a vault for real-time updates
378
+ *
379
+ * @example
380
+ * ```ts
381
+ * const unwatch = sdk.watchVault(vaultAddress, {
382
+ * onParticipantJoined: (addr, total) => {
383
+ * console.log(`${addr} joined! Total: ${total}`);
384
+ * refetchParticipants();
385
+ * },
386
+ * onSettled: (yield, fee) => {
387
+ * showClaimButton();
388
+ * },
389
+ * });
390
+ *
391
+ * // Later: stop watching
392
+ * unwatch();
393
+ * ```
394
+ */
395
+ watchVault(vaultAddress, callbacks) {
396
+ const unwatchers = [];
397
+ if (callbacks.onParticipantJoined) {
398
+ const unwatch = this.publicClient.watchContractEvent({
399
+ address: vaultAddress,
400
+ abi: VaultATFiABI,
401
+ eventName: "Staked",
402
+ onLogs: async (logs) => {
403
+ for (const log of logs) {
404
+ try {
405
+ const participant = log.args?.participant;
406
+ const count = await this.publicClient.readContract({
407
+ address: vaultAddress,
408
+ abi: VaultATFiABI,
409
+ functionName: "getParticipantCount"
410
+ });
411
+ callbacks.onParticipantJoined(participant, Number(count));
412
+ } catch (e) {
413
+ callbacks.onError?.(e);
414
+ }
415
+ }
416
+ }
417
+ });
418
+ unwatchers.push(unwatch);
419
+ }
420
+ if (callbacks.onParticipantVerified) {
421
+ const unwatch = this.publicClient.watchContractEvent({
422
+ address: vaultAddress,
423
+ abi: VaultATFiABI,
424
+ eventName: "Verified",
425
+ onLogs: async (logs) => {
426
+ for (const log of logs) {
427
+ try {
428
+ const participant = log.args?.participant;
429
+ const count = await this.publicClient.readContract({
430
+ address: vaultAddress,
431
+ abi: VaultATFiABI,
432
+ functionName: "verifiedCount"
433
+ });
434
+ callbacks.onParticipantVerified(participant, Number(count));
435
+ } catch (e) {
436
+ callbacks.onError?.(e);
437
+ }
438
+ }
439
+ }
440
+ });
441
+ unwatchers.push(unwatch);
442
+ }
443
+ if (callbacks.onSettled) {
444
+ const unwatch = this.publicClient.watchContractEvent({
445
+ address: vaultAddress,
446
+ abi: VaultATFiABI,
447
+ eventName: "Settled",
448
+ onLogs: async (logs) => {
449
+ for (const log of logs) {
450
+ try {
451
+ const args = log.args;
452
+ const assetToken = await this.publicClient.readContract({
453
+ address: vaultAddress,
454
+ abi: VaultATFiABI,
455
+ functionName: "assetToken"
456
+ });
457
+ const tokenInfo = getTokenByAddress(assetToken);
458
+ const decimals = tokenInfo?.decimals ?? 6;
459
+ callbacks.onSettled(
460
+ fromTokenUnits(args.totalYield, decimals),
461
+ fromTokenUnits(args.protocolFee, decimals)
462
+ );
463
+ } catch (e) {
464
+ callbacks.onError?.(e);
465
+ }
466
+ }
467
+ }
468
+ });
469
+ unwatchers.push(unwatch);
470
+ }
471
+ if (callbacks.onClaimed) {
472
+ const unwatch = this.publicClient.watchContractEvent({
473
+ address: vaultAddress,
474
+ abi: VaultATFiABI,
475
+ eventName: "Claimed",
476
+ onLogs: async (logs) => {
477
+ for (const log of logs) {
478
+ try {
479
+ const args = log.args;
480
+ const assetToken = await this.publicClient.readContract({
481
+ address: vaultAddress,
482
+ abi: VaultATFiABI,
483
+ functionName: "assetToken"
484
+ });
485
+ const tokenInfo = getTokenByAddress(assetToken);
486
+ const decimals = tokenInfo?.decimals ?? 6;
487
+ callbacks.onClaimed(
488
+ args.participant,
489
+ fromTokenUnits(args.amount, decimals)
490
+ );
491
+ } catch (e) {
492
+ callbacks.onError?.(e);
493
+ }
494
+ }
495
+ }
496
+ });
497
+ unwatchers.push(unwatch);
498
+ }
499
+ if (callbacks.onStakingStatusChanged) {
500
+ const unwatchOpen = this.publicClient.watchContractEvent({
501
+ address: vaultAddress,
502
+ abi: VaultATFiABI,
503
+ eventName: "StakingOpened",
504
+ onLogs: () => callbacks.onStakingStatusChanged(true)
505
+ });
506
+ const unwatchClose = this.publicClient.watchContractEvent({
507
+ address: vaultAddress,
508
+ abi: VaultATFiABI,
509
+ eventName: "StakingClosed",
510
+ onLogs: () => callbacks.onStakingStatusChanged(false)
511
+ });
512
+ unwatchers.push(unwatchOpen, unwatchClose);
513
+ }
514
+ return () => {
515
+ unwatchers.forEach((unwatch) => unwatch());
516
+ };
517
+ }
518
+ // ============ Write Functions (with built-in simulation) ============
519
+ ensureWallet() {
520
+ if (!this.walletClient) {
521
+ throw new ATFiError("Wallet not connected. Use ATFiSDK.readOnly() for read operations only.", "CONTRACT_ERROR" /* CONTRACT_ERROR */);
522
+ }
523
+ return this.walletClient;
524
+ }
525
+ /**
526
+ * Create a new event (commitment vault)
527
+ */
528
+ async createEvent(params) {
529
+ this.ensureWallet();
530
+ const simulation = await this._simulateCreateEvent(params);
531
+ return {
532
+ simulation,
533
+ execute: async (callbacks) => {
534
+ if (!simulation.success) {
535
+ throw new ATFiError(simulation.error?.message || "Simulation failed", simulation.error?.code || "CONTRACT_ERROR" /* CONTRACT_ERROR */);
536
+ }
537
+ return this._executeCreateEvent(params, callbacks);
538
+ }
539
+ };
540
+ }
541
+ /**
542
+ * Register for an event (stake tokens)
543
+ */
544
+ async register(params) {
545
+ this.ensureWallet();
546
+ const simulation = await this._simulateRegister(params);
547
+ return {
548
+ simulation,
549
+ execute: async (callbacks) => {
550
+ if (!simulation.success) {
551
+ throw new ATFiError(simulation.error?.message || "Simulation failed", simulation.error?.code || "CONTRACT_ERROR" /* CONTRACT_ERROR */);
552
+ }
553
+ return this._executeRegister(params, callbacks);
554
+ }
555
+ };
556
+ }
557
+ /**
558
+ * Start an event (deposit to yield if enabled)
559
+ */
560
+ async startEvent(params) {
561
+ this.ensureWallet();
562
+ const simulation = await this._simulateStartEvent(params);
563
+ return {
564
+ simulation,
565
+ execute: async (callbacks) => {
566
+ if (!simulation.success) {
567
+ throw new ATFiError(simulation.error?.message || "Simulation failed", simulation.error?.code || "CONTRACT_ERROR" /* CONTRACT_ERROR */);
568
+ }
569
+ return this._executeStartEvent(params, callbacks);
570
+ }
571
+ };
572
+ }
573
+ /**
574
+ * Verify participants (mark attendance)
575
+ */
576
+ async verifyParticipant(params) {
577
+ this.ensureWallet();
578
+ const simulation = await this._simulateVerifyParticipant(params);
579
+ return {
580
+ simulation,
581
+ execute: async (callbacks) => {
582
+ if (!simulation.success) {
583
+ throw new ATFiError(simulation.error?.message || "Simulation failed", simulation.error?.code || "CONTRACT_ERROR" /* CONTRACT_ERROR */);
584
+ }
585
+ return this._executeVerifyParticipant(params, callbacks);
586
+ }
587
+ };
588
+ }
589
+ /**
590
+ * Settle an event (distribute rewards)
591
+ */
592
+ async settleEvent(params) {
593
+ this.ensureWallet();
594
+ const simulation = await this._simulateSettleEvent(params);
595
+ return {
596
+ simulation,
597
+ execute: async (callbacks) => {
598
+ if (!simulation.success) {
599
+ throw new ATFiError(simulation.error?.message || "Simulation failed", simulation.error?.code || "CONTRACT_ERROR" /* CONTRACT_ERROR */);
600
+ }
601
+ return this._executeSettleEvent(params, callbacks);
602
+ }
603
+ };
604
+ }
605
+ /**
606
+ * Claim rewards after event settlement
607
+ */
608
+ async claim(params) {
609
+ this.ensureWallet();
610
+ const simulation = await this._simulateClaim(params);
611
+ return {
612
+ simulation,
613
+ execute: async (callbacks) => {
614
+ if (!simulation.success) {
615
+ throw new ATFiError(simulation.error?.message || "Simulation failed", simulation.error?.code || "CONTRACT_ERROR" /* CONTRACT_ERROR */);
616
+ }
617
+ return this._executeClaim(params, callbacks);
618
+ }
619
+ };
620
+ }
621
+ // ============ Read Functions ============
622
+ /**
623
+ * Get detailed event information
624
+ */
625
+ async getEventInfo(vaultAddress) {
626
+ const [
627
+ vaultInfo,
628
+ vaultId,
629
+ owner,
630
+ hasYield,
631
+ totalStaked,
632
+ verifiedCount,
633
+ yieldInfo
634
+ ] = await Promise.all([
635
+ this.publicClient.readContract({
636
+ address: vaultAddress,
637
+ abi: VaultATFiABI,
638
+ functionName: "getVaultInfo"
639
+ }),
640
+ this.publicClient.readContract({
641
+ address: vaultAddress,
642
+ abi: VaultATFiABI,
643
+ functionName: "vaultId"
644
+ }),
645
+ this.publicClient.readContract({
646
+ address: vaultAddress,
647
+ abi: VaultATFiABI,
648
+ functionName: "owner"
649
+ }),
650
+ this.publicClient.readContract({
651
+ address: vaultAddress,
652
+ abi: VaultATFiABI,
653
+ functionName: "hasYield"
654
+ }),
655
+ this.publicClient.readContract({
656
+ address: vaultAddress,
657
+ abi: VaultATFiABI,
658
+ functionName: "totalStaked"
659
+ }),
660
+ this.publicClient.readContract({
661
+ address: vaultAddress,
662
+ abi: VaultATFiABI,
663
+ functionName: "verifiedCount"
664
+ }),
665
+ this.publicClient.readContract({
666
+ address: vaultAddress,
667
+ abi: VaultATFiABI,
668
+ functionName: "getYieldInfo"
669
+ })
670
+ ]);
671
+ const info = vaultInfo;
672
+ const yield_ = yieldInfo;
673
+ const tokenInfo = getTokenByAddress(info[0]);
674
+ const decimals = tokenInfo?.decimals ?? 6;
675
+ const symbol = tokenInfo?.symbol ?? "UNKNOWN";
676
+ return {
677
+ vaultId,
678
+ vaultAddress,
679
+ owner,
680
+ assetToken: info[0],
681
+ tokenSymbol: symbol,
682
+ tokenDecimals: decimals,
683
+ stakeAmount: fromTokenUnits(info[1], decimals),
684
+ maxParticipants: Number(info[2]),
685
+ currentParticipants: Number(info[3]),
686
+ verifiedCount: Number(verifiedCount),
687
+ stakingOpen: info[4],
688
+ eventStarted: info[5],
689
+ settled: info[6],
690
+ hasYield,
691
+ totalStaked: fromTokenUnits(totalStaked, decimals),
692
+ yieldInfo: hasYield ? {
693
+ currentBalance: fromTokenUnits(yield_[1], decimals),
694
+ deposited: fromTokenUnits(yield_[2], decimals),
695
+ estimatedYield: fromTokenUnits(yield_[3], decimals)
696
+ } : void 0
697
+ };
698
+ }
699
+ /**
700
+ * Get participant status
701
+ */
702
+ async getParticipantStatus(vaultAddress, participantAddress) {
703
+ const [participant, status, claimable, assetToken] = await Promise.all([
704
+ this.publicClient.readContract({
705
+ address: vaultAddress,
706
+ abi: VaultATFiABI,
707
+ functionName: "participants",
708
+ args: [participantAddress]
709
+ }),
710
+ this.publicClient.readContract({
711
+ address: vaultAddress,
712
+ abi: VaultATFiABI,
713
+ functionName: "getStatus",
714
+ args: [participantAddress]
715
+ }),
716
+ this.publicClient.readContract({
717
+ address: vaultAddress,
718
+ abi: VaultATFiABI,
719
+ functionName: "getClaimable",
720
+ args: [participantAddress]
721
+ }),
722
+ this.publicClient.readContract({
723
+ address: vaultAddress,
724
+ abi: VaultATFiABI,
725
+ functionName: "assetToken"
726
+ })
727
+ ]);
728
+ const p = participant;
729
+ const tokenInfo = getTokenByAddress(assetToken);
730
+ const decimals = tokenInfo?.decimals ?? 6;
731
+ return {
732
+ address: participantAddress,
733
+ hasStaked: p[0],
734
+ isVerified: p[1],
735
+ hasClaimed: p[2],
736
+ claimableAmount: fromTokenUnits(claimable, decimals),
737
+ status
738
+ };
739
+ }
740
+ /**
741
+ * Get all events (vaults) created - uses batched calls for efficiency
742
+ */
743
+ async getAllEvents() {
744
+ const vaultCount = await this.publicClient.readContract({
745
+ address: this.factoryAddress,
746
+ abi: FactoryATFiABI,
747
+ functionName: "getVaultCount"
748
+ });
749
+ const count = Number(vaultCount);
750
+ if (count === 0) return [];
751
+ const vaultAddressPromises = [];
752
+ for (let i = 1; i <= count; i++) {
753
+ vaultAddressPromises.push(
754
+ this.publicClient.readContract({
755
+ address: this.factoryAddress,
756
+ abi: FactoryATFiABI,
757
+ functionName: "getVault",
758
+ args: [BigInt(i)]
759
+ })
760
+ );
761
+ }
762
+ const vaultAddresses = await Promise.all(vaultAddressPromises);
763
+ const validAddresses = vaultAddresses.filter(
764
+ (addr) => addr !== "0x0000000000000000000000000000000000000000"
765
+ );
766
+ const eventInfoPromises = validAddresses.map((addr) => this.getEventInfo(addr));
767
+ const eventInfos = await Promise.all(eventInfoPromises);
768
+ return eventInfos.map((info) => {
769
+ let status;
770
+ if (info.settled) {
771
+ status = "SETTLED" /* SETTLED */;
772
+ } else if (info.eventStarted) {
773
+ status = "STARTED" /* STARTED */;
774
+ } else {
775
+ status = "OPEN" /* OPEN */;
776
+ }
777
+ return {
778
+ vaultId: info.vaultId,
779
+ vaultAddress: info.vaultAddress,
780
+ owner: info.owner,
781
+ assetToken: info.assetToken,
782
+ stakeAmount: info.stakeAmount,
783
+ maxParticipants: info.maxParticipants,
784
+ currentParticipants: info.currentParticipants,
785
+ status
786
+ };
787
+ });
788
+ }
789
+ /**
790
+ * Get vault address by ID
791
+ */
792
+ async getVaultAddress(vaultId) {
793
+ const address = await this.publicClient.readContract({
794
+ address: this.factoryAddress,
795
+ abi: FactoryATFiABI,
796
+ functionName: "getVault",
797
+ args: [BigInt(vaultId)]
798
+ });
799
+ if (address === "0x0000000000000000000000000000000000000000") {
800
+ return null;
801
+ }
802
+ return address;
803
+ }
804
+ /**
805
+ * Get total vault count
806
+ */
807
+ async getVaultCount() {
808
+ const count = await this.publicClient.readContract({
809
+ address: this.factoryAddress,
810
+ abi: FactoryATFiABI,
811
+ functionName: "getVaultCount"
812
+ });
813
+ return Number(count);
814
+ }
815
+ // ============ Private: Simulation Methods ============
816
+ async _simulateCreateEvent(params) {
817
+ const { stakeAmount, maxParticipants, useYield = false, token = "USDC" } = params;
818
+ if (useYield && token !== "USDC") {
819
+ return {
820
+ success: false,
821
+ error: { code: "YIELD_ONLY_USDC" /* YIELD_ONLY_USDC */, message: "Yield mode only supports USDC" }
822
+ };
823
+ }
824
+ const tokenInfo = getTokenBySymbol(token);
825
+ if (!tokenInfo) {
826
+ return {
827
+ success: false,
828
+ error: { code: "TOKEN_NOT_SUPPORTED" /* TOKEN_NOT_SUPPORTED */, message: `Token ${token} not supported` }
829
+ };
830
+ }
831
+ if (maxParticipants <= 0 || maxParticipants > 1e4) {
832
+ return {
833
+ success: false,
834
+ error: { code: "INVALID_AMOUNT" /* INVALID_AMOUNT */, message: "Max participants must be between 1 and 10000" }
835
+ };
836
+ }
837
+ const stakeAmountBigInt = toTokenUnits(stakeAmount, tokenInfo.decimals);
838
+ if (stakeAmountBigInt <= 0n) {
839
+ return {
840
+ success: false,
841
+ error: { code: "INVALID_AMOUNT" /* INVALID_AMOUNT */, message: "Stake amount must be greater than 0" }
842
+ };
843
+ }
844
+ try {
845
+ const wallet = this.ensureWallet();
846
+ const account = wallet.account;
847
+ if (!account) {
848
+ return { success: false, error: { code: "CONTRACT_ERROR" /* CONTRACT_ERROR */, message: "No account connected" } };
849
+ }
850
+ const functionName = useYield ? "createVault" : "createVaultNoYield";
851
+ await this.publicClient.simulateContract({
852
+ address: this.factoryAddress,
853
+ abi: FactoryATFiABI,
854
+ functionName,
855
+ args: [tokenInfo.address, stakeAmountBigInt, BigInt(maxParticipants)],
856
+ account
857
+ });
858
+ const vaultCount = await this.publicClient.readContract({
859
+ address: this.factoryAddress,
860
+ abi: FactoryATFiABI,
861
+ functionName: "getVaultCount"
862
+ });
863
+ const gasEstimate = await this.publicClient.estimateContractGas({
864
+ address: this.factoryAddress,
865
+ abi: FactoryATFiABI,
866
+ functionName,
867
+ args: [tokenInfo.address, stakeAmountBigInt, BigInt(maxParticipants)],
868
+ account
869
+ });
870
+ return {
871
+ success: true,
872
+ expectedVaultId: vaultCount + 1n,
873
+ token: { address: tokenInfo.address, symbol: tokenInfo.symbol, decimals: tokenInfo.decimals },
874
+ stakeAmount,
875
+ maxParticipants,
876
+ useYield,
877
+ gasEstimate
878
+ };
879
+ } catch (error) {
880
+ const parsed = parseContractError(error);
881
+ return { success: false, error: { code: parsed.code, message: parsed.message } };
882
+ }
883
+ }
884
+ async _simulateRegister(params) {
885
+ const { vaultAddress } = params;
886
+ try {
887
+ const wallet = this.ensureWallet();
888
+ const account = wallet.account;
889
+ if (!account) {
890
+ return { success: false, error: { code: "CONTRACT_ERROR" /* CONTRACT_ERROR */, message: "No account connected" } };
891
+ }
892
+ const [stakeAmount, assetToken, stakingOpen, eventStarted, currentParticipants, maxParticipants] = await Promise.all([
893
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "stakeAmount" }),
894
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "assetToken" }),
895
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "stakingOpen" }),
896
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "eventStarted" }),
897
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "getParticipantCount" }),
898
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "maxParticipants" })
899
+ ]);
900
+ const tokenInfo = getTokenByAddress(assetToken);
901
+ const decimals = tokenInfo?.decimals ?? 6;
902
+ const symbol = tokenInfo?.symbol ?? "UNKNOWN";
903
+ const baseResult = {
904
+ stakeAmount: fromTokenUnits(stakeAmount, decimals),
905
+ tokenSymbol: symbol,
906
+ currentParticipants: Number(currentParticipants),
907
+ maxParticipants: Number(maxParticipants)
908
+ };
909
+ if (!stakingOpen) {
910
+ return { success: false, error: { code: "STAKING_CLOSED" /* STAKING_CLOSED */, message: "Staking is closed" }, ...baseResult };
911
+ }
912
+ if (eventStarted) {
913
+ return { success: false, error: { code: "EVENT_ALREADY_STARTED" /* EVENT_ALREADY_STARTED */, message: "Event already started" }, ...baseResult };
914
+ }
915
+ if (currentParticipants >= maxParticipants) {
916
+ return { success: false, error: { code: "MAX_PARTICIPANTS_REACHED" /* MAX_PARTICIPANTS_REACHED */, message: "Event is full" }, ...baseResult };
917
+ }
918
+ const participant = await this.publicClient.readContract({
919
+ address: vaultAddress,
920
+ abi: VaultATFiABI,
921
+ functionName: "participants",
922
+ args: [account.address]
923
+ });
924
+ if (participant[0]) {
925
+ return { success: false, error: { code: "ALREADY_STAKED" /* ALREADY_STAKED */, message: "Already registered" }, ...baseResult };
926
+ }
927
+ const [balance, allowance] = await Promise.all([
928
+ this.publicClient.readContract({ address: assetToken, abi: ERC20ABI, functionName: "balanceOf", args: [account.address] }),
929
+ this.publicClient.readContract({ address: assetToken, abi: ERC20ABI, functionName: "allowance", args: [account.address, vaultAddress] })
930
+ ]);
931
+ const needsApproval = allowance < stakeAmount;
932
+ if (balance < stakeAmount) {
933
+ return {
934
+ success: false,
935
+ error: { code: "INSUFFICIENT_BALANCE" /* INSUFFICIENT_BALANCE */, message: `Insufficient ${symbol} balance` },
936
+ ...baseResult,
937
+ userBalance: fromTokenUnits(balance, decimals),
938
+ currentAllowance: fromTokenUnits(allowance, decimals),
939
+ needsApproval
940
+ };
941
+ }
942
+ await this.publicClient.simulateContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "stake", account });
943
+ const gasEstimate = await this.publicClient.estimateContractGas({ address: vaultAddress, abi: VaultATFiABI, functionName: "stake", account });
944
+ return {
945
+ success: true,
946
+ ...baseResult,
947
+ userBalance: fromTokenUnits(balance, decimals),
948
+ currentAllowance: fromTokenUnits(allowance, decimals),
949
+ needsApproval,
950
+ gasEstimate
951
+ };
952
+ } catch (error) {
953
+ const parsed = parseContractError(error);
954
+ return { success: false, error: { code: parsed.code, message: parsed.message } };
955
+ }
956
+ }
957
+ async _simulateStartEvent(params) {
958
+ const { vaultAddress } = params;
959
+ try {
960
+ const wallet = this.ensureWallet();
961
+ const account = wallet.account;
962
+ if (!account) {
963
+ return { success: false, error: { code: "CONTRACT_ERROR" /* CONTRACT_ERROR */, message: "No account connected" } };
964
+ }
965
+ const [owner, totalStaked, hasYield, eventStarted, participantCount, assetToken] = await Promise.all([
966
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "owner" }),
967
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "totalStaked" }),
968
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "hasYield" }),
969
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "eventStarted" }),
970
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "getParticipantCount" }),
971
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "assetToken" })
972
+ ]);
973
+ const tokenInfo = getTokenByAddress(assetToken);
974
+ const decimals = tokenInfo?.decimals ?? 6;
975
+ const baseResult = {
976
+ totalStaked: fromTokenUnits(totalStaked, decimals),
977
+ hasYield,
978
+ participantCount: Number(participantCount)
979
+ };
980
+ if (owner.toLowerCase() !== account.address.toLowerCase()) {
981
+ return { success: false, error: { code: "NOT_OWNER" /* NOT_OWNER */, message: "Only owner can start" }, ...baseResult };
982
+ }
983
+ if (eventStarted) {
984
+ return { success: false, error: { code: "EVENT_ALREADY_STARTED" /* EVENT_ALREADY_STARTED */, message: "Already started" }, ...baseResult };
985
+ }
986
+ if (participantCount === 0n) {
987
+ return { success: false, error: { code: "INVALID_AMOUNT" /* INVALID_AMOUNT */, message: "No participants" }, ...baseResult };
988
+ }
989
+ await this.publicClient.simulateContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "depositToYield", account });
990
+ const gasEstimate = await this.publicClient.estimateContractGas({ address: vaultAddress, abi: VaultATFiABI, functionName: "depositToYield", account });
991
+ return { success: true, ...baseResult, gasEstimate };
992
+ } catch (error) {
993
+ const parsed = parseContractError(error);
994
+ return { success: false, error: { code: parsed.code, message: parsed.message } };
995
+ }
996
+ }
997
+ async _simulateVerifyParticipant(params) {
998
+ const { vaultAddress, participants } = params;
999
+ try {
1000
+ const wallet = this.ensureWallet();
1001
+ const account = wallet.account;
1002
+ if (!account) {
1003
+ return { success: false, error: { code: "CONTRACT_ERROR" /* CONTRACT_ERROR */, message: "No account connected" } };
1004
+ }
1005
+ const owner = await this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "owner" });
1006
+ if (owner.toLowerCase() !== account.address.toLowerCase()) {
1007
+ return { success: false, error: { code: "NOT_OWNER" /* NOT_OWNER */, message: "Only owner can verify" } };
1008
+ }
1009
+ const toVerify = [];
1010
+ const alreadyVerified = [];
1011
+ const notStaked = [];
1012
+ const participantChecks = await Promise.all(
1013
+ participants.map(
1014
+ (addr) => this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "participants", args: [addr] })
1015
+ )
1016
+ );
1017
+ for (let i = 0; i < participants.length; i++) {
1018
+ const [hasStaked, isVerified] = participantChecks[i];
1019
+ if (!hasStaked) notStaked.push(participants[i]);
1020
+ else if (isVerified) alreadyVerified.push(participants[i]);
1021
+ else toVerify.push(participants[i]);
1022
+ }
1023
+ if (notStaked.length > 0) {
1024
+ return { success: false, error: { code: "NOT_STAKED" /* NOT_STAKED */, message: `${notStaked.length} not staked` }, toVerify, alreadyVerified, notStaked };
1025
+ }
1026
+ if (toVerify.length === 0) {
1027
+ return { success: false, error: { code: "ALREADY_VERIFIED" /* ALREADY_VERIFIED */, message: "All already verified" }, toVerify, alreadyVerified, notStaked };
1028
+ }
1029
+ const currentVerified = await this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "verifiedCount" });
1030
+ let gasEstimate;
1031
+ if (participants.length === 1) {
1032
+ await this.publicClient.simulateContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "verify", args: [participants[0]], account });
1033
+ gasEstimate = await this.publicClient.estimateContractGas({ address: vaultAddress, abi: VaultATFiABI, functionName: "verify", args: [participants[0]], account });
1034
+ } else {
1035
+ await this.publicClient.simulateContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "verifyBatch", args: [participants], account });
1036
+ gasEstimate = await this.publicClient.estimateContractGas({ address: vaultAddress, abi: VaultATFiABI, functionName: "verifyBatch", args: [participants], account });
1037
+ }
1038
+ return {
1039
+ success: true,
1040
+ toVerify,
1041
+ alreadyVerified,
1042
+ notStaked,
1043
+ currentVerified: Number(currentVerified),
1044
+ newVerifiedCount: Number(currentVerified) + toVerify.length,
1045
+ gasEstimate
1046
+ };
1047
+ } catch (error) {
1048
+ const parsed = parseContractError(error);
1049
+ return { success: false, error: { code: parsed.code, message: parsed.message } };
1050
+ }
1051
+ }
1052
+ async _simulateSettleEvent(params) {
1053
+ const { vaultAddress } = params;
1054
+ try {
1055
+ const wallet = this.ensureWallet();
1056
+ const account = wallet.account;
1057
+ if (!account) {
1058
+ return { success: false, error: { code: "CONTRACT_ERROR" /* CONTRACT_ERROR */, message: "No account connected" } };
1059
+ }
1060
+ const [owner, totalStaked, verifiedCount, participantCount, settled, hasYield, assetToken, stakeAmount, yieldInfo] = await Promise.all([
1061
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "owner" }),
1062
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "totalStaked" }),
1063
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "verifiedCount" }),
1064
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "getParticipantCount" }),
1065
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "settled" }),
1066
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "hasYield" }),
1067
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "assetToken" }),
1068
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "stakeAmount" }),
1069
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "getYieldInfo" })
1070
+ ]);
1071
+ const tokenInfo = getTokenByAddress(assetToken);
1072
+ const decimals = tokenInfo?.decimals ?? 6;
1073
+ const noShowCount = Number(participantCount) - Number(verifiedCount);
1074
+ const baseResult = {
1075
+ totalStaked: fromTokenUnits(totalStaked, decimals),
1076
+ verifiedCount: Number(verifiedCount),
1077
+ noShowCount
1078
+ };
1079
+ if (owner.toLowerCase() !== account.address.toLowerCase()) {
1080
+ return { success: false, error: { code: "NOT_OWNER" /* NOT_OWNER */, message: "Only owner can settle" }, ...baseResult };
1081
+ }
1082
+ if (settled) {
1083
+ return { success: false, error: { code: "VAULT_ALREADY_SETTLED" /* VAULT_ALREADY_SETTLED */, message: "Already settled" }, ...baseResult };
1084
+ }
1085
+ const yield_ = yieldInfo;
1086
+ const estimatedYield = hasYield ? yield_[3] : 0n;
1087
+ const noShowStakes = BigInt(noShowCount) * stakeAmount;
1088
+ const protocolFeeOnYield = estimatedYield / 10n;
1089
+ const protocolFeeOnNoShow = noShowStakes / 10n;
1090
+ const totalProtocolFees = protocolFeeOnYield + protocolFeeOnNoShow;
1091
+ const netBonus = noShowStakes - protocolFeeOnNoShow + (estimatedYield - protocolFeeOnYield);
1092
+ const rewardPerParticipant = Number(verifiedCount) > 0 ? stakeAmount + netBonus / BigInt(Number(verifiedCount)) : 0n;
1093
+ await this.publicClient.simulateContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "settle", account });
1094
+ const gasEstimate = await this.publicClient.estimateContractGas({ address: vaultAddress, abi: VaultATFiABI, functionName: "settle", account });
1095
+ return {
1096
+ success: true,
1097
+ ...baseResult,
1098
+ estimatedYield: fromTokenUnits(estimatedYield, decimals),
1099
+ estimatedProtocolFees: fromTokenUnits(totalProtocolFees, decimals),
1100
+ estimatedNoShowFees: fromTokenUnits(protocolFeeOnNoShow, decimals),
1101
+ estimatedRewardPerParticipant: fromTokenUnits(rewardPerParticipant, decimals),
1102
+ gasEstimate
1103
+ };
1104
+ } catch (error) {
1105
+ const parsed = parseContractError(error);
1106
+ return { success: false, error: { code: parsed.code, message: parsed.message } };
1107
+ }
1108
+ }
1109
+ async _simulateClaim(params) {
1110
+ const { vaultAddress } = params;
1111
+ try {
1112
+ const wallet = this.ensureWallet();
1113
+ const account = wallet.account;
1114
+ if (!account) {
1115
+ return { success: false, error: { code: "CONTRACT_ERROR" /* CONTRACT_ERROR */, message: "No account connected" } };
1116
+ }
1117
+ const [claimable, participant, settled, assetToken, stakeAmount] = await Promise.all([
1118
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "getClaimable", args: [account.address] }),
1119
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "participants", args: [account.address] }),
1120
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "settled" }),
1121
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "assetToken" }),
1122
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "stakeAmount" })
1123
+ ]);
1124
+ const tokenInfo = getTokenByAddress(assetToken);
1125
+ const decimals = tokenInfo?.decimals ?? 6;
1126
+ const symbol = tokenInfo?.symbol ?? "UNKNOWN";
1127
+ const p = participant;
1128
+ if (!settled) return { success: false, error: { code: "VAULT_NOT_SETTLED" /* VAULT_NOT_SETTLED */, message: "Not settled yet" }, tokenSymbol: symbol };
1129
+ if (!p[0]) return { success: false, error: { code: "NOT_STAKED" /* NOT_STAKED */, message: "Not registered" }, tokenSymbol: symbol };
1130
+ if (!p[1]) return { success: false, error: { code: "NOT_VERIFIED" /* NOT_VERIFIED */, message: "Not verified" }, tokenSymbol: symbol, stakeAmount: fromTokenUnits(stakeAmount, decimals) };
1131
+ if (p[2]) return { success: false, error: { code: "ALREADY_CLAIMED" /* ALREADY_CLAIMED */, message: "Already claimed" }, tokenSymbol: symbol };
1132
+ if (claimable === 0n) return { success: false, error: { code: "NOTHING_TO_CLAIM" /* NOTHING_TO_CLAIM */, message: "Nothing to claim" }, tokenSymbol: symbol };
1133
+ const claimableAmount = claimable;
1134
+ const stakeAmountBigInt = stakeAmount;
1135
+ const bonusShare = claimableAmount > stakeAmountBigInt ? claimableAmount - stakeAmountBigInt : 0n;
1136
+ await this.publicClient.simulateContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "claim", account });
1137
+ const gasEstimate = await this.publicClient.estimateContractGas({ address: vaultAddress, abi: VaultATFiABI, functionName: "claim", account });
1138
+ return {
1139
+ success: true,
1140
+ claimableAmount: fromTokenUnits(claimableAmount, decimals),
1141
+ tokenSymbol: symbol,
1142
+ stakeAmount: fromTokenUnits(stakeAmountBigInt, decimals),
1143
+ bonusShare: fromTokenUnits(bonusShare, decimals),
1144
+ gasEstimate
1145
+ };
1146
+ } catch (error) {
1147
+ const parsed = parseContractError(error);
1148
+ return { success: false, error: { code: parsed.code, message: parsed.message } };
1149
+ }
1150
+ }
1151
+ // ============ Private: Execution Methods ============
1152
+ async _executeCreateEvent(params, callbacks) {
1153
+ const { stakeAmount, maxParticipants, useYield = false, token = "USDC" } = params;
1154
+ const tokenInfo = getTokenBySymbol(token);
1155
+ const stakeAmountBigInt = toTokenUnits(stakeAmount, tokenInfo.decimals);
1156
+ const wallet = this.ensureWallet();
1157
+ const account = wallet.account;
1158
+ const functionName = useYield ? "createVault" : "createVaultNoYield";
1159
+ callbacks?.onSubmitting?.();
1160
+ const hash = await wallet.writeContract({
1161
+ address: this.factoryAddress,
1162
+ abi: FactoryATFiABI,
1163
+ functionName,
1164
+ args: [tokenInfo.address, stakeAmountBigInt, BigInt(maxParticipants)],
1165
+ account,
1166
+ chain: null
1167
+ });
1168
+ callbacks?.onSubmitted?.(hash);
1169
+ callbacks?.onConfirming?.();
1170
+ const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
1171
+ const vaultCreatedLog = receipt.logs.find((log) => {
1172
+ try {
1173
+ return decodeEventLog({ abi: FactoryATFiABI, data: log.data, topics: log.topics }).eventName === "VaultCreated";
1174
+ } catch {
1175
+ return false;
1176
+ }
1177
+ });
1178
+ if (!vaultCreatedLog) throw new ATFiError("VaultCreated event not found", "CONTRACT_ERROR" /* CONTRACT_ERROR */);
1179
+ const decoded = decodeEventLog({ abi: FactoryATFiABI, data: vaultCreatedLog.data, topics: vaultCreatedLog.topics });
1180
+ const args = decoded.args;
1181
+ return { vaultId: args.vaultId, vaultAddress: args.vault, txHash: hash };
1182
+ }
1183
+ async _executeRegister(params, callbacks) {
1184
+ const { vaultAddress } = params;
1185
+ const wallet = this.ensureWallet();
1186
+ const account = wallet.account;
1187
+ const [stakeAmount, assetToken] = await Promise.all([
1188
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "stakeAmount" }),
1189
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "assetToken" })
1190
+ ]);
1191
+ const tokenInfo = getTokenByAddress(assetToken);
1192
+ const decimals = tokenInfo?.decimals ?? 6;
1193
+ const allowance = await this.publicClient.readContract({
1194
+ address: assetToken,
1195
+ abi: ERC20ABI,
1196
+ functionName: "allowance",
1197
+ args: [account.address, vaultAddress]
1198
+ });
1199
+ if (allowance < stakeAmount) {
1200
+ callbacks?.onApproving?.();
1201
+ const approveHash = await wallet.writeContract({
1202
+ address: assetToken,
1203
+ abi: ERC20ABI,
1204
+ functionName: "approve",
1205
+ args: [vaultAddress, stakeAmount],
1206
+ account,
1207
+ chain: null
1208
+ });
1209
+ callbacks?.onApproved?.(approveHash);
1210
+ await this.publicClient.waitForTransactionReceipt({ hash: approveHash });
1211
+ }
1212
+ callbacks?.onSubmitting?.();
1213
+ const hash = await wallet.writeContract({
1214
+ address: vaultAddress,
1215
+ abi: VaultATFiABI,
1216
+ functionName: "stake",
1217
+ account,
1218
+ chain: null
1219
+ });
1220
+ callbacks?.onSubmitted?.(hash);
1221
+ callbacks?.onConfirming?.();
1222
+ await this.publicClient.waitForTransactionReceipt({ hash });
1223
+ return { txHash: hash, stakeAmount: fromTokenUnits(stakeAmount, decimals) };
1224
+ }
1225
+ async _executeStartEvent(params, callbacks) {
1226
+ const { vaultAddress } = params;
1227
+ const wallet = this.ensureWallet();
1228
+ const account = wallet.account;
1229
+ callbacks?.onSubmitting?.();
1230
+ const hash = await wallet.writeContract({
1231
+ address: vaultAddress,
1232
+ abi: VaultATFiABI,
1233
+ functionName: "depositToYield",
1234
+ account,
1235
+ chain: null
1236
+ });
1237
+ callbacks?.onSubmitted?.(hash);
1238
+ callbacks?.onConfirming?.();
1239
+ const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
1240
+ const [totalStaked, hasYield, assetToken] = await Promise.all([
1241
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "totalStaked" }),
1242
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "hasYield" }),
1243
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "assetToken" })
1244
+ ]);
1245
+ const tokenInfo = getTokenByAddress(assetToken);
1246
+ const decimals = tokenInfo?.decimals ?? 6;
1247
+ let sharesReceived;
1248
+ const depositLog = receipt.logs.find((log) => {
1249
+ try {
1250
+ return decodeEventLog({ abi: VaultATFiABI, data: log.data, topics: log.topics }).eventName === "DepositedToYield";
1251
+ } catch {
1252
+ return false;
1253
+ }
1254
+ });
1255
+ if (depositLog && hasYield) {
1256
+ const decoded = decodeEventLog({ abi: VaultATFiABI, data: depositLog.data, topics: depositLog.topics });
1257
+ sharesReceived = decoded.args.shares.toString();
1258
+ }
1259
+ return { txHash: hash, totalStaked: fromTokenUnits(totalStaked, decimals), hasYield, sharesReceived };
1260
+ }
1261
+ async _executeVerifyParticipant(params, callbacks) {
1262
+ const { vaultAddress, participants } = params;
1263
+ const wallet = this.ensureWallet();
1264
+ const account = wallet.account;
1265
+ callbacks?.onSubmitting?.();
1266
+ let hash;
1267
+ if (participants.length === 1) {
1268
+ hash = await wallet.writeContract({
1269
+ address: vaultAddress,
1270
+ abi: VaultATFiABI,
1271
+ functionName: "verify",
1272
+ args: [participants[0]],
1273
+ account,
1274
+ chain: null
1275
+ });
1276
+ } else {
1277
+ hash = await wallet.writeContract({
1278
+ address: vaultAddress,
1279
+ abi: VaultATFiABI,
1280
+ functionName: "verifyBatch",
1281
+ args: [participants],
1282
+ account,
1283
+ chain: null
1284
+ });
1285
+ }
1286
+ callbacks?.onSubmitted?.(hash);
1287
+ callbacks?.onConfirming?.();
1288
+ await this.publicClient.waitForTransactionReceipt({ hash });
1289
+ const totalVerified = await this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "verifiedCount" });
1290
+ return { txHash: hash, verifiedCount: participants.length, totalVerified: Number(totalVerified) };
1291
+ }
1292
+ async _executeSettleEvent(params, callbacks) {
1293
+ const { vaultAddress } = params;
1294
+ const wallet = this.ensureWallet();
1295
+ const account = wallet.account;
1296
+ const assetToken = await this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "assetToken" });
1297
+ const tokenInfo = getTokenByAddress(assetToken);
1298
+ const decimals = tokenInfo?.decimals ?? 6;
1299
+ callbacks?.onSubmitting?.();
1300
+ const hash = await wallet.writeContract({
1301
+ address: vaultAddress,
1302
+ abi: VaultATFiABI,
1303
+ functionName: "settle",
1304
+ account,
1305
+ chain: null
1306
+ });
1307
+ callbacks?.onSubmitted?.(hash);
1308
+ callbacks?.onConfirming?.();
1309
+ const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
1310
+ const settledLog = receipt.logs.find((log) => {
1311
+ try {
1312
+ return decodeEventLog({ abi: VaultATFiABI, data: log.data, topics: log.topics }).eventName === "Settled";
1313
+ } catch {
1314
+ return false;
1315
+ }
1316
+ });
1317
+ let totalYieldEarned = "0", protocolFees = "0", noShowFees = "0";
1318
+ if (settledLog) {
1319
+ const decoded = decodeEventLog({ abi: VaultATFiABI, data: settledLog.data, topics: settledLog.topics });
1320
+ const args = decoded.args;
1321
+ totalYieldEarned = fromTokenUnits(args.totalYield, decimals);
1322
+ protocolFees = fromTokenUnits(args.protocolFee, decimals);
1323
+ noShowFees = fromTokenUnits(args.noShowFee, decimals);
1324
+ }
1325
+ return { txHash: hash, totalYieldEarned, protocolFees, noShowFees };
1326
+ }
1327
+ async _executeClaim(params, callbacks) {
1328
+ const { vaultAddress } = params;
1329
+ const wallet = this.ensureWallet();
1330
+ const account = wallet.account;
1331
+ const [claimable, assetToken] = await Promise.all([
1332
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "getClaimable", args: [account.address] }),
1333
+ this.publicClient.readContract({ address: vaultAddress, abi: VaultATFiABI, functionName: "assetToken" })
1334
+ ]);
1335
+ const tokenInfo = getTokenByAddress(assetToken);
1336
+ const decimals = tokenInfo?.decimals ?? 6;
1337
+ callbacks?.onSubmitting?.();
1338
+ const hash = await wallet.writeContract({
1339
+ address: vaultAddress,
1340
+ abi: VaultATFiABI,
1341
+ functionName: "claim",
1342
+ account,
1343
+ chain: null
1344
+ });
1345
+ callbacks?.onSubmitted?.(hash);
1346
+ callbacks?.onConfirming?.();
1347
+ await this.publicClient.waitForTransactionReceipt({ hash });
1348
+ return { txHash: hash, amountClaimed: fromTokenUnits(claimable, decimals) };
1349
+ }
1350
+ };
1351
+ export {
1352
+ ATFiError,
1353
+ ATFiErrorCode,
1354
+ ATFiSDK,
1355
+ CHAIN_ID,
1356
+ CONTRACTS,
1357
+ ERC20ABI,
1358
+ EventStatus,
1359
+ FactoryATFiABI,
1360
+ ParticipantStatus,
1361
+ TOKENS,
1362
+ VaultATFiABI,
1363
+ formatAmount,
1364
+ fromTokenUnits,
1365
+ getTokenByAddress,
1366
+ getTokenBySymbol,
1367
+ parseContractError,
1368
+ toTokenUnits
1369
+ };