Skip to content

Commit 51c642e

Browse files
committed
refactor(sdk): rename StorageInfo → ServiceInfo, restructure pricing
- Rename getStorageInfo() → getServiceInfo() - Restructure pricing fields for clarity - Simplify allowance checks Fixes: #360
1 parent a5c428c commit 51c642e

File tree

9 files changed

+138
-203
lines changed

9 files changed

+138
-203
lines changed

docs/src/content/docs/guides/storage.mdx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,11 @@ Deletion of individual pieces is not supported at this time but is on the roadma
286286
Get comprehensive information about the storage service:
287287

288288
```typescript
289-
// Get storage service info including pricing and providers
290-
const info = await synapse.getStorageInfo()
291-
console.log('Price per TiB/month:', info.pricing.noCDN.perTiBPerMonth)
289+
// Get service information including pricing and providers
290+
const info = await synapse.storage.getServiceInfo()
291+
console.log('Storage price per TiB/month:', info.pricing.storagePricePerTiBPerMonth)
292+
console.log('CDN egress price per TiB:', info.pricing.cdnEgressPricePerTiB)
293+
console.log('Minimum price per month:', info.pricing.minimumPricePerMonth)
292294
console.log('Available providers:', info.providers.length)
293295
console.log('Network:', info.serviceParameters.network)
294296

docs/src/content/docs/intro/getting-started.mdx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -651,9 +651,11 @@ The SDK batches up to 32 uploads by default (configurable via `uploadBatchSize`)
651651
Get comprehensive information about the storage service:
652652

653653
```typescript
654-
// Get storage service info including pricing and providers
655-
const info = await synapse.getStorageInfo()
656-
console.log('Price per TiB/month:', info.pricing.noCDN.perTiBPerMonth)
654+
// Get service information including pricing and providers
655+
const info = await synapse.storage.getServiceInfo()
656+
console.log('Storage price per TiB/month:', info.pricing.storagePricePerTiBPerMonth)
657+
console.log('CDN egress price per TiB:', info.pricing.cdnEgressPricePerTiB)
658+
console.log('Minimum price per month:', info.pricing.minimumPricePerMonth)
657659
console.log('Available providers:', info.providers.length)
658660
console.log('Network:', info.serviceParameters.network)
659661

packages/synapse-sdk/src/storage/manager.ts

