aiia-vault-sdk 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/SeedRoundFundraiser.ts +742 -0
  2. package/TradingVault.ts +863 -0
  3. package/abis/SeedRoundFundraiser.json +1519 -0
  4. package/abis/TradingVault.json +1647 -0
  5. package/common.ts +131 -0
  6. package/contracts/SeedRoundFundraiser.ts +1670 -0
  7. package/contracts/TradingVault.ts +1752 -0
  8. package/contracts/common.ts +131 -0
  9. package/contracts/factories/SeedRoundFundraiser__factory.ts +1495 -0
  10. package/contracts/factories/index.ts +4 -0
  11. package/contracts/index.ts +6 -0
  12. package/contracts.json +28 -0
  13. package/dist/SeedRoundFundraiser.d.ts +130 -0
  14. package/dist/SeedRoundFundraiser.js +445 -0
  15. package/dist/TradingVault.d.ts +175 -0
  16. package/dist/TradingVault.js +521 -0
  17. package/dist/abis/SeedRoundFundraiser.json +1519 -0
  18. package/dist/abis/TradingVault.json +1647 -0
  19. package/dist/common.d.ts +50 -0
  20. package/dist/common.js +2 -0
  21. package/dist/contracts/SeedRoundFundraiser.d.ts +936 -0
  22. package/dist/contracts/SeedRoundFundraiser.js +2 -0
  23. package/dist/contracts/TradingVault.d.ts +930 -0
  24. package/dist/contracts/TradingVault.js +2 -0
  25. package/dist/contracts.json +28 -0
  26. package/dist/index.d.ts +3 -0
  27. package/dist/index.js +19 -0
  28. package/dist/types.d.ts +291 -0
  29. package/dist/types.js +2 -0
  30. package/dist/utils.d.ts +95 -0
  31. package/dist/utils.js +370 -0
  32. package/dist/whitelist-tokens.json +14 -0
  33. package/index.ts +3 -0
  34. package/package.json +21 -0
  35. package/temp/aiia-vault-sdk-1.0.0.tgz +0 -0
  36. package/tsconfig.json +15 -0
  37. package/types.ts +301 -0
  38. package/utils.ts +576 -0
  39. package/whitelist-tokens.json +14 -0
