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