Lines changed: 24 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ import type {
3232
PieceRetriever,
3333
PreflightInfo,
3434
ProviderInfo,
35+
ServiceInfo,
3536
StorageContextCallbacks,
36-
StorageInfo,
3737
StorageServiceOptions,
3838
UploadCallbacks,
3939
UploadResult,
@@ -367,14 +367,12 @@ export class StorageManager {
367367
}
368368

369369
/**
370-
* Get comprehensive information about the storage service including
371-
* approved providers, pricing, contract addresses, and current allowances
372-
* @returns Complete storage service information
370+
* Get service information including pricing, providers, and configuration
371+
* @returns Service information with pricing, approved providers, and contract addresses
373372
*/
374-
async getStorageInfo(): Promise<StorageInfo> {
373+
async getServiceInfo(): Promise<ServiceInfo> {
375374
try {
376-
// Helper function to get allowances with error handling
377-
const getOptionalAllowances = async (): Promise<StorageInfo['allowances']> => {
375+
const getOptionalAllowances = async (): Promise<ServiceInfo['allowances']> => {
378376
try {
379377
const warmStorageAddress = this._synapse.getWarmStorageAddress()
380378
const approval = await this._synapse.payments.serviceApproval(warmStorageAddress, TOKENS.USDFC)
@@ -388,79 +386,58 @@ export class StorageManager {
388386
lockupUsed: approval.lockupUsed,
389387
}
390388
} catch {
391-
// Return null if wallet not connected or any error occurs
392389
return null
393390
}
394391
}
395392

396-
// Create SPRegistryService to get providers
397393
const registryAddress = this._warmStorageService.getServiceProviderRegistryAddress()
398394
const spRegistry = new SPRegistryService(this._synapse.getProvider(), registryAddress)
399395

400-
// Fetch all data in parallel for performance
401396
const [pricingData, approvedIds, allowances] = await Promise.all([
402397
this._warmStorageService.getServicePrice(),
403398
this._warmStorageService.getApprovedProviderIds(),
404399
getOptionalAllowances(),
405400
])
406401

407-
// Get provider details for approved IDs
408402
const providers = await spRegistry.getProviders(approvedIds)
409-
410-
// Calculate pricing per different time units
411-
const epochsPerMonth = BigInt(pricingData.epochsPerMonth)
412-
413-
// TODO: StorageInfo needs updating to reflect that CDN costs are usage-based
414-
415-
// Calculate per-epoch pricing (base storage cost)
416-
const noCDNPerEpoch = BigInt(pricingData.pricePerTiBPerMonthNoCDN) / epochsPerMonth
417-
// CDN costs are usage-based (egress charges), so base storage cost is the same
418-
const withCDNPerEpoch = BigInt(pricingData.pricePerTiBPerMonthNoCDN) / epochsPerMonth
419-
420-
// Calculate per-day pricing (base storage cost)
421-
const noCDNPerDay = BigInt(pricingData.pricePerTiBPerMonthNoCDN) / TIME_CONSTANTS.DAYS_PER_MONTH
422-
// CDN costs are usage-based (egress charges), so base storage cost is the same
423-
const withCDNPerDay = BigInt(pricingData.pricePerTiBPerMonthNoCDN) / TIME_CONSTANTS.DAYS_PER_MONTH
424-
425-
// Filter out providers with zero addresses
426403
const validProviders = providers.filter((p: ProviderInfo) => p.serviceProvider !== ethers.ZeroAddress)
427404

428-
const network = this._synapse.getNetwork()
429-
430405
return {
431406
pricing: {
432-
noCDN: {
433-
perTiBPerMonth: BigInt(pricingData.pricePerTiBPerMonthNoCDN),
434-
perTiBPerDay: noCDNPerDay,
435-
perTiBPerEpoch: noCDNPerEpoch,
436-
},
437-
// CDN costs are usage-based (egress charges), base storage cost is the same
438-
withCDN: {
439-
perTiBPerMonth: BigInt(pricingData.pricePerTiBPerMonthNoCDN),
440-
perTiBPerDay: withCDNPerDay,
441-
perTiBPerEpoch: withCDNPerEpoch,
442-
},
407+
storagePricePerTiBPerMonth: pricingData.pricePerTiBPerMonthNoCDN,
408+
minimumPricePerMonth: pricingData.minimumPricePerMonth,
409+
cdnEgressPricePerTiB: pricingData.pricePerTiBCdnEgress,
410+
cacheMissEgressPricePerTiB: pricingData.pricePerTiBCacheMissEgress,
443411
tokenAddress: pricingData.tokenAddress,
444-
tokenSymbol: 'USDFC', // Hardcoded as we know it's always USDFC
412+
tokenSymbol: 'USDFC',
445413
},
446414
providers: validProviders,
447415
serviceParameters: {
448-
network,
449-
epochsPerMonth,
416+
network: this._synapse.getNetwork(),
417+
epochsPerMonth: pricingData.epochsPerMonth,
450418
epochsPerDay: TIME_CONSTANTS.EPOCHS_PER_DAY,
451419
epochDuration: TIME_CONSTANTS.EPOCH_DURATION,
452420
minUploadSize: SIZE_CONSTANTS.MIN_UPLOAD_SIZE,
453421
maxUploadSize: SIZE_CONSTANTS.MAX_UPLOAD_SIZE,
454422
warmStorageAddress: this._synapse.getWarmStorageAddress(),
455423
paymentsAddress: this._warmStorageService.getPaymentsAddress(),
456424
pdpVerifierAddress: this._warmStorageService.getPDPVerifierAddress(),
425+
serviceProviderRegistryAddress: this._warmStorageService.getServiceProviderRegistryAddress(),
426+
sessionKeyRegistryAddress: this._warmStorageService.getSessionKeyRegistryAddress(),
457427
},
458428
allowances,
459429
}
460430
} catch (error) {
461-
throw new Error(
462-
`Failed to get storage service information: ${error instanceof Error ? error.message : String(error)}`
463-
)
431+
throw new Error(`Failed to get service information: ${error instanceof Error ? error.message : String(error)}`)
464432
}
465433
}
434+
435+
/**
436+
* Get service information including pricing, providers, and configuration
437+
* @deprecated Use getServiceInfo() instead
438+
* @returns Service information with pricing, approved providers, and contract addresses
439+
*/
440+
async getStorageInfo(): Promise<ServiceInfo> {
441+
return await this.getServiceInfo()
442+
}
466443
}

packages/synapse-sdk/src/synapse.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import type {
1717
PieceCID,
1818
PieceRetriever,
1919
ProviderInfo,
20-
StorageInfo,
2120
StorageServiceOptions,
2221
SubgraphConfig,
2322
SynapseOptions,
@@ -461,15 +460,4 @@ export class Synapse {
461460
throw new Error(`Failed to get provider info: ${error instanceof Error ? error.message : String(error)}`)
462461
}
463462
}
464-
465-
/**
466-
* Get comprehensive information about the storage service including
467-
* approved providers, pricing, contract addresses, and current allowances
468-
* @deprecated Use synapse.storage.getStorageInfo() instead. This method will be removed in a future version.
469-
* @returns Complete storage service information
470-
*/
471-
async getStorageInfo(): Promise<StorageInfo> {
472-
console.warn('synapse.getStorageInfo() is deprecated. Use synapse.storage.getStorageInfo() instead.')
473-
return await this._storageManager.getStorageInfo()
474-
}
475463
}

packages/synapse-sdk/src/test/synapse.test.ts

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -584,41 +584,43 @@ describe('Synapse', () => {
584584
})
585585
})
586586