@@ -0,0 +1,4 @@
1
+ /* Autogenerated file. Do not edit manually. */
2
+ /* tslint:disable */
3
+ /* eslint-disable */
4
+ export { SeedRoundFundraiser__factory } from "./SeedRoundFundraiser__factory";
@@ -0,0 +1,6 @@
1
+ /* Autogenerated file. Do not edit manually. */
2
+ /* tslint:disable */
3
+ /* eslint-disable */
4
+ export type { SeedRoundFundraiser } from "./SeedRoundFundraiser";
5
+ export * as factories from "./factories";
6
+ export { SeedRoundFundraiser__factory } from "./factories/SeedRoundFundraiser__factory";
package/contracts.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "sepolia": {
3
+ "Currency-old": "0x8c1598399bEb88F9a2aF5966438D4f481512C2f8",
4
+ "Reward-old": "0x098048C7F6Afd2dA8661965e2d34bf009faA12F2",
5
+ "TradingVault": "0x1567fEF642c15bbc0738200F04c52e4966cFA0c9",
6
+ "TradingVault-implemented": "0x74890EC41c499d998d9131a738EFF51229A7f989",
7
+ "TradingVault-implemented-old": "0x74890EC41c499d998d9131a738EFF51229A7f989",
8
+ "Currency": "0x2677818cf5e8519273f354FBDA21F794309d8D98",
9
+ "Reward": "0x09F827Fa3307cF467F51782722A5e3f43a2598dc",
10
+ "SeedRoundFundraiser": "0xDB40B1E554718555B2E55574B36f0974635c93f4",
11
+ "SeedRoundFundraiser-implemented": "0xEF7bDB1A5D287d6B3f9a6bD9008471C728249732",
12
+ "WETH": "0xC82AE9c8b25F5b48ac200efd3e86Ca372AE1AD91"
13
+ },
14
+ "hardhat": {
15
+ "Currency": "0x5FbDB2315678afecb367f032d93F642f64180aa3",
16
+ "Reward": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",
17
+ "TradingVault": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
18
+ "TradingVault-implemented": "0x5FbDB2315678afecb367f032d93F642f64180aa3"
19
+ },
20
+ "base-sepolia": {
21
+ "Currency": "0xDB2e50234a3BE8aA4200C96712F190cf712cd8ec",
22
+ "Reward": "0xa5Ef2328aa2F6F231D15cdcF48503974D0938eD4",
23
+ "SeedRoundFundraiser": "0xbd520dbcb8e0b062D10d7879D27C20d214a262F6",
24
+ "SeedRoundFundraiser-implemented": "0x539C6D1f51d42f4A1376B0998b4Fff602C9908a6",
25
+ "WETH": "0x08a2d38807B1D345b6c1642f8030a29DC2Cc7223",
26
+ "SeedRoundFundraiser-implemented-old": "0x823f099526F2c69bD764686bb4D41afeD7509366"
27
+ }
28
+ }
@@ -0,0 +1,130 @@
1
+ import { ethers } from "ethers";
2
+ import { ParsedSeedRoundFundraiserEvent, ParsedSeedRoundFundraiserEventRaw } from "./types";
3
+ import { type SendTransactionMutateAsync } from "@wagmi/core/query";
4
+ import { Config } from "@wagmi/core/dist/types/createConfig";
5
+ export interface WhitelistedToken {
6
+ isWhitelisted: boolean;
7
+ price: number;
8
+ }
9
+ export interface WhitelistedTokenInfo {
10
+ address: string;
11
+ isWhitelisted: boolean;
12
+ price: number;
13
+ symbol: string;
14
+ maxContribution: number;
15
+ maxContributionRaw: number;
16
+ decimals: number;
17
+ }
18
+ export interface RoundConfig {
19
+ startTime: number;
20
+ endTime: number;
21
+ targetFund: number;
22
+ totalAllocation: number;
23
+ maxFundPerAccount: number;
24
+ exists: boolean;
25
+ ended: boolean;
26
+ claimingEnabled: boolean;
27
+ refundEnabled: boolean;
28
+ }
29
+ export interface UserContribution {
30
+ fundAmount: number;
31
+ tokenAllocation: number;
32
+ claimed: boolean;
33
+ refunded: boolean;
34
+ contributedToken: string;
35
+ contributedAmount: number;
36
+ }
37
+ export declare class SeedRoundFundraiserSDK {
38
+ name: string;
39
+ private contract;
40
+ private providers;
41
+ private contractAddress;
42
+ private isBootstrapped;
43
+ private PRICE_PRECISION;
44
+ private whitelistedTokensArray;
45
+ private networkName;
46
+ constructor(rpcUrls: string | string[], contractAddress?: string);
47
+ private getNetworkNameFromRpc;
48
+ private importWhitelistedTokens;
49
+ getWhitelistedTokenInfo(tokenAddress: string): Promise<WhitelistedTokenInfo | null>;
50
+ getAllWhitelistedTokensInfo(): Promise<WhitelistedTokenInfo[]>;
51
+ private getRandomProvider;
52
+ private getContractWithRandomProvider;
53
+ bootstrap(): Promise<void>;
54
+ signAndSendTransaction(tx: ethers.ContractTransaction, wallet: ethers.Wallet | SendTransactionMutateAsync<Config, any>, callbacks?: {
55
+ onSubmit?: (tx: string) => void | Promise<void>;
56
+ onFinally?: (status: {
57
+ status: boolean | null;
58
+ confirmations: number;
59
+ txHash: string;
60
+ isCompleted: boolean;
61
+ attempts: number;
62
+ }) => void | Promise<void>;
63
+ onError?: (error: Error) => void | Promise<void>;
64
+ }): Promise<{
65
+ transaction: {
66
+ hash: string;
67
+ };
68
+ status: {
69
+ status: boolean | null;
70
+ confirmations: number;
71
+ isCompleted: boolean;
72
+ attempts: number;
73
+ };
74
+ }>;
75
+ buildAddWhitelistedTokenTx(token: string, price: number): Promise<ethers.ContractTransaction>;
76
+ buildUpdateTokenPriceTx(token: string, newPrice: number): Promise<ethers.ContractTransaction>;
77
+ buildRemoveWhitelistedTokenTx(token: string): Promise<ethers.ContractTransaction>;
78
+ buildCreateRoundTx(startTime: number, endTime: number, targetFund: number, totalAllocation: number, maxFundPerAccount: number): Promise<ethers.ContractTransaction>;
79
+ buildUpdateRoundTx(roundId: number, startTime: number, endTime: number, targetFund: number, totalAllocation: number, maxFundPerAccount: number): Promise<ethers.ContractTransaction>;
80
+ buildEndRoundTx(roundId: number): Promise<ethers.ContractTransaction>;
81
+ buildSetClaimingEnabledTx(roundId: number, enabled: boolean): Promise<ethers.ContractTransaction>;
82
+ buildSetRefundEnabledTx(roundId: number, enabled: boolean): Promise<ethers.ContractTransaction>;
83
+ buildContributeTx(roundId: number, token: string, amount: number): Promise<ethers.ContractTransaction>;
84
+ buildClaimTokensTx(): Promise<ethers.ContractTransaction>;
85
+ buildRefundTx(): Promise<ethers.ContractTransaction>;
86
+ buildWithdrawFundsTx(token: string, amount: number): Promise<ethers.ContractTransaction>;
87
+ buildClaimTokensByRoundIdTx(roundId: number): Promise<ethers.ContractTransaction>;
88
+ getWhitelistedToken(token: string): Promise<WhitelistedToken>;
89
+ getRound(roundId: number): Promise<RoundConfig>;
90
+ getUserContribution(roundId: number, user: string): Promise<UserContribution>;
91
+ getRoundRaisedFunds(roundId: number): Promise<number>;
92
+ getRoundParticipants(roundId: number): Promise<number>;
93
+ getUserParticipatedRound(user: string): Promise<number>;
94
+ getProjectToken(): Promise<string>;
95
+ getTotalRounds(): Promise<number>;
96
+ getTotalRaisedFunds(): Promise<number>;
97
+ isRoundActive(roundId: number): Promise<boolean>;
98
+ /**
99
+ * Get the ID of the latest round
100
+ * @returns The ID of the latest round or -1 if no rounds exist
101
+ */
102
+ getLatestRoundId(): Promise<number>;
103
+ /**
104
+ * Get comprehensive information about a specific round
105
+ * @param roundId The ID of the round to get information for
106
+ * @returns An object containing all information about the specified round
107
+ */
108
+ getRoundInfo(roundId: number): Promise<{
109
+ roundId: number;
110
+ config: RoundConfig;
111
+ raisedFunds: number;
112
+ participants: number;
113
+ isActive: boolean;
114
+ }>;
115
+ getUserTotalContribution(user: string): Promise<{
116
+ totalFundAmount: number;
117
+ totalTokenAllocation: number;
118
+ }>;
119
+ getTransactionStatus(txHash: string, maxRetries?: number): Promise<{
120
+ hash: string;
121
+ status: boolean | null;
122
+ confirmations: number;
123
+ isCompleted: boolean;
124
+ attempts: number;
125
+ }>;
126
+ getContractAddress(): string;
127
+ getAllEvents(fromBlock: number, toBlock: number): Promise<ParsedSeedRoundFundraiserEventRaw[]>;
128
+ streamEvents(fromBlock: number, onEvent: (event: ParsedSeedRoundFundraiserEvent) => Promise<void>, saveLatestBlock: (blockNumber: number) => Promise<void>, batchSize?: number, sleepTime?: number): Promise<void>;
129
+ formatEventArgs: (event: ParsedSeedRoundFundraiserEventRaw) => ParsedSeedRoundFundraiserEvent;
130
+ }
@@ -0,0 +1,445 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SeedRoundFundraiserSDK = void 0;
7
+ const ethers_1 = require("ethers");
8
+ const SeedRoundFundraiser_json_1 = __importDefault(require("./abis/SeedRoundFundraiser.json"));
9
+ const contracts_json_1 = __importDefault(require("./contracts.json"));
10
+ const utils_1 = require("./utils");
11
+ const whitelist_tokens_json_1 = __importDefault(require("./whitelist-tokens.json"));
12
+ class SeedRoundFundraiserSDK {
13
+ constructor(rpcUrls, contractAddress) {
14
+ this.name = "SeedRoundFundraiser";
15
+ this.isBootstrapped = false;
16
+ this.PRICE_PRECISION = 1e18;
17
+ this.whitelistedTokensArray = [];
18
+ this.formatEventArgs = (event) => {
19
+ const { eventName, args } = event;
20
+ switch (eventName) {
21
+ case "TokenWhitelisted":
22
+ return {
23
+ ...event,
24
+ args: {
25
+ ...args,
26
+ token: args.token.toLowerCase(),
27
+ price: Number(args.price) / this.PRICE_PRECISION,
28
+ },
29
+ };
30
+ case "TokenPriceUpdated":
31
+ return {
32
+ ...event,
33
+ args: {
34
+ ...args,
35
+ token: args.token.toLowerCase(),
36
+ oldPrice: Number(args.oldPrice) / this.PRICE_PRECISION,
37
+ newPrice: Number(args.newPrice) / this.PRICE_PRECISION,
38
+ },
39
+ };
40
+ case "TokenRemovedFromWhitelist":
41
+ return {
42
+ ...event,
43
+ args: {
44
+ ...args,
45
+ token: args.token.toLowerCase(),
46
+ },
47
+ };
48
+ case "RoundCreated":
49
+ case "RoundUpdated":
50
+ return {
51
+ ...event,
52
+ args: {
53
+ ...args,
54
+ roundId: Number(args.roundId),
55
+ startTime: Number(args.startTime),
56
+ endTime: Number(args.endTime),
57
+ targetFund: Number(args.targetFund) / this.PRICE_PRECISION,
58
+ totalAllocation: Number(args.totalAllocation),
59
+ maxFundPerAccount: Number(args.maxFundPerAccount) / this.PRICE_PRECISION,
60
+ },
61
+ };
62
+ case "RoundEnded":
63
+ return {
64
+ ...event,
65
+ args: {
66
+ ...args,
67
+ roundId: Number(args.roundId),
68
+ raisedFunds: Number(args.raisedFunds) / this.PRICE_PRECISION,
69
+ participants: Number(args.participants),
70
+ },
71
+ };
72
+ case "Contribution":
73
+ return {
74
+ ...event,
75
+ args: {
76
+ ...args,
77
+ roundId: Number(args.roundId),
78
+ contributor: args.contributor.toLowerCase(),
79
+ token: args.token.toLowerCase(),
80
+ amount: Number(args.amount),
81
+ fundAmount: Number(args.fundAmount) / this.PRICE_PRECISION,
82
+ tokenAllocation: Number(args.tokenAllocation),
83
+ },
84
+ };
85
+ case "TokensClaimed":
86
+ return {
87
+ ...event,
88
+ args: {
89
+ ...args,
90
+ roundId: Number(args.roundId),
91
+ user: args.user.toLowerCase(),
92
+ amount: Number(args.amount),
93
+ },
94
+ };
95
+ case "ProjectTokenUpdated":
96
+ return {
97
+ ...event,
98
+ args: {
99
+ ...args,
100
+ oldToken: args.oldToken.toLowerCase(),
101
+ newToken: args.newToken.toLowerCase(),
102
+ },
103
+ };
104
+ case "ClaimingEnabledUpdated":
105
+ case "RefundEnabledUpdated":
106
+ return {
107
+ ...event,
108
+ args: {
109
+ ...args,
110
+ roundId: Number(args.roundId),
111
+ enabled: args.enabled,
112
+ },
113
+ };
114
+ case "Refunded":
115
+ return {
116
+ ...event,
117
+ args: {
118
+ ...args,
119
+ roundId: Number(args.roundId),
120
+ user: args.user.toLowerCase(),
121
+ token: args.token.toLowerCase(),
122
+ amount: Number(args.amount),
123
+ },
124
+ };
125
+ default:
126
+ return event;
127
+ }
128
+ };
129
+ // Convert single RPC to array if needed
130
+ const rpcArray = Array.isArray(rpcUrls) ? rpcUrls : [rpcUrls];
131
+ // Create providers for each RPC
132
+ this.providers = rpcArray.map((rpc) => new ethers_1.ethers.JsonRpcProvider(rpc));
133
+ // Get a random provider for initial setup
134
+ const initialProvider = (0, utils_1.getRandomProvider)(this.providers);
135
+ // Determine contract address based on RPC URL if not provided
136
+ this.contractAddress = (0, utils_1.resolveContractAddress)(rpcArray[0], this.name, contracts_json_1.default, contractAddress);
137
+ // Initialize contract with initial provider
138
+ this.contract = new ethers_1.ethers.Contract(this.contractAddress, SeedRoundFundraiser_json_1.default.abi, initialProvider);
139
+ // Determine network name from RPC URL
140
+ this.networkName = this.getNetworkNameFromRpc(rpcArray[0]);
141
+ // Import whitelisted tokens from JSON file
142
+ this.importWhitelistedTokens();
143
+ }
144
+ getNetworkNameFromRpc(rpcUrl) {
145
+ const rpcLower = rpcUrl.toLowerCase();
146
+ // Extract network name from RPC URL or use a default method
147
+ if (rpcLower.includes("sepolia.base")) {
148
+ return "base-sepolia";
149
+ }
150
+ else if (rpcLower.includes("sepolia")) {
151
+ return "sepolia";
152
+ }
153
+ else if (rpcLower.includes("mainnet")) {
154
+ return "mainnet";
155
+ }
156
+ else if (rpcLower.includes("localhost") ||
157
+ rpcLower.includes("127.0.0.1")) {
158
+ return "hardhat";
159
+ }
160
+ // Default to sepolia if can't determine
161
+ return "sepolia";
162
+ }
163
+ importWhitelistedTokens() {
164
+ try {
165
+ // Try to read the whitelist-tokens.json file
166
+ // Check if the network exists in the whitelist data
167
+ if (whitelist_tokens_json_1.default[this.networkName]) {
168
+ this.whitelistedTokensArray = whitelist_tokens_json_1.default[this.networkName].map((address) => address.toLowerCase());
169
+ console.log(`Imported ${this.whitelistedTokensArray.length} whitelisted tokens for ${this.networkName} network`);
170
+ }
171
+ else {
172
+ console.log(`No whitelisted tokens found for ${this.networkName} network`);
173
+ }
174
+ }
175
+ catch (error) {
176
+ console.error("Error importing whitelisted tokens:", error);
177
+ }
178
+ }
179
+ // Get whitelisted token info from the array
180
+ async getWhitelistedTokenInfo(tokenAddress) {
181
+ // Convert to lowercase for case-insensitive comparison
182
+ const normalizedAddress = tokenAddress.toLowerCase();
183
+ // Check if token is in the whitelisted array
184
+ if (!this.whitelistedTokensArray.includes(normalizedAddress)) {
185
+ return null;
186
+ }
187
+ // Get token info from contract
188
+ const tokenInfo = await this.getWhitelistedToken(normalizedAddress);
189
+ // Skip if not whitelisted in contract
190
+ if (!tokenInfo.isWhitelisted) {
191
+ return null;
192
+ }
193
+ let symbol = "ETH";
194
+ let decimals = 18;
195
+ // Get token symbol and decimals
196
+ if (normalizedAddress !== ethers_1.ethers.ZeroAddress) {
197
+ [symbol, decimals] = await Promise.all([
198
+ (0, utils_1.getTokenSymbol)(normalizedAddress, this.getRandomProvider()),
199
+ (0, utils_1.getTokenDecimals)(normalizedAddress, this.getRandomProvider()),
200
+ ]);
201
+ }
202
+ // Get latest active round to determine max contribution
203
+ const latestRoundId = await this.getLatestRoundId();
204
+ let maxTokenContribution = 0;
205
+ if (latestRoundId >= 0) {
206
+ const roundInfo = await this.getRound(latestRoundId);
207
+ if (roundInfo.exists && !roundInfo.ended) {
208
+ // Calculate max token contribution based on maxFundPerAccount and token price
209
+ // maxTokens = (maxFundPerAccount / tokenPrice) * 10^decimals
210
+ maxTokenContribution = roundInfo.maxFundPerAccount / tokenInfo.price;
211
+ }
212
+ }
213
+ return {
214
+ address: normalizedAddress,
215
+ isWhitelisted: tokenInfo.isWhitelisted,
216
+ price: tokenInfo.price,
217
+ symbol: symbol,
218
+ maxContribution: maxTokenContribution,
219
+ maxContributionRaw: Math.floor(maxTokenContribution * Math.pow(10, decimals)),
220
+ decimals: decimals,
221
+ };
222
+ }
223
+ // Get all whitelisted tokens info
224
+ async getAllWhitelistedTokensInfo() {
225
+ const results = [];
226
+ for (const tokenAddress of this.whitelistedTokensArray) {
227
+ const tokenInfo = await this.getWhitelistedTokenInfo(tokenAddress);
228
+ if (tokenInfo) {
229
+ results.push(tokenInfo);
230
+ }
231
+ }
232
+ return results;
233
+ }
234
+ getRandomProvider() {
235
+ return (0, utils_1.getRandomProvider)(this.providers);
236
+ }
237
+ getContractWithRandomProvider() {
238
+ return new ethers_1.ethers.Contract(this.contractAddress, SeedRoundFundraiser_json_1.default.abi, this.getRandomProvider());
239
+ }
240
+ async bootstrap() {
241
+ if (this.isBootstrapped) {
242
+ return;
243
+ }
244
+ // Check health of all RPCs and remove inactive ones
245
+ const healthChecks = await Promise.all(this.providers.map((provider, index) => (0, utils_1.checkRpcHealth)(provider, index)));
246
+ // Filter out inactive providers
247
+ this.providers = this.providers.filter((_, index) => healthChecks[index]);
248
+ if (this.providers.length === 0) {
249
+ throw new Error("No active RPC providers available");
250
+ }
251
+ this.isBootstrapped = true;
252
+ }
253
+ async signAndSendTransaction(tx, wallet, callbacks = {}) {
254
+ return (0, utils_1.signAndSendTransaction)(tx, wallet, () => this.getRandomProvider(), callbacks, this.contract);
255
+ }
256
+ // Transaction builders
257
+ async buildAddWhitelistedTokenTx(token, price) {
258
+ const priceBigInt = BigInt(Math.floor(price * this.PRICE_PRECISION));
259
+ return await this.contract.addWhitelistedToken.populateTransaction(token, priceBigInt);
260
+ }
261
+ async buildUpdateTokenPriceTx(token, newPrice) {
262
+ const priceBigInt = BigInt(Math.floor(newPrice * this.PRICE_PRECISION));
263
+ return await this.contract.updateTokenPrice.populateTransaction(token, priceBigInt);
264
+ }
265
+ async buildRemoveWhitelistedTokenTx(token) {
266
+ return await this.contract.removeWhitelistedToken.populateTransaction(token);
267
+ }
268
+ async buildCreateRoundTx(startTime, endTime, targetFund, totalAllocation, maxFundPerAccount) {
269
+ const targetFundBigInt = BigInt(Math.floor(targetFund * this.PRICE_PRECISION));
270
+ const maxFundPerAccountBigInt = BigInt(Math.floor(maxFundPerAccount * this.PRICE_PRECISION));
271
+ const decimals = await (0, utils_1.getTokenDecimals)(await this.getProjectToken(), this.getRandomProvider());
272
+ const totalAllocationBigInt = BigInt(Math.floor(totalAllocation * Math.pow(10, decimals)));
273
+ return await this.contract.createRound.populateTransaction(startTime, endTime, targetFundBigInt, totalAllocationBigInt, maxFundPerAccountBigInt);
274
+ }
275
+ async buildUpdateRoundTx(roundId, startTime, endTime, targetFund, totalAllocation, maxFundPerAccount) {
276
+ const targetFundBigInt = BigInt(Math.floor(targetFund * this.PRICE_PRECISION));
277
+ const maxFundPerAccountBigInt = BigInt(Math.floor(maxFundPerAccount * this.PRICE_PRECISION));
278
+ return await this.contract.updateRound.populateTransaction(roundId, startTime, endTime, targetFundBigInt, totalAllocation, maxFundPerAccountBigInt);
279
+ }
280
+ async buildEndRoundTx(roundId) {
281
+ return await this.contract.endRound.populateTransaction(roundId);
282
+ }
283
+ async buildSetClaimingEnabledTx(roundId, enabled) {
284
+ return await this.contract.setClaimingEnabled.populateTransaction(roundId, enabled);
285
+ }
286
+ async buildSetRefundEnabledTx(roundId, enabled) {
287
+ return await this.contract.setRefundEnabled.populateTransaction(roundId, enabled);
288
+ }
289
+ async buildContributeTx(roundId, token, amount) {
290
+ let decimals = 18;
291
+ if (token !== ethers_1.ethers.ZeroAddress) {
292
+ decimals = await (0, utils_1.getTokenDecimals)(token, this.getRandomProvider());
293
+ }
294
+ const amountWei = ethers_1.ethers.parseUnits(amount.toString(), decimals);
295
+ const tx = await this.contract.contribute.populateTransaction(roundId, token, token === ethers_1.ethers.ZeroAddress ? 0 : amountWei);
296
+ if (token === ethers_1.ethers.ZeroAddress) {
297
+ tx.value = amountWei;
298
+ }
299
+ return tx;
300
+ }
301
+ async buildClaimTokensTx() {
302
+ return await this.contract.claimTokens.populateTransaction();
303
+ }
304
+ async buildRefundTx() {
305
+ return await this.contract.refund.populateTransaction();
306
+ }
307
+ async buildWithdrawFundsTx(token, amount) {
308
+ const decimals = await (0, utils_1.getTokenDecimals)(token, this.getRandomProvider());
309
+ const amountBigInt = BigInt(Math.floor(amount * Math.pow(10, decimals)));
310
+ return await this.contract.withdrawFunds.populateTransaction(token, amountBigInt);
311
+ }
312
+ async buildClaimTokensByRoundIdTx(roundId) {
313
+ return await this.contract.claimTokensByRoundId.populateTransaction(roundId);
314
+ }
315
+ // Read methods
316
+ async getWhitelistedToken(token) {
317
+ const result = await this.contract.whitelistedTokens(token);
318
+ return {
319
+ isWhitelisted: result.isWhitelisted,
320
+ price: Number(result.price) / this.PRICE_PRECISION,
321
+ };
322
+ }
323
+ async getRound(roundId) {
324
+ const result = await this.contract.rounds(roundId);
325
+ return {
326
+ startTime: Number(result.startTime),
327
+ endTime: Number(result.endTime),
328
+ targetFund: Number(result.targetFund) / this.PRICE_PRECISION,
329
+ totalAllocation: Number(result.totalAllocation),
330
+ maxFundPerAccount: Number(result.maxFundPerAccount) / this.PRICE_PRECISION,
331
+ exists: result.exists,
332
+ ended: result.ended,
333
+ claimingEnabled: result.claimingEnabled,
334
+ refundEnabled: result.refundEnabled,
335
+ };
336
+ }
337
+ async getUserContribution(roundId, user) {
338
+ const result = await this.contract.userContributions(roundId, user);
339
+ return {
340
+ fundAmount: Number(result.fundAmount) / this.PRICE_PRECISION,
341
+ tokenAllocation: Number(result.tokenAllocation),
342
+ claimed: result.claimed,
343
+ refunded: result.refunded,
344
+ contributedToken: result.contributedToken,
345
+ contributedAmount: Number(result.contributedAmount),
346
+ };
347
+ }
348
+ async getRoundRaisedFunds(roundId) {
349
+ const result = await this.contract.roundRaisedFunds(roundId);
350
+ return Number(result) / this.PRICE_PRECISION;
351
+ }
352
+ async getRoundParticipants(roundId) {
353
+ const result = await this.contract.roundParticipants(roundId);
354
+ return Number(result);
355
+ }
356
+ async getUserParticipatedRound(user) {
357
+ const result = await this.contract.userParticipatedRound(user);
358
+ return Number(result);
359
+ }
360
+ async getProjectToken() {
361
+ return await this.contract.projectToken();
362
+ }
363
+ async getTotalRounds() {
364
+ const result = await this.contract.totalRounds();
365
+ return Number(result);
366
+ }
367
+ async getTotalRaisedFunds() {
368
+ const result = await this.contract.totalRaisedFunds();
369
+ return Number(result) / this.PRICE_PRECISION;
370
+ }
371
+ async isRoundActive(roundId) {
372
+ return await this.contract.isRoundActive(roundId);
373
+ }
374
+ /**
375
+ * Get the ID of the latest round
376
+ * @returns The ID of the latest round or -1 if no rounds exist
377
+ */
378
+ async getLatestRoundId() {
379
+ // Get total number of rounds
380
+ const totalRounds = await this.getTotalRounds();
381
+ // If no rounds exist, return -1
382
+ if (totalRounds === 0) {
383
+ return -1;
384
+ }
385
+ // Latest round ID (0-indexed, so subtract 1)
386
+ return totalRounds - 1;
387
+ }
388
+ /**
389
+ * Get comprehensive information about a specific round
390
+ * @param roundId The ID of the round to get information for
391
+ * @returns An object containing all information about the specified round
392
+ */
393
+ async getRoundInfo(roundId) {
394
+ // Get total number of rounds
395
+ const totalRounds = await this.getTotalRounds();
396
+ // Check if roundId is valid
397
+ if (roundId < 0 || roundId >= totalRounds) {
398
+ throw new Error(`Invalid round ID: ${roundId}`);
399
+ }
400
+ // Get round configuration
401
+ const roundConfig = await this.getRound(roundId);
402
+ // Get additional information
403
+ const raisedFunds = await this.getRoundRaisedFunds(roundId);
404
+ const participants = await this.getRoundParticipants(roundId);
405
+ const isActive = await this.isRoundActive(roundId);
406
+ return {
407
+ roundId,
408
+ config: roundConfig,
409
+ raisedFunds,
410
+ participants,
411
+ isActive,
412
+ };
413
+ }
414
+ async getUserTotalContribution(user) {
415
+ const result = await this.contract.getUserTotalContribution(user);
416
+ return {
417
+ totalFundAmount: Number(result.totalFundAmount) / this.PRICE_PRECISION,
418
+ totalTokenAllocation: Number(result.totalTokenAllocation),
419
+ };
420
+ }
421
+ async getTransactionStatus(txHash, maxRetries = 10) {
422
+ return await (0, utils_1.getTransactionStatus)(this.getRandomProvider(), txHash, maxRetries);
423
+ }
424
+ getContractAddress() {
425
+ return this.contractAddress;
426
+ }
427
+ async getAllEvents(fromBlock, toBlock) {
428
+ await this.bootstrap();
429
+ return (0, utils_1.getAllEvents)(this.contract, () => this.getRandomProvider(), () => this.getContractWithRandomProvider(), fromBlock, toBlock);
430
+ }
431
+ async streamEvents(fromBlock, onEvent, saveLatestBlock, batchSize = 1000, sleepTime = 5000) {
432
+ await this.bootstrap();
433
+ return (0, utils_1.streamEvents)({
434
+ getProvider: () => this.getRandomProvider(),
435
+ getAllEvents: (fromBlock, toBlock) => this.getAllEvents(fromBlock, toBlock),
436
+ formatEvent: (event) => this.formatEventArgs(event),
437
+ onEvent,
438
+ saveLatestBlock,
439
+ fromBlock,
440
+ batchSize,
441
+ sleepTime,
442
+ });
443
+ }
444
+ }
445
+ exports.SeedRoundFundraiserSDK = SeedRoundFundraiserSDK;