11import yn from "yn" ;
2+ import nodeFetch from "node-fetch" ;
23import { readFileSync } from "fs" ;
34import { Command , Flags } from "@oclif/core" ;
45import {
@@ -13,12 +14,14 @@ import { Address } from "viem";
1314
1415import { createStatus , updateStatusFailure , updateStatusSuccess } from "../../lib/utils/status.js" ;
1516import { getProvider } from "../../lib/utils/getProvider.js" ;
16- import { createOutputPath } from "../../lib/utils/createOutputPath.js" ;
17+ import { createOutputPath , drawPath } from "../../lib/utils/createOutputPath.js" ;
1718import { createExitCode } from "../../lib/utils/createExitCode.js" ;
1819import { getAllPrizeVaultsAndAccountsWithBalance } from "../../lib/utils/getAllPrizeVaultsAndAccountsWithBalance.js" ;
1920import { writeToOutput } from "../../lib/utils/writeOutput.js" ;
2021import { Winner } from "../../types.js" ;
2122
23+ import { Status } from "../../types.js" ;
24+
2225const DEFAULT_RETRY_ATTEMPTS = 10 ;
2326const DEFAULT_RETRY_INTERVAL = 5 ;
2427
@@ -66,6 +69,17 @@ export default class CompileWinners extends Command {
6669 description : "Custom address for a Multicall contract" ,
6770 required : false ,
6871 } ) ,
72+ remoteStatusUrl : Flags . string ( {
73+ char : "r" ,
74+ description :
75+ "Remote URL where status.json would exist (eg. 'https://raw.githubusercontent.com/GenerationSoftware/pt-v5-winners/refs/heads/main/winners/vaultAccounts')" ,
76+ required : false ,
77+ } ) ,
78+ localFileStatusPath : Flags . string ( {
79+ char : "l" ,
80+ description : "Local file path where status.json would exist (eg. './winners/vaultAccounts')" ,
81+ required : false ,
82+ } ) ,
6983 } ;
7084
7185 static args = [ ] ;
@@ -83,7 +97,7 @@ export default class CompileWinners extends Command {
8397 const prizePoolInfo : PrizePoolInfo = await getPrizePoolInfo ( readProvider , contracts ) ;
8498 const drawId = prizePoolInfo . drawId ;
8599
86- this . warn ( "Failed to fetch depositors (" + error + ")" ) ;
100+ this . warn ( "Failed to calculate winners (" + error + ")" ) ;
87101 const statusFailure = updateStatusFailure ( CompileWinners . statusLoading . createdAt , error ) ;
88102
89103 if ( drawId ) {
@@ -102,7 +116,16 @@ export default class CompileWinners extends Command {
102116
103117 public async run ( ) : Promise < void > {
104118 const { flags } = await this . parse ( CompileWinners ) ;
105- const { chainId, prizePool, outDir, contractJsonUrl, subgraphUrl, multicallAddress } = flags ;
119+ const {
120+ chainId,
121+ prizePool,
122+ outDir,
123+ contractJsonUrl,
124+ subgraphUrl,
125+ multicallAddress,
126+ remoteStatusUrl,
127+ localFileStatusPath,
128+ } = flags ;
106129
107130 console . log ( "" ) ;
108131 console . log ( `Running "utils:compileWinners"` ) ;
@@ -114,17 +137,24 @@ export default class CompileWinners extends Command {
114137 const drawId = prizePoolInfo . drawId ;
115138 const isDrawFinalized = prizePoolInfo . isDrawFinalized ;
116139
140+ console . log ( `--- ARGS ---` ) ;
117141 console . log ( `chainId: ${ chainId } ` ) ;
118142 console . log ( `prizePool: ${ prizePool . toLowerCase ( ) } ` ) ;
119- console . log ( `drawId: #${ drawId ? drawId : "" } ` ) ;
120143 console . log ( `contractJsonUrl: ${ contractJsonUrl } ` ) ;
121144 console . log ( `subgraphUrl: ${ subgraphUrl } ` ) ;
122145 console . log ( `outDir: ${ outDir } ` ) ;
146+ console . log ( `--- OPTIONAL ARGS ---` ) ;
123147 console . log ( `multicallAddress: ${ multicallAddress } ` ) ;
148+ console . log ( `remoteStatusUrl: ${ remoteStatusUrl } ` ) ;
149+ console . log ( `localFileStatusPath: ${ localFileStatusPath } ` ) ;
124150 console . log ( `--- ENV ---` ) ;
125151 console . log ( `JSON_RPC_URL: ${ process . env . JSON_RPC_URL } ` ) ;
126152 console . log ( `DEBUG: ${ yn ( process . env . DEBUG ) } ` ) ;
127153 console . log ( `PRIZE_TIERS_TO_COMPUTE: ${ process . env . PRIZE_TIERS_TO_COMPUTE } ` ) ;
154+ console . log ( `--- STATUS ---` ) ;
155+ console . log ( `drawId: #${ drawId ? drawId : "" } ` ) ;
156+ console . log ( `isDrawFinalized: ${ isDrawFinalized } ` ) ;
157+ console . log ( `` ) ;
128158
129159 if ( ! drawId ) {
130160 console . log ( "" ) ;
@@ -143,10 +173,32 @@ export default class CompileWinners extends Command {
143173 return ;
144174 }
145175
146- if ( status === "success" ) {
147- console . log ( "" ) ;
148- console . warn ( "Winners have already been calculated for current draw." ) ;
149- return ;
176+ if ( remoteStatusUrl ) {
177+ const status = await downloadRemoteStatusJson (
178+ remoteStatusUrl ,
179+ chainId ,
180+ prizePool . toLowerCase ( ) ,
181+ drawId . toString ( )
182+ ) ;
183+ if ( status ?. status === "SUCCESS" ) {
184+ console . log ( "" ) ;
185+ console . warn ( "Winners have already been calculated for current draw." ) ;
186+ return ;
187+ }
188+ }
189+
190+ if ( localFileStatusPath ) {
191+ const status = readLocalFileStatusJson (
192+ localFileStatusPath ,
193+ chainId ,
194+ prizePool . toLowerCase ( ) ,
195+ drawId . toString ( )
196+ ) ;
197+ if ( status ?. status === "SUCCESS" ) {
198+ console . log ( "" ) ;
199+ console . warn ( "Winners have already been calculated for current draw." ) ;
200+ return ;
201+ }
150202 }
151203
152204 /* -------------------------------------------------- */
@@ -303,3 +355,67 @@ export async function tryNTimes<T>({
303355export function delay ( time : number ) : Promise < void > {
304356 return new Promise < void > ( ( resolve ) => setTimeout ( resolve , time * 1000 ) ) ;
305357}
358+
359+ /**
360+ * Downloads the status.json for provided drawId if it exists
361+ *
362+ * @param {remoteStatusUrl } string
363+ *
364+ * @returns {Status } Parsed status.json object
365+ */
366+ export const downloadRemoteStatusJson = async (
367+ remoteStatusUrl : string ,
368+ chainId : string ,
369+ prizePoolAddress : string ,
370+ drawId : string ,
371+ fetch ?: any
372+ ) : Promise < Status > => {
373+ let status ;
374+
375+ if ( ! fetch ) {
376+ fetch = nodeFetch ;
377+ }
378+
379+ try {
380+ const outputPath = drawPath ( chainId , prizePoolAddress , drawId ) ;
381+ const url = `${ remoteStatusUrl } /${ outputPath } status.json` ;
382+ const response = await fetch ( url ) ;
383+ if ( ! response . ok ) {
384+ console . warn ( response . statusText ) ;
385+ } else {
386+ status = await response . json ( ) ;
387+ }
388+ } catch ( err ) {
389+ console . log ( err ) ;
390+ }
391+
392+ return status ;
393+ } ;
394+
395+ /**
396+ * Reads the status.json from the local filesystem if it exists for the provided drawId
397+ *
398+ * @param {readLocalFileStatusJson } string
399+ *
400+ * @returns {Status } Parsed status.json object
401+ */
402+ export const readLocalFileStatusJson = (
403+ localFileStatusPath : string ,
404+ chainId : string ,
405+ prizePoolAddress : string ,
406+ drawId : string
407+ ) : Status => {
408+ let status ;
409+
410+ const path = drawPath ( chainId , prizePoolAddress , drawId ) ;
411+ const statusPath = `${ localFileStatusPath } /${ path } status.json` ;
412+ const fileJson = readFileSync ( statusPath , "utf8" ) ;
413+
414+ if ( ! fileJson ) {
415+ console . warn ( "no status.json file?" ) ;
416+ } else {
417+ status = JSON . parse ( fileJson ) ;
418+ }
419+
420+ return status ;
421+ } ;
0 commit comments