587-
describe('getStorageInfo', () => {
588-
it('should return comprehensive storage information', async () => {
587+
describe('getServiceInfo', () => {
588+
it('should return comprehensive service information', async () => {
589589
server.use(JSONRPC({ ...presets.basic }))
590590

591591
const synapse = await Synapse.create({ signer })
592-
const storageInfo = await synapse.getStorageInfo()
592+
const serviceInfo = await synapse.storage.getServiceInfo()
593593

594594
// Check pricing
595-
assert.exists(storageInfo.pricing)
596-
assert.exists(storageInfo.pricing.noCDN)
597-
assert.exists(storageInfo.pricing.withCDN)
595+
assert.exists(serviceInfo.pricing)
596+
assert.exists(serviceInfo.pricing.storagePricePerTiBPerMonth)
597+
assert.exists(serviceInfo.pricing.minimumPricePerMonth)
598+
assert.exists(serviceInfo.pricing.cdnEgressPricePerTiB)
599+
assert.exists(serviceInfo.pricing.cacheMissEgressPricePerTiB)
598600

599-
// Verify pricing calculations (2 USDFC per TiB per month)
600-
const expectedNoCDNMonthly = parseUnits('2', 18) // 2 USDFC
601-
assert.equal(storageInfo.pricing.noCDN.perTiBPerMonth, expectedNoCDNMonthly)
601+
// Verify pricing (2 USDFC per TiB per month)
602+
const expectedStorageMonthly = parseUnits('2', 18) // 2 USDFC
603+
assert.equal(serviceInfo.pricing.storagePricePerTiBPerMonth, expectedStorageMonthly)
602604

603605
// Check providers
604-
assert.equal(storageInfo.providers.length, 2)
605-
assert.equal(storageInfo.providers[0].serviceProvider, ADDRESSES.serviceProvider1)
606-
assert.equal(storageInfo.providers[1].serviceProvider, ADDRESSES.serviceProvider2)
606+
assert.equal(serviceInfo.providers.length, 2)
607+
assert.equal(serviceInfo.providers[0].serviceProvider, ADDRESSES.serviceProvider1)
608+
assert.equal(serviceInfo.providers[1].serviceProvider, ADDRESSES.serviceProvider2)
607609

608610
// Check service parameters
609-
assert.equal(storageInfo.serviceParameters.network, 'calibration')
610-
assert.equal(storageInfo.serviceParameters.epochsPerMonth, 86400n)
611-
assert.equal(storageInfo.serviceParameters.epochsPerDay, 2880n)
612-
assert.equal(storageInfo.serviceParameters.epochDuration, 30)
613-
assert.equal(storageInfo.serviceParameters.minUploadSize, 127)
614-
assert.equal(storageInfo.serviceParameters.maxUploadSize, 200 * 1024 * 1024)
611+
assert.equal(serviceInfo.serviceParameters.network, 'calibration')
612+
assert.equal(serviceInfo.serviceParameters.epochsPerMonth, 86400n)
613+
assert.equal(serviceInfo.serviceParameters.epochsPerDay, 2880n)
614+
assert.equal(serviceInfo.serviceParameters.epochDuration, 30)
615+
assert.equal(serviceInfo.serviceParameters.minUploadSize, 127)
616+
assert.equal(serviceInfo.serviceParameters.maxUploadSize, 200 * 1024 * 1024)
615617

616-
// Check allowances (including operator approval flag)
617-
assert.exists(storageInfo.allowances)
618-
assert.equal(storageInfo.allowances?.isApproved, true)
619-
assert.equal(storageInfo.allowances?.service, ADDRESSES.calibration.warmStorage)
620-
assert.equal(storageInfo.allowances?.rateAllowance, 1000000n)
621-
assert.equal(storageInfo.allowances?.lockupAllowance, 10000000n)
618+
// Check allowances
619+
assert.exists(serviceInfo.allowances)
620+
assert.equal(serviceInfo.allowances?.isApproved, true)
621+
assert.equal(serviceInfo.allowances?.service, ADDRESSES.calibration.warmStorage)
622+
assert.equal(serviceInfo.allowances?.rateAllowance, 1000000n)
623+
assert.equal(serviceInfo.allowances?.lockupAllowance, 10000000n)
622624
})
623625

624626
it('should handle missing allowances gracefully', async () => {
@@ -632,13 +634,13 @@ describe('Synapse', () => {
632634
)
633635

634636
const synapse = await Synapse.create({ signer })
635-
const storageInfo = await synapse.getStorageInfo()
637+
const serviceInfo = await synapse.storage.getServiceInfo()
636638

637639
// Should still return data with null allowances
638-
assert.exists(storageInfo.pricing)
639-
assert.exists(storageInfo.providers)
640-
assert.exists(storageInfo.serviceParameters)
641-
assert.deepEqual(storageInfo.allowances, {
640+
assert.exists(serviceInfo.pricing)
641+
assert.exists(serviceInfo.providers)
642+
assert.exists(serviceInfo.serviceParameters)
643+
assert.deepEqual(serviceInfo.allowances, {
642644
isApproved: false,
643645
service: ADDRESSES.calibration.warmStorage,
644646
rateAllowance: 0n,
@@ -717,11 +719,11 @@ describe('Synapse', () => {
717719
)
718720

719721
const synapse = await Synapse.create({ signer })
720-
const storageInfo = await synapse.getStorageInfo()
722+
const serviceInfo = await synapse.storage.getServiceInfo()
721723

722724
// Should filter out zero address provider
723-
assert.equal(storageInfo.providers.length, 1)
724-
assert.equal(storageInfo.providers[0].serviceProvider, ADDRESSES.serviceProvider1)
725+
assert.equal(serviceInfo.providers.length, 1)
726+
assert.equal(serviceInfo.providers[0].serviceProvider, ADDRESSES.serviceProvider1)
725727
})
726728

727729
it('should handle contract call failures', async () => {
@@ -738,7 +740,7 @@ describe('Synapse', () => {
738740
)
739741
try {
740742
const synapse = await Synapse.create({ signer })
741-
await synapse.getStorageInfo()
743+
await synapse.storage.getServiceInfo()
742744
assert.fail('Should have thrown')
743745
} catch (error: any) {
744746
// The error should bubble up from the contract call

packages/synapse-sdk/src/test/warm-storage-service.test.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -673,22 +673,11 @@ describe('WarmStorageService', () => {
673673
const costs = await warmStorageService.calculateStorageCost(sizeInBytes)
674674

675675
assert.exists(costs.perEpoch)
676-
assert.exists(costs.perDay)
677676
assert.exists(costs.perMonth)
678-
assert.exists(costs.withCDN)
679-
assert.exists(costs.withCDN.perEpoch)
680-
assert.exists(costs.withCDN.perDay)
681-
assert.exists(costs.withCDN.perMonth)
682677

683678
// Verify costs are reasonable
684679
assert.isTrue(costs.perEpoch > 0n)
685-
assert.isTrue(costs.perDay > costs.perEpoch)
686-
assert.isTrue(costs.perMonth > costs.perDay)
687-
688-
// CDN costs are usage-based (egress pricing), so withCDN equals base storage cost
689-
assert.equal(costs.withCDN.perEpoch, costs.perEpoch)
690-
assert.equal(costs.withCDN.perDay, costs.perDay)
691-
assert.equal(costs.withCDN.perMonth, costs.perMonth)
680+
assert.isTrue(costs.perMonth > costs.perEpoch)
692681
})
693682

694683
it('should scale costs linearly with size', async () => {
@@ -707,9 +696,7 @@ describe('WarmStorageService', () => {
707696
const ratio = Number(costs10GiB.perEpoch) / Number(costs1GiB.perEpoch)
708697
assert.closeTo(ratio, 10, 0.01)
709698

710-
// Verify the relationship holds for day and month calculations
711-
assert.equal(costs10GiB.perDay.toString(), (costs10GiB.perEpoch * 2880n).toString())
712-
// For month calculation, allow for rounding errors due to integer division
699+
// Verify the relationship holds for month calculation
713700
const expectedMonth = costs10GiB.perEpoch * TIME_CONSTANTS.EPOCHS_PER_MONTH
714701
const monthRatio = Number(costs10GiB.perMonth) / Number(expectedMonth)
715702
assert.closeTo(monthRatio, 1, 0.0001) // Allow 0.01% difference due to rounding

0 commit comments

Comments
 (0)