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,742 @@
1
+ import { ethers } from "ethers";
2
+ import { SeedRoundFundraiser } from "./contracts/SeedRoundFundraiser";
3
+ import SeedRoundFundraiserABI from "./abis/SeedRoundFundraiser.json";
4
+ import contracts from "./contracts.json";
5
+ import {
6
+ ParsedSeedRoundFundraiserEvent,
7
+ ParsedSeedRoundFundraiserEventRaw,
8
+ } from "./types";
9
+ import { type SendTransactionMutateAsync } from "@wagmi/core/query";
10
+ import { Config } from "@wagmi/core/dist/types/createConfig";
11
+ import {
12
+ getRandomProvider,
13
+ checkRpcHealth,
14
+ getTransactionStatus,
15
+ getTokenDecimals,
16
+ getTokenSymbol,
17
+ resolveContractAddress,
18
+ streamEvents,
19
+ getAllEvents,
20
+ signAndSendTransaction,
21
+ } from "./utils";
22
+ import whitelistData from "./whitelist-tokens.json";
23
+
24
+ export interface WhitelistedToken {
25
+ isWhitelisted: boolean;
26
+ price: number; // Price in USD with PRICE_PRECISION decimals
27
+ }
28
+
29
+ export interface WhitelistedTokenInfo {
30
+ address: string;
31
+ isWhitelisted: boolean;
32
+ price: number;
33
+ symbol: string;
34
+ maxContribution: number;
35
+ maxContributionRaw: number;
36
+ decimals: number;
37
+ }
38
+
39
+ export interface RoundConfig {
40
+ startTime: number;
41
+ endTime: number;
42
+ targetFund: number; // In USD with PRICE_PRECISION decimals
43
+ totalAllocation: number; // Total tokens to be allocated
44
+ maxFundPerAccount: number; // Max fund per account in USD with PRICE_PRECISION decimals
45
+ exists: boolean;
46
+ ended: boolean;
47
+ claimingEnabled: boolean; // Flag to control token claiming for this round
48
+ refundEnabled: boolean; // Flag to control refunds for this round
49
+ }
50
+
51
+ export interface UserContribution {
52
+ fundAmount: number; // In USD with PRICE_PRECISION decimals
53
+ tokenAllocation: number; // Token allocation
54
+ claimed: boolean;
55
+ refunded: boolean; // Flag to track if user has been refunded
56
+ contributedToken: string; // The token address used for contribution
57
+ contributedAmount: number; // The actual token amount contributed
58
+ }
59
+
60
+ export class SeedRoundFundraiserSDK {
61
+ name = "SeedRoundFundraiser";
62
+ private contract: SeedRoundFundraiser;
63
+ private providers: ethers.Provider[];
64
+ private contractAddress: string;
65
+ private isBootstrapped: boolean = false;
66
+ private PRICE_PRECISION = 1e18;
67
+ private whitelistedTokensArray: string[] = [];
68
+ private networkName: string;
69
+
70
+ constructor(rpcUrls: string | string[], contractAddress?: string) {
71
+ // Convert single RPC to array if needed
72
+ const rpcArray = Array.isArray(rpcUrls) ? rpcUrls : [rpcUrls];
73
+
74
+ // Create providers for each RPC
75
+ this.providers = rpcArray.map((rpc) => new ethers.JsonRpcProvider(rpc));
76
+
77
+ // Get a random provider for initial setup
78
+ const initialProvider = getRandomProvider(this.providers);
79
+
80
+ // Determine contract address based on RPC URL if not provided
81
+ this.contractAddress = resolveContractAddress(
82
+ rpcArray[0],
83
+ this.name,
84
+ contracts,
85
+ contractAddress
86
+ );
87
+
88
+ // Initialize contract with initial provider
89
+ this.contract = new ethers.Contract(
90
+ this.contractAddress,
91
+ SeedRoundFundraiserABI.abi,
92
+ initialProvider
93
+ ) as unknown as SeedRoundFundraiser;
94
+
95
+ // Determine network name from RPC URL
96
+ this.networkName = this.getNetworkNameFromRpc(rpcArray[0]);
97
+
98
+ // Import whitelisted tokens from JSON file
99
+ this.importWhitelistedTokens();
100
+ }
101
+
102
+ private getNetworkNameFromRpc(rpcUrl: string): string {
103
+ const rpcLower = rpcUrl.toLowerCase();
104
+ // Extract network name from RPC URL or use a default method
105
+ if (rpcLower.includes("sepolia.base")) {
106
+ return "base-sepolia";
107
+ } else if (rpcLower.includes("sepolia")) {
108
+ return "sepolia";
109
+ } else if (rpcLower.includes("mainnet")) {
110
+ return "mainnet";
111
+ } else if (
112
+ rpcLower.includes("localhost") ||
113
+ rpcLower.includes("127.0.0.1")
114
+ ) {
115
+ return "hardhat";
116
+ }
117
+ // Default to sepolia if can't determine
118
+ return "sepolia";
119
+ }
120
+
121
+ private importWhitelistedTokens() {
122
+ try {
123
+ // Try to read the whitelist-tokens.json file
124
+
125
+ // Check if the network exists in the whitelist data
126
+ if ((whitelistData as any)[this.networkName]) {
127
+ this.whitelistedTokensArray = (whitelistData as any)[
128
+ this.networkName
129
+ ].map((address: string) => address.toLowerCase());
130
+ console.log(
131
+ `Imported ${this.whitelistedTokensArray.length} whitelisted tokens for ${this.networkName} network`
132
+ );
133
+ } else {
134
+ console.log(
135
+ `No whitelisted tokens found for ${this.networkName} network`
136
+ );
137
+ }
138
+ } catch (error) {
139
+ console.error("Error importing whitelisted tokens:", error);
140
+ }
141
+ }
142
+
143
+ // Get whitelisted token info from the array
144
+ async getWhitelistedTokenInfo(
145
+ tokenAddress: string
146
+ ): Promise<WhitelistedTokenInfo | null> {
147
+ // Convert to lowercase for case-insensitive comparison
148
+ const normalizedAddress = tokenAddress.toLowerCase();
149
+
150
+ // Check if token is in the whitelisted array
151
+ if (!this.whitelistedTokensArray.includes(normalizedAddress)) {
152
+ return null;
153
+ }
154
+
155
+ // Get token info from contract
156
+ const tokenInfo = await this.getWhitelistedToken(normalizedAddress);
157
+
158
+ // Skip if not whitelisted in contract
159
+ if (!tokenInfo.isWhitelisted) {
160
+ return null;
161
+ }
162
+
163
+ let symbol = "ETH";
164
+ let decimals = 18;
165
+
166
+ // Get token symbol and decimals
167
+ if (normalizedAddress !== ethers.ZeroAddress) {
168
+ [symbol, decimals] = await Promise.all([
169
+ getTokenSymbol(normalizedAddress, this.getRandomProvider()),
170
+ getTokenDecimals(normalizedAddress, this.getRandomProvider()),
171
+ ]);
172
+ }
173
+
174
+ // Get latest active round to determine max contribution
175
+ const latestRoundId = await this.getLatestRoundId();
176
+ let maxTokenContribution = 0;
177
+
178
+ if (latestRoundId >= 0) {
179
+ const roundInfo = await this.getRound(latestRoundId);
180
+ if (roundInfo.exists && !roundInfo.ended) {
181
+ // Calculate max token contribution based on maxFundPerAccount and token price
182
+ // maxTokens = (maxFundPerAccount / tokenPrice) * 10^decimals
183
+ maxTokenContribution = roundInfo.maxFundPerAccount / tokenInfo.price;
184
+ }
185
+ }
186
+
187
+ return {
188
+ address: normalizedAddress,
189
+ isWhitelisted: tokenInfo.isWhitelisted,
190
+ price: tokenInfo.price,
191
+ symbol: symbol,
192
+ maxContribution: maxTokenContribution,
193
+ maxContributionRaw: Math.floor(
194
+ maxTokenContribution * Math.pow(10, decimals)
195
+ ),
196
+ decimals: decimals,
197
+ };
198
+ }
199
+
200
+ // Get all whitelisted tokens info
201
+ async getAllWhitelistedTokensInfo(): Promise<WhitelistedTokenInfo[]> {
202
+ const results: WhitelistedTokenInfo[] = [];
203
+
204
+ for (const tokenAddress of this.whitelistedTokensArray) {
205
+ const tokenInfo = await this.getWhitelistedTokenInfo(tokenAddress);
206
+ if (tokenInfo) {
207
+ results.push(tokenInfo);
208
+ }
209
+ }
210
+
211
+ return results;
212
+ }
213
+
214
+ private getRandomProvider(): ethers.Provider {
215
+ return getRandomProvider(this.providers);
216
+ }
217
+
218
+ private getContractWithRandomProvider(): SeedRoundFundraiser {
219
+ return new ethers.Contract(
220
+ this.contractAddress,
221
+ SeedRoundFundraiserABI.abi,
222
+ this.getRandomProvider()
223
+ ) as unknown as SeedRoundFundraiser;
224
+ }
225
+
226
+ async bootstrap() {
227
+ if (this.isBootstrapped) {
228
+ return;
229
+ }
230
+
231
+ // Check health of all RPCs and remove inactive ones
232
+ const healthChecks = await Promise.all(
233
+ this.providers.map((provider, index) => checkRpcHealth(provider, index))
234
+ );
235
+
236
+ // Filter out inactive providers
237
+ this.providers = this.providers.filter((_, index) => healthChecks[index]);
238
+
239
+ if (this.providers.length === 0) {
240
+ throw new Error("No active RPC providers available");
241
+ }
242
+
243
+ this.isBootstrapped = true;
244
+ }
245
+
246
+ async signAndSendTransaction(
247
+ tx: ethers.ContractTransaction,
248
+ wallet: ethers.Wallet | SendTransactionMutateAsync<Config, any>,
249
+ callbacks: {
250
+ onSubmit?: (tx: string) => void | Promise<void>;
251
+ onFinally?: (status: {
252
+ status: boolean | null;
253
+ confirmations: number;
254
+ txHash: string;
255
+ isCompleted: boolean;
256
+ attempts: number;
257
+ }) => void | Promise<void>;
258
+ onError?: (error: Error) => void | Promise<void>;
259
+ } = {}
260
+ ): Promise<{
261
+ transaction: {
262
+ hash: string;
263
+ };
264
+ status: {
265
+ status: boolean | null;
266
+ confirmations: number;
267
+ isCompleted: boolean;
268
+ attempts: number;
269
+ };
270
+ }> {
271
+ return signAndSendTransaction(
272
+ tx,
273
+ wallet,
274
+ () => this.getRandomProvider(),
275
+ callbacks,
276
+ this.contract
277
+ );
278
+ }
279
+
280
+ // Transaction builders
281
+ async buildAddWhitelistedTokenTx(token: string, price: number) {
282
+ const priceBigInt = BigInt(Math.floor(price * this.PRICE_PRECISION));
283
+ return await this.contract.addWhitelistedToken.populateTransaction(
284
+ token,
285
+ priceBigInt
286
+ );
287
+ }
288
+
289
+ async buildUpdateTokenPriceTx(token: string, newPrice: number) {
290
+ const priceBigInt = BigInt(Math.floor(newPrice * this.PRICE_PRECISION));
291
+ return await this.contract.updateTokenPrice.populateTransaction(
292
+ token,
293
+ priceBigInt
294
+ );
295
+ }
296
+
297
+ async buildRemoveWhitelistedTokenTx(token: string) {
298
+ return await this.contract.removeWhitelistedToken.populateTransaction(
299
+ token
300
+ );
301
+ }
302
+
303
+ async buildCreateRoundTx(
304
+ startTime: number,
305
+ endTime: number,
306
+ targetFund: number,
307
+ totalAllocation: number,
308
+ maxFundPerAccount: number
309
+ ) {
310
+ const targetFundBigInt = BigInt(
311
+ Math.floor(targetFund * this.PRICE_PRECISION)
312
+ );
313
+ const maxFundPerAccountBigInt = BigInt(
314
+ Math.floor(maxFundPerAccount * this.PRICE_PRECISION)
315
+ );
316
+ const decimals = await getTokenDecimals(
317
+ await this.getProjectToken(),
318
+ this.getRandomProvider()
319
+ );
320
+ const totalAllocationBigInt = BigInt(
321
+ Math.floor(totalAllocation * Math.pow(10, decimals))
322
+ );
323
+ return await this.contract.createRound.populateTransaction(
324
+ startTime,
325
+ endTime,
326
+ targetFundBigInt,
327
+ totalAllocationBigInt,
328
+ maxFundPerAccountBigInt
329
+ );
330
+ }
331
+
332
+ async buildUpdateRoundTx(
333
+ roundId: number,
334
+ startTime: number,
335
+ endTime: number,
336
+ targetFund: number,
337
+ totalAllocation: number,
338
+ maxFundPerAccount: number
339
+ ) {
340
+ const targetFundBigInt = BigInt(
341
+ Math.floor(targetFund * this.PRICE_PRECISION)
342
+ );
343
+ const maxFundPerAccountBigInt = BigInt(
344
+ Math.floor(maxFundPerAccount * this.PRICE_PRECISION)
345
+ );
346
+ return await this.contract.updateRound.populateTransaction(
347
+ roundId,
348
+ startTime,
349
+ endTime,
350
+ targetFundBigInt,
351
+ totalAllocation,
352
+ maxFundPerAccountBigInt
353
+ );
354
+ }
355
+
356
+ async buildEndRoundTx(roundId: number) {
357
+ return await this.contract.endRound.populateTransaction(roundId);
358
+ }
359
+
360
+ async buildSetClaimingEnabledTx(roundId: number, enabled: boolean) {
361
+ return await this.contract.setClaimingEnabled.populateTransaction(
362
+ roundId,
363
+ enabled
364
+ );
365
+ }
366
+
367
+ async buildSetRefundEnabledTx(roundId: number, enabled: boolean) {
368
+ return await this.contract.setRefundEnabled.populateTransaction(
369
+ roundId,
370
+ enabled
371
+ );
372
+ }
373
+
374
+ async buildContributeTx(roundId: number, token: string, amount: number) {
375
+ let decimals = 18;
376
+
377
+ if (token !== ethers.ZeroAddress) {
378
+ decimals = await getTokenDecimals(token, this.getRandomProvider());
379
+ }
380
+
381
+ const amountWei = ethers.parseUnits(amount.toString(), decimals);
382
+
383
+ const tx = await this.contract.contribute.populateTransaction(
384
+ roundId,
385
+ token,
386
+ token === ethers.ZeroAddress ? 0 : amountWei
387
+ );
388
+
389
+ if (token === ethers.ZeroAddress) {
390
+ tx.value = amountWei;
391
+ }
392
+
393
+ return tx;
394
+ }
395
+
396
+ async buildClaimTokensTx() {
397
+ return await this.contract.claimTokens.populateTransaction();
398
+ }
399
+
400
+ async buildRefundTx() {
401
+ return await this.contract.refund.populateTransaction();
402
+ }
403
+
404
+ async buildWithdrawFundsTx(token: string, amount: number) {
405
+ const decimals = await getTokenDecimals(token, this.getRandomProvider());
406
+ const amountBigInt = BigInt(Math.floor(amount * Math.pow(10, decimals)));
407
+ return await this.contract.withdrawFunds.populateTransaction(
408
+ token,
409
+ amountBigInt
410
+ );
411
+ }
412
+
413
+ async buildClaimTokensByRoundIdTx(roundId: number) {
414
+ return await this.contract.claimTokensByRoundId.populateTransaction(
415
+ roundId
416
+ );
417
+ }
418
+
419
+ // Read methods
420
+ async getWhitelistedToken(token: string): Promise<WhitelistedToken> {
421
+ const result = await this.contract.whitelistedTokens(token);
422
+ return {
423
+ isWhitelisted: result.isWhitelisted,
424
+ price: Number(result.price) / this.PRICE_PRECISION,
425
+ };
426
+ }
427
+
428
+ async getRound(roundId: number): Promise<RoundConfig> {
429
+ const result = await this.contract.rounds(roundId);
430
+ return {
431
+ startTime: Number(result.startTime),
432
+ endTime: Number(result.endTime),
433
+ targetFund: Number(result.targetFund) / this.PRICE_PRECISION,
434
+ totalAllocation: Number(result.totalAllocation),
435
+ maxFundPerAccount:
436
+ Number(result.maxFundPerAccount) / this.PRICE_PRECISION,
437
+ exists: result.exists,
438
+ ended: result.ended,
439
+ claimingEnabled: result.claimingEnabled,
440
+ refundEnabled: result.refundEnabled,
441
+ };
442
+ }
443
+
444
+ async getUserContribution(
445
+ roundId: number,
446
+ user: string
447
+ ): Promise<UserContribution> {
448
+ const result = await this.contract.userContributions(roundId, user);
449
+ return {
450
+ fundAmount: Number(result.fundAmount) / this.PRICE_PRECISION,
451
+ tokenAllocation: Number(result.tokenAllocation),
452
+ claimed: result.claimed,
453
+ refunded: result.refunded,
454
+ contributedToken: result.contributedToken,
455
+ contributedAmount: Number(result.contributedAmount),
456
+ };
457
+ }
458
+
459
+ async getRoundRaisedFunds(roundId: number): Promise<number> {
460
+ const result = await this.contract.roundRaisedFunds(roundId);
461
+ return Number(result) / this.PRICE_PRECISION;
462
+ }
463
+
464
+ async getRoundParticipants(roundId: number): Promise<number> {
465
+ const result = await this.contract.roundParticipants(roundId);
466
+ return Number(result);
467
+ }
468
+
469
+ async getUserParticipatedRound(user: string): Promise<number> {
470
+ const result = await this.contract.userParticipatedRound(user);
471
+ return Number(result);
472
+ }
473
+
474
+ async getProjectToken(): Promise<string> {
475
+ return await this.contract.projectToken();
476
+ }
477
+
478
+ async getTotalRounds(): Promise<number> {
479
+ const result = await this.contract.totalRounds();
480
+ return Number(result);
481
+ }
482
+
483
+ async getTotalRaisedFunds(): Promise<number> {
484
+ const result = await this.contract.totalRaisedFunds();
485
+ return Number(result) / this.PRICE_PRECISION;
486
+ }
487
+
488
+ async isRoundActive(roundId: number): Promise<boolean> {
489
+ return await this.contract.isRoundActive(roundId);
490
+ }
491
+
492
+ /**
493
+ * Get the ID of the latest round
494
+ * @returns The ID of the latest round or -1 if no rounds exist
495
+ */
496
+ async getLatestRoundId(): Promise<number> {
497
+ // Get total number of rounds
498
+ const totalRounds = await this.getTotalRounds();
499
+
500
+ // If no rounds exist, return -1
501
+ if (totalRounds === 0) {
502
+ return -1;
503
+ }
504
+
505
+ // Latest round ID (0-indexed, so subtract 1)
506
+ return totalRounds - 1;
507
+ }
508
+
509
+ /**
510
+ * Get comprehensive information about a specific round
511
+ * @param roundId The ID of the round to get information for
512
+ * @returns An object containing all information about the specified round
513
+ */
514
+ async getRoundInfo(roundId: number): Promise<{
515
+ roundId: number;
516
+ config: RoundConfig;
517
+ raisedFunds: number;
518
+ participants: number;
519
+ isActive: boolean;
520
+ }> {
521
+ // Get total number of rounds
522
+ const totalRounds = await this.getTotalRounds();
523
+
524
+ // Check if roundId is valid
525
+ if (roundId < 0 || roundId >= totalRounds) {
526
+ throw new Error(`Invalid round ID: ${roundId}`);
527
+ }
528
+
529
+ // Get round configuration
530
+ const roundConfig = await this.getRound(roundId);
531
+
532
+ // Get additional information
533
+ const raisedFunds = await this.getRoundRaisedFunds(roundId);
534
+ const participants = await this.getRoundParticipants(roundId);
535
+ const isActive = await this.isRoundActive(roundId);
536
+
537
+ return {
538
+ roundId,
539
+ config: roundConfig,
540
+ raisedFunds,
541
+ participants,
542
+ isActive,
543
+ };
544
+ }
545
+
546
+ async getUserTotalContribution(user: string): Promise<{
547
+ totalFundAmount: number;
548
+ totalTokenAllocation: number;
549
+ }> {
550
+ const result = await this.contract.getUserTotalContribution(user);
551
+ return {
552
+ totalFundAmount: Number(result.totalFundAmount) / this.PRICE_PRECISION,
553
+ totalTokenAllocation: Number(result.totalTokenAllocation),
554
+ };
555
+ }
556
+
557
+ async getTransactionStatus(
558
+ txHash: string,
559
+ maxRetries: number = 10
560
+ ): Promise<{
561
+ hash: string;
562
+ status: boolean | null;
563
+ confirmations: number;
564
+ isCompleted: boolean;
565
+ attempts: number;
566
+ }> {
567
+ return await getTransactionStatus(
568
+ this.getRandomProvider(),
569
+ txHash,
570
+ maxRetries
571
+ );
572
+ }
573
+
574
+ getContractAddress(): string {
575
+ return this.contractAddress;
576
+ }
577
+
578
+ async getAllEvents(
579
+ fromBlock: number,
580
+ toBlock: number
581
+ ): Promise<ParsedSeedRoundFundraiserEventRaw[]> {
582
+ await this.bootstrap();
583
+ return getAllEvents<ParsedSeedRoundFundraiserEventRaw, SeedRoundFundraiser>(
584
+ this.contract,
585
+ () => this.getRandomProvider(),
586
+ () => this.getContractWithRandomProvider(),
587
+ fromBlock,
588
+ toBlock
589
+ );
590
+ }
591
+
592
+ async streamEvents(
593
+ fromBlock: number,
594
+ onEvent: (event: ParsedSeedRoundFundraiserEvent) => Promise<void>,
595
+ saveLatestBlock: (blockNumber: number) => Promise<void>,
596
+ batchSize: number = 1000,
597
+ sleepTime: number = 5000
598
+ ) {
599
+ await this.bootstrap();
600
+
601
+ return streamEvents<
602
+ ParsedSeedRoundFundraiserEventRaw,
603
+ ParsedSeedRoundFundraiserEvent
604
+ >({
605
+ getProvider: () => this.getRandomProvider(),
606
+ getAllEvents: (fromBlock, toBlock) =>
607
+ this.getAllEvents(fromBlock, toBlock),
608
+ formatEvent: (event) => this.formatEventArgs(event),
609
+ onEvent,
610
+ saveLatestBlock,
611
+ fromBlock,
612
+ batchSize,
613
+ sleepTime,
614
+ });
615
+ }
616
+
617
+ formatEventArgs = (
618
+ event: ParsedSeedRoundFundraiserEventRaw
619
+ ): ParsedSeedRoundFundraiserEvent => {
620
+ const { eventName, args } = event;
621
+
622
+ switch (eventName) {
623
+ case "TokenWhitelisted":
624
+ return {
625
+ ...event,
626
+ args: {
627
+ ...args,
628
+ token: args.token.toLowerCase(),
629
+ price: Number(args.price) / this.PRICE_PRECISION,
630
+ },
631
+ };
632
+
633
+ case "TokenPriceUpdated":
634
+ return {
635
+ ...event,
636
+ args: {
637
+ ...args,
638
+ token: args.token.toLowerCase(),
639
+ oldPrice: Number(args.oldPrice) / this.PRICE_PRECISION,
640
+ newPrice: Number(args.newPrice) / this.PRICE_PRECISION,
641
+ },
642
+ };
643
+
644
+ case "TokenRemovedFromWhitelist":
645
+ return {
646
+ ...event,
647
+ args: {
648
+ ...args,
649
+ token: args.token.toLowerCase(),
650
+ },
651
+ };
652
+
653
+ case "RoundCreated":
654
+ case "RoundUpdated":
655
+ return {
656
+ ...event,
657
+ args: {
658
+ ...args,
659
+ roundId: Number(args.roundId),
660
+ startTime: Number(args.startTime),
661
+ endTime: Number(args.endTime),
662
+ targetFund: Number(args.targetFund) / this.PRICE_PRECISION,
663
+ totalAllocation: Number(args.totalAllocation),
664
+ maxFundPerAccount:
665
+ Number(args.maxFundPerAccount) / this.PRICE_PRECISION,
666
+ },
667
+ };
668
+
669
+ case "RoundEnded":
670
+ return {
671
+ ...event,
672
+ args: {
673
+ ...args,
674
+ roundId: Number(args.roundId),
675
+ raisedFunds: Number(args.raisedFunds) / this.PRICE_PRECISION,
676
+ participants: Number(args.participants),
677
+ },
678
+ };
679
+
680
+ case "Contribution":
681
+ return {
682
+ ...event,
683
+ args: {
684
+ ...args,
685
+ roundId: Number(args.roundId),
686
+ contributor: args.contributor.toLowerCase(),
687
+ token: args.token.toLowerCase(),
688
+ amount: Number(args.amount),
689
+ fundAmount: Number(args.fundAmount) / this.PRICE_PRECISION,
690
+ tokenAllocation: Number(args.tokenAllocation),
691
+ },
692
+ };
693
+
694
+ case "TokensClaimed":
695
+ return {
696
+ ...event,
697
+ args: {
698
+ ...args,
699
+ roundId: Number(args.roundId),
700
+ user: args.user.toLowerCase(),
701
+ amount: Number(args.amount),
702
+ },
703
+ };
704
+
705
+ case "ProjectTokenUpdated":
706
+ return {
707
+ ...event,
708
+ args: {
709
+ ...args,
710
+ oldToken: args.oldToken.toLowerCase(),
711
+ newToken: args.newToken.toLowerCase(),
712
+ },
713
+ };
714
+
715
+ case "ClaimingEnabledUpdated":
716
+ case "RefundEnabledUpdated":
717
+ return {
718
+ ...event,
719
+ args: {
720
+ ...args,
721
+ roundId: Number(args.roundId),
722
+ enabled: args.enabled,
723
+ },
724
+ };
725
+
726
+ case "Refunded":
727
+ return {
728
+ ...event,
729
+ args: {
730
+ ...args,
731
+ roundId: Number(args.roundId),
732
+ user: args.user.toLowerCase(),
733
+ token: args.token.toLowerCase(),
734
+ amount: Number(args.amount),
735
+ },
736
+ };
737
+
738
+ default:
739
+ return event;
740
+ }
741
+ };
742
+ }