Skip to content

Commit 1baf798

Browse files
committed
call setWinner
1 parent f6488af commit 1baf798

File tree

3 files changed

+162
-18
lines changed

3 files changed

+162
-18
lines changed

src/abi/TokenFactory.json

Lines changed: 107 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,30 @@
431431
"stateMutability": "view",
432432
"type": "function"
433433
},
434+
{
435+
"inputs": [
436+
{
437+
"internalType": "uint256",
438+
"name": "",
439+
"type": "uint256"
440+
},
441+
{
442+
"internalType": "address",
443+
"name": "",
444+
"type": "address"
445+
}
446+
],
447+
"name": "collateralByDay",
448+
"outputs": [
449+
{
450+
"internalType": "uint256",
451+
"name": "",
452+
"type": "uint256"
453+
}
454+
],
455+
"stateMutability": "view",
456+
"type": "function"
457+
},
434458
{
435459
"inputs": [
436460
{
@@ -460,6 +484,25 @@
460484
"stateMutability": "nonpayable",
461485
"type": "function"
462486
},
487+
{
488+
"inputs": [
489+
{
490+
"internalType": "address",
491+
"name": "",
492+
"type": "address"
493+
}
494+
],
495+
"name": "creationDate",
496+
"outputs": [
497+
{
498+
"internalType": "uint256",
499+
"name": "",
500+
"type": "uint256"
501+
}
502+
],
503+
"stateMutability": "view",
504+
"type": "function"
505+
},
463506
{
464507
"inputs": [],
465508
"name": "fee",
@@ -486,6 +529,38 @@
486529
"stateMutability": "view",
487530
"type": "function"
488531
},
532+
{
533+
"inputs": [
534+
{
535+
"internalType": "uint256",
536+
"name": "day",
537+
"type": "uint256"
538+
}
539+
],
540+
"name": "getWinnerByDay",
541+
"outputs": [
542+
{
543+
"internalType": "address",
544+
"name": "",
545+
"type": "address"
546+
}
547+
],
548+
"stateMutability": "view",
549+
"type": "function"
550+
},
551+
{
552+
"inputs": [],
553+
"name": "maxFundingRateInterval",
554+
"outputs": [
555+
{
556+
"internalType": "uint256",
557+
"name": "",
558+
"type": "uint256"
559+
}
560+
],
561+
"stateMutability": "view",
562+
"type": "function"
563+
},
489564
{
490565
"inputs": [],
491566
"name": "owner",
@@ -553,16 +628,36 @@
553628
{
554629
"inputs": [
555630
{
556-
"internalType": "address",
557-
"name": "winnerAddress",
558-
"type": "address"
631+
"internalType": "uint256",
632+
"name": "interval",
633+
"type": "uint256"
559634
}
560635
],
636+
"name": "setMaxFundingRateInterval",
637+
"outputs": [],
638+
"stateMutability": "nonpayable",
639+
"type": "function"
640+
},
641+
{
642+
"inputs": [],
561643
"name": "setWinner",
562644
"outputs": [],
563645
"stateMutability": "nonpayable",
564646
"type": "function"
565647
},
648+
{
649+
"inputs": [],
650+
"name": "startOfCurrentDay",
651+
"outputs": [
652+
{
653+
"internalType": "uint256",
654+
"name": "",
655+
"type": "uint256"
656+
}
657+
],
658+
"stateMutability": "view",
659+
"type": "function"
660+
},
566661
{
567662
"inputs": [],
568663
"name": "tokenImplementation",
@@ -635,15 +730,21 @@
635730
"type": "function"
636731
},
637732
{
638-
"inputs": [],
639-
"name": "winnerToken",
640-
"outputs": [
733+
"inputs": [
641734
{
642735
"internalType": "address",
643736
"name": "",
644737
"type": "address"
645738
}
646739
],
740+
"name": "winners",
741+
"outputs": [
742+
{
743+
"internalType": "uint256",
744+
"name": "",
745+
"type": "uint256"
746+
}
747+
],
647748
"stateMutability": "view",
648749
"type": "function"
649750
}

src/config/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ export default () => ({
2727
RPC_URL: process.env.RPC_URL || 'https://a.api.s0.t.hmny.io',
2828
RATE_LIMITER_TTL: parseInt(process.env.RATE_LIMITER_TTL) || 10000,
2929
RATE_LIMITER_LIMIT: parseInt(process.env.RATE_LIMITER_LIMIT) || 20,
30-
PUMP_FUN_CONTRACT_ADDRESS: process.env.PUMP_FUN_CONTRACT_ADDRESS || '',
31-
PUMP_FUN_INITIAL_BLOCK_NUMBER: parseInt(process.env.PUMP_FUN_INITIAL_BLOCK_NUMBER || '0'),
32-
GOOGLE_CLOUD_CONFIG: getGoogleCloudConfig()
30+
TOKEN_FACTORY_ADDRESS: process.env.TOKEN_FACTORY_ADDRESS || '',
31+
INDEXER_INITIAL_BLOCK_NUMBER: parseInt(process.env.INDEXER_INITIAL_BLOCK_NUMBER || '0'),
32+
GOOGLE_CLOUD_CONFIG: getGoogleCloudConfig(),
33+
SERVICE_PRIVATE_KEY: process.env.SERVICE_PRIVATE_KEY || '',
3334
});

src/indexer/indexer.service.ts

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ import {UserService} from "../user/user.service";
99
import {DataSource} from "typeorm";
1010
import * as TokenFactoryABI from "../abi/TokenFactory.json";
1111
import {AppService} from "../app.service";
12+
import {Cron, CronExpression} from "@nestjs/schedule";
1213

1314
@Injectable()
1415
export class IndexerService {
1516
private readonly logger = new Logger(IndexerService.name);
1617
private readonly web3: Web3
18+
private readonly accountAddress: string
1719
private readonly tokenFactoryContract: Contract<ContractAbi>
18-
private readonly tokenContract: Contract<ContractAbi>
1920
private readonly blocksIndexingRange = 1000
2021

2122
constructor(
@@ -25,28 +26,32 @@ export class IndexerService {
2526
private dataSource: DataSource,
2627
) {
2728
const rpcUrl = configService.get('RPC_URL')
28-
const contractAddress = configService.get('PUMP_FUN_CONTRACT_ADDRESS')
29-
const initialBlockNumber = configService.get('PUMP_FUN_INITIAL_BLOCK_NUMBER')
29+
const contractAddress = configService.get('TOKEN_FACTORY_ADDRESS')
30+
const initialBlockNumber = configService.get('INDEXER_INITIAL_BLOCK_NUMBER')
3031

3132
if(!contractAddress) {
32-
this.logger.error(`[PUMP_FUN_CONTRACT_ADDRESS] is missing but required, exit`)
33+
this.logger.error(`[TOKEN_FACTORY_ADDRESS] is missing but required, exit`)
3334
process.exit(1)
3435
}
3536

3637
if(!initialBlockNumber) {
37-
this.logger.error(`[PUMP_FUN_INITIAL_BLOCK_NUMBER] is missing but required, exit`)
38+
this.logger.error(`[INDEXER_INITIAL_BLOCK_NUMBER] is missing but required, exit`)
3839
process.exit(1)
3940
}
4041

4142
this.logger.log(`Starting app service, RPC_URL=${
4243
rpcUrl
43-
}, PUMP_FUN_CONTRACT_ADDRESS=${
44+
}, TOKEN_FACTORY_ADDRESS=${
4445
contractAddress
45-
}, PUMP_FUN_INITIAL_BLOCK_NUMBER=${
46+
}, INDEXER_INITIAL_BLOCK_NUMBER=${
4647
initialBlockNumber
4748
}`)
4849

4950
this.web3 = new Web3(rpcUrl);
51+
const account = this.web3.eth.accounts.privateKeyToAccount(configService.get('SERVICE_PRIVATE_KEY'))
52+
this.accountAddress = account.address
53+
this.web3.eth.accounts.wallet.add(account);
54+
this.logger.log(`Service account address=${account.address}`)
5055
this.tokenFactoryContract = new this.web3.eth.Contract(TokenFactoryABI, contractAddress);
5156
this.bootstrap().then(
5257
() => {
@@ -62,9 +67,9 @@ export class IndexerService {
6267
where: {}
6368
})
6469
if(!indexerState) {
65-
const blockNumber = +this.configService.get<number>('PUMP_FUN_INITIAL_BLOCK_NUMBER')
70+
const blockNumber = +this.configService.get<number>('INDEXER_INITIAL_BLOCK_NUMBER')
6671
if(!blockNumber) {
67-
this.logger.error('[PUMP_FUN_INITIAL_BLOCK_NUMBER] is empty but required, exit')
72+
this.logger.error('[INDEXER_INITIAL_BLOCK_NUMBER] is empty but required, exit')
6873
process.exit(1)
6974
}
7075
await this.dataSource.manager.insert(IndexerState, {
@@ -307,4 +312,41 @@ export class IndexerService {
307312

308313
this.eventsTrackingLoop()
309314
}
315+
316+
@Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT)
317+
async callSetWinner() {
318+
let txnHash = ''
319+
let gasFees = 0n
320+
321+
for(let i = 0; i < 3; i++) {
322+
try {
323+
gasFees = await this.tokenFactoryContract.methods
324+
.setWinner()
325+
.estimateGas({ from: this.accountAddress });
326+
const gasPrice = await this.web3.eth.getGasPrice();
327+
const tx = {
328+
from: this.accountAddress,
329+
to: this.configService.get('TOKEN_FACTORY_ADDRESS'),
330+
gas: gasFees,
331+
gasPrice,
332+
data: this.tokenFactoryContract.methods.setWinner().encodeABI(),
333+
};
334+
const signPromise = await this.web3.eth.accounts.signTransaction(tx, this.configService.get('SERVICE_PRIVATE_KEY'));
335+
const sendTxn =
336+
await this.web3.eth.sendSignedTransaction(
337+
signPromise.rawTransaction,
338+
);
339+
txnHash = sendTxn.transactionHash.toString()
340+
break;
341+
} catch (e) {
342+
this.logger.warn(`Failed to send setWinner transaction, attempt: ${(i + 1)} / 3:`, e)
343+
}
344+
}
345+
346+
if(txnHash) {
347+
this.logger.log(`[setWinner] successfully called, transaction hash=${txnHash}, gasFees=${gasFees}`)
348+
} else {
349+
this.logger.error('Failed to call setWinner!')
350+
}
351+
}
310352
}

0 commit comments

Comments
 (0)