@@ -54,6 +54,8 @@ import {
5454 getCurrentEpoch ,
5555 METADATA_KEYS ,
5656 SIZE_CONSTANTS ,
57+ TIME_CONSTANTS ,
58+ TOKENS ,
5759 timeUntilEpoch ,
5860} from '../utils/index.ts'
5961import { combineMetadata , metadataMatches , objectToEntries , validatePieceMetadata } from '../utils/metadata.ts'
@@ -785,34 +787,70 @@ export class StorageContext {
785787
786788 /**
787789 * Static method to perform preflight checks for an upload
788- * @param size - The size of data to upload in bytes
789- * @param withCDN - Whether CDN is enabled
790+ * Composes cost calculation from WarmStorageService and readiness checks from PaymentsService
790791 * @param warmStorageService - WarmStorageService instance
791792 * @param paymentsService - PaymentsService instance
793+ * @param size - The size of data to upload in bytes
792794 * @returns Preflight check results without provider/dataSet specifics
793795 */
794796 static async performPreflightCheck (
795797 warmStorageService : WarmStorageService ,
796798 paymentsService : PaymentsService ,
797- size : number ,
798- withCDN : boolean
799+ size : number
799800 ) : Promise < PreflightInfo > {
800801 // Validate size before proceeding
801802 StorageContext . validateRawSize ( size , 'preflightUpload' )
802803
803- // Check allowances and get costs in a single call
804- const allowanceCheck = await warmStorageService . checkAllowanceForStorage ( size , withCDN , paymentsService )
804+ // Calculate upload cost
805+ const cost = await warmStorageService . calculateUploadCost ( size )
805806
806- // Return preflight info
807- return {
808- estimatedCost : {
809- perEpoch : allowanceCheck . costs . perEpoch ,
810- perDay : allowanceCheck . costs . perDay ,
811- perMonth : allowanceCheck . costs . perMonth ,
807+ // Calculate rate per epoch from floor-adjusted monthly price
808+ const pricing = await warmStorageService . getServicePrice ( )
809+ const ratePerEpoch = cost . withFloorPerMonth / pricing . epochsPerMonth
810+
811+ // Calculate lockup requirements
812+ const lockupEpochs = BigInt ( TIME_CONSTANTS . DEFAULT_LOCKUP_DAYS * TIME_CONSTANTS . EPOCHS_PER_DAY )
813+ const lockupNeeded = ratePerEpoch * lockupEpochs
814+
815+ // Check payment readiness
816+ const readiness = await paymentsService . checkServiceReadiness (
817+ warmStorageService . getContractAddress ( ) ,
818+ {
819+ rateNeeded : ratePerEpoch ,
820+ lockupNeeded,
821+ lockupPeriodNeeded : lockupEpochs ,
812822 } ,
823+ TOKENS . USDFC
824+ )
825+
826+ // Build error message if not sufficient
827+ let message : string | undefined
828+ if ( ! readiness . sufficient ) {
829+ const issues : string [ ] = [ ]
830+ if ( ! readiness . checks . hasSufficientFunds && readiness . gaps ?. fundsNeeded ) {
831+ issues . push ( `Insufficient funds: need ${ readiness . gaps . fundsNeeded } more` )
832+ }
833+ if ( ! readiness . checks . isOperatorApproved ) {
834+ issues . push ( 'Operator not approved for service' )
835+ }
836+ if ( ! readiness . checks . hasRateAllowance && readiness . gaps ?. rateAllowanceNeeded ) {
837+ issues . push ( `Insufficient rate allowance: need ${ readiness . gaps . rateAllowanceNeeded } more` )
838+ }
839+ if ( ! readiness . checks . hasLockupAllowance && readiness . gaps ?. lockupAllowanceNeeded ) {
840+ issues . push ( `Insufficient lockup allowance: need ${ readiness . gaps . lockupAllowanceNeeded } more` )
841+ }
842+ if ( ! readiness . checks . hasValidLockupPeriod && readiness . gaps ?. lockupPeriodNeeded ) {
843+ issues . push ( `Lockup period too short: need ${ readiness . gaps . lockupPeriodNeeded } more epochs` )
844+ }
845+ message = issues . join ( '; ' )
846+ }
847+
848+ return {
849+ estimatedCostPerMonth : cost . withFloorPerMonth ,
813850 allowanceCheck : {
814- sufficient : allowanceCheck . sufficient ,
815- message : allowanceCheck . message ,
851+ sufficient : readiness . sufficient ,
852+ message,
853+ checks : readiness . checks ,
816854 } ,
817855 selectedProvider : null ,
818856 selectedDataSetId : null ,
@@ -829,8 +867,7 @@ export class StorageContext {
829867 const preflightResult = await StorageContext . performPreflightCheck (
830868 this . _warmStorageService ,
831869 this . _synapse . payments ,
832- size ,
833- this . _withCDN
870+ size
834871 )
835872
836873 // Return preflight info with provider and dataSet specifics
0 commit comments