diff --git a/README.md b/README.md index c484921..f2c4c3c 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ PORT=3456 # Daemon port DATABASE_PATH=./pins.db # SQLite database CAR_STORAGE_PATH=./cars # CAR file directory LOG_LEVEL=info # Logging level +WITH_CDN=true # Enable/Disable CDN for content uploads (default: false) ``` ### Default Directories @@ -193,4 +194,4 @@ Dual-licensed under [MIT](LICENSE-MIT) + [Apache 2.0](LICENSE-APACHE) - [IPFS Pinning Service API](https://ipfs.github.io/pinning-services-api-spec/) - [Synapse SDK](https://github.com/filecoin-project/synapse-sdk) -- [USDFC Documentation](https://docs.secured.finance/usdfc-stablecoin) \ No newline at end of file +- [USDFC Documentation](https://docs.secured.finance/usdfc-stablecoin) diff --git a/src/add/add.ts b/src/add/add.ts index 1d4f307..6074d87 100644 --- a/src/add/add.ts +++ b/src/add/add.ts @@ -9,6 +9,8 @@ import { readFile, stat } from 'node:fs/promises' import { RPC_URLS } from '@filoz/synapse-sdk' import pc from 'picocolors' import pino from 'pino' +import { warnAboutCDNPricingLimitations } from '../common/cdn-warning.js' +import { envToBool } from '../common/env-vars.js' import { displayUploadResults, performUpload, validatePaymentSetup } from '../common/upload-flow.js' import { cleanupSynapseService, @@ -71,6 +73,17 @@ export async function runAdd(options: AddOptions): Promise { level: process.env.LOG_LEVEL || 'error', }) + // Check CDN status and warn if enabled + const withCDN = envToBool(process.env.WITH_CDN, false) + if (withCDN) { + const proceed = await warnAboutCDNPricingLimitations() + if (!proceed) { + cancel('Add cancelled') + process.exitCode = 1 + throw new Error('CDN pricing limitations warning cancelled') + } + } + let tempCarPath: string | undefined try { diff --git a/src/common/cdn-warning.ts b/src/common/cdn-warning.ts new file mode 100644 index 0000000..0a803dc --- /dev/null +++ b/src/common/cdn-warning.ts @@ -0,0 +1,28 @@ +import { cancel, confirm } from '@clack/prompts' +import pc from 'picocolors' +import { log } from '../utils/cli-logger.js' + +export async function warnAboutCDNPricingLimitations(): Promise { + log.warn(pc.red('CDN Pricing Notice')) + log.newline() + log.line('Filecoin-pin currently does not support CDN pricing in payment calculations.') + log.newline() + log.line('This means:') + log.indent('• Deposit calculations may not be accurate for CDN storage') + log.indent('• You may need additional USDFC deposits for CDN-enabled uploads') + log.indent('• Filcdn is transitioning to egress-based billing (from fixed fees)') + log.newline() + log.flush() + + const shouldProceed = await confirm({ + message: 'Do you want to proceed with CDN-enabled upload?', + initialValue: false, + }) + + if (shouldProceed === null) { + cancel('Operation cancelled') + process.exitCode = 1 + } + + return Boolean(shouldProceed) +} diff --git a/src/common/env-vars.ts b/src/common/env-vars.ts new file mode 100644 index 0000000..1f55a71 --- /dev/null +++ b/src/common/env-vars.ts @@ -0,0 +1,11 @@ +/** + * Generic helpers for environment variable parsing and validation. + */ + +export const envToBool = (value: string | undefined, defaultValue: boolean): boolean => { + if (value === undefined) return defaultValue + const normalized = value.trim().toLowerCase() + if (['1', 'true', 'yes', 'on'].includes(normalized)) return true + if (['0', 'false', 'no', 'off'].includes(normalized)) return false + return defaultValue +} diff --git a/src/import/import.ts b/src/import/import.ts index d3e5c59..0c78299 100644 --- a/src/import/import.ts +++ b/src/import/import.ts @@ -12,6 +12,8 @@ import { CarReader } from '@ipld/car' import { CID } from 'multiformats/cid' import pc from 'picocolors' import pino from 'pino' +import { warnAboutCDNPricingLimitations } from '../common/cdn-warning.js' +import { envToBool } from '../common/env-vars.js' import { displayUploadResults, performUpload, validatePaymentSetup } from '../common/upload-flow.js' import { cleanupSynapseService, @@ -130,6 +132,17 @@ export async function runCarImport(options: ImportOptions): Promise