@@ -12,6 +12,8 @@ import { CarReader } from '@ipld/car'
1212import { CID } from 'multiformats/cid'
1313import pc from 'picocolors'
1414import pino from 'pino'
15+ import { checkInsufficientFunds , formatUSDFC } from '../payments/setup.js'
16+ import { checkFILBalance , checkUSDFCBalance , validatePaymentCapacity } from '../synapse/payments.js'
1517import { cleanupSynapseService , initializeSynapse } from '../synapse/service.js'
1618import { uploadToSynapse } from '../synapse/upload.js'
1719import { createSpinner , formatFileSize , intro } from '../utils/cli-helpers.js'
@@ -166,8 +168,100 @@ export async function runCarImport(options: ImportOptions): Promise<ImportResult
166168
167169 spinner . stop ( `${ pc . green ( '✓' ) } Connected to ${ pc . bold ( network ) } ` )
168170
169- // Step 5: Read CAR file and upload to Synapse
170- spinner . start ( 'Uploading to Filecoin...' )
171+ // Step 5: Validate payment setup
172+ spinner . start ( 'Validating payment setup...' )
173+
174+ // First check basic requirements (FIL and USDFC balance)
175+ const { isCalibnet, hasSufficientGas } = await checkFILBalance ( synapseService . synapse )
176+ const usdfcBalance = await checkUSDFCBalance ( synapseService . synapse )
177+
178+ // Check basic requirements using existing function
179+ const hasBasicRequirements = checkInsufficientFunds ( hasSufficientGas , usdfcBalance , isCalibnet , false )
180+
181+ if ( ! hasBasicRequirements ) {
182+ spinner . stop ( `${ pc . red ( '✗' ) } Payment setup incomplete` )
183+ log . line ( '' )
184+ log . line ( `${ pc . yellow ( '⚠' ) } Your payment setup is not complete. Please run:` )
185+ log . indent ( pc . cyan ( 'filecoin-pin payments setup' ) )
186+ log . line ( '' )
187+ log . line ( 'For more information, run:' )
188+ log . indent ( pc . cyan ( 'filecoin-pin payments status' ) )
189+ log . flush ( )
190+ await cleanupSynapseService ( )
191+ process . exit ( 1 )
192+ }
193+
194+ // Now check capacity for this specific file
195+ const capacityCheck = await validatePaymentCapacity ( synapseService . synapse , fileStat . size )
196+
197+ if ( ! capacityCheck . canUpload ) {
198+ spinner . stop ( `${ pc . red ( '✗' ) } Insufficient payment capacity for this file` )
199+ log . line ( '' )
200+ log . line ( pc . bold ( 'File Requirements:' ) )
201+ log . indent ( `File size: ${ formatFileSize ( fileStat . size ) } (${ capacityCheck . storageTiB . toFixed ( 4 ) } TiB)` )
202+ log . indent ( `Storage cost: ${ formatUSDFC ( capacityCheck . required . rateAllowance ) } USDFC/epoch` )
203+ log . indent ( `10-day lockup: ${ formatUSDFC ( capacityCheck . required . lockupAllowance ) } USDFC` )
204+ log . line ( '' )
205+
206+ log . line ( pc . bold ( `${ pc . red ( 'Issues found:' ) } ` ) )
207+ if ( capacityCheck . issues . insufficientDeposit ) {
208+ log . indent (
209+ `${ pc . red ( '✗' ) } Insufficient deposit (need ${ formatUSDFC ( capacityCheck . issues . insufficientDeposit ) } more)`
210+ )
211+ }
212+ if ( capacityCheck . issues . insufficientRateAllowance ) {
213+ log . indent (
214+ `${ pc . red ( '✗' ) } Rate allowance too low (need ${ formatUSDFC ( capacityCheck . issues . insufficientRateAllowance ) } more per epoch)`
215+ )
216+ }
217+ if ( capacityCheck . issues . insufficientLockupAllowance ) {
218+ log . indent (
219+ `${ pc . red ( '✗' ) } Lockup allowance too low (need ${ formatUSDFC ( capacityCheck . issues . insufficientLockupAllowance ) } more)`
220+ )
221+ }
222+ log . line ( '' )
223+
224+ log . line ( pc . bold ( 'Suggested actions:' ) )
225+ capacityCheck . suggestions . forEach ( ( suggestion ) => {
226+ log . indent ( `• ${ suggestion } ` )
227+ } )
228+ log . line ( '' )
229+
230+ // Calculate suggested parameters for payment setup
231+ const suggestedDeposit = capacityCheck . issues . insufficientDeposit
232+ ? formatUSDFC ( capacityCheck . issues . insufficientDeposit )
233+ : '0'
234+ const suggestedStorage = `${ Math . ceil ( capacityCheck . storageTiB * 10 ) / 10 } TiB/month`
235+
236+ log . line ( `${ pc . yellow ( '⚠' ) } To fix these issues, run:` )
237+ if ( capacityCheck . issues . insufficientDeposit ) {
238+ log . indent (
239+ pc . cyan ( `filecoin-pin payments setup --deposit ${ suggestedDeposit } --storage ${ suggestedStorage } --auto` )
240+ )
241+ } else {
242+ log . indent ( pc . cyan ( `filecoin-pin payments setup --storage ${ suggestedStorage } --auto` ) )
243+ }
244+ log . flush ( )
245+ await cleanupSynapseService ( )
246+ process . exit ( 1 )
247+ }
248+
249+ // Show warning if suggestions exist (even if upload is possible)
250+ if ( capacityCheck . suggestions . length > 0 && capacityCheck . canUpload ) {
251+ spinner . stop ( `${ pc . yellow ( '⚠' ) } Payment capacity check passed with warnings` )
252+ log . line ( '' )
253+ log . line ( pc . bold ( 'Suggestions:' ) )
254+ capacityCheck . suggestions . forEach ( ( suggestion ) => {
255+ log . indent ( `• ${ suggestion } ` )
256+ } )
257+ log . flush ( )
258+ spinner . start ( 'Uploading to Filecoin...' )
259+ } else {
260+ spinner . stop ( `${ pc . green ( '✓' ) } Payment capacity verified` )
261+ spinner . start ( 'Uploading to Filecoin...' )
262+ }
263+
264+ // Step 6: Read CAR file and upload to Synapse
171265
172266 // Read the entire CAR file (streaming not yet supported in Synapse)
173267 const carData = await readFile ( options . filePath )
0 commit comments